Loading drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c +23 −6 Original line number Diff line number Diff line Loading @@ -1239,7 +1239,8 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, } } if (dsi_ctrl->hw.ops.mask_error_intr) if (dsi_ctrl->hw.ops.mask_error_intr && !dsi_ctrl->esd_check_underway) dsi_ctrl->hw.ops.mask_error_intr(&dsi_ctrl->hw, BIT(DSI_FIFO_OVERFLOW), false); dsi_ctrl->hw.ops.reset_cmd_fifo(&dsi_ctrl->hw); Loading Loading @@ -2898,7 +2899,8 @@ int dsi_ctrl_cmd_tx_trigger(struct dsi_ctrl *dsi_ctrl, u32 flags) dsi_ctrl->cell_index); } } if (dsi_ctrl->hw.ops.mask_error_intr) if (dsi_ctrl->hw.ops.mask_error_intr && !dsi_ctrl->esd_check_underway) dsi_ctrl->hw.ops.mask_error_intr(&dsi_ctrl->hw, BIT(DSI_FIFO_OVERFLOW), false); Loading Loading @@ -3396,7 +3398,8 @@ u32 dsi_ctrl_collect_misr(struct dsi_ctrl *dsi_ctrl) return misr; } void dsi_ctrl_mask_error_status_interrupts(struct dsi_ctrl *dsi_ctrl) void dsi_ctrl_mask_error_status_interrupts(struct dsi_ctrl *dsi_ctrl, u32 idx, bool mask_enable) { if (!dsi_ctrl || !dsi_ctrl->hw.ops.error_intr_ctrl || !dsi_ctrl->hw.ops.clear_error_status) { Loading @@ -3409,9 +3412,23 @@ void dsi_ctrl_mask_error_status_interrupts(struct dsi_ctrl *dsi_ctrl) * register */ mutex_lock(&dsi_ctrl->ctrl_lock); dsi_ctrl->hw.ops.error_intr_ctrl(&dsi_ctrl->hw, false); if (idx & BIT(DSI_ERR_INTR_ALL)) { /* * The behavior of mask_enable is different in ctrl register * and mask register and hence mask_enable is manipulated for * selective error interrupt masking vs total error interrupt * masking. */ dsi_ctrl->hw.ops.error_intr_ctrl(&dsi_ctrl->hw, !mask_enable); dsi_ctrl->hw.ops.clear_error_status(&dsi_ctrl->hw, DSI_ERROR_INTERRUPT_COUNT); } else { dsi_ctrl->hw.ops.mask_error_intr(&dsi_ctrl->hw, idx, mask_enable); dsi_ctrl->hw.ops.clear_error_status(&dsi_ctrl->hw, DSI_ERROR_INTERRUPT_COUNT); } mutex_unlock(&dsi_ctrl->ctrl_lock); } Loading drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h +6 −1 Original line number Diff line number Diff line Loading @@ -221,6 +221,7 @@ struct dsi_ctrl_interrupts { * @cmd_buffer_size: Size of command buffer. * @vaddr: CPU virtual address of cmd buffer. * @secure_mode: Indicates if secure-session is in progress * @esd_check_underway: Indicates if esd status check is in progress * @debugfs_root: Root for debugfs entries. * @misr_enable: Frame MISR enable/disable * @misr_cache: Cached Frame MISR value Loading Loading @@ -266,6 +267,7 @@ struct dsi_ctrl { u32 cmd_len; void *vaddr; bool secure_mode; bool esd_check_underway; /* Debug Information */ struct dentry *debugfs_root; Loading Loading @@ -743,8 +745,11 @@ void dsi_ctrl_isr_configure(struct dsi_ctrl *dsi_ctrl, bool enable); * dsi_ctrl_mask_error_status_interrupts() - API to mask dsi ctrl error status * interrupts * @dsi_ctrl: DSI controller handle. * @idx: id indicating which interrupts to enable/disable. * @mask_enable: boolean to enable/disable masking. */ void dsi_ctrl_mask_error_status_interrupts(struct dsi_ctrl *dsi_ctrl); void dsi_ctrl_mask_error_status_interrupts(struct dsi_ctrl *dsi_ctrl, u32 idx, bool mask_enable); /** * dsi_ctrl_irq_update() - Put a irq vote to process DSI error Loading drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c +9 −6 Original line number Diff line number Diff line Loading @@ -1420,17 +1420,20 @@ void dsi_ctrl_hw_cmn_mask_error_intr(struct dsi_ctrl_hw *ctrl, u32 idx, bool en) reg = DSI_R32(ctrl, 0x10c); if (idx & BIT(DSI_FIFO_OVERFLOW)) { if (en) reg |= (0xf << 16); else reg &= ~(0xf << 16); if (en) { reg |= (0x1f << 16); reg |= BIT(9); } else { reg &= ~(0x1f << 16); reg &= ~BIT(9); } } if (idx & BIT(DSI_FIFO_UNDERFLOW)) { if (en) reg |= (0xf << 26); reg |= (0x1b << 26); else reg &= ~(0xf << 26); reg &= ~(0x1b << 26); } if (idx & BIT(DSI_LP_Rx_TIMEOUT)) { Loading drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +1 −0 Original line number Diff line number Diff line Loading @@ -600,6 +600,7 @@ enum dsi_error_status { DSI_FIFO_OVERFLOW = 1, DSI_FIFO_UNDERFLOW, DSI_LP_Rx_TIMEOUT, DSI_ERR_INTR_ALL, }; #endif /* _DSI_DEFS_H_ */ drivers/gpu/drm/msm/dsi-staging/dsi_display.c +54 −7 Original line number Diff line number Diff line Loading @@ -59,7 +59,8 @@ static const struct of_device_id dsi_display_dt_match[] = { static struct dsi_display *primary_display; static struct dsi_display *secondary_display; static void dsi_display_mask_ctrl_error_interrupts(struct dsi_display *display) static void dsi_display_mask_ctrl_error_interrupts(struct dsi_display *display, u32 mask, bool enable) { int i; struct dsi_display_ctrl *ctrl; Loading @@ -72,7 +73,25 @@ static void dsi_display_mask_ctrl_error_interrupts(struct dsi_display *display) ctrl = &display->ctrl[i]; if (!ctrl) continue; dsi_ctrl_mask_error_status_interrupts(ctrl->ctrl); dsi_ctrl_mask_error_status_interrupts(ctrl->ctrl, mask, enable); } } static void dsi_display_set_ctrl_esd_check_flag(struct dsi_display *display, bool enable) { int i; struct dsi_display_ctrl *ctrl; if (!display) return; for (i = 0; (i < display->ctrl_count) && (i < MAX_DSI_CTRLS_PER_DISPLAY); i++) { ctrl = &display->ctrl[i]; if (!ctrl) continue; ctrl->ctrl->esd_check_underway = enable; } } Loading Loading @@ -671,10 +690,6 @@ static int dsi_display_status_reg_read(struct dsi_display *display) } } exit: /* mask only error interrupts */ if (rc <= 0) dsi_display_mask_ctrl_error_interrupts(display); dsi_display_cmd_engine_disable(display); done: return rc; Loading Loading @@ -715,6 +730,7 @@ int dsi_display_check_status(void *display, bool te_check_override) struct dsi_panel *panel; u32 status_mode; int rc = 0x1; u32 mask; if (!dsi_display || !dsi_display->panel) return -EINVAL; Loading @@ -730,6 +746,12 @@ int dsi_display_check_status(void *display, bool te_check_override) } SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY); /* Prevent another ESD check,when ESD recovery is underway */ if (atomic_read(&panel->esd_recovery_pending)) { dsi_panel_release_panel_lock(panel); return rc; } if (te_check_override && gpio_is_valid(dsi_display->disp_te_gpio)) status_mode = ESD_MODE_PANEL_TE; else Loading @@ -738,6 +760,11 @@ int dsi_display_check_status(void *display, bool te_check_override) dsi_display_clk_ctrl(dsi_display->dsi_clk_handle, DSI_ALL_CLKS, DSI_CLK_ON); /* Mask error interrupts before attempting ESD read */ mask = BIT(DSI_FIFO_OVERFLOW) | BIT(DSI_FIFO_UNDERFLOW); dsi_display_set_ctrl_esd_check_flag(dsi_display, true); dsi_display_mask_ctrl_error_interrupts(dsi_display, mask, true); if (status_mode == ESD_MODE_REG_READ) { rc = dsi_display_status_reg_read(dsi_display); } else if (status_mode == ESD_MODE_SW_BTA) { Loading @@ -749,6 +776,16 @@ int dsi_display_check_status(void *display, bool te_check_override) panel->esd_config.esd_enabled = false; } /* Unmask error interrupts */ if (rc > 0) { dsi_display_set_ctrl_esd_check_flag(dsi_display, false); dsi_display_mask_ctrl_error_interrupts(dsi_display, mask, false); } else { /* Handle Panel failures during display disable sequence */ atomic_set(&panel->esd_recovery_pending, 1); } dsi_display_clk_ctrl(dsi_display->dsi_clk_handle, DSI_ALL_CLKS, DSI_CLK_OFF); dsi_panel_release_panel_lock(panel); Loading Loading @@ -2753,7 +2790,7 @@ static int dsi_host_detach(struct mipi_dsi_host *host, static ssize_t dsi_host_transfer(struct mipi_dsi_host *host, const struct mipi_dsi_msg *msg) { struct dsi_display *display = to_dsi_display(host); struct dsi_display *display; int rc = 0, ret = 0; if (!host || !msg) { Loading @@ -2761,6 +2798,14 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host, return 0; } display = to_dsi_display(host); /* Avoid sending DCS commands when ESD recovery is pending */ if (atomic_read(&display->panel->esd_recovery_pending)) { pr_debug("ESD recovery pending\n"); return 0; } rc = dsi_display_clk_ctrl(display->dsi_clk_handle, DSI_ALL_CLKS, DSI_CLK_ON); if (rc) { Loading Loading @@ -5877,6 +5922,8 @@ int dsi_display_prepare(struct dsi_display *display) mode = display->panel->cur_mode; dsi_display_set_ctrl_esd_check_flag(display, false); if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) { if (display->is_cont_splash_enabled) { pr_err("DMS is not supposed to be set on first frame\n"); Loading Loading
drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c +23 −6 Original line number Diff line number Diff line Loading @@ -1239,7 +1239,8 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, } } if (dsi_ctrl->hw.ops.mask_error_intr) if (dsi_ctrl->hw.ops.mask_error_intr && !dsi_ctrl->esd_check_underway) dsi_ctrl->hw.ops.mask_error_intr(&dsi_ctrl->hw, BIT(DSI_FIFO_OVERFLOW), false); dsi_ctrl->hw.ops.reset_cmd_fifo(&dsi_ctrl->hw); Loading Loading @@ -2898,7 +2899,8 @@ int dsi_ctrl_cmd_tx_trigger(struct dsi_ctrl *dsi_ctrl, u32 flags) dsi_ctrl->cell_index); } } if (dsi_ctrl->hw.ops.mask_error_intr) if (dsi_ctrl->hw.ops.mask_error_intr && !dsi_ctrl->esd_check_underway) dsi_ctrl->hw.ops.mask_error_intr(&dsi_ctrl->hw, BIT(DSI_FIFO_OVERFLOW), false); Loading Loading @@ -3396,7 +3398,8 @@ u32 dsi_ctrl_collect_misr(struct dsi_ctrl *dsi_ctrl) return misr; } void dsi_ctrl_mask_error_status_interrupts(struct dsi_ctrl *dsi_ctrl) void dsi_ctrl_mask_error_status_interrupts(struct dsi_ctrl *dsi_ctrl, u32 idx, bool mask_enable) { if (!dsi_ctrl || !dsi_ctrl->hw.ops.error_intr_ctrl || !dsi_ctrl->hw.ops.clear_error_status) { Loading @@ -3409,9 +3412,23 @@ void dsi_ctrl_mask_error_status_interrupts(struct dsi_ctrl *dsi_ctrl) * register */ mutex_lock(&dsi_ctrl->ctrl_lock); dsi_ctrl->hw.ops.error_intr_ctrl(&dsi_ctrl->hw, false); if (idx & BIT(DSI_ERR_INTR_ALL)) { /* * The behavior of mask_enable is different in ctrl register * and mask register and hence mask_enable is manipulated for * selective error interrupt masking vs total error interrupt * masking. */ dsi_ctrl->hw.ops.error_intr_ctrl(&dsi_ctrl->hw, !mask_enable); dsi_ctrl->hw.ops.clear_error_status(&dsi_ctrl->hw, DSI_ERROR_INTERRUPT_COUNT); } else { dsi_ctrl->hw.ops.mask_error_intr(&dsi_ctrl->hw, idx, mask_enable); dsi_ctrl->hw.ops.clear_error_status(&dsi_ctrl->hw, DSI_ERROR_INTERRUPT_COUNT); } mutex_unlock(&dsi_ctrl->ctrl_lock); } Loading
drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h +6 −1 Original line number Diff line number Diff line Loading @@ -221,6 +221,7 @@ struct dsi_ctrl_interrupts { * @cmd_buffer_size: Size of command buffer. * @vaddr: CPU virtual address of cmd buffer. * @secure_mode: Indicates if secure-session is in progress * @esd_check_underway: Indicates if esd status check is in progress * @debugfs_root: Root for debugfs entries. * @misr_enable: Frame MISR enable/disable * @misr_cache: Cached Frame MISR value Loading Loading @@ -266,6 +267,7 @@ struct dsi_ctrl { u32 cmd_len; void *vaddr; bool secure_mode; bool esd_check_underway; /* Debug Information */ struct dentry *debugfs_root; Loading Loading @@ -743,8 +745,11 @@ void dsi_ctrl_isr_configure(struct dsi_ctrl *dsi_ctrl, bool enable); * dsi_ctrl_mask_error_status_interrupts() - API to mask dsi ctrl error status * interrupts * @dsi_ctrl: DSI controller handle. * @idx: id indicating which interrupts to enable/disable. * @mask_enable: boolean to enable/disable masking. */ void dsi_ctrl_mask_error_status_interrupts(struct dsi_ctrl *dsi_ctrl); void dsi_ctrl_mask_error_status_interrupts(struct dsi_ctrl *dsi_ctrl, u32 idx, bool mask_enable); /** * dsi_ctrl_irq_update() - Put a irq vote to process DSI error Loading
drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c +9 −6 Original line number Diff line number Diff line Loading @@ -1420,17 +1420,20 @@ void dsi_ctrl_hw_cmn_mask_error_intr(struct dsi_ctrl_hw *ctrl, u32 idx, bool en) reg = DSI_R32(ctrl, 0x10c); if (idx & BIT(DSI_FIFO_OVERFLOW)) { if (en) reg |= (0xf << 16); else reg &= ~(0xf << 16); if (en) { reg |= (0x1f << 16); reg |= BIT(9); } else { reg &= ~(0x1f << 16); reg &= ~BIT(9); } } if (idx & BIT(DSI_FIFO_UNDERFLOW)) { if (en) reg |= (0xf << 26); reg |= (0x1b << 26); else reg &= ~(0xf << 26); reg &= ~(0x1b << 26); } if (idx & BIT(DSI_LP_Rx_TIMEOUT)) { Loading
drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +1 −0 Original line number Diff line number Diff line Loading @@ -600,6 +600,7 @@ enum dsi_error_status { DSI_FIFO_OVERFLOW = 1, DSI_FIFO_UNDERFLOW, DSI_LP_Rx_TIMEOUT, DSI_ERR_INTR_ALL, }; #endif /* _DSI_DEFS_H_ */
drivers/gpu/drm/msm/dsi-staging/dsi_display.c +54 −7 Original line number Diff line number Diff line Loading @@ -59,7 +59,8 @@ static const struct of_device_id dsi_display_dt_match[] = { static struct dsi_display *primary_display; static struct dsi_display *secondary_display; static void dsi_display_mask_ctrl_error_interrupts(struct dsi_display *display) static void dsi_display_mask_ctrl_error_interrupts(struct dsi_display *display, u32 mask, bool enable) { int i; struct dsi_display_ctrl *ctrl; Loading @@ -72,7 +73,25 @@ static void dsi_display_mask_ctrl_error_interrupts(struct dsi_display *display) ctrl = &display->ctrl[i]; if (!ctrl) continue; dsi_ctrl_mask_error_status_interrupts(ctrl->ctrl); dsi_ctrl_mask_error_status_interrupts(ctrl->ctrl, mask, enable); } } static void dsi_display_set_ctrl_esd_check_flag(struct dsi_display *display, bool enable) { int i; struct dsi_display_ctrl *ctrl; if (!display) return; for (i = 0; (i < display->ctrl_count) && (i < MAX_DSI_CTRLS_PER_DISPLAY); i++) { ctrl = &display->ctrl[i]; if (!ctrl) continue; ctrl->ctrl->esd_check_underway = enable; } } Loading Loading @@ -671,10 +690,6 @@ static int dsi_display_status_reg_read(struct dsi_display *display) } } exit: /* mask only error interrupts */ if (rc <= 0) dsi_display_mask_ctrl_error_interrupts(display); dsi_display_cmd_engine_disable(display); done: return rc; Loading Loading @@ -715,6 +730,7 @@ int dsi_display_check_status(void *display, bool te_check_override) struct dsi_panel *panel; u32 status_mode; int rc = 0x1; u32 mask; if (!dsi_display || !dsi_display->panel) return -EINVAL; Loading @@ -730,6 +746,12 @@ int dsi_display_check_status(void *display, bool te_check_override) } SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY); /* Prevent another ESD check,when ESD recovery is underway */ if (atomic_read(&panel->esd_recovery_pending)) { dsi_panel_release_panel_lock(panel); return rc; } if (te_check_override && gpio_is_valid(dsi_display->disp_te_gpio)) status_mode = ESD_MODE_PANEL_TE; else Loading @@ -738,6 +760,11 @@ int dsi_display_check_status(void *display, bool te_check_override) dsi_display_clk_ctrl(dsi_display->dsi_clk_handle, DSI_ALL_CLKS, DSI_CLK_ON); /* Mask error interrupts before attempting ESD read */ mask = BIT(DSI_FIFO_OVERFLOW) | BIT(DSI_FIFO_UNDERFLOW); dsi_display_set_ctrl_esd_check_flag(dsi_display, true); dsi_display_mask_ctrl_error_interrupts(dsi_display, mask, true); if (status_mode == ESD_MODE_REG_READ) { rc = dsi_display_status_reg_read(dsi_display); } else if (status_mode == ESD_MODE_SW_BTA) { Loading @@ -749,6 +776,16 @@ int dsi_display_check_status(void *display, bool te_check_override) panel->esd_config.esd_enabled = false; } /* Unmask error interrupts */ if (rc > 0) { dsi_display_set_ctrl_esd_check_flag(dsi_display, false); dsi_display_mask_ctrl_error_interrupts(dsi_display, mask, false); } else { /* Handle Panel failures during display disable sequence */ atomic_set(&panel->esd_recovery_pending, 1); } dsi_display_clk_ctrl(dsi_display->dsi_clk_handle, DSI_ALL_CLKS, DSI_CLK_OFF); dsi_panel_release_panel_lock(panel); Loading Loading @@ -2753,7 +2790,7 @@ static int dsi_host_detach(struct mipi_dsi_host *host, static ssize_t dsi_host_transfer(struct mipi_dsi_host *host, const struct mipi_dsi_msg *msg) { struct dsi_display *display = to_dsi_display(host); struct dsi_display *display; int rc = 0, ret = 0; if (!host || !msg) { Loading @@ -2761,6 +2798,14 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host, return 0; } display = to_dsi_display(host); /* Avoid sending DCS commands when ESD recovery is pending */ if (atomic_read(&display->panel->esd_recovery_pending)) { pr_debug("ESD recovery pending\n"); return 0; } rc = dsi_display_clk_ctrl(display->dsi_clk_handle, DSI_ALL_CLKS, DSI_CLK_ON); if (rc) { Loading Loading @@ -5877,6 +5922,8 @@ int dsi_display_prepare(struct dsi_display *display) mode = display->panel->cur_mode; dsi_display_set_ctrl_esd_check_flag(display, false); if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) { if (display->is_cont_splash_enabled) { pr_err("DMS is not supposed to be set on first frame\n"); Loading