disp: msm: dsi: Check panel's power_mode during resume

Check the panel's power_mode after it turns on, to see if the panel can turn
on correctly. If it doesn't not, then trigger the ESD recovery to fix it.

Port from: 767ee61

Change-Id: Iaf7f5da55a839037b0fa1e25ac84faf5df480ae5
Signed-off-by: Bang Nguyen <bangnguyen@motorola.com>
Reviewed-on: https://gerrit.mot.com/1697279
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Guobin Zhang <zhanggb@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
Bang Nguyen 2019-07-30 13:45:53 -05:00 • committed by tongkun1
commit ffaa831b2a
4 changed files with 148 additions and 3 deletions

View file

@ -731,6 +731,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;

View file

@ -764,6 +764,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

View file

@ -11,6 +11,7 @@
#include <linux/pwm.h>
#include <video/mipi_display.h>
#include "dsi_display.h"
#include "dsi_panel.h"
#include "dsi_ctrl_hw.h"
#include "dsi_parser.h"
@ -3535,6 +3536,74 @@ static void dsi_panel_setup_vm_ops(struct dsi_panel *panel, bool trusted_vm_env)
panel->panel_ops.parse_gpios = dsi_panel_parse_gpios;
panel->panel_ops.parse_power_cfg = dsi_panel_parse_power_cfg;
}
static int dsi_panel_parse_mot_panel_config(struct dsi_panel *panel,
struct device_node *of_node)
{
int rc;
struct drm_panel_esd_config *esd_config = &panel->esd_config;
rc = of_property_read_u32(of_node,
"qcom,mdss-dsi-panel-on-check-value",
&panel->disp_on_chk_val);
if (rc) {
/*
* No panel_on_chk_val is configured in dts, then check for ESD
* setting */
if ((esd_config->status_cmd.count == 1) &&
(esd_config->status_value) &&
(esd_config->status_value[0] != 0)) {
panel->disp_on_chk_val = esd_config->status_value[0];
DSI_INFO("disp_on_chk_val is set with ESD's chk value\n");
} else {
DSI_INFO("hardcode disp_on_chk_val\n");
panel->disp_on_chk_val = 0x9c;
}
} else
DSI_INFO("disp_on_chk_val = 0x%x is defined\n",
panel->disp_on_chk_val);
panel->no_panel_on_read_support = of_property_read_bool(of_node,
"qcom,mdss-dsi-no-panel-on-read-support");
return rc;
}
static int dsi_panel_get_pwr_mode(struct dsi_panel *panel, u8 *val)
{
int rc = 0;
struct dsi_cmd_desc cmd;
struct dsi_display *display = NULL;
u32 flags;
u8 payload = MIPI_DCS_GET_POWER_MODE;
display = container_of(panel->host, struct dsi_display, host);
if (!display) {
DSI_ERR("failed to retrieve display handle\n", display);
rc = -EINVAL;
goto end;
}
memset(&cmd, 0x00, sizeof(struct dsi_cmd_desc));
flags = DSI_CTRL_CMD_READ;
cmd.msg.type = MIPI_DSI_DCS_READ;
cmd.last_command = 1;
cmd.msg.flags = MIPI_DSI_MSG_LASTCOMMAND;
cmd.msg.channel = 0;
cmd.msg.tx_len = 1;
cmd.msg.tx_buf = &payload;
cmd.msg.rx_len = 1;
cmd.msg.rx_buf = val;
rc = dsi_display_cmd_mipi_transfer(display, &cmd.msg, flags);
if (rc <= 0) {
DSI_ERR("Failed to call dsi_display_cmd_transfer. rc=%d\n", rc);
rc = -EIO;
} else
rc = 0;
end:
return rc;
}
struct dsi_panel *dsi_panel_get(struct device *parent,
@ -3575,6 +3644,10 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
"qcom,mdss-dsi-panel-physical-type", NULL);
if (panel_physical_type && !strcmp(panel_physical_type, "oled"))
panel->panel_type = DSI_DISPLAY_PANEL_TYPE_OLED;
rc = dsi_panel_parse_mot_panel_config(panel, of_node);
if (rc)
DSI_DEBUG("failed to parse mot_panel_config, rc = %d\n", rc);
rc = dsi_panel_parse_host_config(panel);
if (rc) {
DSI_ERR("failed to parse host configuration, rc=%d\n",
@ -4737,6 +4810,7 @@ int dsi_panel_post_switch(struct dsi_panel *panel)
int dsi_panel_enable(struct dsi_panel *panel)
{
int rc = 0;
u8 pwr_mode;
if (!panel) {
DSI_ERR("Invalid params\n");
@ -4747,11 +4821,31 @@ int dsi_panel_enable(struct dsi_panel *panel)
mutex_lock(&panel->panel_lock);
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_ON);
if (rc)
if (rc) {
DSI_ERR("[%s] failed to send DSI_CMD_SET_ON cmds, rc=%d\n",
panel->name, rc);
else
panel->panel_initialized = true;
goto err;
}
if (!panel->no_panel_on_read_support) {
rc = dsi_panel_get_pwr_mode(panel, &pwr_mode);
if (rc) {
DSI_ERR("[%s] Failed to read pwr_mode, rc = %d",
panel->name, rc);
goto err;
}
if (pwr_mode != panel->disp_on_chk_val) {
DSI_ERR("%s: Read Pwr_mode=0%x is not matched with expected value =0x%x\n",
__func__, pwr_mode, panel->disp_on_chk_val);
} else
DSI_INFO("-. Pwr_mode(0x0A) = 0x%x\n", pwr_mode);
} else
DSI_INFO("-: no_panel_on_read_support is set\n");
panel->panel_initialized = true;
err:
mutex_unlock(&panel->panel_lock);
return rc;
}

View file

@ -274,6 +274,9 @@ struct dsi_panel {
bool esd_utag_enable;
u64 panel_ver;
char panel_name[DSI_PANEL_MAX_PANEL_LEN];
u32 disp_on_chk_val;
bool no_panel_on_read_support;
};
static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel)