Loading drivers/gpu/drm/msm/dsi-staging/dsi_display.c +8 −6 Original line number Diff line number Diff line Loading @@ -694,7 +694,7 @@ static int dsi_display_status_check_te(struct dsi_display *display) reinit_completion(&display->esd_te_gate); if (!wait_for_completion_timeout(&display->esd_te_gate, esd_te_timeout)) { pr_err("ESD check failed\n"); pr_err("TE check failed\n"); rc = -EINVAL; } Loading @@ -703,7 +703,7 @@ static int dsi_display_status_check_te(struct dsi_display *display) return rc; } int dsi_display_check_status(void *display) int dsi_display_check_status(void *display, bool te_check_override) { struct dsi_display *dsi_display = display; struct dsi_panel *panel; Loading @@ -713,18 +713,20 @@ int dsi_display_check_status(void *display) if (dsi_display == NULL) return -EINVAL; panel = dsi_display->panel; status_mode = panel->esd_config.status_mode; mutex_lock(&dsi_display->display_lock); panel = dsi_display->panel; if (!panel->panel_initialized) { pr_debug("Panel not initialized\n"); mutex_unlock(&dsi_display->display_lock); return rc; } if (te_check_override && gpio_is_valid(dsi_display->disp_te_gpio)) status_mode = ESD_MODE_PANEL_TE; else status_mode = panel->esd_config.status_mode; dsi_display_clk_ctrl(dsi_display->dsi_clk_handle, DSI_ALL_CLKS, DSI_CLK_ON); Loading drivers/gpu/drm/msm/dsi-staging/dsi_display.h +2 −1 Original line number Diff line number Diff line Loading @@ -581,8 +581,9 @@ int dsi_display_set_backlight(void *display, u32 bl_lvl); /** * dsi_display_check_status() - check if panel is dead or alive * @display: Handle to display. * @te_check_override: Whether check for TE from panel or default check */ int dsi_display_check_status(void *display); int dsi_display_check_status(void *display, bool te_check_override); /** * dsi_display_cmd_transfer() - transfer command to the panel Loading drivers/gpu/drm/msm/sde/sde_connector.c +51 −12 Original line number Diff line number Diff line Loading @@ -1731,12 +1731,59 @@ sde_connector_best_encoder(struct drm_connector *connector) return c_conn->encoder; } static void _sde_connector_report_panel_dead(struct sde_connector *conn) { struct drm_event event; bool panel_dead = true; if (!conn) return; event.type = DRM_EVENT_PANEL_DEAD; event.length = sizeof(bool); msm_mode_object_event_notify(&conn->base.base, conn->base.dev, &event, (u8 *)&panel_dead); sde_encoder_display_failure_notification(conn->encoder); 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); } int sde_connector_esd_status(struct drm_connector *conn) { struct sde_connector *sde_conn = NULL; int ret = 0; if (!conn) return ret; sde_conn = to_sde_connector(conn); if (!sde_conn || !sde_conn->ops.check_status) return ret; /* protect this call with ESD status check call */ mutex_lock(&sde_conn->lock); ret = sde_conn->ops.check_status(sde_conn->display, true); mutex_unlock(&sde_conn->lock); if (ret <= 0) { /* cancel if any pending esd work */ sde_connector_schedule_status_work(conn, false); _sde_connector_report_panel_dead(sde_conn); ret = -ETIMEDOUT; } else { SDE_DEBUG("Successfully received TE from panel\n"); ret = 0; } SDE_EVT32(ret); return ret; } static void sde_connector_check_status_work(struct work_struct *work) { struct sde_connector *conn; struct drm_event event; int rc = 0; bool panel_dead = false; conn = container_of(to_delayed_work(work), struct sde_connector, status_work); Loading @@ -1753,7 +1800,7 @@ static void sde_connector_check_status_work(struct work_struct *work) return; } rc = conn->ops.check_status(conn->display); rc = conn->ops.check_status(conn->display, false); mutex_unlock(&conn->lock); if (conn->force_panel_dead) { Loading @@ -1777,15 +1824,7 @@ static void sde_connector_check_status_work(struct work_struct *work) } status_dead: SDE_EVT32(rc, 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); panel_dead = true; event.type = DRM_EVENT_PANEL_DEAD; event.length = sizeof(bool); msm_mode_object_event_notify(&conn->base.base, conn->base.dev, &event, (u8 *)&panel_dead); sde_encoder_display_failure_notification(conn->encoder); _sde_connector_report_panel_dead(conn); } static const struct drm_connector_helper_funcs sde_connector_helper_ops = { Loading drivers/gpu/drm/msm/sde/sde_connector.h +9 −1 Original line number Diff line number Diff line Loading @@ -228,9 +228,10 @@ struct sde_connector_ops { /** * check_status - check status of connected display panel * @display: Pointer to private display handle * @te_check_override: Whether check TE from panel or default check * Returns: positive value for success, negetive or zero for failure */ int (*check_status)(void *display); int (*check_status)(void *display, bool te_check_override); /** * cmd_transfer - Transfer command to the connected display panel Loading Loading @@ -770,4 +771,11 @@ void sde_connector_helper_bridge_disable(struct drm_connector *connector); */ int sde_connector_get_panel_vfp(struct drm_connector *connector, struct drm_display_mode *mode); /** * sde_connector_esd_status - helper function to check te status * @connector: Pointer to DRM connector object */ int sde_connector_esd_status(struct drm_connector *connector); #endif /* _SDE_CONNECTOR_H_ */ drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c +7 −2 Original line number Diff line number Diff line Loading @@ -473,6 +473,10 @@ static int _sde_encoder_phys_cmd_handle_ppdone_timeout( atomic_read(&phys_enc->pending_kickoff_cnt), frame_event); /* check if panel is still sending TE signal or not */ if (sde_connector_esd_status(phys_enc->connector)) goto exit; if (cmd_enc->pp_timeout_report_cnt >= PP_TIMEOUT_MAX_TRIALS) { cmd_enc->pp_timeout_report_cnt = PP_TIMEOUT_MAX_TRIALS; frame_event |= SDE_ENCODER_FRAME_EVENT_PANEL_DEAD; Loading @@ -490,11 +494,12 @@ static int _sde_encoder_phys_cmd_handle_ppdone_timeout( SDE_EVT32(DRMID(phys_enc->parent), SDE_EVTLOG_FATAL); } atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); /* request a ctl reset before the next kickoff */ phys_enc->enable_state = SDE_ENC_ERR_NEEDS_HW_RESET; exit: atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); if (phys_enc->parent_ops.handle_frame_done) phys_enc->parent_ops.handle_frame_done( phys_enc->parent, phys_enc, frame_event); Loading Loading
drivers/gpu/drm/msm/dsi-staging/dsi_display.c +8 −6 Original line number Diff line number Diff line Loading @@ -694,7 +694,7 @@ static int dsi_display_status_check_te(struct dsi_display *display) reinit_completion(&display->esd_te_gate); if (!wait_for_completion_timeout(&display->esd_te_gate, esd_te_timeout)) { pr_err("ESD check failed\n"); pr_err("TE check failed\n"); rc = -EINVAL; } Loading @@ -703,7 +703,7 @@ static int dsi_display_status_check_te(struct dsi_display *display) return rc; } int dsi_display_check_status(void *display) int dsi_display_check_status(void *display, bool te_check_override) { struct dsi_display *dsi_display = display; struct dsi_panel *panel; Loading @@ -713,18 +713,20 @@ int dsi_display_check_status(void *display) if (dsi_display == NULL) return -EINVAL; panel = dsi_display->panel; status_mode = panel->esd_config.status_mode; mutex_lock(&dsi_display->display_lock); panel = dsi_display->panel; if (!panel->panel_initialized) { pr_debug("Panel not initialized\n"); mutex_unlock(&dsi_display->display_lock); return rc; } if (te_check_override && gpio_is_valid(dsi_display->disp_te_gpio)) status_mode = ESD_MODE_PANEL_TE; else status_mode = panel->esd_config.status_mode; dsi_display_clk_ctrl(dsi_display->dsi_clk_handle, DSI_ALL_CLKS, DSI_CLK_ON); Loading
drivers/gpu/drm/msm/dsi-staging/dsi_display.h +2 −1 Original line number Diff line number Diff line Loading @@ -581,8 +581,9 @@ int dsi_display_set_backlight(void *display, u32 bl_lvl); /** * dsi_display_check_status() - check if panel is dead or alive * @display: Handle to display. * @te_check_override: Whether check for TE from panel or default check */ int dsi_display_check_status(void *display); int dsi_display_check_status(void *display, bool te_check_override); /** * dsi_display_cmd_transfer() - transfer command to the panel Loading
drivers/gpu/drm/msm/sde/sde_connector.c +51 −12 Original line number Diff line number Diff line Loading @@ -1731,12 +1731,59 @@ sde_connector_best_encoder(struct drm_connector *connector) return c_conn->encoder; } static void _sde_connector_report_panel_dead(struct sde_connector *conn) { struct drm_event event; bool panel_dead = true; if (!conn) return; event.type = DRM_EVENT_PANEL_DEAD; event.length = sizeof(bool); msm_mode_object_event_notify(&conn->base.base, conn->base.dev, &event, (u8 *)&panel_dead); sde_encoder_display_failure_notification(conn->encoder); 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); } int sde_connector_esd_status(struct drm_connector *conn) { struct sde_connector *sde_conn = NULL; int ret = 0; if (!conn) return ret; sde_conn = to_sde_connector(conn); if (!sde_conn || !sde_conn->ops.check_status) return ret; /* protect this call with ESD status check call */ mutex_lock(&sde_conn->lock); ret = sde_conn->ops.check_status(sde_conn->display, true); mutex_unlock(&sde_conn->lock); if (ret <= 0) { /* cancel if any pending esd work */ sde_connector_schedule_status_work(conn, false); _sde_connector_report_panel_dead(sde_conn); ret = -ETIMEDOUT; } else { SDE_DEBUG("Successfully received TE from panel\n"); ret = 0; } SDE_EVT32(ret); return ret; } static void sde_connector_check_status_work(struct work_struct *work) { struct sde_connector *conn; struct drm_event event; int rc = 0; bool panel_dead = false; conn = container_of(to_delayed_work(work), struct sde_connector, status_work); Loading @@ -1753,7 +1800,7 @@ static void sde_connector_check_status_work(struct work_struct *work) return; } rc = conn->ops.check_status(conn->display); rc = conn->ops.check_status(conn->display, false); mutex_unlock(&conn->lock); if (conn->force_panel_dead) { Loading @@ -1777,15 +1824,7 @@ static void sde_connector_check_status_work(struct work_struct *work) } status_dead: SDE_EVT32(rc, 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); panel_dead = true; event.type = DRM_EVENT_PANEL_DEAD; event.length = sizeof(bool); msm_mode_object_event_notify(&conn->base.base, conn->base.dev, &event, (u8 *)&panel_dead); sde_encoder_display_failure_notification(conn->encoder); _sde_connector_report_panel_dead(conn); } static const struct drm_connector_helper_funcs sde_connector_helper_ops = { Loading
drivers/gpu/drm/msm/sde/sde_connector.h +9 −1 Original line number Diff line number Diff line Loading @@ -228,9 +228,10 @@ struct sde_connector_ops { /** * check_status - check status of connected display panel * @display: Pointer to private display handle * @te_check_override: Whether check TE from panel or default check * Returns: positive value for success, negetive or zero for failure */ int (*check_status)(void *display); int (*check_status)(void *display, bool te_check_override); /** * cmd_transfer - Transfer command to the connected display panel Loading Loading @@ -770,4 +771,11 @@ void sde_connector_helper_bridge_disable(struct drm_connector *connector); */ int sde_connector_get_panel_vfp(struct drm_connector *connector, struct drm_display_mode *mode); /** * sde_connector_esd_status - helper function to check te status * @connector: Pointer to DRM connector object */ int sde_connector_esd_status(struct drm_connector *connector); #endif /* _SDE_CONNECTOR_H_ */
drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c +7 −2 Original line number Diff line number Diff line Loading @@ -473,6 +473,10 @@ static int _sde_encoder_phys_cmd_handle_ppdone_timeout( atomic_read(&phys_enc->pending_kickoff_cnt), frame_event); /* check if panel is still sending TE signal or not */ if (sde_connector_esd_status(phys_enc->connector)) goto exit; if (cmd_enc->pp_timeout_report_cnt >= PP_TIMEOUT_MAX_TRIALS) { cmd_enc->pp_timeout_report_cnt = PP_TIMEOUT_MAX_TRIALS; frame_event |= SDE_ENCODER_FRAME_EVENT_PANEL_DEAD; Loading @@ -490,11 +494,12 @@ static int _sde_encoder_phys_cmd_handle_ppdone_timeout( SDE_EVT32(DRMID(phys_enc->parent), SDE_EVTLOG_FATAL); } atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); /* request a ctl reset before the next kickoff */ phys_enc->enable_state = SDE_ENC_ERR_NEEDS_HW_RESET; exit: atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); if (phys_enc->parent_ops.handle_frame_done) phys_enc->parent_ops.handle_frame_done( phys_enc->parent, phys_enc, frame_event); Loading