Loading drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +62 −39 Original line number Diff line number Diff line Loading @@ -1050,12 +1050,52 @@ static int sde_encoder_phys_vid_prepare_for_kickoff( return rc; } static void sde_encoder_phys_vid_single_vblank_wait( struct sde_encoder_phys *phys_enc) { int ret; struct sde_encoder_phys_vid *vid_enc = to_sde_encoder_phys_vid(phys_enc); /* * Wait for a vsync so we know the ENABLE=0 latched before * the (connector) source of the vsync's gets disabled, * otherwise we end up in a funny state if we re-enable * before the disable latches, which results that some of * the settings changes for the new modeset (like new * scanout buffer) don't latch properly.. */ ret = sde_encoder_phys_vid_control_vblank_irq(phys_enc, true); if (ret) { SDE_ERROR_VIDENC(vid_enc, "failed to enable vblank irq: %d\n", ret); SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0, ret, SDE_EVTLOG_FUNC_CASE1, SDE_EVTLOG_ERROR); } else { ret = _sde_encoder_phys_vid_wait_for_vblank(phys_enc, false); if (ret) { atomic_set(&phys_enc->pending_kickoff_cnt, 0); SDE_ERROR_VIDENC(vid_enc, "failure waiting for disable: %d\n", ret); SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0, ret, SDE_EVTLOG_FUNC_CASE2, SDE_EVTLOG_ERROR); } sde_encoder_phys_vid_control_vblank_irq(phys_enc, false); } } static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc) { struct msm_drm_private *priv; struct sde_encoder_phys_vid *vid_enc; unsigned long lock_flags; int ret; struct intf_status intf_status = {0}; if (!phys_enc || !phys_enc->parent || !phys_enc->parent->dev || !phys_enc->parent->dev->dev_private) { Loading @@ -1075,6 +1115,8 @@ static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc) if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing)) return; else if (!sde_encoder_phys_vid_is_master(phys_enc)) goto exit; if (phys_enc->enable_state == SDE_ENC_DISABLED) { SDE_ERROR("already disabled\n"); Loading @@ -1083,43 +1125,20 @@ static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc) spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 0); if (sde_encoder_phys_vid_is_master(phys_enc)) sde_encoder_phys_inc_pending(phys_enc); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); if (!sde_encoder_phys_vid_is_master(phys_enc)) goto exit; 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, &intf_status); /* * Wait for a vsync so we know the ENABLE=0 latched before * the (connector) source of the vsync's gets disabled, * otherwise we end up in a funny state if we re-enable * before the disable latches, which results that some of * the settings changes for the new modeset (like new * scanout buffer) don't latch properly.. */ ret = sde_encoder_phys_vid_control_vblank_irq(phys_enc, true); if (ret) { SDE_ERROR_VIDENC(vid_enc, "failed to enable vblank irq: %d\n", ret); SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0, ret, SDE_EVTLOG_FUNC_CASE1, SDE_EVTLOG_ERROR); } else { ret = _sde_encoder_phys_vid_wait_for_vblank(phys_enc, false); if (ret) { atomic_set(&phys_enc->pending_kickoff_cnt, 0); SDE_ERROR_VIDENC(vid_enc, "failure waiting for disable: %d\n", ret); SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0, ret, SDE_EVTLOG_FUNC_CASE2, SDE_EVTLOG_ERROR); } sde_encoder_phys_vid_control_vblank_irq(phys_enc, false); if (intf_status.is_en) { spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); sde_encoder_phys_inc_pending(phys_enc); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); sde_encoder_phys_vid_single_vblank_wait(phys_enc); } sde_encoder_helper_phys_disable(phys_enc, NULL); Loading Loading @@ -1150,11 +1169,15 @@ static void sde_encoder_phys_vid_handle_post_kickoff( * Video encoders need to turn on their interfaces now */ if (phys_enc->enable_state == SDE_ENC_ENABLING) { if (sde_encoder_phys_vid_is_master(phys_enc)) { SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0); spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 1); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 1); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); } phys_enc->enable_state = SDE_ENC_ENABLED; } Loading drivers/gpu/drm/msm/sde/sde_hw_intf.c +17 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ #define INTF_MISR_SIGNATURE 0x184 #define INTF_MUX 0x25C #define INTF_STATUS 0x26C #define INTF_AVR_CONTROL 0x270 #define INTF_AVR_MODE 0x274 #define INTF_AVR_TRIGGER 0x278 Loading Loading @@ -387,6 +388,21 @@ static void sde_hw_intf_get_status( } } static void sde_hw_intf_v1_get_status( struct sde_hw_intf *intf, struct intf_status *s) { struct sde_hw_blk_reg_map *c = &intf->hw; 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); } else { s->line_count = 0; s->frame_count = 0; } } static void sde_hw_intf_setup_misr(struct sde_hw_intf *intf, bool enable, u32 frame_count) { Loading Loading @@ -625,6 +641,7 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops, ops->get_autorefresh = sde_hw_intf_get_autorefresh_config; 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; } } Loading Loading
drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +62 −39 Original line number Diff line number Diff line Loading @@ -1050,12 +1050,52 @@ static int sde_encoder_phys_vid_prepare_for_kickoff( return rc; } static void sde_encoder_phys_vid_single_vblank_wait( struct sde_encoder_phys *phys_enc) { int ret; struct sde_encoder_phys_vid *vid_enc = to_sde_encoder_phys_vid(phys_enc); /* * Wait for a vsync so we know the ENABLE=0 latched before * the (connector) source of the vsync's gets disabled, * otherwise we end up in a funny state if we re-enable * before the disable latches, which results that some of * the settings changes for the new modeset (like new * scanout buffer) don't latch properly.. */ ret = sde_encoder_phys_vid_control_vblank_irq(phys_enc, true); if (ret) { SDE_ERROR_VIDENC(vid_enc, "failed to enable vblank irq: %d\n", ret); SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0, ret, SDE_EVTLOG_FUNC_CASE1, SDE_EVTLOG_ERROR); } else { ret = _sde_encoder_phys_vid_wait_for_vblank(phys_enc, false); if (ret) { atomic_set(&phys_enc->pending_kickoff_cnt, 0); SDE_ERROR_VIDENC(vid_enc, "failure waiting for disable: %d\n", ret); SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0, ret, SDE_EVTLOG_FUNC_CASE2, SDE_EVTLOG_ERROR); } sde_encoder_phys_vid_control_vblank_irq(phys_enc, false); } } static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc) { struct msm_drm_private *priv; struct sde_encoder_phys_vid *vid_enc; unsigned long lock_flags; int ret; struct intf_status intf_status = {0}; if (!phys_enc || !phys_enc->parent || !phys_enc->parent->dev || !phys_enc->parent->dev->dev_private) { Loading @@ -1075,6 +1115,8 @@ static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc) if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing)) return; else if (!sde_encoder_phys_vid_is_master(phys_enc)) goto exit; if (phys_enc->enable_state == SDE_ENC_DISABLED) { SDE_ERROR("already disabled\n"); Loading @@ -1083,43 +1125,20 @@ static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc) spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 0); if (sde_encoder_phys_vid_is_master(phys_enc)) sde_encoder_phys_inc_pending(phys_enc); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); if (!sde_encoder_phys_vid_is_master(phys_enc)) goto exit; 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, &intf_status); /* * Wait for a vsync so we know the ENABLE=0 latched before * the (connector) source of the vsync's gets disabled, * otherwise we end up in a funny state if we re-enable * before the disable latches, which results that some of * the settings changes for the new modeset (like new * scanout buffer) don't latch properly.. */ ret = sde_encoder_phys_vid_control_vblank_irq(phys_enc, true); if (ret) { SDE_ERROR_VIDENC(vid_enc, "failed to enable vblank irq: %d\n", ret); SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0, ret, SDE_EVTLOG_FUNC_CASE1, SDE_EVTLOG_ERROR); } else { ret = _sde_encoder_phys_vid_wait_for_vblank(phys_enc, false); if (ret) { atomic_set(&phys_enc->pending_kickoff_cnt, 0); SDE_ERROR_VIDENC(vid_enc, "failure waiting for disable: %d\n", ret); SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0, ret, SDE_EVTLOG_FUNC_CASE2, SDE_EVTLOG_ERROR); } sde_encoder_phys_vid_control_vblank_irq(phys_enc, false); if (intf_status.is_en) { spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); sde_encoder_phys_inc_pending(phys_enc); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); sde_encoder_phys_vid_single_vblank_wait(phys_enc); } sde_encoder_helper_phys_disable(phys_enc, NULL); Loading Loading @@ -1150,11 +1169,15 @@ static void sde_encoder_phys_vid_handle_post_kickoff( * Video encoders need to turn on their interfaces now */ if (phys_enc->enable_state == SDE_ENC_ENABLING) { if (sde_encoder_phys_vid_is_master(phys_enc)) { SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0); spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 1); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 1); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); } phys_enc->enable_state = SDE_ENC_ENABLED; } Loading
drivers/gpu/drm/msm/sde/sde_hw_intf.c +17 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ #define INTF_MISR_SIGNATURE 0x184 #define INTF_MUX 0x25C #define INTF_STATUS 0x26C #define INTF_AVR_CONTROL 0x270 #define INTF_AVR_MODE 0x274 #define INTF_AVR_TRIGGER 0x278 Loading Loading @@ -387,6 +388,21 @@ static void sde_hw_intf_get_status( } } static void sde_hw_intf_v1_get_status( struct sde_hw_intf *intf, struct intf_status *s) { struct sde_hw_blk_reg_map *c = &intf->hw; 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); } else { s->line_count = 0; s->frame_count = 0; } } static void sde_hw_intf_setup_misr(struct sde_hw_intf *intf, bool enable, u32 frame_count) { Loading Loading @@ -625,6 +641,7 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops, ops->get_autorefresh = sde_hw_intf_get_autorefresh_config; 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; } } Loading