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:
hujing3 authored and Gilberto Gambugge committed 2023-06-01 00:43:20 -03:00
1 parent e9809af5c5
commit f55d542166
4 files changed
+120

No files matched your search

+98
View File
@@ -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--) {
+10
View File
@@ -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";
}
+8
View File
@@ -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;
+4
View File
@@ -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;