diff --git a/msm/dsi/dsi_display.h b/msm/dsi/dsi_display.h index 7406d78295..9b4da4063d 100644 --- a/msm/dsi/dsi_display.h +++ b/msm/dsi/dsi_display.h @@ -184,6 +184,7 @@ struct dsi_display_ext_bridge { * @misr_frame_count Number of frames to accumulate the MISR value * @esd_trigger field indicating ESD trigger through debugfs * @poms_te_work POMS delayed work for disabling panel TE + * @esd_fail_count Count of continuous ESD check failures * @te_source vsync source pin information * @clk_gating_config Clocks for which clock gating needs to be enabled * @queue_cmd_waits Indicates if wait for dma commands done has to be queued. @@ -277,6 +278,8 @@ struct dsi_display { struct dsi_display_boot_param *boot_disp; + u32 esd_fail_count; + u32 te_source; u32 clk_gating_config; bool queue_cmd_waits; diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index aad5a8863c..d911d78b03 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -2380,6 +2380,8 @@ static void _sde_connector_report_panel_dead(struct sde_connector *conn, bool skip_pre_kickoff) { struct drm_event event; + struct dsi_display *display; + u32 const max_conseq_esd_fail_count = 5; if (!conn) return; @@ -2402,6 +2404,17 @@ static void _sde_connector_report_panel_dead(struct sde_connector *conn, SDE_EVT32(SDE_EVTLOG_ERROR); SDE_ERROR("esd check failed report PANEL_DEAD conn_id: %d enc_id: %d\n", conn->base.base.id, conn->encoder->base.id); + + if (conn->connector_type != DRM_MODE_CONNECTOR_DSI) + return; + + display = (struct dsi_display *)conn->display; + display->esd_fail_count++; + if (display->esd_fail_count == max_conseq_esd_fail_count) { + SDE_ERROR("Triggered reset on multiple PANEL_DEAD instances\n"); + SDE_DBG_DUMP("all", "dbg_bus", "dsi_dbg_bus", + "vbif_dbg_bus", "panic"); + } } int sde_connector_esd_status(struct drm_connector *conn) @@ -2439,8 +2452,16 @@ int sde_connector_esd_status(struct drm_connector *conn) SDE_DEBUG("Successfully received TE from panel\n"); ret = 0; } - SDE_EVT32(ret); + if (sde_conn->connector_type == DRM_MODE_CONNECTOR_DSI) { + /* Reset esd_fail_count on recovery */ + if (!ret) + display->esd_fail_count = 0; + SDE_EVT32(ret, display->esd_fail_count); + return ret; + } + + SDE_EVT32(ret); return ret; } @@ -2449,6 +2470,7 @@ static void sde_connector_check_status_work(struct work_struct *work) struct sde_connector *conn; int rc = 0; struct device *dev; + struct dsi_display *display; conn = container_of(to_delayed_work(work), struct sde_connector, status_work); @@ -2481,6 +2503,12 @@ static void sde_connector_check_status_work(struct work_struct *work) conn->esd_status_interval : STATUS_CHECK_INTERVAL_MS; schedule_delayed_work(&conn->status_work, msecs_to_jiffies(interval)); + + /* Successful ESD check */ + if (conn->connector_type == DRM_MODE_CONNECTOR_DSI) { + display = conn->display; + display->esd_fail_count = 0; + } return; }