msm: mdss: handle DSI error interrupts during dynamic fps
During dynamic fps using PLL approach, it is expected that DSI FIFO underflow and DSI PLL unlock can happen sometimes. Make sure to mask these errors so that DSI error interrupt is not generated because of this. Clear the errors once dynamic refresh operation is done and unmask these errors later. Change-Id: I05ccbb7af1588b9ed81fd33ac14ef5b29882a42d Signed-off-by: Padmanabhan Komanduru <pkomandu@codeaurora.org>
This commit is contained in:
parent
04977d266e
commit
5d6f763016
3 changed files with 47 additions and 20 deletions
|
@ -1733,6 +1733,38 @@ int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void __mdss_dsi_mask_dfps_errors(struct mdss_dsi_ctrl_pdata *ctrl,
|
||||
bool mask)
|
||||
{
|
||||
u32 data = 0;
|
||||
|
||||
/*
|
||||
* Assumption is that the DSI clocks will be enabled
|
||||
* when this API is called from dfps thread
|
||||
*/
|
||||
if (mask) {
|
||||
/* mask FIFO underflow and PLL unlock bits */
|
||||
mdss_dsi_set_reg(ctrl, 0x10c, 0x7c000000, 0x7c000000);
|
||||
} else {
|
||||
data = MIPI_INP((ctrl->ctrl_base) + 0x0120);
|
||||
if (data & BIT(16)) {
|
||||
pr_debug("pll unlocked: 0x%x\n", data);
|
||||
/* clear PLL unlock bit */
|
||||
MIPI_OUTP((ctrl->ctrl_base) + 0x120, BIT(16));
|
||||
}
|
||||
|
||||
data = MIPI_INP((ctrl->ctrl_base) + 0x00c);
|
||||
if (data & 0x88880000) {
|
||||
pr_debug("dsi fifo underflow: 0x%x\n", data);
|
||||
/* clear DSI FIFO underflow and empty */
|
||||
MIPI_OUTP((ctrl->ctrl_base) + 0x00c, 0x99990000);
|
||||
}
|
||||
|
||||
/* restore FIFO underflow and PLL unlock bits */
|
||||
mdss_dsi_set_reg(ctrl, 0x10c, 0x7c000000, 0x0);
|
||||
}
|
||||
}
|
||||
|
||||
static void __mdss_dsi_update_video_mode_total(struct mdss_panel_data *pdata,
|
||||
int new_fps)
|
||||
{
|
||||
|
@ -1935,7 +1967,6 @@ static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata,
|
|||
struct mdss_dsi_ctrl_pdata *sctrl_pdata = NULL;
|
||||
struct mdss_panel_info *pinfo, *spinfo;
|
||||
int rc = 0;
|
||||
u32 data;
|
||||
|
||||
if (pdata == NULL) {
|
||||
pr_err("%s Invalid pdata\n", __func__);
|
||||
|
@ -2055,12 +2086,9 @@ static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata,
|
|||
MIPI_OUTP((sctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL,
|
||||
0x00);
|
||||
|
||||
data = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0120);
|
||||
if (data & BIT(16)) {
|
||||
pr_debug("pll unlocked: 0x%x\n", data);
|
||||
/* clear PLL unlock bit */
|
||||
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x120, BIT(16));
|
||||
}
|
||||
__mdss_dsi_mask_dfps_errors(ctrl_pdata, false);
|
||||
if (sctrl_pdata)
|
||||
__mdss_dsi_mask_dfps_errors(sctrl_pdata, false);
|
||||
|
||||
/* Move the mux clocks to main byte and pixel clocks */
|
||||
rc = clk_set_parent(ctrl_pdata->mux_byte_clk,
|
||||
|
@ -2188,6 +2216,9 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps)
|
|||
__mdss_dsi_update_video_mode_total(pdata, new_fps);
|
||||
} else if (pinfo->dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) {
|
||||
/* Clock update method */
|
||||
|
||||
__mdss_dsi_mask_dfps_errors(ctrl_pdata, true);
|
||||
|
||||
if (phy_rev == DSI_PHY_REV_20) {
|
||||
rc = mdss_dsi_phy_calc_timing_param(pinfo, phy_rev,
|
||||
new_fps);
|
||||
|
|
|
@ -692,6 +692,8 @@ void mdss_dsi_dsc_config(struct mdss_dsi_ctrl_pdata *ctrl,
|
|||
struct dsc_desc *dsc);
|
||||
void mdss_dsi_dfps_config_8996(struct mdss_dsi_ctrl_pdata *ctrl);
|
||||
void mdss_dsi_set_burst_mode(struct mdss_dsi_ctrl_pdata *ctrl);
|
||||
void mdss_dsi_set_reg(struct mdss_dsi_ctrl_pdata *ctrl, int off,
|
||||
u32 mask, u32 val);
|
||||
|
||||
static inline const char *__mdss_dsi_pm_name(enum dsi_pm_type module)
|
||||
{
|
||||
|
|
|
@ -134,7 +134,7 @@ void mdss_dsi_ctrl_init(struct device *ctrl_dev,
|
|||
}
|
||||
}
|
||||
|
||||
static void mdss_dsi_set_reg(struct mdss_dsi_ctrl_pdata *ctrl, int off,
|
||||
void mdss_dsi_set_reg(struct mdss_dsi_ctrl_pdata *ctrl, int off,
|
||||
u32 mask, u32 val)
|
||||
{
|
||||
u32 data;
|
||||
|
@ -2978,7 +2978,7 @@ bool mdss_dsi_dln0_phy_err(struct mdss_dsi_ctrl_pdata *ctrl, bool print_en)
|
|||
|
||||
static bool mdss_dsi_fifo_status(struct mdss_dsi_ctrl_pdata *ctrl)
|
||||
{
|
||||
u32 status, isr;
|
||||
u32 status;
|
||||
unsigned char *base;
|
||||
bool ret = false;
|
||||
|
||||
|
@ -2990,17 +2990,7 @@ static bool mdss_dsi_fifo_status(struct mdss_dsi_ctrl_pdata *ctrl)
|
|||
if (status & 0xcccc4409) {
|
||||
MIPI_OUTP(base + 0x000c, status);
|
||||
|
||||
/*
|
||||
* When dynamic refresh operation is under progress, it is
|
||||
* expected to have FIFO underflow error sometimes. In such
|
||||
* cases, do not trigger the underflow recovery process and
|
||||
* avoid printing the error status on console.
|
||||
*/
|
||||
isr = MIPI_INP(ctrl->ctrl_base + 0x0110);
|
||||
if (isr & DSI_INTR_DYNAMIC_REFRESH_MASK)
|
||||
status &= ~(0x88880000);
|
||||
else
|
||||
pr_err("%s: status=%x\n", __func__, status);
|
||||
pr_err("%s: status=%x\n", __func__, status);
|
||||
|
||||
if (status & 0x44440000) {/* DLNx_HS_FIFO_OVERFLOW */
|
||||
dsi_send_events(ctrl, DSI_EV_DLNx_FIFO_OVERFLOW, 0);
|
||||
|
@ -3048,6 +3038,10 @@ static bool mdss_dsi_clk_status(struct mdss_dsi_ctrl_pdata *ctrl)
|
|||
|
||||
if (status & 0x10000) { /* DSI_CLK_PLL_UNLOCKED */
|
||||
MIPI_OUTP(base + 0x0120, status);
|
||||
/* If PLL unlock is masked, do not report error */
|
||||
if (MIPI_INP(base + 0x10c) & BIT(28))
|
||||
return false;
|
||||
|
||||
dsi_send_events(ctrl, DSI_EV_PLL_UNLOCKED, 0);
|
||||
pr_err("%s: status=%x\n", __func__, status);
|
||||
ret = true;
|
||||
|
|
Loading…
Add table
Reference in a new issue