diff --git a/msm/sde/sde_encoder_phys_cmd.c b/msm/sde/sde_encoder_phys_cmd.c index f499ae1f2a..4d447f59ab 100644 --- a/msm/sde/sde_encoder_phys_cmd.c +++ b/msm/sde/sde_encoder_phys_cmd.c @@ -439,6 +439,9 @@ static void sde_encoder_phys_cmd_cont_splash_mode_set( hw_pp->ops.get_autorefresh(hw_pp, &cmd_enc->autorefresh.cfg); } + + if (hw_intf->ops.reset_counter) + hw_intf->ops.reset_counter(hw_intf); } _sde_encoder_phys_cmd_setup_irq_hw_idx(phys_enc); @@ -682,12 +685,9 @@ static bool _sde_encoder_phys_cmd_is_ongoing_pptx( hw_pp->ops.get_vsync_info(hw_pp, &info); } - SDE_EVT32(DRMID(phys_enc->parent), - phys_enc->hw_pp->idx - PINGPONG_0, - phys_enc->hw_intf->idx - INTF_0, - atomic_read(&phys_enc->pending_kickoff_cnt), - info.wr_ptr_line_count, - phys_enc->cached_mode.vdisplay); + SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0, + phys_enc->hw_intf->idx - INTF_0, atomic_read(&phys_enc->pending_kickoff_cnt), + info.wr_ptr_line_count, info.intf_frame_count, phys_enc->cached_mode.vdisplay); if (info.wr_ptr_line_count > 0 && info.wr_ptr_line_count < phys_enc->cached_mode.vdisplay) @@ -1348,6 +1348,9 @@ static void sde_encoder_phys_cmd_disable(struct sde_encoder_phys *phys_enc) phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, false); sde_encoder_helper_phys_disable(phys_enc, NULL); + + if (phys_enc->hw_intf->ops.reset_counter) + phys_enc->hw_intf->ops.reset_counter(phys_enc->hw_intf); } phys_enc->enable_state = SDE_ENC_DISABLED; diff --git a/msm/sde/sde_encoder_phys_vid.c b/msm/sde/sde_encoder_phys_vid.c index 2b448f0aa2..e0570b207d 100644 --- a/msm/sde/sde_encoder_phys_vid.c +++ b/msm/sde/sde_encoder_phys_vid.c @@ -1085,6 +1085,9 @@ static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc) sde_encoder_phys_inc_pending(phys_enc); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); + if (phys_enc->hw_intf->ops.reset_counter) + phys_enc->hw_intf->ops.reset_counter(phys_enc->hw_intf); + sde_encoder_phys_vid_single_vblank_wait(phys_enc); if (phys_enc->hw_intf->ops.get_status) phys_enc->hw_intf->ops.get_status(phys_enc->hw_intf, diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 1655f13580..047772ee6c 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -2447,8 +2447,10 @@ static int sde_intf_parse_dt(struct device_node *np, set_bit(SDE_INTF_TE_ALIGN_VSYNC, &intf->features); if (SDE_HW_MAJOR(sde_cfg->hwversion) >= - SDE_HW_MAJOR(SDE_HW_VER_810)) + SDE_HW_MAJOR(SDE_HW_VER_810)) { set_bit(SDE_INTF_WD_TIMER, &intf->features); + set_bit(SDE_INTF_RESET_COUNTER, &intf->features); + } } end: diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index cff9508baf..13650983d3 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -498,6 +498,7 @@ enum { * @SDE_INTF_TE_ALIGN_VSYNC INTF block has POMS Align vsync support * @SDE_INTF_WD_TIMER INTF block has WD Timer support * @SDE_INTF_STATUS INTF block has INTF_STATUS register + * @SDE_INTF_RESET_COUNTER INTF block has frame/line counter reset support * @SDE_INTF_MAX */ enum { @@ -506,6 +507,7 @@ enum { SDE_INTF_TE_ALIGN_VSYNC, SDE_INTF_WD_TIMER, SDE_INTF_STATUS, + SDE_INTF_RESET_COUNTER, SDE_INTF_MAX }; diff --git a/msm/sde/sde_hw_intf.c b/msm/sde/sde_hw_intf.c index b4b64d3ff9..9f569d1588 100644 --- a/msm/sde/sde_hw_intf.c +++ b/msm/sde/sde_hw_intf.c @@ -192,6 +192,13 @@ static inline void _check_and_set_comp_bit(struct sde_hw_intf *ctx, (*intf_cfg2) |= BIT(12); } +static void sde_hw_intf_reset_counter(struct sde_hw_intf *ctx) +{ + struct sde_hw_blk_reg_map *c = &ctx->hw; + + SDE_REG_WRITE(c, INTF_LINE_COUNT, BIT(31)); +} + static void sde_hw_intf_setup_timing_engine(struct sde_hw_intf *ctx, const struct intf_timing_params *p, const struct sde_format *fmt) @@ -458,7 +465,7 @@ static void sde_hw_intf_get_status( s->is_en = SDE_REG_READ(c, INTF_TIMING_ENGINE_EN); if (s->is_en) { s->frame_count = SDE_REG_READ(c, INTF_FRAME_COUNT); - s->line_count = SDE_REG_READ(c, INTF_LINE_COUNT); + s->line_count = SDE_REG_READ(c, INTF_LINE_COUNT) & 0xffff; } else { s->line_count = 0; s->frame_count = 0; @@ -474,7 +481,7 @@ static void sde_hw_intf_v1_get_status( s->is_en = SDE_REG_READ(c, INTF_STATUS) & BIT(0); if (s->is_en) { s->frame_count = SDE_REG_READ(c, INTF_FRAME_COUNT); - s->line_count = SDE_REG_READ(c, INTF_LINE_COUNT); + s->line_count = SDE_REG_READ(c, INTF_LINE_COUNT) & 0xffff; } else { s->line_count = 0; s->frame_count = 0; @@ -537,7 +544,7 @@ static u32 sde_hw_intf_get_line_count(struct sde_hw_intf *intf) c = &intf->hw; - return SDE_REG_READ(c, INTF_LINE_COUNT); + return SDE_REG_READ(c, INTF_LINE_COUNT) & 0xffff; } static u32 sde_hw_intf_get_underrun_line_count(struct sde_hw_intf *intf) @@ -847,6 +854,9 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops, ops->check_and_reset_tearcheck = sde_hw_intf_v1_check_and_reset_tearcheck; } + + if (cap & BIT(SDE_INTF_RESET_COUNTER)) + ops->reset_counter = sde_hw_intf_reset_counter; } static struct sde_hw_blk_ops sde_hw_ops = { diff --git a/msm/sde/sde_hw_intf.h b/msm/sde/sde_hw_intf.h index 2bb97b6798..9dcc21796c 100644 --- a/msm/sde/sde_hw_intf.h +++ b/msm/sde/sde_hw_intf.h @@ -205,6 +205,11 @@ struct sde_hw_intf_ops { int (*check_and_reset_tearcheck)(struct sde_hw_intf *intf, struct intf_tear_status *status); + /** + * Reset the interface frame & line counter + */ + void (*reset_counter)(struct sde_hw_intf *intf); + /** * Enable processing of 2 pixels per clock */