disp: msm: dsi: Send report_panel_dead in underflow or overflow cases

In the case of DSI underflow or overflow, skip enabling back the DSI error
interrupts and instead send panel_dead. The error interrupt will be enabled
later by HAL as part of handling panel_dead event. Not enabling back the
DSI error interrupts immediately can prevent IRQ storm from occurring.

Change-Id: I769872bb5ac9ef8826c3e4caaab7723901dfc7d8
Signed-off-by: Rohith Iyer <quic_rohiiyer@quicinc.com>
Este commit está contenido en:
Rohith Iyer
2023-07-12 15:21:06 -07:00
padre 17ec75404a
commit 5413180441
Se han modificado 5 ficheros con 37 adiciones y 4 borrados

Ver fichero

@@ -17,6 +17,7 @@
#include "dsi_ctrl.h"
#include "dsi_ctrl_hw.h"
#include "dsi_clk.h"
#include "dsi_display.h"
#include "dsi_pwr.h"
#include "dsi_catalog.h"
#include "dsi_panel.h"
@@ -2717,6 +2718,8 @@ static void dsi_ctrl_handle_error_status(struct dsi_ctrl *dsi_ctrl,
unsigned long error)
{
struct dsi_event_cb_info cb_info;
struct dsi_display *display;
bool skip_irq_enable = false;
cb_info = dsi_ctrl->irq_info.irq_err_cb;
@@ -2766,6 +2769,9 @@ static void dsi_ctrl_handle_error_status(struct dsi_ctrl *dsi_ctrl,
cb_info.event_idx,
dsi_ctrl->cell_index,
0, 0, 0, 0);
display = cb_info.event_usr_ptr;
dsi_display_report_dead(display);
skip_irq_enable = true;
}
}
@@ -2777,6 +2783,9 @@ static void dsi_ctrl_handle_error_status(struct dsi_ctrl *dsi_ctrl,
cb_info.event_idx,
dsi_ctrl->cell_index,
0, 0, 0, 0);
display = cb_info.event_usr_ptr;
dsi_display_report_dead(display);
skip_irq_enable = true;
}
}
@@ -2802,7 +2811,7 @@ static void dsi_ctrl_handle_error_status(struct dsi_ctrl *dsi_ctrl,
}
/* enable back DSI interrupts */
if (dsi_ctrl->hw.ops.error_intr_ctrl)
if (dsi_ctrl->hw.ops.error_intr_ctrl && !skip_irq_enable)
dsi_ctrl->hw.ops.error_intr_ctrl(&dsi_ctrl->hw, true);
}

Ver fichero

@@ -9131,6 +9131,16 @@ int dsi_display_unprepare(struct dsi_display *display)
return rc;
}
void dsi_display_report_dead(struct dsi_display *display)
{
struct sde_connector *c_conn = to_sde_connector(display->drm_conn);
/* disable work queue */
sde_connector_schedule_status_work(display->drm_conn, false);
sde_connector_report_panel_dead(c_conn, false);
}
void __init dsi_display_register(void)
{
dsi_phy_drv_register();

Ver fichero

@@ -848,4 +848,11 @@ int dsi_display_update_transfer_time(void *display, u32 transfer_time);
*/
int dsi_display_get_panel_scan_line(void *display, u16 *scan_line, ktime_t *scan_line_ts);
/**
* dsi_display_report_dead() - report panel dead and cancel work queue
* @display: handle to display
*
*/
void dsi_display_report_dead(struct dsi_display *display);
#endif /* _DSI_DISPLAY_H_ */

Ver fichero

@@ -2784,7 +2784,7 @@ static int sde_connector_atomic_check(struct drm_connector *connector,
return 0;
}
static void _sde_connector_report_panel_dead(struct sde_connector *conn,
void sde_connector_report_panel_dead(struct sde_connector *conn,
bool skip_pre_kickoff)
{
struct drm_event event;
@@ -2865,7 +2865,7 @@ int sde_connector_esd_status(struct drm_connector *conn)
if (ret <= 0) {
/* cancel if any pending esd work */
sde_connector_schedule_status_work(conn, false);
_sde_connector_report_panel_dead(sde_conn, true);
sde_connector_report_panel_dead(sde_conn, true);
ret = -ETIMEDOUT;
} else {
SDE_DEBUG("Successfully received TE from panel\n");
@@ -2916,7 +2916,7 @@ static void sde_connector_check_status_work(struct work_struct *work)
return;
}
_sde_connector_report_panel_dead(conn, false);
sde_connector_report_panel_dead(conn, false);
}
static const struct drm_connector_helper_funcs sde_connector_helper_ops = {

Ver fichero

@@ -1386,4 +1386,11 @@ const char *sde_conn_get_topology_name(struct drm_connector *conn,
*/
bool sde_connector_is_line_insertion_supported(struct sde_connector *sde_conn);
/*
* sde_connector_report_panel_dead - report panel dead notification
* @sde_conn: Pointer to sde connector structure
* @skip_pre_kickoff: boolean to skip pre kickoff
*/
void sde_connector_report_panel_dead(struct sde_connector *conn, bool skip_pre_kickoff);
#endif /* _SDE_CONNECTOR_H_ */