Loading drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +21 −4 Original line number Diff line number Diff line Loading @@ -337,23 +337,40 @@ static void sde_encoder_phys_vid_vblank_irq(void *arg, int irq_idx) { struct sde_encoder_phys_vid *vid_enc = arg; struct sde_encoder_phys *phys_enc; struct sde_hw_ctl *hw_ctl; unsigned long lock_flags; int new_cnt; u32 flush_register = 0; int new_cnt = -1, old_cnt = -1; if (!vid_enc) return; phys_enc = &vid_enc->base; hw_ctl = phys_enc->hw_ctl; if (phys_enc->parent_ops.handle_vblank_virt) phys_enc->parent_ops.handle_vblank_virt(phys_enc->parent, phys_enc); old_cnt = atomic_read(&phys_enc->pending_kickoff_cnt); /* * only decrement the pending flush count if we've actually flushed * hardware. due to sw irq latency, vblank may have already happened * so we need to double-check with hw that it accepted the flush bits */ spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); SDE_EVT32_IRQ(DRMID(phys_enc->parent), vid_enc->hw_intf->idx - INTF_0, new_cnt); if (hw_ctl && hw_ctl->ops.get_flush_register) flush_register = hw_ctl->ops.get_flush_register(hw_ctl); if (flush_register == 0) new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); SDE_EVT32_IRQ(DRMID(phys_enc->parent), vid_enc->hw_intf->idx - INTF_0, old_cnt, new_cnt, flush_register); /* Signal any waiting atomic commit thread */ wake_up_all(&phys_enc->pending_kickoff_wq); } Loading drivers/gpu/drm/msm/sde/sde_hw_ctl.c +7 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,12 @@ static inline void sde_hw_ctl_trigger_flush(struct sde_hw_ctl *ctx) SDE_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); } static inline u32 sde_hw_ctl_get_flush_register(struct sde_hw_ctl *ctx) { struct sde_hw_blk_reg_map *c = &ctx->hw; return SDE_REG_READ(c, CTL_FLUSH); } static inline uint32_t sde_hw_ctl_get_bitmask_sspp(struct sde_hw_ctl *ctx, enum sde_sspp sspp) Loading Loading @@ -529,6 +535,7 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops, ops->update_pending_flush = sde_hw_ctl_update_pending_flush; ops->get_pending_flush = sde_hw_ctl_get_pending_flush; ops->trigger_flush = sde_hw_ctl_trigger_flush; ops->get_flush_register = sde_hw_ctl_get_flush_register; ops->trigger_start = sde_hw_ctl_trigger_start; ops->setup_intf_cfg = sde_hw_ctl_intf_cfg; ops->reset = sde_hw_ctl_reset_control; Loading drivers/gpu/drm/msm/sde/sde_hw_ctl.h +7 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,13 @@ struct sde_hw_ctl_ops { */ void (*trigger_flush)(struct sde_hw_ctl *ctx); /** * Read the value of the flush register * @ctx : ctl path ctx pointer * @Return: value of the ctl flush register. */ u32 (*get_flush_register)(struct sde_hw_ctl *ctx); /** * Setup ctl_path interface config * @ctx Loading Loading
drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +21 −4 Original line number Diff line number Diff line Loading @@ -337,23 +337,40 @@ static void sde_encoder_phys_vid_vblank_irq(void *arg, int irq_idx) { struct sde_encoder_phys_vid *vid_enc = arg; struct sde_encoder_phys *phys_enc; struct sde_hw_ctl *hw_ctl; unsigned long lock_flags; int new_cnt; u32 flush_register = 0; int new_cnt = -1, old_cnt = -1; if (!vid_enc) return; phys_enc = &vid_enc->base; hw_ctl = phys_enc->hw_ctl; if (phys_enc->parent_ops.handle_vblank_virt) phys_enc->parent_ops.handle_vblank_virt(phys_enc->parent, phys_enc); old_cnt = atomic_read(&phys_enc->pending_kickoff_cnt); /* * only decrement the pending flush count if we've actually flushed * hardware. due to sw irq latency, vblank may have already happened * so we need to double-check with hw that it accepted the flush bits */ spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); SDE_EVT32_IRQ(DRMID(phys_enc->parent), vid_enc->hw_intf->idx - INTF_0, new_cnt); if (hw_ctl && hw_ctl->ops.get_flush_register) flush_register = hw_ctl->ops.get_flush_register(hw_ctl); if (flush_register == 0) new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); SDE_EVT32_IRQ(DRMID(phys_enc->parent), vid_enc->hw_intf->idx - INTF_0, old_cnt, new_cnt, flush_register); /* Signal any waiting atomic commit thread */ wake_up_all(&phys_enc->pending_kickoff_wq); } Loading
drivers/gpu/drm/msm/sde/sde_hw_ctl.c +7 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,12 @@ static inline void sde_hw_ctl_trigger_flush(struct sde_hw_ctl *ctx) SDE_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); } static inline u32 sde_hw_ctl_get_flush_register(struct sde_hw_ctl *ctx) { struct sde_hw_blk_reg_map *c = &ctx->hw; return SDE_REG_READ(c, CTL_FLUSH); } static inline uint32_t sde_hw_ctl_get_bitmask_sspp(struct sde_hw_ctl *ctx, enum sde_sspp sspp) Loading Loading @@ -529,6 +535,7 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops, ops->update_pending_flush = sde_hw_ctl_update_pending_flush; ops->get_pending_flush = sde_hw_ctl_get_pending_flush; ops->trigger_flush = sde_hw_ctl_trigger_flush; ops->get_flush_register = sde_hw_ctl_get_flush_register; ops->trigger_start = sde_hw_ctl_trigger_start; ops->setup_intf_cfg = sde_hw_ctl_intf_cfg; ops->reset = sde_hw_ctl_reset_control; Loading
drivers/gpu/drm/msm/sde/sde_hw_ctl.h +7 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,13 @@ struct sde_hw_ctl_ops { */ void (*trigger_flush)(struct sde_hw_ctl *ctx); /** * Read the value of the flush register * @ctx : ctl path ctx pointer * @Return: value of the ctl flush register. */ u32 (*get_flush_register)(struct sde_hw_ctl *ctx); /** * Setup ctl_path interface config * @ctx Loading