Loading msm/msm_drv.c +1 −9 Original line number Diff line number Diff line Loading @@ -365,14 +365,6 @@ static int vblank_ctrl_queue_work(struct msm_drm_private *priv, cur_work->crtc_id = crtc_id; cur_work->enable = enable; cur_work->priv = priv; /* During modeset scenario, vblank request is queued to * display thread to avoid enabling irq resulting in * vblank refcount mismatch */ if (crtc->state && drm_atomic_crtc_needs_modeset(crtc->state)) worker = &priv->disp_thread[crtc_id].worker; else worker = &priv->event_thread[crtc_id].worker; kthread_queue_work(worker, &cur_work->work); Loading msm/sde/sde_encoder_phys.h +2 −0 Original line number Diff line number Diff line Loading @@ -275,6 +275,7 @@ struct sde_encoder_irq { * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes * @enable_state: Enable state tracking * @vblank_refcount: Reference count of vblank request * @vblank_cached_refcount: Reference count of vblank cached request * @wbirq_refcount: Reference count of wb irq request * @vsync_cnt: Vsync count for the physical encoder * @underrun_cnt: Underrun count for the physical encoder Loading Loading @@ -324,6 +325,7 @@ struct sde_encoder_phys { enum sde_enc_enable_state enable_state; struct mutex *vblank_ctl_lock; atomic_t vblank_refcount; atomic_t vblank_cached_refcount; atomic_t wbirq_refcount; atomic_t vsync_cnt; atomic_t underrun_cnt; Loading msm/sde/sde_encoder_phys_cmd.c +34 −16 Original line number Diff line number Diff line Loading @@ -328,6 +328,7 @@ static void _sde_encoder_phys_cmd_setup_irq_hw_idx( struct sde_encoder_irq *irq; struct sde_kms *sde_kms; int ret = 0; u32 vblank_refcount; if (!phys_enc->sde_kms || !phys_enc->hw_pp || !phys_enc->hw_ctl) { SDE_ERROR("invalid args %d %d %d\n", !phys_enc->sde_kms, Loading @@ -342,20 +343,28 @@ static void _sde_encoder_phys_cmd_setup_irq_hw_idx( sde_kms = phys_enc->sde_kms; mutex_lock(&sde_kms->vblank_ctl_global_lock); if (atomic_read(&phys_enc->vblank_refcount)) { SDE_ERROR( "vblank_refcount mismatch detected, try to reset %d\n", atomic_read(&phys_enc->vblank_refcount)); mutex_lock(phys_enc->vblank_ctl_lock); vblank_refcount = atomic_read(&phys_enc->vblank_refcount); if (vblank_refcount) { ret = sde_encoder_helper_unregister_irq(phys_enc, INTR_IDX_RDPTR); if (ret) SDE_ERROR( "control vblank irq registration error %d\n", ret); if (vblank_refcount > 1) SDE_ERROR( "vblank_refcount mismatch detected, try to reset %d\n", atomic_read(&phys_enc->vblank_refcount)); else atomic_set(&phys_enc->vblank_cached_refcount, 1); SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0, vblank_refcount, atomic_read(&phys_enc->vblank_cached_refcount)); } atomic_set(&phys_enc->vblank_refcount, 0); mutex_unlock(phys_enc->vblank_ctl_lock); irq = &phys_enc->irq[INTR_IDX_CTL_START]; irq->hw_idx = phys_enc->hw_ctl->idx; Loading Loading @@ -389,9 +398,6 @@ static void _sde_encoder_phys_cmd_setup_irq_hw_idx( irq->hw_idx = phys_enc->hw_intf->idx; else irq->hw_idx = phys_enc->hw_pp->idx; mutex_unlock(&sde_kms->vblank_ctl_global_lock); } static void sde_encoder_phys_cmd_cont_splash_mode_set( Loading Loading @@ -811,7 +817,7 @@ static int sde_encoder_phys_cmd_control_vblank_irq( struct sde_encoder_phys_cmd *cmd_enc = to_sde_encoder_phys_cmd(phys_enc); int ret = 0; int refcount; u32 refcount, cached_refcount; struct sde_kms *sde_kms; if (!phys_enc || !phys_enc->hw_pp) { Loading @@ -820,18 +826,24 @@ static int sde_encoder_phys_cmd_control_vblank_irq( } sde_kms = phys_enc->sde_kms; mutex_lock(&sde_kms->vblank_ctl_global_lock); refcount = atomic_read(&phys_enc->vblank_refcount); mutex_lock(phys_enc->vblank_ctl_lock); /* Slave encoders don't report vblank */ if (!sde_encoder_phys_cmd_is_master(phys_enc)) goto end; refcount = atomic_read(&phys_enc->vblank_refcount); cached_refcount = atomic_read(&phys_enc->vblank_cached_refcount); /* protect against negative */ if (!enable && refcount == 0) { if (cached_refcount == 1) { atomic_set(&phys_enc->vblank_cached_refcount, 0); goto end; } else { ret = -EINVAL; goto end; } } SDE_DEBUG_CMDENC(cmd_enc, "[%pS] enable=%d/%d\n", __builtin_return_address(0), enable, refcount); Loading @@ -850,7 +862,13 @@ static int sde_encoder_phys_cmd_control_vblank_irq( atomic_inc_return(&phys_enc->vblank_refcount); } if (enable && cached_refcount) { atomic_inc(&phys_enc->vblank_refcount); atomic_set(&phys_enc->vblank_cached_refcount, 0); } end: mutex_unlock(phys_enc->vblank_ctl_lock); if (ret) { SDE_ERROR_CMDENC(cmd_enc, "control vblank irq error %d, enable %d, refcount %d\n", Loading @@ -860,7 +878,6 @@ static int sde_encoder_phys_cmd_control_vblank_irq( enable, refcount, SDE_EVTLOG_ERROR); } mutex_unlock(&sde_kms->vblank_ctl_global_lock); return ret; } Loading Loading @@ -2071,6 +2088,7 @@ struct sde_encoder_phys *sde_encoder_phys_cmd_init( irq->cb.func = sde_encoder_phys_cmd_wr_ptr_irq; atomic_set(&phys_enc->vblank_refcount, 0); atomic_set(&phys_enc->vblank_cached_refcount, 0); atomic_set(&phys_enc->pending_kickoff_cnt, 0); atomic_set(&phys_enc->pending_retire_fence_cnt, 0); atomic_set(&cmd_enc->pending_vblank_cnt, 0); Loading msm/sde/sde_kms.c +0 −1 Original line number Diff line number Diff line Loading @@ -3624,7 +3624,6 @@ static int sde_kms_hw_init(struct msm_kms *kms) dev->mode_config.max_height = sde_kms->catalog->max_display_height; mutex_init(&sde_kms->secure_transition_lock); mutex_init(&sde_kms->vblank_ctl_global_lock); atomic_set(&sde_kms->detach_sec_cb, 0); atomic_set(&sde_kms->detach_all_cb, 0); Loading msm/sde/sde_kms.h +0 −1 Original line number Diff line number Diff line Loading @@ -302,7 +302,6 @@ struct sde_kms { atomic_t detach_sec_cb; atomic_t detach_all_cb; struct mutex secure_transition_lock; struct mutex vblank_ctl_global_lock; bool first_kickoff; bool qdss_enabled; Loading Loading
msm/msm_drv.c +1 −9 Original line number Diff line number Diff line Loading @@ -365,14 +365,6 @@ static int vblank_ctrl_queue_work(struct msm_drm_private *priv, cur_work->crtc_id = crtc_id; cur_work->enable = enable; cur_work->priv = priv; /* During modeset scenario, vblank request is queued to * display thread to avoid enabling irq resulting in * vblank refcount mismatch */ if (crtc->state && drm_atomic_crtc_needs_modeset(crtc->state)) worker = &priv->disp_thread[crtc_id].worker; else worker = &priv->event_thread[crtc_id].worker; kthread_queue_work(worker, &cur_work->work); Loading
msm/sde/sde_encoder_phys.h +2 −0 Original line number Diff line number Diff line Loading @@ -275,6 +275,7 @@ struct sde_encoder_irq { * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes * @enable_state: Enable state tracking * @vblank_refcount: Reference count of vblank request * @vblank_cached_refcount: Reference count of vblank cached request * @wbirq_refcount: Reference count of wb irq request * @vsync_cnt: Vsync count for the physical encoder * @underrun_cnt: Underrun count for the physical encoder Loading Loading @@ -324,6 +325,7 @@ struct sde_encoder_phys { enum sde_enc_enable_state enable_state; struct mutex *vblank_ctl_lock; atomic_t vblank_refcount; atomic_t vblank_cached_refcount; atomic_t wbirq_refcount; atomic_t vsync_cnt; atomic_t underrun_cnt; Loading
msm/sde/sde_encoder_phys_cmd.c +34 −16 Original line number Diff line number Diff line Loading @@ -328,6 +328,7 @@ static void _sde_encoder_phys_cmd_setup_irq_hw_idx( struct sde_encoder_irq *irq; struct sde_kms *sde_kms; int ret = 0; u32 vblank_refcount; if (!phys_enc->sde_kms || !phys_enc->hw_pp || !phys_enc->hw_ctl) { SDE_ERROR("invalid args %d %d %d\n", !phys_enc->sde_kms, Loading @@ -342,20 +343,28 @@ static void _sde_encoder_phys_cmd_setup_irq_hw_idx( sde_kms = phys_enc->sde_kms; mutex_lock(&sde_kms->vblank_ctl_global_lock); if (atomic_read(&phys_enc->vblank_refcount)) { SDE_ERROR( "vblank_refcount mismatch detected, try to reset %d\n", atomic_read(&phys_enc->vblank_refcount)); mutex_lock(phys_enc->vblank_ctl_lock); vblank_refcount = atomic_read(&phys_enc->vblank_refcount); if (vblank_refcount) { ret = sde_encoder_helper_unregister_irq(phys_enc, INTR_IDX_RDPTR); if (ret) SDE_ERROR( "control vblank irq registration error %d\n", ret); if (vblank_refcount > 1) SDE_ERROR( "vblank_refcount mismatch detected, try to reset %d\n", atomic_read(&phys_enc->vblank_refcount)); else atomic_set(&phys_enc->vblank_cached_refcount, 1); SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0, vblank_refcount, atomic_read(&phys_enc->vblank_cached_refcount)); } atomic_set(&phys_enc->vblank_refcount, 0); mutex_unlock(phys_enc->vblank_ctl_lock); irq = &phys_enc->irq[INTR_IDX_CTL_START]; irq->hw_idx = phys_enc->hw_ctl->idx; Loading Loading @@ -389,9 +398,6 @@ static void _sde_encoder_phys_cmd_setup_irq_hw_idx( irq->hw_idx = phys_enc->hw_intf->idx; else irq->hw_idx = phys_enc->hw_pp->idx; mutex_unlock(&sde_kms->vblank_ctl_global_lock); } static void sde_encoder_phys_cmd_cont_splash_mode_set( Loading Loading @@ -811,7 +817,7 @@ static int sde_encoder_phys_cmd_control_vblank_irq( struct sde_encoder_phys_cmd *cmd_enc = to_sde_encoder_phys_cmd(phys_enc); int ret = 0; int refcount; u32 refcount, cached_refcount; struct sde_kms *sde_kms; if (!phys_enc || !phys_enc->hw_pp) { Loading @@ -820,18 +826,24 @@ static int sde_encoder_phys_cmd_control_vblank_irq( } sde_kms = phys_enc->sde_kms; mutex_lock(&sde_kms->vblank_ctl_global_lock); refcount = atomic_read(&phys_enc->vblank_refcount); mutex_lock(phys_enc->vblank_ctl_lock); /* Slave encoders don't report vblank */ if (!sde_encoder_phys_cmd_is_master(phys_enc)) goto end; refcount = atomic_read(&phys_enc->vblank_refcount); cached_refcount = atomic_read(&phys_enc->vblank_cached_refcount); /* protect against negative */ if (!enable && refcount == 0) { if (cached_refcount == 1) { atomic_set(&phys_enc->vblank_cached_refcount, 0); goto end; } else { ret = -EINVAL; goto end; } } SDE_DEBUG_CMDENC(cmd_enc, "[%pS] enable=%d/%d\n", __builtin_return_address(0), enable, refcount); Loading @@ -850,7 +862,13 @@ static int sde_encoder_phys_cmd_control_vblank_irq( atomic_inc_return(&phys_enc->vblank_refcount); } if (enable && cached_refcount) { atomic_inc(&phys_enc->vblank_refcount); atomic_set(&phys_enc->vblank_cached_refcount, 0); } end: mutex_unlock(phys_enc->vblank_ctl_lock); if (ret) { SDE_ERROR_CMDENC(cmd_enc, "control vblank irq error %d, enable %d, refcount %d\n", Loading @@ -860,7 +878,6 @@ static int sde_encoder_phys_cmd_control_vblank_irq( enable, refcount, SDE_EVTLOG_ERROR); } mutex_unlock(&sde_kms->vblank_ctl_global_lock); return ret; } Loading Loading @@ -2071,6 +2088,7 @@ struct sde_encoder_phys *sde_encoder_phys_cmd_init( irq->cb.func = sde_encoder_phys_cmd_wr_ptr_irq; atomic_set(&phys_enc->vblank_refcount, 0); atomic_set(&phys_enc->vblank_cached_refcount, 0); atomic_set(&phys_enc->pending_kickoff_cnt, 0); atomic_set(&phys_enc->pending_retire_fence_cnt, 0); atomic_set(&cmd_enc->pending_vblank_cnt, 0); Loading
msm/sde/sde_kms.c +0 −1 Original line number Diff line number Diff line Loading @@ -3624,7 +3624,6 @@ static int sde_kms_hw_init(struct msm_kms *kms) dev->mode_config.max_height = sde_kms->catalog->max_display_height; mutex_init(&sde_kms->secure_transition_lock); mutex_init(&sde_kms->vblank_ctl_global_lock); atomic_set(&sde_kms->detach_sec_cb, 0); atomic_set(&sde_kms->detach_all_cb, 0); Loading
msm/sde/sde_kms.h +0 −1 Original line number Diff line number Diff line Loading @@ -302,7 +302,6 @@ struct sde_kms { atomic_t detach_sec_cb; atomic_t detach_all_cb; struct mutex secure_transition_lock; struct mutex vblank_ctl_global_lock; bool first_kickoff; bool qdss_enabled; Loading