Loading drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +25 −22 Original line number Diff line number Diff line Loading @@ -405,7 +405,7 @@ static void sde_encoder_phys_vid_vblank_irq(void *arg, int irq_idx) to_sde_encoder_phys_vid(phys_enc); struct sde_hw_ctl *hw_ctl; unsigned long lock_flags; u32 flush_register = 0; u32 flush_register = ~0; u32 reset_status = 0; int new_cnt = -1, old_cnt = -1; u32 event = 0; Loading @@ -419,42 +419,45 @@ static void sde_encoder_phys_vid_vblank_irq(void *arg, int irq_idx) SDE_ATRACE_BEGIN("vblank_irq"); /* signal only for master, where there is a pending kickoff */ if (sde_encoder_phys_vid_is_master(phys_enc) && atomic_add_unless( &phys_enc->pending_retire_fence_cnt, -1, 0)) { event = SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE | SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE; if (phys_enc->parent_ops.handle_frame_done) phys_enc->parent_ops.handle_frame_done(phys_enc->parent, phys_enc, event); } 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); old_cnt = atomic_read(&phys_enc->pending_kickoff_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); if (flush_register) goto not_flushed; new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); /* signal only for master, where there is a pending kickoff */ if (sde_encoder_phys_vid_is_master(phys_enc)) { if (atomic_add_unless(&phys_enc->pending_retire_fence_cnt, -1, 0)) event |= SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE | SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE; } not_flushed: if (hw_ctl && hw_ctl->ops.get_reset) reset_status = hw_ctl->ops.get_reset(hw_ctl); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); if (event && phys_enc->parent_ops.handle_frame_done) phys_enc->parent_ops.handle_frame_done(phys_enc->parent, phys_enc, event); if (phys_enc->parent_ops.handle_vblank_virt) phys_enc->parent_ops.handle_vblank_virt(phys_enc->parent, phys_enc); SDE_EVT32_IRQ(DRMID(phys_enc->parent), vid_enc->hw_intf->idx - INTF_0, old_cnt, new_cnt, reset_status ? SDE_EVTLOG_ERROR : 0, flush_register, event); Loading Loading
drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +25 −22 Original line number Diff line number Diff line Loading @@ -405,7 +405,7 @@ static void sde_encoder_phys_vid_vblank_irq(void *arg, int irq_idx) to_sde_encoder_phys_vid(phys_enc); struct sde_hw_ctl *hw_ctl; unsigned long lock_flags; u32 flush_register = 0; u32 flush_register = ~0; u32 reset_status = 0; int new_cnt = -1, old_cnt = -1; u32 event = 0; Loading @@ -419,42 +419,45 @@ static void sde_encoder_phys_vid_vblank_irq(void *arg, int irq_idx) SDE_ATRACE_BEGIN("vblank_irq"); /* signal only for master, where there is a pending kickoff */ if (sde_encoder_phys_vid_is_master(phys_enc) && atomic_add_unless( &phys_enc->pending_retire_fence_cnt, -1, 0)) { event = SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE | SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE; if (phys_enc->parent_ops.handle_frame_done) phys_enc->parent_ops.handle_frame_done(phys_enc->parent, phys_enc, event); } 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); old_cnt = atomic_read(&phys_enc->pending_kickoff_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); if (flush_register) goto not_flushed; new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); /* signal only for master, where there is a pending kickoff */ if (sde_encoder_phys_vid_is_master(phys_enc)) { if (atomic_add_unless(&phys_enc->pending_retire_fence_cnt, -1, 0)) event |= SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE | SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE; } not_flushed: if (hw_ctl && hw_ctl->ops.get_reset) reset_status = hw_ctl->ops.get_reset(hw_ctl); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); if (event && phys_enc->parent_ops.handle_frame_done) phys_enc->parent_ops.handle_frame_done(phys_enc->parent, phys_enc, event); if (phys_enc->parent_ops.handle_vblank_virt) phys_enc->parent_ops.handle_vblank_virt(phys_enc->parent, phys_enc); SDE_EVT32_IRQ(DRMID(phys_enc->parent), vid_enc->hw_intf->idx - INTF_0, old_cnt, new_cnt, reset_status ? SDE_EVTLOG_ERROR : 0, flush_register, event); Loading