kernel:dsi: ESD te support for video mode panel
Add ESD TE check on video mode panel to fix TP noise issue when configed as read_reg ESD Change-Id: Idf6ce40fd4275a03f169f8c3bca48e56303b1c77 Signed-off-by: hujing3 <hujing3@lenovo.com> Reviewed-on: https://gerrit.mot.com/1820691 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
1 parent
e9809af5c5
commit
f55d542166
4 files changed
+120
No files matched your search
@@ -837,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)
|
||||
{
|
||||
@@ -895,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 {
|
||||
@@ -4055,6 +4072,76 @@ 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;
|
||||
@@ -4117,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--) {
|
||||
|
||||
@@ -2761,6 +2761,12 @@ static int dsi_panel_parse_gpios(struct dsi_panel *panel)
|
||||
panel->reset_config.tp_rst_gpio = utils->get_named_gpio(utils->data,
|
||||
"qcom,mdss-dsi-tp-rst-gpio", 0);
|
||||
|
||||
panel->video_te_gpio = utils->get_named_gpio(utils->data,
|
||||
"qcom,video-te-gpio", 0);
|
||||
if (panel->video_te_gpio && gpio_is_valid(panel->video_te_gpio)) {
|
||||
DSI_INFO("%s:%d, Video TE gpio is specified\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
panel->reset_config.disp_en_gpio = utils->get_named_gpio(utils->data,
|
||||
"qcom,5v-boost-gpio",
|
||||
0);
|
||||
@@ -3829,6 +3835,8 @@ static int dsi_panel_parse_esd_config(struct dsi_panel *panel)
|
||||
esd_config->status_mode = ESD_MODE_SW_BTA;
|
||||
} else if (!strcmp(string, "reg_read")) {
|
||||
esd_config->status_mode = ESD_MODE_REG_READ;
|
||||
} else if (!strcmp(string, "te_signal_check_video")) {
|
||||
esd_config->status_mode = ESD_MODE_PANEL_TE_VIDEO;
|
||||
} else if (!strcmp(string, "te_signal_check")) {
|
||||
if (panel->panel_mode == DSI_OP_CMD_MODE) {
|
||||
esd_config->status_mode = ESD_MODE_PANEL_TE;
|
||||
@@ -3858,6 +3866,8 @@ static int dsi_panel_parse_esd_config(struct dsi_panel *panel)
|
||||
esd_mode = "register_read";
|
||||
} else if (panel->esd_config.status_mode == ESD_MODE_SW_BTA) {
|
||||
esd_mode = "bta_trigger";
|
||||
} else if (panel->esd_config.status_mode == ESD_MODE_PANEL_TE_VIDEO) {
|
||||
esd_mode = "te_check_video";
|
||||
} else if (panel->esd_config.status_mode == ESD_MODE_PANEL_TE) {
|
||||
esd_mode = "te_check";
|
||||
}
|
||||
|
||||
@@ -196,6 +196,7 @@ 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
|
||||
@@ -291,6 +292,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;
|
||||
|
||||
@@ -2293,6 +2293,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;
|
||||
@@ -2328,6 +2329,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;
|
||||
|
||||
Reference in new issue
Block a user