Loading drivers/gpu/drm/msm/sde/sde_crtc.c +54 −2 Original line number Diff line number Diff line Loading @@ -2190,21 +2190,62 @@ static int _sde_crtc_vblank_no_lock(struct sde_crtc *sde_crtc, bool en) return 0; } static void sde_crtc_handle_power_event(u32 event_type, void *arg) { struct drm_crtc *crtc = arg; struct sde_crtc *sde_crtc; struct drm_encoder *encoder; if (!crtc) { SDE_ERROR("invalid crtc\n"); return; } sde_crtc = to_sde_crtc(crtc); mutex_lock(&sde_crtc->crtc_lock); SDE_EVT32(DRMID(crtc), event_type); if (event_type == SDE_POWER_EVENT_POST_ENABLE) { /* restore encoder; crtc will be programmed during commit */ drm_for_each_encoder(encoder, crtc->dev) { if (encoder->crtc != crtc) continue; sde_encoder_virt_restore(encoder); } } else if (event_type == SDE_POWER_EVENT_POST_DISABLE) { struct drm_plane *plane; /* * set revalidate flag in planes, so it will be re-programmed * in the next frame update */ drm_atomic_crtc_for_each_plane(plane, crtc) sde_plane_set_revalidate(plane, true); } mutex_unlock(&sde_crtc->crtc_lock); } static void sde_crtc_disable(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; struct drm_encoder *encoder; struct msm_drm_private *priv; unsigned long flags; struct sde_crtc_irq_info *node = NULL; int ret; if (!crtc || !crtc->dev || !crtc->state) { if (!crtc || !crtc->dev || !crtc->dev->dev_private || !crtc->state) { SDE_ERROR("invalid crtc\n"); return; } sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(crtc->state); priv = crtc->dev->dev_private; SDE_DEBUG("crtc%d\n", crtc->base.id); Loading Loading @@ -2244,6 +2285,10 @@ static void sde_crtc_disable(struct drm_crtc *crtc) cstate->rsc_update = false; } if (sde_crtc->power_event) sde_power_handle_unregister_event(&priv->phandle, sde_crtc->power_event); memset(sde_crtc->mixers, 0, sizeof(sde_crtc->mixers)); sde_crtc->num_mixers = 0; Loading @@ -2265,14 +2310,16 @@ static void sde_crtc_enable(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc; struct drm_encoder *encoder; struct msm_drm_private *priv; unsigned long flags; struct sde_crtc_irq_info *node = NULL; int ret; if (!crtc) { if (!crtc || !crtc->dev || !crtc->dev->dev_private) { SDE_ERROR("invalid crtc\n"); return; } priv = crtc->dev->dev_private; SDE_DEBUG("crtc%d\n", crtc->base.id); SDE_EVT32(DRMID(crtc)); Loading @@ -2295,6 +2342,11 @@ static void sde_crtc_enable(struct drm_crtc *crtc) sde_crtc->name, node->event); } spin_unlock_irqrestore(&sde_crtc->spin_lock, flags); sde_crtc->power_event = sde_power_handle_register_event( &priv->phandle, SDE_POWER_EVENT_POST_ENABLE | SDE_POWER_EVENT_POST_DISABLE, sde_crtc_handle_power_event, crtc, sde_crtc->name); } struct plane_state { Loading drivers/gpu/drm/msm/sde/sde_crtc.h +3 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,7 @@ struct sde_crtc_event { * @event_free_list : List of available event structures * @event_lock : Spinlock around event handling code * @misr_enable : boolean entry indicates misr enable/disable status. * @power_event : registered power event handle */ struct sde_crtc { struct drm_crtc base; Loading Loading @@ -187,6 +188,8 @@ struct sde_crtc { struct list_head event_free_list; spinlock_t event_lock; bool misr_enable; struct sde_power_event *power_event; }; #define to_sde_crtc(x) container_of(x, struct sde_crtc, base) Loading drivers/gpu/drm/msm/sde/sde_encoder.c +59 −25 Original line number Diff line number Diff line Loading @@ -1169,34 +1169,79 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, } } static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) static void _sde_encoder_virt_enable_helper(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; struct msm_drm_private *priv; struct sde_kms *sde_kms; int i = 0; int ret = 0; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); return; } else if (!drm_enc->dev) { SDE_ERROR("invalid dev\n"); return; } else if (!drm_enc->dev->dev_private) { SDE_ERROR("invalid dev_private\n"); if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) { SDE_ERROR("invalid parameters\n"); return; } priv = drm_enc->dev->dev_private; sde_enc = to_sde_encoder_virt(drm_enc); priv = drm_enc->dev->dev_private; sde_kms = to_sde_kms(priv->kms); if (!sde_enc || !sde_enc->cur_master) { SDE_ERROR("invalid sde encoder/master\n"); return; } sde_kms = to_sde_kms(priv->kms); if (!sde_kms) { SDE_ERROR("invalid sde_kms\n"); return; } if (sde_enc->cur_master->hw_mdptop && sde_enc->cur_master->hw_mdptop->ops.reset_ubwc) sde_enc->cur_master->hw_mdptop->ops.reset_ubwc( sde_enc->cur_master->hw_mdptop, sde_kms->catalog); if (_sde_is_dsc_enabled(sde_enc)) { ret = _sde_encoder_dsc_setup(sde_enc); if (ret) SDE_ERROR_ENC(sde_enc, "failed to setup DSC:%d\n", ret); } } void sde_encoder_virt_restore(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; int i; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); return; } sde_enc = to_sde_encoder_virt(drm_enc); for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys && (phys != sde_enc->cur_master) && phys->ops.restore) phys->ops.restore(phys); } if (sde_enc->cur_master && sde_enc->cur_master->ops.restore) sde_enc->cur_master->ops.restore(sde_enc->cur_master); _sde_encoder_virt_enable_helper(drm_enc); } static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; int i, ret = 0; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); return; } sde_enc = to_sde_encoder_virt(drm_enc); SDE_DEBUG_ENC(sde_enc, "\n"); SDE_EVT32(DRMID(drm_enc)); Loading Loading @@ -1230,21 +1275,10 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) phys->ops.enable(phys); } if (sde_enc->cur_master && sde_enc->cur_master->ops.enable) if (sde_enc->cur_master->ops.enable) sde_enc->cur_master->ops.enable(sde_enc->cur_master); if (sde_enc->cur_master && sde_enc->cur_master->hw_mdptop && sde_enc->cur_master->hw_mdptop->ops.reset_ubwc) sde_enc->cur_master->hw_mdptop->ops.reset_ubwc( sde_enc->cur_master->hw_mdptop, sde_kms->catalog); if (_sde_is_dsc_enabled(sde_enc)) { ret = _sde_encoder_dsc_setup(sde_enc); if (ret) SDE_ERROR_ENC(sde_enc, "failed to setup DSC: %d\n", ret); } _sde_encoder_virt_enable_helper(drm_enc); } static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) Loading drivers/gpu/drm/msm/sde/sde_encoder.h +6 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,12 @@ int sde_encoder_wait_for_commit_done(struct drm_encoder *drm_encoder); */ enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder); /** * sde_encoder_virt_restore - restore the encoder configs * @encoder: encoder pointer */ void sde_encoder_virt_restore(struct drm_encoder *encoder); /** * enum sde_encoder_property - property tags for sde enoder * @SDE_ENCODER_PROPERTY_INLINE_ROTATE_REFILL: # of prefill line, 0 to disable Loading drivers/gpu/drm/msm/sde/sde_encoder_phys.h +2 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ struct sde_encoder_virt_ops { * SDE_ENC_ERR_NEEDS_HW_RESET state * @irq_control: Handler to enable/disable all the encoder IRQs * @update_split_role: Update the split role of the phys enc * @restore: Restore all the encoder configs. */ struct sde_encoder_phys_ops { Loading Loading @@ -157,6 +158,7 @@ struct sde_encoder_phys_ops { void (*irq_control)(struct sde_encoder_phys *phys, bool enable); void (*update_split_role)(struct sde_encoder_phys *phys_enc, enum sde_enc_split_role role); void (*restore)(struct sde_encoder_phys *phys); }; /** Loading Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +54 −2 Original line number Diff line number Diff line Loading @@ -2190,21 +2190,62 @@ static int _sde_crtc_vblank_no_lock(struct sde_crtc *sde_crtc, bool en) return 0; } static void sde_crtc_handle_power_event(u32 event_type, void *arg) { struct drm_crtc *crtc = arg; struct sde_crtc *sde_crtc; struct drm_encoder *encoder; if (!crtc) { SDE_ERROR("invalid crtc\n"); return; } sde_crtc = to_sde_crtc(crtc); mutex_lock(&sde_crtc->crtc_lock); SDE_EVT32(DRMID(crtc), event_type); if (event_type == SDE_POWER_EVENT_POST_ENABLE) { /* restore encoder; crtc will be programmed during commit */ drm_for_each_encoder(encoder, crtc->dev) { if (encoder->crtc != crtc) continue; sde_encoder_virt_restore(encoder); } } else if (event_type == SDE_POWER_EVENT_POST_DISABLE) { struct drm_plane *plane; /* * set revalidate flag in planes, so it will be re-programmed * in the next frame update */ drm_atomic_crtc_for_each_plane(plane, crtc) sde_plane_set_revalidate(plane, true); } mutex_unlock(&sde_crtc->crtc_lock); } static void sde_crtc_disable(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; struct drm_encoder *encoder; struct msm_drm_private *priv; unsigned long flags; struct sde_crtc_irq_info *node = NULL; int ret; if (!crtc || !crtc->dev || !crtc->state) { if (!crtc || !crtc->dev || !crtc->dev->dev_private || !crtc->state) { SDE_ERROR("invalid crtc\n"); return; } sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(crtc->state); priv = crtc->dev->dev_private; SDE_DEBUG("crtc%d\n", crtc->base.id); Loading Loading @@ -2244,6 +2285,10 @@ static void sde_crtc_disable(struct drm_crtc *crtc) cstate->rsc_update = false; } if (sde_crtc->power_event) sde_power_handle_unregister_event(&priv->phandle, sde_crtc->power_event); memset(sde_crtc->mixers, 0, sizeof(sde_crtc->mixers)); sde_crtc->num_mixers = 0; Loading @@ -2265,14 +2310,16 @@ static void sde_crtc_enable(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc; struct drm_encoder *encoder; struct msm_drm_private *priv; unsigned long flags; struct sde_crtc_irq_info *node = NULL; int ret; if (!crtc) { if (!crtc || !crtc->dev || !crtc->dev->dev_private) { SDE_ERROR("invalid crtc\n"); return; } priv = crtc->dev->dev_private; SDE_DEBUG("crtc%d\n", crtc->base.id); SDE_EVT32(DRMID(crtc)); Loading @@ -2295,6 +2342,11 @@ static void sde_crtc_enable(struct drm_crtc *crtc) sde_crtc->name, node->event); } spin_unlock_irqrestore(&sde_crtc->spin_lock, flags); sde_crtc->power_event = sde_power_handle_register_event( &priv->phandle, SDE_POWER_EVENT_POST_ENABLE | SDE_POWER_EVENT_POST_DISABLE, sde_crtc_handle_power_event, crtc, sde_crtc->name); } struct plane_state { Loading
drivers/gpu/drm/msm/sde/sde_crtc.h +3 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,7 @@ struct sde_crtc_event { * @event_free_list : List of available event structures * @event_lock : Spinlock around event handling code * @misr_enable : boolean entry indicates misr enable/disable status. * @power_event : registered power event handle */ struct sde_crtc { struct drm_crtc base; Loading Loading @@ -187,6 +188,8 @@ struct sde_crtc { struct list_head event_free_list; spinlock_t event_lock; bool misr_enable; struct sde_power_event *power_event; }; #define to_sde_crtc(x) container_of(x, struct sde_crtc, base) Loading
drivers/gpu/drm/msm/sde/sde_encoder.c +59 −25 Original line number Diff line number Diff line Loading @@ -1169,34 +1169,79 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, } } static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) static void _sde_encoder_virt_enable_helper(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; struct msm_drm_private *priv; struct sde_kms *sde_kms; int i = 0; int ret = 0; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); return; } else if (!drm_enc->dev) { SDE_ERROR("invalid dev\n"); return; } else if (!drm_enc->dev->dev_private) { SDE_ERROR("invalid dev_private\n"); if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) { SDE_ERROR("invalid parameters\n"); return; } priv = drm_enc->dev->dev_private; sde_enc = to_sde_encoder_virt(drm_enc); priv = drm_enc->dev->dev_private; sde_kms = to_sde_kms(priv->kms); if (!sde_enc || !sde_enc->cur_master) { SDE_ERROR("invalid sde encoder/master\n"); return; } sde_kms = to_sde_kms(priv->kms); if (!sde_kms) { SDE_ERROR("invalid sde_kms\n"); return; } if (sde_enc->cur_master->hw_mdptop && sde_enc->cur_master->hw_mdptop->ops.reset_ubwc) sde_enc->cur_master->hw_mdptop->ops.reset_ubwc( sde_enc->cur_master->hw_mdptop, sde_kms->catalog); if (_sde_is_dsc_enabled(sde_enc)) { ret = _sde_encoder_dsc_setup(sde_enc); if (ret) SDE_ERROR_ENC(sde_enc, "failed to setup DSC:%d\n", ret); } } void sde_encoder_virt_restore(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; int i; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); return; } sde_enc = to_sde_encoder_virt(drm_enc); for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys && (phys != sde_enc->cur_master) && phys->ops.restore) phys->ops.restore(phys); } if (sde_enc->cur_master && sde_enc->cur_master->ops.restore) sde_enc->cur_master->ops.restore(sde_enc->cur_master); _sde_encoder_virt_enable_helper(drm_enc); } static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; int i, ret = 0; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); return; } sde_enc = to_sde_encoder_virt(drm_enc); SDE_DEBUG_ENC(sde_enc, "\n"); SDE_EVT32(DRMID(drm_enc)); Loading Loading @@ -1230,21 +1275,10 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) phys->ops.enable(phys); } if (sde_enc->cur_master && sde_enc->cur_master->ops.enable) if (sde_enc->cur_master->ops.enable) sde_enc->cur_master->ops.enable(sde_enc->cur_master); if (sde_enc->cur_master && sde_enc->cur_master->hw_mdptop && sde_enc->cur_master->hw_mdptop->ops.reset_ubwc) sde_enc->cur_master->hw_mdptop->ops.reset_ubwc( sde_enc->cur_master->hw_mdptop, sde_kms->catalog); if (_sde_is_dsc_enabled(sde_enc)) { ret = _sde_encoder_dsc_setup(sde_enc); if (ret) SDE_ERROR_ENC(sde_enc, "failed to setup DSC: %d\n", ret); } _sde_encoder_virt_enable_helper(drm_enc); } static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) Loading
drivers/gpu/drm/msm/sde/sde_encoder.h +6 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,12 @@ int sde_encoder_wait_for_commit_done(struct drm_encoder *drm_encoder); */ enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder); /** * sde_encoder_virt_restore - restore the encoder configs * @encoder: encoder pointer */ void sde_encoder_virt_restore(struct drm_encoder *encoder); /** * enum sde_encoder_property - property tags for sde enoder * @SDE_ENCODER_PROPERTY_INLINE_ROTATE_REFILL: # of prefill line, 0 to disable Loading
drivers/gpu/drm/msm/sde/sde_encoder_phys.h +2 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ struct sde_encoder_virt_ops { * SDE_ENC_ERR_NEEDS_HW_RESET state * @irq_control: Handler to enable/disable all the encoder IRQs * @update_split_role: Update the split role of the phys enc * @restore: Restore all the encoder configs. */ struct sde_encoder_phys_ops { Loading Loading @@ -157,6 +158,7 @@ struct sde_encoder_phys_ops { void (*irq_control)(struct sde_encoder_phys *phys, bool enable); void (*update_split_role)(struct sde_encoder_phys *phys_enc, enum sde_enc_split_role role); void (*restore)(struct sde_encoder_phys *phys); }; /** Loading