diff --git a/msm/sde/sde_encoder_phys_cmd.c b/msm/sde/sde_encoder_phys_cmd.c index 8f9cb841d1..b2e1bf00b6 100644 --- a/msm/sde/sde_encoder_phys_cmd.c +++ b/msm/sde/sde_encoder_phys_cmd.c @@ -1783,8 +1783,11 @@ static void _sde_encoder_autorefresh_disable_seq2( u32 autorefresh_status = 0; struct sde_encoder_phys_cmd *cmd_enc = to_sde_encoder_phys_cmd(phys_enc); + struct intf_tear_status tear_status; + struct sde_hw_intf *hw_intf = phys_enc->hw_intf; - if (!hw_mdp->ops.get_autorefresh_status) { + if (!hw_mdp->ops.get_autorefresh_status || + !hw_intf->ops.check_and_reset_tearcheck) { SDE_DEBUG_CMDENC(cmd_enc, "autofresh disable seq2 not supported\n"); return; @@ -1793,10 +1796,11 @@ static void _sde_encoder_autorefresh_disable_seq2( /* * If autorefresh is still enabled after sequence-1, proceed with * below sequence-2. - * 1. Disable TEAR CHECK - * 2. Disable autorefresh config - * 4. Poll for autorefresh to be disabled - * 5. Enable TEAR CHECK + * 1. Disable autorefresh config + * 2. Run in loop: + * 2.1 Poll for autorefresh to be disabled + * 2.2 Log read and write count status + * 2.3 Replace te write count with start_pos to meet trigger window */ autorefresh_status = hw_mdp->ops.get_autorefresh_status(hw_mdp, phys_enc->intf_idx); @@ -1813,52 +1817,36 @@ static void _sde_encoder_autorefresh_disable_seq2( autorefresh_status, SDE_EVTLOG_FUNC_CASE2); } - if (autorefresh_status & BIT(7)) { - SDE_ERROR_CMDENC(cmd_enc, "autofresh status:0x%x intf:%d\n", - autorefresh_status, phys_enc->intf_idx - INTF_0); - - if (phys_enc->has_intf_te && - phys_enc->hw_intf->ops.enable_tearcheck) - phys_enc->hw_intf->ops.enable_tearcheck( - phys_enc->hw_intf, false); - else if (phys_enc->hw_pp->ops.enable_tearcheck) - phys_enc->hw_pp->ops.enable_tearcheck( - phys_enc->hw_pp, false); - - _sde_encoder_phys_cmd_config_autorefresh(phys_enc, 0); - - do { - usleep_range(AUTOREFRESH_SEQ2_POLL_TIME, - AUTOREFRESH_SEQ2_POLL_TIME + 1); - if ((trial * AUTOREFRESH_SEQ2_POLL_TIME) - > AUTOREFRESH_SEQ2_POLL_TIMEOUT) { - SDE_ERROR_CMDENC(cmd_enc, - "disable autorefresh failed\n"); - SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", - "panic"); - break; - } - - trial++; - autorefresh_status = - hw_mdp->ops.get_autorefresh_status(hw_mdp, - phys_enc->intf_idx); + while (autorefresh_status & BIT(7)) { + if (!trial) { SDE_ERROR_CMDENC(cmd_enc, - "autofresh status:0x%x intf:%d\n", - autorefresh_status, - phys_enc->intf_idx - INTF_0); - SDE_EVT32(DRMID(phys_enc->parent), - phys_enc->intf_idx - INTF_0, - autorefresh_status); - } while (autorefresh_status & BIT(7)); + "autofresh status:0x%x intf:%d\n", autorefresh_status, + phys_enc->intf_idx - INTF_0); - if (phys_enc->has_intf_te && - phys_enc->hw_intf->ops.enable_tearcheck) - phys_enc->hw_intf->ops.enable_tearcheck( - phys_enc->hw_intf, true); - else if (phys_enc->hw_pp->ops.enable_tearcheck) - phys_enc->hw_pp->ops.enable_tearcheck( - phys_enc->hw_pp, true); + _sde_encoder_phys_cmd_config_autorefresh(phys_enc, 0); + } + + usleep_range(AUTOREFRESH_SEQ2_POLL_TIME, + AUTOREFRESH_SEQ2_POLL_TIME + 1); + if ((trial * AUTOREFRESH_SEQ2_POLL_TIME) + > AUTOREFRESH_SEQ2_POLL_TIMEOUT) { + SDE_ERROR_CMDENC(cmd_enc, + "disable autorefresh failed\n"); + SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", "panic"); + break; + } + + trial++; + autorefresh_status = hw_mdp->ops.get_autorefresh_status(hw_mdp, + phys_enc->intf_idx); + hw_intf->ops.check_and_reset_tearcheck(hw_intf, &tear_status); + SDE_ERROR_CMDENC(cmd_enc, + "autofresh status:0x%x intf:%d tear_read:0x%x tear_write:0x%x\n", + autorefresh_status, phys_enc->intf_idx - INTF_0, + tear_status.read_count, tear_status.write_count); + SDE_EVT32(DRMID(phys_enc->parent), phys_enc->intf_idx - INTF_0, + autorefresh_status, tear_status.read_count, + tear_status.write_count); } } diff --git a/msm/sde/sde_hw_intf.c b/msm/sde/sde_hw_intf.c index 1add8f268c..33f872d6d6 100644 --- a/msm/sde/sde_hw_intf.c +++ b/msm/sde/sde_hw_intf.c @@ -672,6 +672,27 @@ static int sde_hw_intf_get_vsync_info(struct sde_hw_intf *intf, return 0; } +static int sde_hw_intf_v1_check_and_reset_tearcheck(struct sde_hw_intf *intf, + struct intf_tear_status *status) +{ + struct sde_hw_blk_reg_map *c = &intf->hw; + u32 start_pos; + + if (!intf || !status) + return -EINVAL; + + c = &intf->hw; + + status->read_count = SDE_REG_READ(c, INTF_TEAR_INT_COUNT_VAL); + start_pos = SDE_REG_READ(c, INTF_TEAR_START_POS); + status->write_count = SDE_REG_READ(c, INTF_TEAR_SYNC_WRCOUNT); + status->write_count &= 0xffff0000; + status->write_count |= start_pos; + SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT, status->write_count); + + return 0; +} + static void sde_hw_intf_vsync_sel(struct sde_hw_intf *intf, u32 vsync_source) { @@ -739,6 +760,8 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops, ops->poll_timeout_wr_ptr = sde_hw_intf_poll_timeout_wr_ptr; ops->vsync_sel = sde_hw_intf_vsync_sel; ops->get_status = sde_hw_intf_v1_get_status; + ops->check_and_reset_tearcheck = + sde_hw_intf_v1_check_and_reset_tearcheck; } } diff --git a/msm/sde/sde_hw_intf.h b/msm/sde/sde_hw_intf.h index c7e32d44e2..6949ed0226 100644 --- a/msm/sde/sde_hw_intf.h +++ b/msm/sde/sde_hw_intf.h @@ -52,6 +52,11 @@ struct intf_status { u32 line_count; /* current line count including blanking */ }; +struct intf_tear_status { + u32 read_count; /* frame & line count for tear init value */ + u32 write_count; /* frame & line count for tear write */ +}; + struct intf_avr_params { u32 default_fps; u32 min_fps; @@ -188,6 +193,12 @@ struct sde_hw_intf_ops { */ void (*enable_compressed_input)(struct sde_hw_intf *intf, bool compression_en, bool dsc_4hs_merge); + + /** + * Check the intf tear check status and reset it to start_pos + */ + int (*check_and_reset_tearcheck)(struct sde_hw_intf *intf, + struct intf_tear_status *status); }; struct sde_hw_intf {