Merge tag 'MMI-T2SN33.73-22-3' of https://github.com/MotorolaMobilityLLC/kernel-msm-techpack-display into lineage-20
"Devon push for Android 13" * tag 'MMI-T2SN33.73-22-3' of https://github.com/MotorolaMobilityLLC/kernel-msm-techpack-display: Revert "disp: msm: use vzalloc for large allocations" disp/msm/dsi:enabel ESD te check for video panel disp/msm/dsi:support to config glbl_hstx_str_ctrl_0 for mipi driver strength disp: msm: use vzalloc for large allocations disp: msm: sde: fix RM poll timeouts during PM suspend/resume usecase disp: msm: avoid BW down vote after splash memory release disp: msm: dsi: Only enable lanes required during phy enable disp: msm: sde: while timing engine enabling poll for active region [PATCH] disp: msm: sde: remove panic from autorefresh disable sequence drm/dsi_panel: send specific demura command when bl change drm/msm/dsi-staging: add default brightness property kernel/display:hawao+oled:change lcm timing HAWAO+OLED: solve mipi driver strength weak problem kernel/display:hawao+oled:change lcm timing Revert "HAWAO+OLED:solve mipi driver strength weak problem" HAWAO+OLED: solve mipi driver strength weak problem disp: msm: Fixing motUtil tool for ACL feature drm: Add the panel color feature for game mode drm: Add the DC panel param feature display: Modify the lcd reset gpio pin. Fix: display blinking issue propagation: panel: add ft8006s special reset timing control display: support ft8006s panel brightness level special align [Guam NA] Fix propagation error in dsi_display.c kernel:dsi: ESD te support for video mode panel kernel:dsi: backlight update for hbm gpio kernel:dsi: backlight update for hbm gpio kernel: dsi: rst pull down config update kernel: dsi: tp_rst seq update kernel: dsi: enable tp_rst & esd fail logs Capri beingup kernel: dsi: add new backlight device to avoid conflict kernel: dsi: download touch firmware after panel reset msm/dsi: add panel tp rst configs kernel: dsi: pull down reset pin when shutdown dsi: add new backlight control type I2C drm/msm/sde: limit the backlight min brightness as bl_min_level Kernel: read panel supplier from device tree disp: msm: Parsing and store panel's 0xDA register info dsi_panel: fix out-of-bounds issue backlight: support device hbm use 51 cmd backlight: add hbm gpio control driver msm/dsi: add backlight and hbm debug log msm/dsi: set brightness at maximum if enabling LCD HBM dsi_panel: Check the return status of the touch screen drm/panel_param: optimize the code Display PanelMode: Add CABC control msm: dsi_panel: refresh rate config option msm: dsi_panel: refresh rate config option disp: msm: Correct DSC 1.1 Rate control for Max val dsi: pushing display notifications Revert"disp:msm:sde: update splash resource allocation for dual display" disp: msm: Restore old backlight setting after exitting HBM disp: msm:: reset the param value to the default value disp: msm: support for HBM_FOD mode disp: msm: add display frequency change notification Revert "Revert "disp: msm: sde: update splash resource allocation for dual display"" Kernel/Display: mot extend code: get lcd para Kernel/display: mot extend - early power Kernel: Add Moto extern display code disp: msm: implement xxx-hbm-is-51cmd dts entry disp: msm: fix checking returned value of xx_cmd_transfer disp: msm: Register for reboot_notifier disp: msm: Support ACL when setting panel param disp: msm: Enable "val" to control HBM property disp: msm: dsi: Reducing logging in dsi_panel.c disp: msm: dsi: Add print info for DSI_CTRL disp: msm : Add the ACL panel param feature disp: msm: Populate the passing panel's info from BL. disp: msm: Set panel enable_status during probing disp: msm: Add panel name to enable status API disp: msm: Report panel's probe status disp: msm: provide API to query for panel enable state disp: msm: Correct the panel's LP11_INIT disp: msm: Adding KMS property testing for motUtil tool disp: msm: add panel's param feature to display FW disp: msm: Provide a dynamic method to disable the ESD. disp: msm: Add DispUtil tool to motUtil Debugfs disp: msm: sde: Add motUtil Debugfs framework disp: msm: dsi: Raise BUG for continous panel recovery failure disp: msm: dsi: Trigger ESD event if display isn't on disp: msm: dsi: Check panel's power_mode during resume disp: msm: dsi: parsing BL setting ESD and panel disp: msm: sde: Change display ESD checking interval to 8s disp: msm: dsi: add prints for DSI/panel turning off/on disp: msm: dsi: Add "bl_ctrl_dummy" to panel bl type disp: msm: dsi: Add support display 2bytes brightness. guam: input add drm support input add touch support disp: msm: sde: synx: Add quic copyright disp: msm: sde: handle partial update transitions in rounded corner. Revert "disp: msm: sde: handle partial update transitions in rounded corner". disp: msm: sde: handle partial update transitions in rounded corner disp: msm: sde: clear partial update mask during last close Conflicts: techpack/display/msm/msm_drv.c techpack/display/msm/msm_drv.h Change-Id: I40dab2ee196d87f2d24439d5b4e7c4cd14b7051d
This commit is contained in:
27 files changed
+4149
-67
No files matched your search
@@ -11,3 +11,4 @@ export CONFIG_QCOM_MDSS_PLL=y
|
||||
export CONFIG_MSM_SDE_ROTATOR=y
|
||||
export CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
|
||||
export CONFIG_DRM_SDE_RSC=y
|
||||
export CONFIG_DRM_DYNAMIC_REFRESH_RATE=y
|
||||
@@ -17,3 +17,4 @@
|
||||
#define CONFIG_MSM_SDE_ROTATOR 1
|
||||
#define CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG 1
|
||||
#define CONFIG_DRM_SDE_RSC 1
|
||||
#define CONFIG_DRM_DYNAMIC_REFRESH_RATE 1
|
||||
@@ -32,6 +32,7 @@ msm_drm-$(CONFIG_DRM_MSM_SDE) += sde/sde_crtc.o \
|
||||
sde/sde_core_perf.o \
|
||||
sde/sde_rm.o \
|
||||
sde/sde_kms_utils.o \
|
||||
sde/sde_motUtil.o \
|
||||
sde/sde_kms.o \
|
||||
sde/sde_plane.o \
|
||||
sde/sde_connector.o \
|
||||
@@ -100,6 +101,7 @@ msm_drm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi_phy.o \
|
||||
dsi/dsi_panel.o \
|
||||
dsi/dsi_clk_manager.o \
|
||||
dsi/dsi_display_test.o \
|
||||
dsi/dsi_display_mot_ext.o \
|
||||
|
||||
msm_drm-$(CONFIG_DSI_PARSER) += dsi/dsi_parser.o \
|
||||
|
||||
|
||||
@@ -281,6 +281,27 @@ enum dsi_dyn_clk_feature_type {
|
||||
* @DSI_CMD_SET_POST_TIMING_SWITCH: Post timing switch
|
||||
* @DSI_CMD_SET_QSYNC_ON Enable qsync mode
|
||||
* @DSI_CMD_SET_QSYNC_OFF Disable qsync mode
|
||||
* @DSI_CMD_SET_HBM_FOD_ON: Turning HBM_FOD on
|
||||
* @DSI_CMD_SET_HBM_ON: Turning HBM on
|
||||
* @DSI_CMD_SET_HBM_OFF: Turning HBM off
|
||||
* @DSI_CMD_SET_ACL_ON: Turning ACL on
|
||||
* @DSI_CMD_SET_ACL_OFF: Turning ACL off
|
||||
* @DSI_CMD_SET_CABC_UI: CABC UI mode
|
||||
* @DSI_CMD_SET_CABC_MV: CABC MV mode
|
||||
* @DSI_CMD_SET_CABC_DIS: CABC DIS mode
|
||||
* @DSI_CMD_SET_DC_ON: DC mode on
|
||||
* @DSI_CMD_SET_DC_OFF: DC mode off
|
||||
* @DSI_CMD_SET_COLOR_VBT : COLOR VBT mode
|
||||
* @DSI_CMD_SET_COLOR_STD: COLOR STD mode
|
||||
* @DSI_CMD_SET_COLOR_GAME : COLOR GAME mode
|
||||
* @DSI_CMD_SET_COLOR_NONE: COLOR NONE mode
|
||||
* @DSI_CMD_SET_BRIGHTNESS_1E: Send demura codes when brightness changes to 0-1E
|
||||
* @DSI_CMD_SET_BRIGHTNESS_1FD: Send demura codes when brightness changes to 1F-1FD
|
||||
* @DSI_CMD_SET_BRIGHTNESS_2FF: Send demura codes when brightness changes to 1FE-2FF
|
||||
* @DSI_CMD_SET_BRIGHTNESS_3FF: Send demura codes when brightness changes to 300-3FF
|
||||
* @DSI_CMD_SET_BRIGHTNESS_4FF: Send demura codes when brightness changes to 400-4FF
|
||||
* @DSI_CMD_SET_BRIGHTNESS_5FF: Send demura codes when brightness changes to 500-5FF
|
||||
* @DSI_CMD_SET_BRIGHTNESS_FFF: Send demura codes when brightness changes to 600-FFF
|
||||
* @DSI_CMD_SET_MAX
|
||||
*/
|
||||
enum dsi_cmd_set_type {
|
||||
@@ -307,6 +328,27 @@ enum dsi_cmd_set_type {
|
||||
DSI_CMD_SET_POST_TIMING_SWITCH,
|
||||
DSI_CMD_SET_QSYNC_ON,
|
||||
DSI_CMD_SET_QSYNC_OFF,
|
||||
DSI_CMD_SET_HBM_FOD_ON,
|
||||
DSI_CMD_SET_HBM_ON,
|
||||
DSI_CMD_SET_HBM_OFF,
|
||||
DSI_CMD_SET_ACL_ON,
|
||||
DSI_CMD_SET_ACL_OFF,
|
||||
DSI_CMD_SET_CABC_UI,
|
||||
DSI_CMD_SET_CABC_MV,
|
||||
DSI_CMD_SET_CABC_DIS,
|
||||
DSI_CMD_SET_DC_ON,
|
||||
DSI_CMD_SET_DC_OFF,
|
||||
DSI_CMD_SET_COLOR_VBT,
|
||||
DSI_CMD_SET_COLOR_STD,
|
||||
DSI_CMD_SET_COLOR_GAME,
|
||||
DSI_CMD_SET_COLOR_NONE,
|
||||
DSI_CMD_SET_BRIGHTNESS_1E,
|
||||
DSI_CMD_SET_BRIGHTNESS_1FD,
|
||||
DSI_CMD_SET_BRIGHTNESS_2FF,
|
||||
DSI_CMD_SET_BRIGHTNESS_3FF,
|
||||
DSI_CMD_SET_BRIGHTNESS_4FF,
|
||||
DSI_CMD_SET_BRIGHTNESS_5FF,
|
||||
DSI_CMD_SET_BRIGHTNESS_FFF,
|
||||
DSI_CMD_SET_MAX
|
||||
};
|
||||
|
||||
|
||||
@@ -45,6 +45,10 @@ static const struct of_device_id dsi_display_dt_match[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static int dsi_display_enable_status (struct dsi_display *display, bool enable);
|
||||
static void dsi_display_is_probed(struct dsi_display *display,
|
||||
int probe_status);
|
||||
|
||||
static void dsi_display_mask_ctrl_error_interrupts(struct dsi_display *display,
|
||||
u32 mask, bool enable)
|
||||
{
|
||||
@@ -246,6 +250,28 @@ error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int dsi_display_set_param(void *display, struct msm_param_info *param_info)
|
||||
{
|
||||
struct dsi_display *dsi_display = display;
|
||||
struct dsi_panel *panel;
|
||||
int rc = 0;
|
||||
|
||||
if (dsi_display == NULL || dsi_display->panel == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
panel = dsi_display->panel;
|
||||
|
||||
DSI_DEBUG("%s+\n", __func__);
|
||||
if (!dsi_panel_initialized(panel))
|
||||
return -EINVAL;
|
||||
|
||||
rc = dsi_panel_set_param(panel, param_info);
|
||||
if (rc)
|
||||
DSI_ERR("[%s] failed to panel to set param. rc=%d\n",
|
||||
dsi_display->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dsi_display_cmd_engine_enable(struct dsi_display *display)
|
||||
{
|
||||
int rc = 0;
|
||||
@@ -697,6 +723,40 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int dsi_display_cmd_mipi_transfer(struct dsi_display *display,
|
||||
struct mipi_dsi_msg *msg,
|
||||
u32 flags)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dsi_display_ctrl *m_ctrl;
|
||||
|
||||
m_ctrl = &display->ctrl[display->cmd_master_idx];
|
||||
|
||||
if (display->tx_cmd_buf == NULL) {
|
||||
rc = dsi_host_alloc_cmd_tx_buffer(display);
|
||||
if (rc) {
|
||||
DSI_ERR("failed to allocate cmd tx buffer memory\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
rc = dsi_display_cmd_engine_enable(display);
|
||||
if (rc) {
|
||||
DSI_ERR("cmd engine enable failed\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
flags |= DSI_CTRL_CMD_FETCH_MEMORY | DSI_CTRL_CMD_CUSTOM_DMA_SCHED;
|
||||
rc = dsi_ctrl_cmd_transfer(m_ctrl->ctrl, msg, &flags);
|
||||
if (((flags & DSI_CTRL_CMD_READ) && rc <= 0) ||
|
||||
(!(flags & DSI_CTRL_CMD_READ) && rc))
|
||||
DSI_ERR("failed to transfer cmd. rc = %d\n", rc);
|
||||
|
||||
dsi_display_cmd_engine_disable(display);
|
||||
done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dsi_display_status_reg_read(struct dsi_display *display)
|
||||
{
|
||||
int rc = 0, i;
|
||||
@@ -777,6 +837,21 @@ static int dsi_display_status_check_te(struct dsi_display *display)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dsi_display_status_check_te_video(struct dsi_display *display)
|
||||
{
|
||||
int rc = 1;
|
||||
struct dsi_panel *panel = display->panel;
|
||||
|
||||
if((panel->video_te_count - panel->video_te_count_priv) > 1) {
|
||||
panel->video_te_count_priv = panel->video_te_count;
|
||||
} else {
|
||||
DSI_ERR("%s: video TE check ERROR te_count %d, priv =%d\n", __func__, panel->video_te_count, panel->video_te_count_priv);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int dsi_display_check_status(struct drm_connector *connector, void *display,
|
||||
bool te_check_override)
|
||||
{
|
||||
@@ -835,6 +910,8 @@ int dsi_display_check_status(struct drm_connector *connector, void *display,
|
||||
rc = dsi_display_status_reg_read(dsi_display);
|
||||
} else if (status_mode == ESD_MODE_SW_BTA) {
|
||||
rc = dsi_display_status_bta_request(dsi_display);
|
||||
} else if (status_mode == ESD_MODE_PANEL_TE_VIDEO) {
|
||||
rc = dsi_display_status_check_te_video(dsi_display);
|
||||
} else if (status_mode == ESD_MODE_PANEL_TE) {
|
||||
rc = dsi_display_status_check_te(dsi_display);
|
||||
} else {
|
||||
@@ -864,6 +941,19 @@ release_panel_lock:
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool dsi_display_force_esd_disable(void *display)
|
||||
{
|
||||
struct dsi_display *dsi_display = display;
|
||||
struct dsi_panel *panel;
|
||||
|
||||
if (dsi_display == NULL)
|
||||
return false;
|
||||
|
||||
panel = dsi_display->panel;
|
||||
|
||||
return (panel->esd_utag_enable? false: true);
|
||||
}
|
||||
|
||||
static int dsi_display_cmd_prepare(const char *cmd_buf, u32 cmd_buf_len,
|
||||
struct dsi_cmd_desc *cmd, u8 *payload, u32 payload_len)
|
||||
{
|
||||
@@ -894,6 +984,166 @@ static int dsi_display_cmd_prepare(const char *cmd_buf, u32 cmd_buf_len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int dsi_display_dispUtil_get_datatype (char dsi_cmd, u8 cmd_type,
|
||||
size_t tx_len, u8 *tx_data_type)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
*tx_data_type = 0;
|
||||
|
||||
/* cmd_type = 0 : DSI DCS cmd;
|
||||
* cmd_type = 1 : DSI Generic cmd */
|
||||
if (cmd_type > DISPUTIL_DSI_GENERIC) {
|
||||
DSI_ERR("%s: Invalid DSI package type[%d] = 0x%x\n",
|
||||
__func__, DISPUTIL_MIPI_CMD_TYPE,
|
||||
cmd_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DSI_DEBUG("dsi_cmd =0x%x cmd_type=0x%x tx_len=0x%x\n",
|
||||
dsi_cmd, cmd_type, (u32)tx_len);
|
||||
|
||||
if (dsi_cmd == DISPUTIL_DSI_WRITE) {
|
||||
/* This is a DSI write command */
|
||||
switch(tx_len) {
|
||||
case 1:
|
||||
if (cmd_type == DISPUTIL_DSI_GENERIC)
|
||||
/* write, generic, no param */
|
||||
*tx_data_type = 0x3;
|
||||
else if (cmd_type == DISPUTIL_DSI_DCS)
|
||||
/* write, DCS, no param */
|
||||
*tx_data_type = 0x5;
|
||||
break;
|
||||
case 2:
|
||||
if (cmd_type == DISPUTIL_DSI_GENERIC)
|
||||
/* Write, generic, 1 param */
|
||||
*tx_data_type = 0x13;
|
||||
else if (cmd_type == DISPUTIL_DSI_DCS)
|
||||
/* write, DCS, 1 param */
|
||||
*tx_data_type = 0x15;
|
||||
break;
|
||||
default:
|
||||
if (cmd_type == DISPUTIL_DSI_GENERIC)
|
||||
/* Write, generic, long*/
|
||||
*tx_data_type = 0x29;
|
||||
else if (cmd_type == DISPUTIL_DSI_DCS)
|
||||
/* write, DCS, long*/
|
||||
*tx_data_type = 0x39;
|
||||
break;
|
||||
}
|
||||
} else if (dsi_cmd == DISPUTIL_DSI_READ) {
|
||||
if ((cmd_type == DISPUTIL_DSI_DCS) && (tx_len > 1)) {
|
||||
/* Note: tx_len will include read command and payload */
|
||||
/* DCS read */
|
||||
DSI_ERR("DCS read supports no parameter. tx_len=%d\n",
|
||||
(u32)tx_len);
|
||||
rc = -EINVAL;
|
||||
} else {
|
||||
switch(tx_len) {
|
||||
case 1:
|
||||
if (cmd_type == DISPUTIL_DSI_GENERIC)
|
||||
/* Read, generic, no param */
|
||||
*tx_data_type = 0x4;
|
||||
else if (cmd_type == DISPUTIL_DSI_DCS)
|
||||
/* Read, DCS, no param */
|
||||
*tx_data_type = 0x6;
|
||||
break;
|
||||
case 2:
|
||||
if (cmd_type == DISPUTIL_DSI_GENERIC)
|
||||
/* Read, Generic, 1 param */
|
||||
*tx_data_type = 0x14;
|
||||
|
||||
break;
|
||||
case 3:
|
||||
if (cmd_type == DISPUTIL_DSI_GENERIC)
|
||||
/* read, generic, 2 params */
|
||||
*tx_data_type = 0x24;
|
||||
break;
|
||||
default:
|
||||
DSI_ERR("Invalid for tx_len= %d\n", (u32)tx_len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
rc = -EINVAL;
|
||||
|
||||
if (rc)
|
||||
DSI_ERR("Invalid input data: dsi_cmd=0x%x tx_data_type =0x%x for tx_len=0x%x\n",
|
||||
dsi_cmd, *tx_data_type, (u32)tx_len);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dsi_display_dispUtil_prepare(const char *cmd_buf, u32 cmd_buf_len,
|
||||
struct dsi_cmd_desc *cmd, u8 *payload, u32 payload_len_max,
|
||||
struct motUtil *motUtil_data)
|
||||
{
|
||||
int rc, i;
|
||||
u8 tx_data_type;
|
||||
|
||||
memset(cmd, 0x00, sizeof(*cmd));
|
||||
|
||||
/*
|
||||
* DISPUTIL_PAYLOAD_LEN_U and SDE_MOT_UTIL_PAYLOAD_LEN_L to
|
||||
* indicate number of payload in bytes
|
||||
*/
|
||||
cmd->msg.tx_len = ((cmd_buf[DISPUTIL_PAYLOAD_LEN_U] << 8) |
|
||||
(cmd_buf[DISPUTIL_PAYLOAD_LEN_L]));
|
||||
rc = dsi_display_dispUtil_get_datatype(cmd_buf[DISPUTIL_CMD_TYPE],
|
||||
cmd_buf[DISPUTIL_MIPI_CMD_TYPE],
|
||||
cmd->msg.tx_len, &tx_data_type);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
cmd->msg.type = tx_data_type;
|
||||
cmd->msg.channel = 0;
|
||||
cmd->last_command = 1;
|
||||
cmd->msg.flags |= MIPI_DSI_MSG_LASTCOMMAND;
|
||||
|
||||
/* DISPUTIL_CMD_TYPE = 1 for DSI write cmd
|
||||
* DISPUTIL_CMD_TYPE = 0 for DSI read cmd */
|
||||
if (cmd_buf[DISPUTIL_CMD_TYPE] == DISPUTIL_DSI_READ) {
|
||||
cmd->msg.flags |= MIPI_DSI_MSG_READ; /* This is a read DSI */
|
||||
cmd->msg.rx_buf = motUtil_data->rd_buf;
|
||||
/* cmd_buf[3] = number bytes host wants to read */
|
||||
cmd->msg.rx_len = cmd_buf[DISPUTIL_NUM_BYTE_RD];
|
||||
|
||||
motUtil_data->read_cmd = true;
|
||||
} else
|
||||
motUtil_data->read_cmd = false;
|
||||
|
||||
/*
|
||||
* DISPUTIL_CMD_XFER_MODE = 0: DSI cmd transfers at HS mode
|
||||
* DISPUTIL_CMD_XFER_MODE = 1: DSI cmd transfers at LP mode
|
||||
*/
|
||||
if (cmd_buf[DISPUTIL_CMD_XFER_MODE] == DISPUTIL_DSI_LP_MODE)
|
||||
cmd->msg.flags |= MIPI_DSI_MSG_USE_LPM;
|
||||
|
||||
cmd->msg.ctrl = 0;
|
||||
cmd->post_wait_ms = 0;
|
||||
|
||||
/*
|
||||
* msg.tx_len is number of bytes of the payload.
|
||||
* Checking msg.tx_len with the payload, DISPUTIL_PAYLOAD,
|
||||
* to make sure they are matched
|
||||
*/
|
||||
if ((cmd->msg.tx_len > (cmd_buf_len - DISPUTIL_PAYLOAD)) ||
|
||||
(cmd->msg.tx_len > payload_len_max)) {
|
||||
DSI_ERR("Incorrect payload length tx_len:%ld, payload_len_max=%d cmd_buf_len=%d\n",
|
||||
cmd->msg.tx_len, payload_len_max, cmd_buf_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < cmd->msg.tx_len; i++)
|
||||
payload[i] = cmd_buf[DISPUTIL_PAYLOAD + i];
|
||||
|
||||
cmd->msg.tx_buf = payload;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int dsi_display_ctrl_get_host_init_state(struct dsi_display *dsi_display,
|
||||
bool *state)
|
||||
{
|
||||
@@ -987,6 +1237,51 @@ static void _dsi_display_continuous_clk_ctrl(struct dsi_display *display,
|
||||
}
|
||||
}
|
||||
|
||||
int dsi_display_motUtil_transfer(void *display, const char *cmd_buf,
|
||||
u32 cmd_buf_len, struct motUtil *motUtil_data)
|
||||
{
|
||||
struct dsi_display *dsi_display = display;
|
||||
struct dsi_cmd_desc cmd;
|
||||
u8 cmd_payload[MAX_CMD_PAYLOAD_SIZE];
|
||||
int rc = 0;
|
||||
bool state = false;
|
||||
|
||||
if (!dsi_display || !cmd_buf) {
|
||||
DSI_ERR("[DSI] invalid params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DSI_INFO("[DSI] Display dispUtil transfer\n");
|
||||
|
||||
rc = dsi_display_dispUtil_prepare(cmd_buf, cmd_buf_len,
|
||||
&cmd, cmd_payload, MAX_CMD_PAYLOAD_SIZE,
|
||||
motUtil_data);
|
||||
if (rc) {
|
||||
DSI_ERR("[DSI] command prepare failed. rc %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
mutex_lock(&dsi_display->display_lock);
|
||||
rc = dsi_display_ctrl_get_host_init_state(dsi_display, &state);
|
||||
if (rc || !state) {
|
||||
DSI_ERR("[DSI] Invalid host state %d rc %d\n",
|
||||
state, rc);
|
||||
rc = -EPERM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* rc will be returned from ops->transfer, which will be 0 or 1 for
|
||||
* DSI write command. rc will be returned for number of read bytes
|
||||
* for DSI read commad
|
||||
*/
|
||||
rc = dsi_display->host.ops->transfer(&dsi_display->host,
|
||||
&cmd.msg);
|
||||
end:
|
||||
mutex_unlock(&dsi_display->display_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int dsi_display_soft_reset(void *display)
|
||||
{
|
||||
struct dsi_display *dsi_display;
|
||||
@@ -2940,9 +3235,12 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
|
||||
msg->flags & MIPI_DSI_MSG_ASYNC_OVERRIDE)
|
||||
cmd_flags |= DSI_CTRL_CMD_ASYNC_WAIT;
|
||||
|
||||
if (msg->rx_buf)
|
||||
cmd_flags |= DSI_CTRL_CMD_READ;
|
||||
rc = dsi_ctrl_cmd_transfer(display->ctrl[ctrl_idx].ctrl, msg,
|
||||
&cmd_flags);
|
||||
if (rc) {
|
||||
if (((cmd_flags & DSI_CTRL_CMD_READ) && rc <= 0) ||
|
||||
(!(cmd_flags & DSI_CTRL_CMD_READ) && rc)) {
|
||||
DSI_ERR("[%s] cmd transfer failed, rc=%d\n",
|
||||
display->name, rc);
|
||||
goto error_disable_cmd_engine;
|
||||
@@ -3762,11 +4060,88 @@ static int dsi_display_parse_dt(struct dsi_display *display)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Parse mot extend feature supporting */
|
||||
display->is_dsi_mot_ext_enabled = of_property_read_bool(of_node,
|
||||
"qcom,platform-mot-ext-feature-enable");
|
||||
if ( display->is_dsi_mot_ext_enabled )
|
||||
display->is_dsi_mot_early_power_enabled = of_property_read_bool(of_node, "qcom,platform-mot-early-power-enable");
|
||||
pr_info("is_dsi_mot_ext_enabled %d, is_dsi_mot_early_power_enabled %d\n", display->is_dsi_mot_ext_enabled, display->is_dsi_mot_early_power_enabled);
|
||||
|
||||
DSI_DEBUG("success\n");
|
||||
error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void dsi_video_te_irq_work(struct work_struct *work)
|
||||
{
|
||||
struct dsi_panel *panel = NULL;
|
||||
struct delayed_work *dw = to_delayed_work(work);
|
||||
|
||||
panel = container_of(dw, struct dsi_panel, te_event_work);
|
||||
if (!panel) {
|
||||
DSI_ERR("%s: invalid panel data\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if(panel->video_te_count%60 == 0)
|
||||
DSI_INFO("%s video te count = %d\n", __func__, panel->video_te_count);
|
||||
|
||||
enable_irq(panel->video_te_irq);
|
||||
}
|
||||
|
||||
extern u32 interval_video_te;
|
||||
static irqreturn_t dsi_video_te_interrupt(int irq, void *data)
|
||||
{
|
||||
struct dsi_panel *panel = data;
|
||||
|
||||
disable_irq_nosync(irq);
|
||||
|
||||
if(panel->video_te_count++ < 3000) {
|
||||
enable_irq(irq);
|
||||
} else {
|
||||
queue_delayed_work(panel->workq, &panel->te_event_work, msecs_to_jiffies(interval_video_te/3));
|
||||
//DSI_DEBUG("%s video_te_count=%d\n", __func__, panel->video_te_count);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int dsi_init_video_te_irq(struct dsi_panel *panel)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
if (gpio_is_valid(panel->video_te_gpio)) {
|
||||
rc = gpio_request(panel->video_te_gpio, "video-te-gpio");
|
||||
if (rc < 0) {
|
||||
DSI_ERR("%s: video te gpio_request fail rc=%d\n", __func__,rc);
|
||||
return rc ;
|
||||
}
|
||||
|
||||
rc = gpio_direction_input(panel->video_te_gpio);
|
||||
if (rc < 0) {
|
||||
DSI_ERR("%s: video te gpio_direction_input fail rc=%d\n", __func__ ,rc);
|
||||
return rc ;
|
||||
}
|
||||
|
||||
panel->video_te_count_priv = 0;
|
||||
panel->video_te_count = 3;
|
||||
panel->video_te_irq = gpio_to_irq(panel->video_te_gpio);
|
||||
DSI_INFO("%s: irq = %d, gpio=%d\n", __func__, panel->video_te_irq, panel->video_te_gpio);
|
||||
|
||||
rc = request_threaded_irq(panel->video_te_irq, dsi_video_te_interrupt, NULL,
|
||||
IRQF_TRIGGER_RISING|IRQF_ONESHOT, "video-te-irq", panel);
|
||||
if (rc < 0) {
|
||||
DSI_ERR("%s: video te request_irq fail rc=%d\n",__func__, rc);
|
||||
return rc ;
|
||||
}
|
||||
} else {
|
||||
DSI_ERR("%s: video te irq gpio not provided\n", __func__);
|
||||
return rc ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dsi_display_res_init(struct dsi_display *display)
|
||||
{
|
||||
int rc = 0;
|
||||
@@ -3814,6 +4189,9 @@ static int dsi_display_res_init(struct dsi_display *display)
|
||||
display->panel->host_config.phy_type;
|
||||
}
|
||||
|
||||
dsi_panel_parse_panel_cfg(display->panel,
|
||||
!strcmp(display->display_type, "primary"));
|
||||
|
||||
rc = dsi_display_parse_lane_map(display);
|
||||
if (rc) {
|
||||
DSI_ERR("Lane map not found, rc=%d\n", rc);
|
||||
@@ -3826,6 +4204,17 @@ static int dsi_display_res_init(struct dsi_display *display)
|
||||
goto error_ctrl_put;
|
||||
}
|
||||
|
||||
if(display->panel->esd_config.status_mode == ESD_MODE_PANEL_TE_VIDEO) {
|
||||
display->panel->workq = create_workqueue("mdss_dsi_video_te");
|
||||
if (!(display->panel->workq)) {
|
||||
DSI_ERR("%s: Error creating video te workqueue\n", __func__);
|
||||
goto error_ctrl_put;
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&(display->panel->te_event_work), dsi_video_te_irq_work);
|
||||
dsi_init_video_te_irq(display->panel);
|
||||
}
|
||||
|
||||
return 0;
|
||||
error_ctrl_put:
|
||||
for (i = i - 1; i >= 0; i--) {
|
||||
@@ -4642,6 +5031,20 @@ static void dsi_display_validate_dms_fps(struct dsi_display_mode *cur_mode,
|
||||
}
|
||||
}
|
||||
|
||||
static int dsi_phy_update_mipi_driver_strength(struct dsi_panel *panel, struct msm_dsi_phy *phy)
|
||||
{
|
||||
if((panel == NULL) || (phy == NULL))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
phy->cfg.dsi_phy_rescode_top = panel->glbl_rescode_top_ctrl;
|
||||
phy->cfg.dsi_phy_rescode_bot = panel->glbl_rescode_bot_ctrl;
|
||||
phy->cfg.dsi_phy_hstx_str_ctrl_0 = panel->glbl_hstx_str_ctrl_0;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int dsi_display_set_mode_sub(struct dsi_display *display,
|
||||
struct dsi_display_mode *mode,
|
||||
@@ -4768,6 +5171,7 @@ static int dsi_display_set_mode_sub(struct dsi_display *display,
|
||||
DSI_ERR("failed to add DSI PHY timing params\n");
|
||||
}
|
||||
}
|
||||
dsi_phy_update_mipi_driver_strength(display->panel, ctrl->phy);
|
||||
error:
|
||||
return rc;
|
||||
}
|
||||
@@ -5188,6 +5592,7 @@ static int dsi_display_bind(struct device *dev,
|
||||
}
|
||||
|
||||
DSI_INFO("Successfully bind display panel '%s'\n", display->name);
|
||||
dsi_display_is_probed(display, 0);
|
||||
display->drm_dev = drm;
|
||||
|
||||
display_for_each_ctrl(i, display) {
|
||||
@@ -5289,6 +5694,20 @@ static void dsi_display_unbind(struct device *dev,
|
||||
mutex_unlock(&display->display_lock);
|
||||
}
|
||||
|
||||
static void dsi_display_dev_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct dsi_display *display = NULL;
|
||||
|
||||
if (!pdev) {
|
||||
DSI_ERR("Invalid device\n");
|
||||
} else {
|
||||
display = platform_get_drvdata(pdev);
|
||||
display->panel->reset_config.reset_force_pull_low =
|
||||
display->panel->utils.read_bool(display->panel->utils.data,
|
||||
"qcom,mdss-dsi-reset-force-pull-low");
|
||||
}
|
||||
}
|
||||
|
||||
static const struct component_ops dsi_display_comp_ops = {
|
||||
.bind = dsi_display_bind,
|
||||
.unbind = dsi_display_unbind,
|
||||
@@ -5297,6 +5716,7 @@ static const struct component_ops dsi_display_comp_ops = {
|
||||
static struct platform_driver dsi_display_driver = {
|
||||
.probe = dsi_display_dev_probe,
|
||||
.remove = dsi_display_dev_remove,
|
||||
.shutdown = dsi_display_dev_shutdown,
|
||||
.driver = {
|
||||
.name = "msm-dsi-display",
|
||||
.of_match_table = dsi_display_dt_match,
|
||||
@@ -5383,11 +5803,15 @@ int dsi_display_dev_probe(struct platform_device *pdev)
|
||||
|
||||
display->display_type = of_get_property(pdev->dev.of_node,
|
||||
"label", NULL);
|
||||
if (!display->display_type)
|
||||
if (!display->display_type) {
|
||||
display->display_type = "primary";
|
||||
display->display_idx = 0;
|
||||
}
|
||||
|
||||
if (!strcmp(display->display_type, "secondary"))
|
||||
if (!strcmp(display->display_type, "secondary")) {
|
||||
index = DSI_SECONDARY;
|
||||
display->display_idx = 1;
|
||||
}
|
||||
|
||||
boot_disp = &boot_displays[index];
|
||||
node = pdev->dev.of_node;
|
||||
@@ -5442,6 +5866,13 @@ int dsi_display_dev_probe(struct platform_device *pdev)
|
||||
goto end;
|
||||
}
|
||||
|
||||
// Initialize mot extend code for early powern and debug tool feature
|
||||
if ( display->is_dsi_mot_ext_enabled && index == DSI_PRIMARY ) {
|
||||
dsi_display_ext_init(display);
|
||||
}
|
||||
pr_info("dsi_display_dev_probe: display(%p), name: %s, is_dsi_mot_early_power_enabled=%d, is_dsi_mot_ext_enabled=%d\n",
|
||||
display, (display->name==NULL)?"Null":display->name, display->is_dsi_mot_early_power_enabled, display->is_dsi_mot_ext_enabled);
|
||||
|
||||
return 0;
|
||||
end:
|
||||
if (display)
|
||||
@@ -6054,8 +6485,12 @@ int dsi_display_get_info(struct drm_connector *connector,
|
||||
|
||||
info->is_connected = true;
|
||||
|
||||
if (!strcmp(display->display_type, "primary"))
|
||||
if (!strcmp(display->display_type, "primary")) {
|
||||
info->display_type = SDE_CONNECTOR_PRIMARY;
|
||||
//Update panel info for Mot early power
|
||||
if ( display->is_dsi_mot_early_power_enabled )
|
||||
display->is_dsi_mot_primary = true;
|
||||
}
|
||||
else if (!strcmp(display->display_type, "secondary"))
|
||||
info->display_type = SDE_CONNECTOR_SECONDARY;
|
||||
|
||||
@@ -6069,6 +6504,14 @@ int dsi_display_get_info(struct drm_connector *connector,
|
||||
(display->panel->qsync_caps.qsync_min_fps_list_len > 0) ?
|
||||
true : false;
|
||||
|
||||
info->panel_id = display->panel->panel_id;
|
||||
info->panel_ver = display->panel->panel_ver;
|
||||
info->panel_regDA = display->panel->panel_regDA;
|
||||
strncpy(info->panel_name, display->panel->panel_name,
|
||||
sizeof(display->panel->panel_name));
|
||||
strncpy(info->panel_supplier, display->panel->panel_supplier,
|
||||
sizeof(display->panel->panel_supplier));
|
||||
|
||||
switch (display->panel->panel_mode) {
|
||||
case DSI_OP_VIDEO_MODE:
|
||||
info->curr_panel_mode = MSM_DISPLAY_VIDEO_MODE;
|
||||
@@ -6783,6 +7226,14 @@ int dsi_display_set_mode(struct dsi_display *display,
|
||||
timing.refresh_rate);
|
||||
|
||||
memcpy(display->panel->cur_mode, &adj_mode, sizeof(adj_mode));
|
||||
|
||||
//Update early power state
|
||||
//This interface is called from dsi bridge, not moto early-power.
|
||||
//It means it is system who want powr on display
|
||||
//From now on early power on is forbidden
|
||||
if ( display->is_dsi_mot_early_power_enabled )
|
||||
display->dsi_mot_ext.early_power_state = DSI_EARLY_POWER_FORBIDDEN;
|
||||
|
||||
error:
|
||||
mutex_unlock(&display->display_lock);
|
||||
return rc;
|
||||
@@ -7144,6 +7595,7 @@ int dsi_display_prepare(struct dsi_display *display)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dsi_display_mode *mode;
|
||||
struct dsi_display_ctrl *ctrl = &display->ctrl[0];
|
||||
|
||||
if (!display) {
|
||||
DSI_ERR("Invalid params\n");
|
||||
@@ -7155,9 +7607,18 @@ int dsi_display_prepare(struct dsi_display *display)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DSI_INFO("panel_name=%s ctrl-index=%d\n",
|
||||
display->panel->name, ctrl->ctrl->cell_index);
|
||||
|
||||
SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY);
|
||||
mutex_lock(&display->display_lock);
|
||||
|
||||
//Check if Mot early power is on going...
|
||||
if ( display->is_dsi_mot_early_power_enabled && display->is_dsi_display_prepared ) {
|
||||
pr_info("already prepared\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
mode = display->panel->cur_mode;
|
||||
|
||||
dsi_display_set_ctrl_esd_check_flag(display, false);
|
||||
@@ -7282,6 +7743,11 @@ int dsi_display_prepare(struct dsi_display *display)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Update prepare statue for Mot early power
|
||||
if ( display->is_dsi_mot_early_power_enabled )
|
||||
display->is_dsi_display_prepared = true;
|
||||
|
||||
goto error;
|
||||
|
||||
error_ctrl_link_off:
|
||||
@@ -7297,7 +7763,8 @@ error_ctrl_clk_off:
|
||||
(void)dsi_display_clk_ctrl(display->dsi_clk_handle,
|
||||
DSI_CORE_CLK, DSI_CLK_OFF);
|
||||
error_panel_post_unprep:
|
||||
(void)dsi_panel_post_unprepare(display->panel);
|
||||
if (!display->is_cont_splash_enabled)
|
||||
(void)dsi_panel_post_unprepare(display->panel);
|
||||
error:
|
||||
mutex_unlock(&display->display_lock);
|
||||
SDE_EVT32(SDE_EVTLOG_FUNC_EXIT);
|
||||
@@ -7566,6 +8033,94 @@ int dsi_display_pre_commit(void *display,
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct dsi_enable_status {
|
||||
struct dsi_display *display;
|
||||
int probed;
|
||||
bool enable;
|
||||
char pname[DSI_PANEL_MAX_PANEL_LEN];
|
||||
};
|
||||
|
||||
static struct dsi_enable_status enable_status[2] = {
|
||||
{
|
||||
.probed = -ENODEV,
|
||||
},
|
||||
{
|
||||
.probed = -ENODEV,
|
||||
},
|
||||
};
|
||||
|
||||
static void dsi_display_is_probed (struct dsi_display *display,
|
||||
int probe_status)
|
||||
|
||||
{
|
||||
int enable_idx;
|
||||
|
||||
if (!display->display_type)
|
||||
enable_idx = 0;
|
||||
|
||||
if (!strcmp(display->display_type, "secondary"))
|
||||
enable_idx = 1;
|
||||
|
||||
enable_status[enable_idx].probed = probe_status;
|
||||
strncpy(enable_status[enable_idx].pname, display->name,
|
||||
sizeof(enable_status[enable_idx].pname));
|
||||
DSI_DEBUG("display->drm_conn[%d] set: probe =%d, name =%s\n",
|
||||
enable_idx, probe_status, display->name);
|
||||
}
|
||||
|
||||
static int dsi_display_enable_status (struct dsi_display *display, bool enable)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!strncmp("DSI-1", display->drm_conn->name, 5)) {
|
||||
DSI_DEBUG("display->drm_conn->name=%s enable = %d MAIN_DISPLAY\n",
|
||||
display->drm_conn->name, enable);
|
||||
enable_status[0].display = display;
|
||||
enable_status[0].enable = enable;
|
||||
} else if (!strncmp("DSI-2", display->drm_conn->name, 5)) {
|
||||
DSI_DEBUG("display->drm_conn->name=%s enable = %d CLI_DISPLAY\n",
|
||||
display->drm_conn->name, enable);
|
||||
enable_status[1].display = display;
|
||||
enable_status[1].enable = enable;
|
||||
} else {
|
||||
DSI_ERR("display->drm_conn: invalid name =%s\n",
|
||||
display->drm_conn->name);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool dsi_display_is_panel_enable (int panel_index, int *probe_status,
|
||||
char **pname)
|
||||
{
|
||||
struct dsi_display *display;
|
||||
bool enable = false;
|
||||
|
||||
if (panel_index > 1) {
|
||||
pr_err("display->drm_conn: invalid panel index =%d\n",
|
||||
panel_index);
|
||||
if (probe_status)
|
||||
*probe_status = -ENODEV;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (probe_status)
|
||||
*probe_status = enable_status[panel_index].probed;
|
||||
if (pname)
|
||||
*pname = &enable_status[panel_index].pname[0];
|
||||
|
||||
display = enable_status[panel_index].display;
|
||||
if (display) {
|
||||
mutex_lock(&display->display_lock);
|
||||
enable = enable_status[panel_index].enable;
|
||||
mutex_unlock(&display->display_lock);
|
||||
}
|
||||
|
||||
return enable;
|
||||
}
|
||||
EXPORT_SYMBOL(dsi_display_is_panel_enable);
|
||||
|
||||
int dsi_display_enable(struct dsi_display *display)
|
||||
{
|
||||
int rc = 0;
|
||||
@@ -7596,6 +8151,7 @@ int dsi_display_enable(struct dsi_display *display)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dsi_display_enable_status(display, 1);
|
||||
display->panel->panel_initialized = true;
|
||||
DSI_DEBUG("cont splash enabled, display enable not required\n");
|
||||
return 0;
|
||||
@@ -7603,6 +8159,12 @@ int dsi_display_enable(struct dsi_display *display)
|
||||
|
||||
mutex_lock(&display->display_lock);
|
||||
|
||||
//Check if Mot early power is on going
|
||||
if ( display->is_dsi_mot_early_power_enabled && dsi_panel_initialized(display->panel)) {
|
||||
pr_info("panel already enabled\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
mode = display->panel->cur_mode;
|
||||
|
||||
if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) {
|
||||
@@ -7620,6 +8182,8 @@ int dsi_display_enable(struct dsi_display *display)
|
||||
display->name, rc);
|
||||
goto error;
|
||||
}
|
||||
|
||||
dsi_display_enable_status(display, true);
|
||||
}
|
||||
|
||||
/* Block sending pps command if modeset is due to fps difference */
|
||||
@@ -7632,6 +8196,7 @@ int dsi_display_enable(struct dsi_display *display)
|
||||
display->name, rc);
|
||||
goto error;
|
||||
}
|
||||
dsi_panel_reset_param(display->panel);
|
||||
}
|
||||
|
||||
if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) {
|
||||
@@ -7755,6 +8320,14 @@ int dsi_display_pre_disable(struct dsi_display *display)
|
||||
DSI_ERR("[%s] panel pre-disable failed, rc=%d\n",
|
||||
display->name, rc);
|
||||
}
|
||||
|
||||
//Update early power state
|
||||
//Here is called from dsi bridge, not moto early-power.
|
||||
//It means it is system who want powr off display
|
||||
//From now on early power on is permitted
|
||||
if ( display->is_dsi_mot_ext_enabled )
|
||||
display->dsi_mot_ext.early_power_state = DSI_EARLY_POWER_IDLE;
|
||||
|
||||
goto exit;
|
||||
|
||||
error_disable_clks:
|
||||
@@ -7778,13 +8351,24 @@ int dsi_display_disable(struct dsi_display *display)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DSI_INFO("%s(%s)+\n", __func__, display->drm_conn->name);
|
||||
SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY);
|
||||
mutex_lock(&display->display_lock);
|
||||
|
||||
//Check is Mot early power is on going
|
||||
pr_info("display %p, name %s is_dsi_mot_primary(%d)\n", display, display->name, display->is_dsi_mot_primary);
|
||||
if ( display->is_dsi_mot_early_power_enabled && !dsi_panel_initialized(display->panel)) {
|
||||
mutex_unlock(&display->display_lock);
|
||||
pr_info("panel already unprepared\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = dsi_display_wake_up(display);
|
||||
if (rc)
|
||||
DSI_ERR("[%s] display wake up failed, rc=%d\n",
|
||||
display->name, rc);
|
||||
else
|
||||
dsi_display_enable_status(display, false);
|
||||
|
||||
if (display->config.panel_mode == DSI_OP_VIDEO_MODE) {
|
||||
rc = dsi_display_vid_engine_disable(display);
|
||||
@@ -7842,6 +8426,13 @@ int dsi_display_unprepare(struct dsi_display *display)
|
||||
SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY);
|
||||
mutex_lock(&display->display_lock);
|
||||
|
||||
//Check if Mot early power is on going
|
||||
if ( display->is_dsi_mot_early_power_enabled && !display->is_dsi_display_prepared) {
|
||||
mutex_unlock(&display->display_lock);
|
||||
pr_info("panel already disabled\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = dsi_display_wake_up(display);
|
||||
if (rc)
|
||||
DSI_ERR("[%s] display wake up failed, rc=%d\n",
|
||||
@@ -7909,6 +8500,10 @@ int dsi_display_unprepare(struct dsi_display *display)
|
||||
display->name, rc);
|
||||
}
|
||||
|
||||
//Update prepare state for Mot early power
|
||||
if ( display->is_dsi_mot_early_power_enabled )
|
||||
display->is_dsi_display_prepared = false;
|
||||
|
||||
mutex_unlock(&display->display_lock);
|
||||
|
||||
/* Free up DSI ERROR event callback */
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
#include "dsi_ctrl.h"
|
||||
#include "dsi_phy.h"
|
||||
#include "dsi_panel.h"
|
||||
#include "sde_connector.h"
|
||||
#include "sde_motUtil.h"
|
||||
#include "dsi_display_mot_ext.h"
|
||||
|
||||
#define MAX_DSI_CTRLS_PER_DISPLAY 2
|
||||
#define DSI_CLIENT_NAME_SIZE 20
|
||||
@@ -141,6 +144,7 @@ struct dsi_display_ext_bridge {
|
||||
* @ext_conn: Pointer to external connector attached to DSI connector
|
||||
* @name: Name of the display.
|
||||
* @display_type: Display type as defined in device tree.
|
||||
* @display_idx: Display index (0-primary, 1-secondary)
|
||||
* @list: List pointer.
|
||||
* @is_active: Is display active.
|
||||
* @is_cont_splash_enabled: Is continuous splash enabled
|
||||
@@ -197,6 +201,7 @@ struct dsi_display {
|
||||
|
||||
const char *name;
|
||||
const char *display_type;
|
||||
int display_idx;
|
||||
struct list_head list;
|
||||
bool is_cont_splash_enabled;
|
||||
bool sw_te_using_wd;
|
||||
@@ -263,6 +268,12 @@ struct dsi_display {
|
||||
struct work_struct fifo_underflow_work;
|
||||
struct work_struct fifo_overflow_work;
|
||||
struct work_struct lp_rx_timeout_work;
|
||||
/* used for moto feature early-pane- power to speed up the power on sequence */
|
||||
bool is_dsi_mot_ext_enabled;
|
||||
bool is_dsi_mot_early_power_enabled;
|
||||
bool is_dsi_display_prepared;
|
||||
bool is_dsi_mot_primary;
|
||||
struct dsi_mot_ext_feature dsi_mot_ext;
|
||||
|
||||
/* firmware panel data */
|
||||
const struct firmware *fw;
|
||||
@@ -561,6 +572,8 @@ int dsi_post_clkoff_cb(void *priv, enum dsi_clk_type clk_type,
|
||||
enum dsi_lclk_type l_type,
|
||||
enum dsi_clk_state curr_state);
|
||||
|
||||
int dsi_display_set_param(void *display, struct msm_param_info *param_info);
|
||||
|
||||
/**
|
||||
* dsi_post_clkon_cb() - Callback after clock is turned on
|
||||
* @priv: private data pointer.
|
||||
@@ -656,6 +669,25 @@ int dsi_display_cmd_transfer(struct drm_connector *connector,
|
||||
void *display, const char *cmd_buffer,
|
||||
u32 cmd_buf_len);
|
||||
|
||||
/**
|
||||
* dsi_display_motUtil_transfer() - Convert motUtil data and transfer command
|
||||
* to the panel
|
||||
* @display: Handle to display.
|
||||
* @cmd_buf: Command buffer
|
||||
* @cmd_buf_len: Command buffer length in bytes
|
||||
* @motUtil_data: motUtil data information
|
||||
*/
|
||||
int dsi_display_motUtil_transfer(void *display, const char *cmd_buf,
|
||||
u32 cmd_buf_len, struct motUtil *motUtil_data);
|
||||
|
||||
|
||||
/**
|
||||
* dsi_display_force_esd_disable() - check if ESD UTAG is forced to disable ESD
|
||||
* @display: Handle to display.
|
||||
*/
|
||||
bool dsi_display_force_esd_disable(void *display);
|
||||
|
||||
|
||||
/**
|
||||
* dsi_display_soft_reset() - perform a soft reset on DSI controller
|
||||
* @display: Handle to display
|
||||
@@ -718,6 +750,20 @@ enum dsi_pixel_format dsi_display_get_dst_format(
|
||||
struct drm_connector *connector,
|
||||
void *display);
|
||||
|
||||
/*
|
||||
* dsi_display_cmd_mipi_transfer() - Sending the MIPI DSI command
|
||||
* @display: Handle to display
|
||||
* @msg: MIPI DSI command information
|
||||
* @flags: Modifier flags
|
||||
* Return: if this is a MIPI DSI read then it will return number read byte
|
||||
* in success case. Otherwise will be "<=0"
|
||||
* if this is a MIPI DSI write then it will return "0" for success
|
||||
*
|
||||
*/
|
||||
int dsi_display_cmd_mipi_transfer(struct dsi_display *display,
|
||||
struct mipi_dsi_msg *msg,
|
||||
u32 flags);
|
||||
|
||||
/**
|
||||
* dsi_display_cont_splash_config() - initialize splash resources
|
||||
* @display: Handle to display
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2019, The Linux Foundation.All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DSI_DISPLAY_MOT_EXT_H_
|
||||
#define _DSI_DISPLAY_MOT_EXT_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc.h>
|
||||
|
||||
#include "msm_drv.h"
|
||||
#include "dsi_defs.h"
|
||||
#include "dsi_ctrl.h"
|
||||
#include "dsi_phy.h"
|
||||
#include "dsi_panel.h"
|
||||
#include "sde_connector.h"
|
||||
#include "sde_motUtil.h"
|
||||
#include "dsi_display.h"
|
||||
#include <linux/alarmtimer.h>
|
||||
|
||||
#define LCD_PARA_LINE_LEN 2*1024
|
||||
|
||||
enum dsi_display_early_power_state {
|
||||
DSI_EARLY_POWER_IDLE = 0,
|
||||
DSI_EARLY_POWER_BEGIN,
|
||||
DSI_EARLY_POWER_PREPARED,
|
||||
DSI_EARLY_POWER_INITIALIZED,
|
||||
DSI_EARLY_POWER_FORBIDDEN,
|
||||
DSI_EARLY_POWER_STATE_NUM
|
||||
};
|
||||
|
||||
struct dsi_mot_ext_feature {
|
||||
struct dsi_display *display;
|
||||
struct workqueue_struct *early_power_workq;
|
||||
struct work_struct early_on_work;
|
||||
struct delayed_work early_off_work;
|
||||
enum dsi_display_early_power_state early_power_state;
|
||||
struct wakeup_source* early_wake_src;
|
||||
};
|
||||
|
||||
/**
|
||||
* dsi_display_ext_init() - Moto early power init
|
||||
* @display: Handle to display.
|
||||
*
|
||||
* Prepare for early power up sequences for the primary panel.
|
||||
*
|
||||
* Return: error code.
|
||||
*/
|
||||
int dsi_display_ext_init(struct dsi_display *display);
|
||||
|
||||
#endif /* _DSI_DISPLAY_MOT_EXT_H_ */
|
||||
Regular → Executable
+1080
-39
File diff suppressed because it is too large.
Load diff
@@ -35,6 +35,38 @@
|
||||
*/
|
||||
#define MIPI_DSI_MSG_ASYNC_OVERRIDE BIT(4)
|
||||
|
||||
#define DSI_PANEL_MAX_PANEL_LEN 128
|
||||
#define MAX_PARAM_NAME 10
|
||||
|
||||
#define BRIGHTNESS_HBM_ON 0xFFFFFFFE
|
||||
#define BRIGHTNESS_HBM_OFF (BRIGHTNESS_HBM_ON - 1)
|
||||
#define HBM_BRIGHTNESS(value) ((value) == HBM_ON_STATE ?\
|
||||
BRIGHTNESS_HBM_ON : BRIGHTNESS_HBM_OFF)
|
||||
|
||||
/* HBM implementation is different, depending on display and backlight hardware
|
||||
* design, which is classified into the following types:
|
||||
* HBM_TYPE_OLED: OLED panel, HBM is controlled by DSI register only, which
|
||||
* is independent on brightness.
|
||||
* HBM_TYPE_LCD_DCS_WLED: LCD panel, HBM is controlled by DSI register, and
|
||||
* brightness is decided by WLED IC on I2C/SPI bus.
|
||||
* HBM_TYPE_LCD_DCS_ONLY: LCD panel, brightness/HBM is controlled by DSI
|
||||
* register only.
|
||||
* HBM_TYPE_LCD_WLED_ONLY: LCD panel, brightness/HBM is controlled by WLED
|
||||
* IC only.
|
||||
* HBM_TYPE_LCD_DCS_GPIO: LCD panel, HBM is controlled by GPIO, and brightness
|
||||
* is controlled by DSI register.
|
||||
*
|
||||
* Note: brightness must be at maximum while enabling HBM for all LCD panels
|
||||
*/
|
||||
|
||||
enum panel_hbm_type {
|
||||
HBM_TYPE_OLED = 0,
|
||||
HBM_TYPE_LCD_DCS_WLED,
|
||||
HBM_TYPE_LCD_DCS_ONLY,
|
||||
HBM_TYPE_LCD_WLED_ONLY,
|
||||
HBM_TYPE_LCD_DCS_GPIO
|
||||
};
|
||||
|
||||
enum dsi_panel_rotation {
|
||||
DSI_PANEL_ROTATE_NONE = 0,
|
||||
DSI_PANEL_ROTATE_HV_FLIP,
|
||||
@@ -46,11 +78,19 @@ enum dsi_backlight_type {
|
||||
DSI_BACKLIGHT_PWM = 0,
|
||||
DSI_BACKLIGHT_WLED,
|
||||
DSI_BACKLIGHT_DCS,
|
||||
DSI_BACKLIGHT_DUMMY,
|
||||
DSI_BACKLIGHT_EXTERNAL,
|
||||
DSI_BACKLIGHT_I2C,
|
||||
DSI_BACKLIGHT_UNKNOWN,
|
||||
DSI_BACKLIGHT_MAX,
|
||||
};
|
||||
|
||||
enum dsi_backlight_level_align_type {
|
||||
DSI_BACKLIGHT_LEVEL_ALIGN_NORMAL = 0,
|
||||
DSI_BACKLIGHT_LEVEL_ALIGN_BIT15_8_BIT3_0 = 1,
|
||||
};
|
||||
|
||||
|
||||
enum bl_update_flag {
|
||||
BL_UPDATE_DELAY_UNTIL_FIRST_FRAME,
|
||||
BL_UPDATE_NONE,
|
||||
@@ -115,13 +155,18 @@ struct dsi_backlight_config {
|
||||
enum dsi_backlight_type type;
|
||||
enum bl_update_flag bl_update;
|
||||
|
||||
bool bl_2bytes_enable;
|
||||
u32 bl_min_level;
|
||||
u32 bl_max_level;
|
||||
u32 brightness_max_level;
|
||||
u32 brightness_default_level;
|
||||
u32 bl_level;
|
||||
u32 bl_scale;
|
||||
u32 bl_scale_sv;
|
||||
u32 bl_level_align;
|
||||
bool bl_inverted_dbv;
|
||||
bool bl_demura_cmd;
|
||||
u32 demura_type;
|
||||
u32 bl_dcs_subtype;
|
||||
|
||||
int en_gpio;
|
||||
@@ -133,6 +178,7 @@ struct dsi_backlight_config {
|
||||
/* WLED params */
|
||||
struct led_trigger *wled;
|
||||
struct backlight_device *raw_bd;
|
||||
struct backlight_device *i2c_bd;
|
||||
};
|
||||
|
||||
struct dsi_reset_seq {
|
||||
@@ -147,13 +193,22 @@ struct dsi_panel_reset_config {
|
||||
int reset_gpio;
|
||||
int disp_en_gpio;
|
||||
int lcd_mode_sel_gpio;
|
||||
int tp_rst_gpio;
|
||||
u32 tp_rst_post_sleep;
|
||||
u32 panel_rst_due_tp_rst_sleep;
|
||||
u32 mode_sel_state;
|
||||
|
||||
bool panel_on_rst_pull_down;
|
||||
bool panel_on_tp_rst_enable;
|
||||
bool reset_force_pull_low;
|
||||
bool panel_rst_due_tp_rst;
|
||||
};
|
||||
|
||||
enum esd_check_status_mode {
|
||||
ESD_MODE_REG_READ,
|
||||
ESD_MODE_SW_BTA,
|
||||
ESD_MODE_PANEL_TE,
|
||||
ESD_MODE_PANEL_TE_VIDEO,
|
||||
ESD_MODE_SW_SIM_SUCCESS,
|
||||
ESD_MODE_SW_SIM_FAILURE,
|
||||
ESD_MODE_MAX
|
||||
@@ -172,6 +227,65 @@ struct drm_panel_esd_config {
|
||||
u32 groups;
|
||||
};
|
||||
|
||||
enum panel_idx {
|
||||
MAIN_IDX = 0,
|
||||
PANEL_IDX_MAX,
|
||||
};
|
||||
|
||||
enum acl_state {
|
||||
ACL_OFF_STATE = 0,
|
||||
ACL_ON_STATE,
|
||||
ACL_STATE_NUM,
|
||||
};
|
||||
|
||||
enum hbm_state {
|
||||
HBM_OFF_STATE = 0,
|
||||
HBM_ON_STATE,
|
||||
HBM_FOD_ON_STATE,
|
||||
HBM_STATE_NUM
|
||||
};
|
||||
|
||||
enum cabc_state {
|
||||
CABC_UI_STATE,
|
||||
CABC_MV_STATE,
|
||||
CABC_DIS_STATE,
|
||||
CABC_STATE_NUM,
|
||||
};
|
||||
|
||||
enum dc_state {
|
||||
DC_OFF_STATE = 0,
|
||||
DC_ON_STATE,
|
||||
DC_STATE_NUM,
|
||||
};
|
||||
|
||||
enum color_state {
|
||||
COLOR_VBT_STATE = 0,
|
||||
COLOR_STD_STATE,
|
||||
COLOR_GAME_STATE,
|
||||
COLOR_NONE_STATE,
|
||||
COLOR_STATE_NUM,
|
||||
};
|
||||
|
||||
struct panel_param_val_map {
|
||||
int state;
|
||||
enum dsi_cmd_set_type type;
|
||||
struct dsi_panel_cmd_set *cmds;
|
||||
};
|
||||
|
||||
struct panel_param {
|
||||
const char *param_name;
|
||||
struct panel_param_val_map *val_map;
|
||||
u16 val_max;
|
||||
const u16 default_value;
|
||||
u16 value;
|
||||
bool is_supported;
|
||||
};
|
||||
|
||||
enum touch_state {
|
||||
TOUCH_DEEP_SLEEP_STATE = 0,
|
||||
TOUCH_LOW_POWER_STATE,
|
||||
};
|
||||
|
||||
struct dsi_panel {
|
||||
const char *name;
|
||||
const char *type;
|
||||
@@ -204,6 +318,13 @@ struct dsi_panel {
|
||||
struct drm_panel_hdr_properties hdr_props;
|
||||
struct drm_panel_esd_config esd_config;
|
||||
|
||||
struct workqueue_struct *workq;
|
||||
struct delayed_work te_event_work;
|
||||
int video_te_gpio;
|
||||
u32 video_te_count;
|
||||
u32 video_te_count_priv;
|
||||
int video_te_irq;
|
||||
|
||||
struct dsi_parser_utils utils;
|
||||
|
||||
bool lp11_init;
|
||||
@@ -211,6 +332,7 @@ struct dsi_panel {
|
||||
bool ulps_suspend_enabled;
|
||||
bool allow_phy_power_off;
|
||||
bool reset_gpio_always_on;
|
||||
bool disp_pre_reset;
|
||||
atomic_t esd_recovery_pending;
|
||||
|
||||
bool panel_initialized;
|
||||
@@ -225,6 +347,31 @@ struct dsi_panel {
|
||||
int panel_test_gpio;
|
||||
int power_mode;
|
||||
enum dsi_panel_physical_type panel_type;
|
||||
|
||||
bool esd_utag_enable;
|
||||
u64 panel_id;
|
||||
u64 panel_ver;
|
||||
u32 panel_regDA;
|
||||
char panel_name[DSI_PANEL_MAX_PANEL_LEN];
|
||||
char panel_supplier[DSI_PANEL_MAX_PANEL_LEN];
|
||||
|
||||
u32 disp_on_chk_val;
|
||||
bool no_panel_on_read_support;
|
||||
|
||||
enum panel_hbm_type hbm_type;
|
||||
u32 bl_lvl_during_hbm;
|
||||
bool panel_hbm_fod;
|
||||
int hbm_en_gpio;
|
||||
bool is_hbm_using_51_cmd;
|
||||
struct panel_param *param_cmds;
|
||||
|
||||
enum touch_state tp_state;
|
||||
bool tp_state_check_enable;
|
||||
|
||||
int glbl_rescode_top_ctrl;
|
||||
int glbl_rescode_bot_ctrl;
|
||||
int glbl_hstx_str_ctrl_0;
|
||||
int reset_avdd_time_interval;
|
||||
};
|
||||
|
||||
static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel)
|
||||
@@ -297,6 +444,8 @@ int dsi_panel_set_nolp(struct dsi_panel *panel);
|
||||
|
||||
int dsi_panel_prepare(struct dsi_panel *panel);
|
||||
|
||||
int dsi_panel_reset(struct dsi_panel *panel);
|
||||
|
||||
int dsi_panel_enable(struct dsi_panel *panel);
|
||||
|
||||
int dsi_panel_post_enable(struct dsi_panel *panel);
|
||||
@@ -340,9 +489,16 @@ struct dsi_panel *dsi_panel_ext_bridge_get(struct device *parent,
|
||||
|
||||
int dsi_panel_parse_esd_reg_read_configs(struct dsi_panel *panel);
|
||||
|
||||
int dsi_panel_parse_panel_cfg(struct dsi_panel *panel, bool is_primary);
|
||||
|
||||
void dsi_panel_ext_bridge_put(struct dsi_panel *panel);
|
||||
|
||||
void dsi_panel_calc_dsi_transfer_time(struct dsi_host_common_cfg *config,
|
||||
struct dsi_display_mode *mode, u32 frame_threshold_us);
|
||||
|
||||
int dsi_panel_set_param(struct dsi_panel *panel,
|
||||
struct msm_param_info *param_info);
|
||||
|
||||
void dsi_panel_reset_param(struct dsi_panel *panel);
|
||||
|
||||
#endif /* _DSI_PANEL_H_ */
|
||||
@@ -115,6 +115,9 @@ struct dsi_phy_cfg {
|
||||
enum dsi_phy_type phy_type;
|
||||
unsigned long bit_clk_rate_hz;
|
||||
u32 data_lanes;
|
||||
int dsi_phy_rescode_top;
|
||||
int dsi_phy_rescode_bot;
|
||||
int dsi_phy_hstx_str_ctrl_0;
|
||||
};
|
||||
|
||||
struct dsi_phy_hw;
|
||||
|
||||
@@ -355,8 +355,21 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy,
|
||||
vreg_ctrl_0 = less_than_1500_mhz ? 0x53 : 0x52;
|
||||
glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x00;
|
||||
glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : 0x3c;
|
||||
if(cfg->dsi_phy_rescode_top >= 0)
|
||||
{
|
||||
glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : cfg->dsi_phy_rescode_top;
|
||||
}
|
||||
if(cfg->dsi_phy_rescode_bot >= 0)
|
||||
{
|
||||
glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : cfg->dsi_phy_rescode_bot;
|
||||
}
|
||||
glbl_str_swi_cal_sel_ctrl = 0x00;
|
||||
glbl_hstx_str_ctrl_0 = 0x88;
|
||||
if(cfg->dsi_phy_hstx_str_ctrl_0 > 0)
|
||||
{
|
||||
glbl_hstx_str_ctrl_0 = cfg->dsi_phy_hstx_str_ctrl_0;
|
||||
DSI_PHY_INFO(phy, "glbl_hstx_str_ctrl_0=0x%2x\n", glbl_hstx_str_ctrl_0);
|
||||
}
|
||||
} else {
|
||||
vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59;
|
||||
glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00;
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <uapi/linux/sched/types.h>
|
||||
#include <drm/drm_of.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
#include "msm_drv.h"
|
||||
#include "msm_kms.h"
|
||||
@@ -386,6 +387,11 @@ static int msm_drm_uninit(struct device *dev)
|
||||
priv->registered = false;
|
||||
}
|
||||
|
||||
if (priv->msm_drv_notifier.notifier_call) {
|
||||
unregister_reboot_notifier(&priv->msm_drv_notifier);
|
||||
priv->msm_drv_notifier.notifier_call = NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
||||
if (fbdev && priv->fbdev)
|
||||
msm_fbdev_free(ddev);
|
||||
@@ -858,6 +864,23 @@ static void msm_idle_init(struct drm_device *ddev)
|
||||
spin_lock_init(&idle->lock);
|
||||
}
|
||||
|
||||
static void msm_pdev_shutdown(struct platform_device *pdev);
|
||||
static int msm_drv_shutdown_notifier_cb(struct notifier_block *nb,
|
||||
unsigned long event, void *unused)
|
||||
{
|
||||
struct device *dev;
|
||||
struct platform_device *pdev;
|
||||
struct msm_drm_private *priv = container_of(nb, struct msm_drm_private,
|
||||
msm_drv_notifier);
|
||||
|
||||
dev = priv->dev->dev;
|
||||
pdev = to_platform_device(dev);
|
||||
dev_warn(dev, "prepare to shutdown\n");
|
||||
msm_pdev_shutdown(pdev);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int msm_drm_init(struct device *dev, struct drm_driver *drv)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
@@ -990,6 +1013,16 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
|
||||
|
||||
drm_kms_helper_poll_init(ddev);
|
||||
|
||||
priv->msm_drv_notifier.notifier_call = msm_drv_shutdown_notifier_cb;
|
||||
priv->msm_drv_notifier.next = NULL;
|
||||
priv->msm_drv_notifier.priority = 1;
|
||||
ret = register_reboot_notifier(&priv->msm_drv_notifier);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to register for reboot_notifier. ret = %d\n",
|
||||
ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <linux/sde_io_util.h>
|
||||
#include <asm/sizes.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/notifier.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_atomic.h>
|
||||
@@ -202,12 +203,19 @@ enum msm_mdp_conn_property {
|
||||
CONNECTOR_PROP_QSYNC_MODE,
|
||||
CONNECTOR_PROP_CMD_FRAME_TRIGGER_MODE,
|
||||
|
||||
/* MOT feature panel*/
|
||||
CONNECTOR_PROP_HBM,
|
||||
CONNECTOR_PROP_CABC,
|
||||
CONNECTOR_PROP_ACL,
|
||||
CONNECTOR_PROP_DC,
|
||||
CONNECTOR_PROP_COLOR,
|
||||
/* total # of properties */
|
||||
CONNECTOR_PROP_COUNT
|
||||
};
|
||||
|
||||
#define MSM_GPU_MAX_RINGS 4
|
||||
#define MAX_H_TILES_PER_DISPLAY 2
|
||||
#define MSM_DISP_NAME_LEN_MAX 128
|
||||
|
||||
/**
|
||||
* enum msm_display_compression_type - compression method used for pixel stream
|
||||
@@ -310,6 +318,28 @@ struct msm_roi_caps {
|
||||
struct msm_roi_alignment align;
|
||||
};
|
||||
|
||||
enum msm_param_state {
|
||||
PARAM_STATE_OFF = 0,
|
||||
PARAM_STATE_ON,
|
||||
PARAM_STATE_NUM,
|
||||
PARAM_STATE_DISABLE = 0xFFFF,
|
||||
};
|
||||
|
||||
enum msm_param_id {
|
||||
PARAM_HBM_ID = 0,
|
||||
PARAM_CABC_ID,
|
||||
PARAM_ACL_ID,
|
||||
PARAM_DC_ID,
|
||||
PARAM_COLOR_ID,
|
||||
PARAM_ID_NUM
|
||||
};
|
||||
|
||||
struct msm_param_info {
|
||||
enum msm_param_id param_idx;
|
||||
enum msm_mdp_conn_property param_conn_idx;
|
||||
int value;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct msm_display_dsc_info - defines dsc configuration
|
||||
* @version: DSC version.
|
||||
@@ -501,6 +531,10 @@ struct msm_resource_caps_info {
|
||||
* @h_tile_instance: Controller instance used per tile. Number of elements is
|
||||
* based on num_of_h_tiles
|
||||
* @is_connected: Set to true if display is connected
|
||||
* @panel_id
|
||||
* @panel_ver
|
||||
* @panel_regDA
|
||||
* @panel_name[MSM_DISP_NAME_LEN_MAX];
|
||||
* @width_mm: Physical width
|
||||
* @height_mm: Physical height
|
||||
* @max_width: Max width of display. In case of hot pluggable display
|
||||
@@ -525,6 +559,12 @@ struct msm_display_info {
|
||||
|
||||
bool is_connected;
|
||||
|
||||
uint64_t panel_id;
|
||||
uint64_t panel_ver;
|
||||
uint32_t panel_regDA;
|
||||
char panel_name[MSM_DISP_NAME_LEN_MAX];
|
||||
char panel_supplier[MSM_DISP_NAME_LEN_MAX];
|
||||
|
||||
unsigned int width_mm;
|
||||
unsigned int height_mm;
|
||||
|
||||
@@ -712,6 +752,8 @@ struct msm_drm_private {
|
||||
bool shutdown_in_progress;
|
||||
|
||||
struct msm_idle idle;
|
||||
|
||||
struct notifier_block msm_drv_notifier;
|
||||
};
|
||||
|
||||
/* get struct msm_kms * from drm_device * */
|
||||
|
||||
@@ -88,6 +88,9 @@ static int sde_backlight_device_update_status(struct backlight_device *bd)
|
||||
if (brightness > display->panel->bl_config.bl_max_level)
|
||||
brightness = display->panel->bl_config.bl_max_level;
|
||||
|
||||
if(brightness && brightness < display->panel->bl_config.bl_min_level)
|
||||
brightness = display->panel->bl_config.bl_min_level;
|
||||
|
||||
/* map UI brightness into driver backlight level with rounding */
|
||||
bl_lvl = mult_frac(brightness, display->panel->bl_config.bl_max_level,
|
||||
display->panel->bl_config.brightness_max_level);
|
||||
@@ -149,7 +152,7 @@ static int sde_backlight_setup(struct sde_connector *c_conn,
|
||||
display = (struct dsi_display *) c_conn->display;
|
||||
bl_config = &display->panel->bl_config;
|
||||
props.max_brightness = bl_config->brightness_max_level;
|
||||
props.brightness = bl_config->brightness_max_level;
|
||||
props.brightness = bl_config->brightness_default_level;
|
||||
snprintf(bl_node_name, BL_NODE_NAME_SIZE, "panel%u-backlight",
|
||||
display_count);
|
||||
c_conn->bl_device = backlight_device_register(bl_node_name, dev->dev,
|
||||
@@ -488,8 +491,10 @@ void sde_connector_schedule_status_work(struct drm_connector *connector,
|
||||
return;
|
||||
|
||||
sde_connector_get_info(connector, &info);
|
||||
if (c_conn->ops.check_status &&
|
||||
(info.capabilities & MSM_DISPLAY_ESD_ENABLED)) {
|
||||
if ((c_conn->ops.force_esd_disable &&
|
||||
(c_conn->ops.force_esd_disable(c_conn->display) == false)) &&
|
||||
(c_conn->ops.check_status &&
|
||||
(info.capabilities & MSM_DISPLAY_ESD_ENABLED))) {
|
||||
if (en) {
|
||||
u32 interval;
|
||||
|
||||
@@ -690,6 +695,24 @@ static int _sde_connector_update_hdr_metadata(struct sde_connector *c_conn,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int _sde_connector_update_param(struct sde_connector *c_conn,
|
||||
struct msm_param_info *param_info)
|
||||
{
|
||||
struct dsi_display *dsi_display;
|
||||
int rc = 0;
|
||||
|
||||
if (!c_conn) {
|
||||
SDE_ERROR("Invalid params sde_connector null\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dsi_display = c_conn->display;
|
||||
if (dsi_display && c_conn->ops.set_param)
|
||||
rc = c_conn->ops.set_param(dsi_display, param_info);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int _sde_connector_update_dirty_properties(
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
@@ -1360,6 +1383,7 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
|
||||
int idx, rc;
|
||||
uint64_t fence_user_fd;
|
||||
uint64_t __user prev_user_fd;
|
||||
struct msm_param_info param_info;
|
||||
|
||||
if (!connector || !state || !property) {
|
||||
SDE_ERROR("invalid argument(s), conn %pK, state %pK, prp %pK\n",
|
||||
@@ -1469,6 +1493,46 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
|
||||
msm_property_set_dirty(&c_conn->property_info,
|
||||
&c_state->property_state, idx);
|
||||
break;
|
||||
case CONNECTOR_PROP_HBM:
|
||||
param_info.value = val;
|
||||
param_info.param_idx = PARAM_HBM_ID;
|
||||
param_info.param_conn_idx = CONNECTOR_PROP_HBM;
|
||||
rc = _sde_connector_update_param(c_conn, ¶m_info);
|
||||
if (rc)
|
||||
goto end;
|
||||
break;
|
||||
case CONNECTOR_PROP_ACL:
|
||||
param_info.value = val;
|
||||
param_info.param_idx = PARAM_ACL_ID;
|
||||
param_info.param_conn_idx = CONNECTOR_PROP_ACL;
|
||||
rc = _sde_connector_update_param(c_conn, ¶m_info);
|
||||
if (rc)
|
||||
goto end;
|
||||
break;
|
||||
case CONNECTOR_PROP_CABC:
|
||||
param_info.value = val;
|
||||
param_info.param_idx = PARAM_CABC_ID;
|
||||
param_info.param_conn_idx = CONNECTOR_PROP_CABC;
|
||||
rc = _sde_connector_update_param(c_conn, ¶m_info);
|
||||
if (rc)
|
||||
goto end;
|
||||
break;
|
||||
case CONNECTOR_PROP_DC:
|
||||
param_info.value = val;
|
||||
param_info.param_idx = PARAM_DC_ID;
|
||||
param_info.param_conn_idx = CONNECTOR_PROP_DC;
|
||||
rc = _sde_connector_update_param(c_conn, ¶m_info);
|
||||
if (rc)
|
||||
goto end;
|
||||
break;
|
||||
case CONNECTOR_PROP_COLOR:
|
||||
param_info.value = val;
|
||||
param_info.param_idx = PARAM_COLOR_ID;
|
||||
param_info.param_conn_idx = CONNECTOR_PROP_COLOR;
|
||||
rc = _sde_connector_update_param(c_conn, ¶m_info);
|
||||
if (rc)
|
||||
goto end;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1969,8 +2033,40 @@ static int sde_connector_init_debugfs(struct drm_connector *connector)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int sde_connector_get_panel_vendor_info(struct drm_connector *connector)
|
||||
{
|
||||
struct sde_connector *sde_connector;
|
||||
struct msm_display_info info;
|
||||
|
||||
if (!connector) {
|
||||
SDE_ERROR("invalid connector\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_connector = to_sde_connector(connector);
|
||||
sde_connector_get_info(connector, &info);
|
||||
connector->display_info.panel_id = info.panel_id;
|
||||
connector->display_info.panel_ver = info.panel_ver;
|
||||
connector->display_info.panel_regDA = info.panel_regDA;
|
||||
strncpy(connector->display_info.panel_name, info.panel_name,
|
||||
sizeof(info.panel_name));
|
||||
strncpy(connector->display_info.panel_supplier, info.panel_supplier,
|
||||
sizeof(info.panel_supplier));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int sde_connector_late_register(struct drm_connector *connector)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = sde_connector_get_panel_vendor_info(connector);
|
||||
if (ret) {
|
||||
SDE_ERROR("failed to retrieve panel vendor info\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return sde_connector_init_debugfs(connector);
|
||||
}
|
||||
|
||||
@@ -2213,6 +2309,7 @@ int sde_connector_esd_status(struct drm_connector *conn)
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 interval_video_te = STATUS_CHECK_INTERVAL_MS;
|
||||
static void sde_connector_check_status_work(struct work_struct *work)
|
||||
{
|
||||
struct sde_connector *conn;
|
||||
@@ -2248,6 +2345,9 @@ static void sde_connector_check_status_work(struct work_struct *work)
|
||||
/* If debugfs property is not set then take default value */
|
||||
interval = conn->esd_status_interval ?
|
||||
conn->esd_status_interval : STATUS_CHECK_INTERVAL_MS;
|
||||
|
||||
interval_video_te = interval;
|
||||
|
||||
schedule_delayed_work(&conn->status_work,
|
||||
msecs_to_jiffies(interval));
|
||||
return;
|
||||
@@ -2351,6 +2451,61 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sde_connector_install_panel_params(struct sde_connector *c_conn)
|
||||
{
|
||||
struct panel_param *param_cmds;
|
||||
uint32_t prop_idx;
|
||||
int i;
|
||||
struct dsi_display *dsi_display;
|
||||
u16 prop_max, prop_min, prop_init;
|
||||
|
||||
if (c_conn->connector_type != DRM_MODE_CONNECTOR_DSI)
|
||||
return 0;
|
||||
|
||||
dsi_display = (struct dsi_display *) (c_conn->display);
|
||||
param_cmds = dsi_display->panel->param_cmds;
|
||||
for (i = 0; i < PARAM_ID_NUM; i++) {
|
||||
SDE_DEBUG("%s:i = %d param_name = %s is_support=%d\n",
|
||||
__func__, i,
|
||||
param_cmds->param_name, param_cmds->is_supported);
|
||||
|
||||
if (!strncmp(param_cmds->param_name, "HBM", 3))
|
||||
prop_idx = CONNECTOR_PROP_HBM;
|
||||
else if (!strncmp(param_cmds->param_name, "CABC", 4))
|
||||
prop_idx = CONNECTOR_PROP_CABC;
|
||||
else if (!strncmp(param_cmds->param_name, "ACL", 3))
|
||||
prop_idx = CONNECTOR_PROP_ACL;
|
||||
else if (!strncmp(param_cmds->param_name, "DC", 2))
|
||||
prop_idx = CONNECTOR_PROP_DC;
|
||||
else if (!strncmp(param_cmds->param_name, "COLOR", 5))
|
||||
prop_idx = CONNECTOR_PROP_COLOR;
|
||||
else {
|
||||
SDE_ERROR("Invalid param_name =%s\n",
|
||||
param_cmds->param_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (param_cmds->is_supported) {
|
||||
prop_max = param_cmds->val_max;
|
||||
prop_min = PARAM_STATE_OFF;
|
||||
prop_init = param_cmds->default_value;
|
||||
} else {
|
||||
prop_max = PARAM_STATE_OFF;
|
||||
prop_min = PARAM_STATE_OFF;
|
||||
prop_init = PARAM_STATE_DISABLE;
|
||||
}
|
||||
|
||||
msm_property_install_volatile_range( &c_conn->property_info,
|
||||
param_cmds->param_name, 0x0,
|
||||
prop_min, prop_max,
|
||||
prop_init, prop_idx);
|
||||
|
||||
param_cmds++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sde_connector_set_blob_data(struct drm_connector *conn,
|
||||
struct drm_connector_state *state,
|
||||
enum msm_mdp_conn_property prop_id)
|
||||
@@ -2681,6 +2836,14 @@ struct drm_connector *sde_connector_init(struct drm_device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
rc = sde_connector_install_panel_params(c_conn);
|
||||
if (rc) {
|
||||
SDE_ERROR_CONN(c_conn,
|
||||
"failed to install property for panel params. rc =%d\n",
|
||||
rc);
|
||||
goto error_cleanup_fence;
|
||||
}
|
||||
|
||||
rc = sde_connector_get_info(&c_conn->base, &display_info);
|
||||
if (!rc && (connector_type == DRM_MODE_CONNECTOR_DSI) &&
|
||||
(display_info.capabilities & MSM_DISPLAY_CAP_VID_MODE))
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "msm_prop.h"
|
||||
#include "sde_kms.h"
|
||||
#include "sde_fence.h"
|
||||
#include "sde_motUtil.h"
|
||||
|
||||
#define SDE_CONNECTOR_NAME_SIZE 16
|
||||
#define SDE_CONNECTOR_DHDR_MEMPOOL_MAX_SIZE SZ_32
|
||||
@@ -264,6 +265,32 @@ struct sde_connector_ops {
|
||||
void *display, const char *cmd_buf,
|
||||
u32 cmd_buf_len);
|
||||
|
||||
/**
|
||||
* motUtil_transfer - Convert motUtil data and Transfer command
|
||||
* to the connected display panel
|
||||
* @display: Pointer to private display handle
|
||||
* @cmd_buf: Command buffer
|
||||
* @cmd_buf_len: Command buffer length in bytes
|
||||
* @motUtil_data: motUtil data information
|
||||
* Returns: Zero for success, negetive for failure
|
||||
*/
|
||||
int (*motUtil_transfer)(void *display, const char *cmd_buf,
|
||||
u32 cmd_buf_len, struct motUtil *motUtil_data);
|
||||
|
||||
/**
|
||||
* force_esd_disable - force to disable check_status
|
||||
* @display: Pointer to private display handle
|
||||
* Returns: true for forcing ESD disable
|
||||
*/
|
||||
bool (*force_esd_disable)(void *display);
|
||||
|
||||
/**
|
||||
* set_param - set display's feature param setting
|
||||
* @display: Pointer to private display handle
|
||||
* Returns: Zero for success, negative for failure
|
||||
*/
|
||||
int (*set_param)(void *display, struct msm_param_info *param_info);
|
||||
|
||||
/**
|
||||
* config_hdr - configure HDR
|
||||
* @connector: Pointer to drm connector structure
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (C) 2013 Red Hat
|
||||
@@ -3377,6 +3378,7 @@ static void sde_crtc_destroy_state(struct drm_crtc *crtc,
|
||||
struct sde_crtc_state *cstate;
|
||||
struct drm_encoder *enc;
|
||||
struct sde_kms *sde_kms;
|
||||
u32 encoder_mask;
|
||||
|
||||
if (!crtc || !state) {
|
||||
SDE_ERROR("invalid argument(s)\n");
|
||||
@@ -3392,9 +3394,11 @@ static void sde_crtc_destroy_state(struct drm_crtc *crtc,
|
||||
return;
|
||||
}
|
||||
|
||||
SDE_DEBUG("crtc%d\n", crtc->base.id);
|
||||
encoder_mask = state->encoder_mask ? state->encoder_mask :
|
||||
crtc->state->encoder_mask;
|
||||
SDE_DEBUG("crtc%d\n, encoder_mask=%d", crtc->base.id, encoder_mask);
|
||||
|
||||
drm_for_each_encoder_mask(enc, crtc->dev, state->encoder_mask)
|
||||
drm_for_each_encoder_mask(enc, crtc->dev, encoder_mask)
|
||||
sde_rm_release(&sde_kms->rm, enc, true);
|
||||
|
||||
__drm_atomic_helper_crtc_destroy_state(state);
|
||||
|
||||
@@ -675,8 +675,18 @@ static bool _sde_encoder_phys_cmd_is_ongoing_pptx(
|
||||
phys_enc->hw_intf->idx - INTF_0,
|
||||
atomic_read(&phys_enc->pending_kickoff_cnt),
|
||||
info.wr_ptr_line_count,
|
||||
info.intf_frame_count,
|
||||
info.wr_ptr_line_count,
|
||||
info.intf_frame_count,
|
||||
info.intf_line_count,
|
||||
phys_enc->cached_mode.vdisplay);
|
||||
|
||||
pr_err("%s enc:%d pp:%d intf:%d kickoff:%d wr_ptr:%d intf frame:%d int line:%d vdisp:%d\n",
|
||||
__func__, DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0,
|
||||
phys_enc->hw_intf->idx - INTF_0, atomic_read(&phys_enc->pending_kickoff_cnt),
|
||||
info.wr_ptr_line_count, info.intf_frame_count,
|
||||
info.intf_line_count, phys_enc->cached_mode.vdisplay);
|
||||
|
||||
if (info.wr_ptr_line_count > 0 && info.wr_ptr_line_count <
|
||||
phys_enc->cached_mode.vdisplay)
|
||||
return true;
|
||||
@@ -1498,6 +1508,8 @@ static int _sde_encoder_phys_cmd_wait_for_wr_ptr(
|
||||
|
||||
ret = frame_pending ? ret : 0;
|
||||
|
||||
SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", "panic");
|
||||
|
||||
/*
|
||||
* There can be few cases of ESD where CTL_START is cleared but
|
||||
* wr_ptr irq doesn't come. Signaling retire fence in these
|
||||
@@ -1826,7 +1838,6 @@ static void _sde_encoder_autorefresh_disable_seq2(
|
||||
> AUTOREFRESH_SEQ2_POLL_TIMEOUT) {
|
||||
SDE_ERROR_CMDENC(cmd_enc,
|
||||
"disable autorefresh failed\n");
|
||||
SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", "panic");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -633,6 +633,9 @@ static int sde_hw_intf_get_vsync_info(struct sde_hw_intf *intf,
|
||||
val = SDE_REG_READ(c, INTF_FRAME_COUNT);
|
||||
info->intf_frame_count = val;
|
||||
|
||||
val = SDE_REG_READ(c, INTF_LINE_COUNT) & 0xffff;
|
||||
info->intf_line_count = val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -697,6 +697,7 @@ struct sde_hw_pp_vsync_info {
|
||||
u32 rd_ptr_line_count;
|
||||
u32 wr_ptr_line_count;
|
||||
u32 intf_frame_count;
|
||||
u32 intf_line_count;
|
||||
};
|
||||
|
||||
#endif /* _SDE_HW_MDSS_H */
|
||||
@@ -490,7 +490,7 @@ void reg_dmav1_setup_dspp_vlutv18(struct sde_hw_dspp *ctx, void *cfg)
|
||||
return;
|
||||
}
|
||||
|
||||
data = kzalloc(VLUT_LEN, GFP_KERNEL);
|
||||
data = vzalloc(VLUT_LEN);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
@@ -537,7 +537,7 @@ void reg_dmav1_setup_dspp_vlutv18(struct sde_hw_dspp *ctx, void *cfg)
|
||||
}
|
||||
|
||||
exit:
|
||||
kfree(data);
|
||||
vfree(data);
|
||||
/* update flush bit */
|
||||
if (!rc && ctl && ctl->ops.update_bitmask_dspp_pavlut) {
|
||||
int dspp_idx;
|
||||
@@ -1152,7 +1152,7 @@ int reg_dmav1_setup_rc_datav1(struct sde_hw_dspp *ctx, void *cfg)
|
||||
}
|
||||
|
||||
DRM_DEBUG_DRIVER("allocating %u bytes of memory for dma\n", buf_sz);
|
||||
data = kzalloc(buf_sz, GFP_KERNEL);
|
||||
data = vzalloc(buf_sz);
|
||||
if (!data) {
|
||||
DRM_ERROR("memory allocation failed ret %d\n", rc);
|
||||
return -ENOMEM;
|
||||
@@ -1188,7 +1188,7 @@ int reg_dmav1_setup_rc_datav1(struct sde_hw_dspp *ctx, void *cfg)
|
||||
}
|
||||
|
||||
exit:
|
||||
kfree(data);
|
||||
vfree(data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1291,7 +1291,7 @@ void reg_dmav1_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg)
|
||||
return;
|
||||
}
|
||||
|
||||
data = kzalloc(PCC_LEN, GFP_KERNEL);
|
||||
data = vzalloc(PCC_LEN);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
@@ -1357,7 +1357,7 @@ void reg_dmav1_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg)
|
||||
DRM_ERROR("failed to kick off ret %d\n", rc);
|
||||
|
||||
exit:
|
||||
kfree(data);
|
||||
vfree(data);
|
||||
}
|
||||
|
||||
void reg_dmav1_setup_dspp_pa_hsicv17(struct sde_hw_dspp *ctx, void *cfg)
|
||||
@@ -2333,7 +2333,7 @@ static int reg_dmav1_setup_vig_igc_common(struct sde_hw_reg_dma_ops *dma_ops,
|
||||
hw_cfg->len, sizeof(struct drm_msm_igc_lut));
|
||||
}
|
||||
|
||||
data = kzalloc(VIG_1D_LUT_IGC_LEN * sizeof(u32), GFP_KERNEL);
|
||||
data = vzalloc(VIG_1D_LUT_IGC_LEN * sizeof(u32));
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -2395,7 +2395,7 @@ static int reg_dmav1_setup_vig_igc_common(struct sde_hw_reg_dma_ops *dma_ops,
|
||||
if (rc)
|
||||
DRM_ERROR("setting opcode failed ret %d\n", rc);
|
||||
exit:
|
||||
kfree(data);
|
||||
vfree(data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2597,7 +2597,7 @@ void reg_dmav1_setup_dma_igcv5(struct sde_hw_pipe *ctx, void *cfg,
|
||||
return;
|
||||
}
|
||||
|
||||
data = kzalloc(DMA_1D_LUT_IGC_LEN * sizeof(u32), GFP_KERNEL);
|
||||
data = vzalloc(DMA_1D_LUT_IGC_LEN * sizeof(u32));
|
||||
if (!data) {
|
||||
DRM_ERROR("failed to allocate memory for igc\n");
|
||||
return;
|
||||
@@ -2658,7 +2658,7 @@ void reg_dmav1_setup_dma_igcv5(struct sde_hw_pipe *ctx, void *cfg,
|
||||
if (rc)
|
||||
DRM_ERROR("failed to kick off ret %d\n", rc);
|
||||
igc_exit:
|
||||
kfree(data);
|
||||
vfree(data);
|
||||
}
|
||||
|
||||
static void dma_gcv5_off(struct sde_hw_pipe *ctx, void *cfg,
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <soc/qcom/scm.h>
|
||||
|
||||
@@ -55,6 +57,8 @@
|
||||
#include "soc/qcom/secure_buffer.h"
|
||||
#include "soc/qcom/qtee_shmbridge.h"
|
||||
|
||||
#include "sde_motUtil.h"
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "sde_trace.h"
|
||||
|
||||
@@ -147,6 +151,7 @@ static int _sde_debugfs_init(struct sde_kms *sde_kms)
|
||||
|
||||
(void) sde_debugfs_vbif_init(sde_kms, debugfs_root);
|
||||
(void) sde_debugfs_core_irq_init(sde_kms, debugfs_root);
|
||||
(void) sde_debugfs_mot_util_init(sde_kms, debugfs_root);
|
||||
|
||||
rc = sde_core_perf_debugfs_init(&sde_kms->perf, debugfs_root);
|
||||
if (rc) {
|
||||
@@ -1430,7 +1435,10 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
|
||||
.post_kickoff = dsi_conn_post_kickoff,
|
||||
.check_status = dsi_display_check_status,
|
||||
.enable_event = dsi_conn_enable_event,
|
||||
.motUtil_transfer = dsi_display_motUtil_transfer,
|
||||
.cmd_transfer = dsi_display_cmd_transfer,
|
||||
.force_esd_disable = dsi_display_force_esd_disable,
|
||||
.set_param = dsi_display_set_param,
|
||||
.cont_splash_config = dsi_display_cont_splash_config,
|
||||
.get_panel_vfp = dsi_display_get_panel_vfp,
|
||||
.get_default_lms = dsi_display_get_default_lms,
|
||||
@@ -1448,6 +1456,8 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
|
||||
.get_dst_format = NULL,
|
||||
.check_status = NULL,
|
||||
.cmd_transfer = NULL,
|
||||
.force_esd_disable = NULL,
|
||||
.set_param = NULL,
|
||||
.cont_splash_config = NULL,
|
||||
.get_panel_vfp = NULL,
|
||||
};
|
||||
@@ -1465,6 +1475,8 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
|
||||
.set_colorspace = dp_connector_set_colorspace,
|
||||
.config_hdr = dp_connector_config_hdr,
|
||||
.cmd_transfer = NULL,
|
||||
.force_esd_disable = NULL,
|
||||
.set_param = NULL,
|
||||
.cont_splash_config = NULL,
|
||||
.get_panel_vfp = NULL,
|
||||
.update_pps = dp_connector_update_pps,
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
#define SDE_KMS_OPS_PREPARE_PLANE_FB BIT(3)
|
||||
|
||||
/* ESD status check interval in miliseconds */
|
||||
#define STATUS_CHECK_INTERVAL_MS 5000
|
||||
#define STATUS_CHECK_INTERVAL_MS 8000
|
||||
|
||||
/**
|
||||
* enum sde_kms_smmu_state: smmu state
|
||||
|
||||
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "motUtil:[%s]" fmt, __func__
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "sde_connector.h"
|
||||
#include "sde_encoder.h"
|
||||
#include "sde_motUtil.h"
|
||||
#include "dsi_display.h"
|
||||
|
||||
|
||||
#define MAIN_DSI_CONN_NAME "DSI-1"
|
||||
#define CLI_DSI_CONN_NAME "DSI-2"
|
||||
|
||||
struct motUtil motUtil_data;
|
||||
|
||||
static ssize_t _sde_debugfs_motUtil_string2num(const char __user *buf,
|
||||
size_t count, char buffer[])
|
||||
{
|
||||
char *input, *input_copy, *token, *input_dup = NULL;
|
||||
const char *delim =" ";
|
||||
u32 buf_size = 0;
|
||||
int rc=0, strtoint;
|
||||
|
||||
/*copy the data from user space*/
|
||||
input = kmalloc(count + 1, GFP_KERNEL);
|
||||
if (!input)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(input, buf, count)) {
|
||||
SDE_ERROR("copy from user failed\n");
|
||||
rc = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
input[count]='\0';
|
||||
SDE_INFO("input_cmd = %s\n", input);
|
||||
|
||||
input_copy = kstrdup(input, GFP_KERNEL);
|
||||
if (!input_copy) {
|
||||
rc = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
input_dup = input_copy,
|
||||
token = strsep(&input_copy, delim);
|
||||
while (token) {
|
||||
rc = kstrtoint(token, 0, &strtoint);
|
||||
if (rc) {
|
||||
rc = -EIO;
|
||||
SDE_ERROR("input buffer conversion failed\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (buf_size >= MAX_CMD_PAYLOAD_SIZE) {
|
||||
SDE_ERROR("buffer size exceeding the limit %d\n",
|
||||
MAX_CMD_PAYLOAD_SIZE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
buffer[buf_size++] = (strtoint & 0xff);
|
||||
token = strsep(&input_copy, delim);
|
||||
}
|
||||
|
||||
SDE_DEBUG("command packet size in bytes: %u\n", buf_size);
|
||||
rc = buf_size;
|
||||
end:
|
||||
kfree(input_dup);
|
||||
kfree(input);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct drm_connector *_sde_debugfs_motUtil_get_drm_conn(
|
||||
struct sde_kms *kms,
|
||||
size_t count, char input[])
|
||||
{
|
||||
struct drm_device *dev = kms->dev;
|
||||
struct drm_connector *conn = NULL;
|
||||
int found_conn = 0;
|
||||
enum sde_motUtil_disp_cmd panel_type = input[DISPUTIL_PANEL_TYPE];
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_for_each_connector_iter(conn, &conn_iter) {
|
||||
if (panel_type == MOTUTIL_MAIN_DISP) {
|
||||
if (!strncmp(conn->name, MAIN_DSI_CONN_NAME, 5)) {
|
||||
SDE_DEBUG("found MAIN disp conn\n");
|
||||
found_conn = 1;
|
||||
break;
|
||||
}
|
||||
} else if (panel_type == MOTUTIL_CLI_DISP) {
|
||||
if (!strncmp(conn->name, CLI_DSI_CONN_NAME, 5)) {
|
||||
SDE_DEBUG("found CLI disp conn\n");
|
||||
found_conn = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
||||
if (found_conn)
|
||||
return conn;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct sde_connector *_sde_debugfs_motUtil_get_sde_conn(
|
||||
struct sde_kms *kms,
|
||||
size_t count, char input[])
|
||||
{
|
||||
struct drm_connector *conn = NULL;
|
||||
struct sde_connector *sde_conn = NULL;
|
||||
|
||||
conn = _sde_debugfs_motUtil_get_drm_conn(kms, count, input);
|
||||
if (conn)
|
||||
sde_conn = to_sde_connector(conn);
|
||||
else
|
||||
DRM_ERROR("Can not find SDE Connector for %s\n",
|
||||
(input[DISPUTIL_PANEL_TYPE] == MOTUTIL_MAIN_DISP) ?
|
||||
"Main Display" : "CLI Display");
|
||||
|
||||
return sde_conn;
|
||||
}
|
||||
|
||||
static int _sde_debugfs_motUtil_transfer(struct sde_kms *kms,
|
||||
size_t count, char input[])
|
||||
{
|
||||
struct sde_connector *sde_conn = NULL;
|
||||
int ret = 0;
|
||||
enum sde_motUtil_disp_cmd panel_type = input[DISPUTIL_PANEL_TYPE];
|
||||
|
||||
if (panel_type > MOTUTIL_CLI_DISP) {
|
||||
SDE_ERROR("Invalid panel number = %d\n", panel_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_conn = _sde_debugfs_motUtil_get_sde_conn(kms, count, input);
|
||||
if (!sde_conn) {
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (sde_conn && !sde_conn->ops.motUtil_transfer) {
|
||||
SDE_ERROR("no motUtil_transfer support for connector name %s\n",
|
||||
sde_conn->name);
|
||||
ret = -ENOENT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (motUtil_data.rd_buf) {
|
||||
mutex_lock(&sde_conn->lock);
|
||||
ret = sde_conn->ops.motUtil_transfer(sde_conn->display,
|
||||
input, count, &motUtil_data);
|
||||
motUtil_data.cmd_status = ret;
|
||||
motUtil_data.read_len = ret;
|
||||
mutex_unlock(&sde_conn->lock);
|
||||
|
||||
ret = count;
|
||||
} else
|
||||
ret = -ENOMEM;
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int _sde_debugfs_motUtil_kms_prop_test(struct sde_kms *kms,
|
||||
size_t count, char input[])
|
||||
{
|
||||
struct drm_connector *conn = NULL;
|
||||
struct sde_connector *sde_conn = NULL;
|
||||
struct drm_property *property;
|
||||
|
||||
int ret = 0;
|
||||
enum msm_mdp_conn_property conn_prop_idx;
|
||||
uint64_t prop_val;
|
||||
|
||||
conn = _sde_debugfs_motUtil_get_drm_conn(kms, count, input);
|
||||
if (!conn) {
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
sde_conn = to_sde_connector(conn);
|
||||
if (!sde_conn) {
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (count < KMSPROPTEST_NEW_VAL) {
|
||||
DRM_ERROR(" Number of Input data is invalid (%zu).\n", count);
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch (input[KMSPROPTEST_PROP_INDEX]) {
|
||||
case KMSPROPTEST_TYPE_HBM:
|
||||
conn_prop_idx = CONNECTOR_PROP_HBM;
|
||||
break;
|
||||
case KMSPROPTEST_TYPE_ACL:
|
||||
conn_prop_idx = CONNECTOR_PROP_ACL;
|
||||
break;
|
||||
case KMSPROPTEST_TYPE_CABC:
|
||||
conn_prop_idx = CONNECTOR_PROP_CABC;
|
||||
break;
|
||||
case KMSPROPTEST_TYPE_DC:
|
||||
conn_prop_idx = CONNECTOR_PROP_DC;
|
||||
break;
|
||||
case KMSPROPTEST_TYPE_COLOR:
|
||||
conn_prop_idx = CONNECTOR_PROP_COLOR;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR(" Invalid KMSPROPTEST_PROP_INDEX = %d\n",
|
||||
input[KMSPROPTEST_PROP_INDEX]);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto end;
|
||||
|
||||
property = msm_property_index_to_drm_property(&sde_conn->property_info,
|
||||
conn_prop_idx);
|
||||
if (!property) {
|
||||
SDE_ERROR("invalid property index %d for sde_conn_name=%s\n",
|
||||
conn_prop_idx, sde_conn->name);
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
prop_val = sde_connector_get_property(conn->state, conn_prop_idx);
|
||||
if (prop_val == PARAM_STATE_DISABLE) {
|
||||
DRM_ERROR("This KMS Property=%d is disabled\n", conn_prop_idx);
|
||||
ret = -EPERM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch(input[KMSPROPTEST_PROP_TYPE]) {
|
||||
case KMSPROPTEST_GETPROP:
|
||||
motUtil_data.read_cmd = true;
|
||||
motUtil_data.val = (int)prop_val;
|
||||
break;
|
||||
case KMSPROPTEST_SETPROP:
|
||||
motUtil_data.read_cmd = false;
|
||||
if (conn->funcs && conn->funcs->atomic_set_property) {
|
||||
ret = conn->funcs->atomic_set_property(conn,
|
||||
conn->state, property,
|
||||
input[KMSPROPTEST_NEW_VAL]);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
DRM_ERROR("Unsupport KMS set property\n");
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Invalid KMSPROPTEST_PROP_TYPE = %d\n",
|
||||
input[KMSPROPTEST_PROP_TYPE]);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
motUtil_data.cmd_status = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t _sde_debugfs_motUtil_exe_command(struct sde_kms *kms,
|
||||
size_t count, char input[])
|
||||
{
|
||||
int ret = 0;
|
||||
enum sde_motUtil_type motUtil_type = input[0];
|
||||
|
||||
motUtil_data.motUtil_type = motUtil_type;
|
||||
switch (motUtil_type) {
|
||||
case MOTUTIL_DISP_UTIL:
|
||||
ret = _sde_debugfs_motUtil_transfer(kms, count, input);
|
||||
break;
|
||||
case MOTUTIL_KMS_PROP_TEST:
|
||||
ret = _sde_debugfs_motUtil_kms_prop_test(kms, count, input);
|
||||
break;
|
||||
default:
|
||||
SDE_ERROR("Un-support motUtil type = %d\n", motUtil_type);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _sde_debugfs_motUtil_open(struct inode *inode,
|
||||
struct file *file)
|
||||
{
|
||||
if (!inode || !file)
|
||||
return -EINVAL;
|
||||
|
||||
/* non-seekable */
|
||||
file->private_data = inode->i_private;
|
||||
return nonseekable_open(inode, file);
|
||||
}
|
||||
|
||||
static ssize_t _sde_debugfs_motUtil_write(struct file *file,
|
||||
const char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
u32 buf_size = 0;
|
||||
char buffer[MAX_CMD_PAYLOAD_SIZE];
|
||||
struct sde_kms *kms = (struct sde_kms *)file->private_data;
|
||||
int ret = 0;
|
||||
|
||||
if (*ppos || !kms) {
|
||||
SDE_ERROR("invalid argument(s)\n");
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
buf_size = _sde_debugfs_motUtil_string2num(buf, count, buffer);
|
||||
if (buf_size <= 0){
|
||||
SDE_ERROR("invalid input\n");
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
mutex_lock(&motUtil_data.lock);
|
||||
ret = _sde_debugfs_motUtil_exe_command(kms, count, buffer);
|
||||
mutex_unlock(&motUtil_data.lock);
|
||||
end:
|
||||
motUtil_data.cmd_status = ret;
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t _sde_debugfs_motUtil_dispUtil_read(char *buffer)
|
||||
{
|
||||
int blen = 0, i;
|
||||
|
||||
if (motUtil_data.read_len) {
|
||||
blen = snprintf(buffer, 16, "motUtil_read: ");
|
||||
for (i = 0; i < motUtil_data.read_len; i ++)
|
||||
blen += snprintf((buffer + blen) , 6, "0x%02x ",
|
||||
*motUtil_data.rd_buf++);
|
||||
|
||||
blen += snprintf((buffer + blen), 2, "\n");
|
||||
} else
|
||||
SDE_ERROR("motUtil failed to read from panel\n");
|
||||
|
||||
return blen;
|
||||
}
|
||||
|
||||
static ssize_t _sde_debugfs_motUtil_read(struct file *file,
|
||||
char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
int blen = 0;
|
||||
char buffer[MAX_CMD_PAYLOAD_SIZE];
|
||||
|
||||
if (*ppos)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&motUtil_data.lock);
|
||||
if (motUtil_data.cmd_status < 0 || !motUtil_data.read_cmd) {
|
||||
blen = snprintf(buffer, MAX_CMD_PAYLOAD_SIZE,
|
||||
"motUtil_status: %d\n",
|
||||
motUtil_data.cmd_status);
|
||||
} else if (motUtil_data.motUtil_type == MOTUTIL_DISP_UTIL) {
|
||||
blen = _sde_debugfs_motUtil_dispUtil_read(buffer);
|
||||
} else if (motUtil_data.motUtil_type == MOTUTIL_KMS_PROP_TEST) {
|
||||
blen = snprintf(buffer, 16, "motUtil_read: ");
|
||||
blen += snprintf((buffer + blen), 12, "0x%08x ",
|
||||
motUtil_data.val);
|
||||
blen += snprintf((buffer + blen), 2, "\n");
|
||||
}
|
||||
|
||||
|
||||
SDE_INFO("%s\n", buffer);
|
||||
|
||||
if (blen <= 0) {
|
||||
SDE_ERROR("snprintf failed, blen %d\n", blen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (copy_to_user(buf, buffer, min(count, (size_t)blen+1))) {
|
||||
SDE_ERROR("copy to user buffer failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
*ppos += blen;
|
||||
mutex_unlock(&motUtil_data.lock);
|
||||
return blen;
|
||||
}
|
||||
|
||||
static const struct file_operations sde_debugfs_motUtil_fops = {
|
||||
.open = _sde_debugfs_motUtil_open,
|
||||
.read = _sde_debugfs_motUtil_read,
|
||||
.write = _sde_debugfs_motUtil_write,
|
||||
};
|
||||
|
||||
int sde_debugfs_mot_util_init(struct sde_kms *sde_kms,
|
||||
struct dentry *parent)
|
||||
{
|
||||
debugfs_create_file("motUtil", 0606, parent,
|
||||
sde_kms, &sde_debugfs_motUtil_fops);
|
||||
|
||||
motUtil_data.rd_buf = kzalloc(SZ_4K, GFP_KERNEL);
|
||||
if (!motUtil_data.rd_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
motUtil_data.te_enable = true;
|
||||
mutex_init(&motUtil_data.lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MOTUTIL_H__
|
||||
#define __MOTUTIL_H__
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* /d/dri/0/debug/motUtil sysfs *
|
||||
* - This is Mot debug sysfs to provide some tools to test panel and panel *
|
||||
* features. This tool only exist with the userdebug and Engineering build *
|
||||
* - Currently, this motUtil will provide 3 kind of tests and it can enhance *
|
||||
* to test more if needed *
|
||||
* - Test#1: DispUtil: This test is able to send any MIPI DSI command and *
|
||||
* it can read any data back from the panel *
|
||||
* - Test#2: TeTest: This test will be used to test the TE trace between *
|
||||
* the panels and MDSS to make sure it works *
|
||||
* - Test#3: kmsPropTest: This test will test the panel features such as *
|
||||
* HBM, ACL, CABC, etc. It can read these features configurations*
|
||||
* in the KMS property and it can change these setting from KMS *
|
||||
* property. *
|
||||
* - Usage: *
|
||||
* - 1st byte will indicate which motUtil test will be run. *
|
||||
* 0x00 = dispUtil, 0x01 = TeTest, 0x02 = kmsPropTest *
|
||||
* --------------------------------------------------------------------------*
|
||||
* - dispUtil: *
|
||||
* 1st byte: 0x00: dispUtil *
|
||||
* 2nd byte: 0x00: primary panel and 0x01: Secondary panel *
|
||||
* 3rd byte: 0x00: MIPI write cmd to panel and 0x01: MIPI read *
|
||||
* 4th byte: 0x00: MIPI HS mode and 0x01: MIPI LP mode *
|
||||
* 5th byte: 0x00: MIPI DCS cmd and 0x01: MIPI generaic cmd *
|
||||
* 6th byte: Indicate number of bytes to read from panel *
|
||||
* 7th and 8th: Indicate number of bytes for the payload cmd *
|
||||
* 9th and .. :the payload cmd *
|
||||
* - Example: *
|
||||
* echo "0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x28" > motUtil *
|
||||
* - This will send a mipi DSC command "0x28" to panel and *
|
||||
* which will request the panel to turn off the panel *
|
||||
* cat motUtil *
|
||||
* - This will report a sending previous cmd status *
|
||||
* 0: send success or errno if it fails *
|
||||
* echo "0x00 0x01 0x01 0x00 0x00 0x01 0x00 0x01 0x0a" > motUtil *
|
||||
* - This will send MIPI read cmd "0xa" to the panel. *
|
||||
* cat motUtil *
|
||||
* - number of reading bytes from previous command or errno if it fails*
|
||||
*---------------------------------------------------------------------------*
|
||||
* - TeTest: This test has been removed *
|
||||
*---------------------------------------------------------------------------*
|
||||
* - kmsPropTest *
|
||||
* 1st byte: kmsPropTest *
|
||||
* 2nd byte: 0x00: primary panel and 0x01: Secondary panel *
|
||||
* 3rd byte: 0x00: get KMS property and 0x01: set KMS property *
|
||||
* 4th byte: 0x00: HBM 0x01: ACL for the KMS property/panel feature *
|
||||
* 5th byte: new data for a "set KMS property" operation *
|
||||
* - Example *
|
||||
* echo "0x02 0x00 0x010 0x00 0x00" > motUtil *
|
||||
* - This will read the HBM setting of the primary panel in the KMS *
|
||||
* property. *
|
||||
* cat motUtil *
|
||||
* - This will return the status of previous cmd. *
|
||||
* 0 if success or errno if it fails *
|
||||
* echo "0x02 0x00 0x01 0x00 0x01" > motUtil *
|
||||
* - This will turn on the HBM feature of the primary panel in the KMS *
|
||||
* property. The panel's backlight will be brighter when HBM is on *
|
||||
* cat motUtil *
|
||||
* - This will return the status of previous cmd. *
|
||||
* 0 if success or errno if it fails *
|
||||
* echo "0x02 0x00 0x010 0x00 0x00" > motUtil *
|
||||
* - This will read back the HBM setting in KMS property *
|
||||
* echo "0x02 0x00 0x01 0x00 0x00" > motUtil *
|
||||
* - This will turn off the HBM feature of the primary panel in the KMS *
|
||||
* property. The panel's backlight will be dimmer when HBM is off *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
enum sde_motUtil_type {
|
||||
MOTUTIL_DISP_UTIL = 0,
|
||||
MOTUTIL_TE_TEST,
|
||||
MOTUTIL_KMS_PROP_TEST,
|
||||
};
|
||||
|
||||
enum sde_motUtil_disp_cmd {
|
||||
DISPUTIL_TYPE = 0,
|
||||
DISPUTIL_PANEL_TYPE,
|
||||
DISPUTIL_CMD_TYPE,
|
||||
DISPUTIL_CMD_XFER_MODE,
|
||||
DISPUTIL_MIPI_CMD_TYPE,
|
||||
DISPUTIL_NUM_BYTE_RD,
|
||||
DISPUTIL_PAYLOAD_LEN_U,
|
||||
DISPUTIL_PAYLOAD_LEN_L,
|
||||
DISPUTIL_PAYLOAD,
|
||||
};
|
||||
|
||||
enum sde_motUtil_kmsPropTest_cmd {
|
||||
KMSPROPTEST_TYPE,
|
||||
KMSPROPTEST_PANEL_TYPE,
|
||||
KMSPROPTEST_PROP_TYPE,
|
||||
KMSPROPTEST_PROP_INDEX,
|
||||
KMSPROPTEST_NEW_VAL,
|
||||
};
|
||||
|
||||
enum sde_motUtil_kmsPropTest_ConnPropType {
|
||||
KMSPROPTEST_TYPE_HBM,
|
||||
KMSPROPTEST_TYPE_ACL,
|
||||
KMSPROPTEST_TYPE_CABC,
|
||||
KMSPROPTEST_TYPE_DC,
|
||||
KMSPROPTEST_TYPE_COLOR,
|
||||
};
|
||||
|
||||
struct motUtil {
|
||||
struct mutex lock;
|
||||
enum sde_motUtil_type motUtil_type;
|
||||
bool read_cmd;
|
||||
int cmd_status;
|
||||
u16 read_len;
|
||||
u8 *rd_buf;
|
||||
int val;
|
||||
bool te_enable;
|
||||
};
|
||||
|
||||
#define DISPUTIL_DSI_WRITE 0
|
||||
#define DISPUTIL_DSI_READ 1
|
||||
|
||||
#define DISPUTIL_DSI_DCS 0
|
||||
#define DISPUTIL_DSI_GENERIC 1
|
||||
|
||||
#define DISPUTIL_DSI_HS_MODE 0
|
||||
#define DISPUTIL_DSI_LP_MODE 1
|
||||
|
||||
#define KMSPROPTEST_GETPROP 0
|
||||
#define KMSPROPTEST_SETPROP 1
|
||||
|
||||
#define MOTUTIL_MAIN_DISP 0
|
||||
#define MOTUTIL_CLI_DISP 1
|
||||
|
||||
int sde_debugfs_mot_util_init(struct sde_kms *sde_kms,
|
||||
struct dentry *parent);
|
||||
|
||||
#endif /* __MOTUTIL_H__ */
|
||||
@@ -3254,6 +3254,7 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
|
||||
u32 *dump_addr = NULL;
|
||||
u32 status = 0;
|
||||
struct sde_debug_bus_entry *head;
|
||||
phys_addr_t phys = 0;
|
||||
int list_size;
|
||||
int i;
|
||||
u32 offset;
|
||||
@@ -3291,7 +3292,8 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
|
||||
|
||||
if (in_mem) {
|
||||
if (!(*dump_mem))
|
||||
*dump_mem = vzalloc(list_size);
|
||||
*dump_mem = dma_alloc_coherent(sde_dbg_base.dev,
|
||||
list_size, &phys, GFP_KERNEL);
|
||||
|
||||
if (*dump_mem) {
|
||||
dump_addr = *dump_mem;
|
||||
@@ -3401,6 +3403,7 @@ static void _sde_dbg_dump_vbif_dbg_bus(struct sde_dbg_vbif_debug_bus *bus)
|
||||
u32 value, d0, d1;
|
||||
unsigned long reg, reg1, reg2;
|
||||
struct vbif_debug_bus_entry *head;
|
||||
phys_addr_t phys = 0;
|
||||
int i, list_size = 0;
|
||||
void __iomem *mem_base = NULL;
|
||||
struct vbif_debug_bus_entry *dbg_bus;
|
||||
@@ -3450,7 +3453,8 @@ static void _sde_dbg_dump_vbif_dbg_bus(struct sde_dbg_vbif_debug_bus *bus)
|
||||
|
||||
if (in_mem) {
|
||||
if (!(*dump_mem))
|
||||
*dump_mem = vzalloc(list_size);
|
||||
*dump_mem = dma_alloc_coherent(sde_dbg_base.dev,
|
||||
list_size, &phys, GFP_KERNEL);
|
||||
|
||||
if (*dump_mem) {
|
||||
dump_addr = *dump_mem;
|
||||
@@ -3541,12 +3545,14 @@ static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
|
||||
int i;
|
||||
u32 reg_dump_size;
|
||||
struct sde_dbg_base *dbg_base = &sde_dbg_base;
|
||||
phys_addr_t phys = 0;
|
||||
|
||||
mutex_lock(&sde_dbg_base.mutex);
|
||||
|
||||
reg_dump_size = _sde_dbg_get_reg_dump_size();
|
||||
if (!dbg_base->reg_dump_base)
|
||||
dbg_base->reg_dump_base = vzalloc(reg_dump_size);
|
||||
dbg_base->reg_dump_base = dma_alloc_coherent(sde_dbg_base.dev,
|
||||
reg_dump_size, &phys, GFP_KERNEL);
|
||||
|
||||
dbg_base->reg_dump_addr = dbg_base->reg_dump_base;
|
||||
|
||||
@@ -4785,7 +4791,6 @@ static void sde_dbg_reg_base_destroy(void)
|
||||
list_del(&blk_base->reg_base_head);
|
||||
kfree(blk_base);
|
||||
}
|
||||
vfree(dbg_base->reg_dump_base);
|
||||
}
|
||||
|
||||
static void sde_dbg_buses_destroy(void)
|
||||
|
||||
@@ -86,7 +86,7 @@ enum sde_dbg_dump_context {
|
||||
* sysfs node or panic. This prevents kernel log from evtlog message
|
||||
* flood.
|
||||
*/
|
||||
#define SDE_EVTLOG_PRINT_ENTRY 256
|
||||
#define SDE_EVTLOG_PRINT_ENTRY 512
|
||||
|
||||
/*
|
||||
* evtlog keeps this number of entries in memory for debug purpose. This
|
||||
@@ -137,7 +137,7 @@ extern struct sde_dbg_evtlog *sde_dbg_base_evtlog;
|
||||
* number must be greater than number of possible writes in at least one
|
||||
* single commit.
|
||||
*/
|
||||
#define SDE_REGLOG_ENTRY 1024
|
||||
#define SDE_REGLOG_ENTRY 2048
|
||||
|
||||
struct sde_dbg_reglog_log {
|
||||
s64 time;
|
||||
|
||||
Reference in new issue
Block a user