Loading drivers/gpu/drm/msm/sde/sde_crtc.c +15 −0 Original line number Diff line number Diff line Loading @@ -3997,6 +3997,21 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg) } break; case SDE_POWER_EVENT_PRE_DISABLE: drm_for_each_encoder(encoder, crtc->dev) { if (encoder->crtc != crtc) continue; /* * disable the vsync source after updating the * rsc state. rsc state update might have vsync wait * and vsync source must be disabled after it. * It will avoid generating any vsync from this point * till mode-2 entry. It is SW workaround for HW * limitation and should not be removed without * checking the updated design. */ sde_encoder_control_te(encoder, false); } for (i = 0; i < sde_crtc->num_mixers; ++i) { m = &sde_crtc->mixers[i]; if (!m->hw_lm || !m->hw_lm->ops.collect_misr || Loading drivers/gpu/drm/msm/sde/sde_encoder.c +25 −18 Original line number Diff line number Diff line Loading @@ -1657,9 +1657,7 @@ struct sde_rsc_client *sde_encoder_get_rsc_client(struct drm_encoder *drm_enc) static void _sde_encoder_resource_control_rsc_update( struct drm_encoder *drm_enc, bool enable) { struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); struct sde_encoder_rsc_config rsc_cfg = { 0 }; int i; if (enable) { rsc_cfg.inline_rotate_prefill = Loading @@ -1668,22 +1666,6 @@ static void _sde_encoder_resource_control_rsc_update( _sde_encoder_update_rsc_client(drm_enc, &rsc_cfg, true); } else { _sde_encoder_update_rsc_client(drm_enc, NULL, false); /** * disable the vsync source after updating the rsc state. rsc * state update might have vsync wait and vsync source must be * disabled after it. It will avoid generating any vsync from * this point till mode-2 entry. It is SW workaround for * HW limitation and should not be removed without checking the * updated design. */ for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys && phys->ops.prepare_idle_pc) phys->ops.prepare_idle_pc(phys); } } } Loading Loading @@ -2194,6 +2176,30 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, SDE_ENC_RC_EVENT_POST_MODESET); } void sde_encoder_control_te(struct drm_encoder *drm_enc, bool enable) { struct sde_encoder_virt *sde_enc; struct sde_encoder_phys *phys; int i; if (!drm_enc) { SDE_ERROR("invalid parameters\n"); return; } sde_enc = to_sde_encoder_virt(drm_enc); if (!sde_enc) { SDE_ERROR("invalid sde encoder\n"); return; } for (i = 0; i < sde_enc->num_phys_encs; i++) { phys = sde_enc->phys_encs[i]; if (phys && phys->ops.control_te) phys->ops.control_te(phys, enable); } } static void _sde_encoder_virt_enable_helper(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; Loading Loading @@ -2231,6 +2237,7 @@ static void _sde_encoder_virt_enable_helper(struct drm_encoder *drm_enc) sde_kms->catalog); _sde_encoder_update_vsync_source(sde_enc, &sde_enc->disp_info, false); sde_encoder_control_te(drm_enc, true); memset(&sde_enc->prv_conn_roi, 0, sizeof(sde_enc->prv_conn_roi)); memset(&sde_enc->cur_conn_roi, 0, sizeof(sde_enc->cur_conn_roi)); Loading drivers/gpu/drm/msm/sde/sde_encoder.h +7 −0 Original line number Diff line number Diff line Loading @@ -162,6 +162,13 @@ int sde_encoder_wait_for_event(struct drm_encoder *drm_encoder, */ enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder); /** * sde_encoder_control_te - control enabling/disabling VSYNC_IN_EN * @encoder: encoder pointer * @enable: boolean to indicate enable/disable */ void sde_encoder_control_te(struct drm_encoder *encoder, bool enable); /** * sde_encoder_virt_restore - restore the encoder configs * @encoder: encoder pointer Loading drivers/gpu/drm/msm/sde/sde_encoder_phys.h +2 −3 Original line number Diff line number Diff line Loading @@ -128,8 +128,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 * @prepare_idle_pc: phys encoder can update the vsync_enable status * on idle power collapse prepare * @control_te: Interface to control the vsync_enable status * @restore: Restore all the encoder configs. * @is_autorefresh_enabled: provides the autorefresh current * enable/disable state. Loading Loading @@ -178,7 +177,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 (*prepare_idle_pc)(struct sde_encoder_phys *phys_enc); void (*control_te)(struct sde_encoder_phys *phys_enc, bool enable); void (*restore)(struct sde_encoder_phys *phys); bool (*is_autorefresh_enabled)(struct sde_encoder_phys *phys); int (*get_line_count)(struct sde_encoder_phys *phys); Loading drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c +2 −22 Original line number Diff line number Diff line Loading @@ -906,7 +906,7 @@ static bool sde_encoder_phys_cmd_is_autorefresh_enabled( return cfg.enable; } static void _sde_encoder_phys_cmd_connect_te( static void sde_encoder_phys_cmd_connect_te( struct sde_encoder_phys *phys_enc, bool enable) { if (!phys_enc || !phys_enc->hw_pp || Loading @@ -917,12 +917,6 @@ static void _sde_encoder_phys_cmd_connect_te( phys_enc->hw_pp->ops.connect_external_te(phys_enc->hw_pp, enable); } static void sde_encoder_phys_cmd_prepare_idle_pc( struct sde_encoder_phys *phys_enc) { _sde_encoder_phys_cmd_connect_te(phys_enc, false); } static int sde_encoder_phys_cmd_get_line_count( struct sde_encoder_phys *phys_enc) { Loading Loading @@ -1229,19 +1223,6 @@ static void sde_encoder_phys_cmd_prepare_commit( SDE_DEBUG_CMDENC(cmd_enc, "disabled autorefresh\n"); } static void sde_encoder_phys_cmd_handle_post_kickoff( struct sde_encoder_phys *phys_enc) { if (!phys_enc) return; /** * re-enable external TE, either for the first time after enabling * or if disabled for Autorefresh */ _sde_encoder_phys_cmd_connect_te(phys_enc, true); } static void sde_encoder_phys_cmd_trigger_start( struct sde_encoder_phys *phys_enc) { Loading Loading @@ -1286,10 +1267,9 @@ static void sde_encoder_phys_cmd_init_ops( ops->irq_control = sde_encoder_phys_cmd_irq_control; ops->update_split_role = sde_encoder_phys_cmd_update_split_role; ops->restore = sde_encoder_phys_cmd_enable_helper; ops->prepare_idle_pc = sde_encoder_phys_cmd_prepare_idle_pc; ops->control_te = sde_encoder_phys_cmd_connect_te; ops->is_autorefresh_enabled = sde_encoder_phys_cmd_is_autorefresh_enabled; ops->handle_post_kickoff = sde_encoder_phys_cmd_handle_post_kickoff; ops->get_line_count = sde_encoder_phys_cmd_get_line_count; } Loading Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +15 −0 Original line number Diff line number Diff line Loading @@ -3997,6 +3997,21 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg) } break; case SDE_POWER_EVENT_PRE_DISABLE: drm_for_each_encoder(encoder, crtc->dev) { if (encoder->crtc != crtc) continue; /* * disable the vsync source after updating the * rsc state. rsc state update might have vsync wait * and vsync source must be disabled after it. * It will avoid generating any vsync from this point * till mode-2 entry. It is SW workaround for HW * limitation and should not be removed without * checking the updated design. */ sde_encoder_control_te(encoder, false); } for (i = 0; i < sde_crtc->num_mixers; ++i) { m = &sde_crtc->mixers[i]; if (!m->hw_lm || !m->hw_lm->ops.collect_misr || Loading
drivers/gpu/drm/msm/sde/sde_encoder.c +25 −18 Original line number Diff line number Diff line Loading @@ -1657,9 +1657,7 @@ struct sde_rsc_client *sde_encoder_get_rsc_client(struct drm_encoder *drm_enc) static void _sde_encoder_resource_control_rsc_update( struct drm_encoder *drm_enc, bool enable) { struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); struct sde_encoder_rsc_config rsc_cfg = { 0 }; int i; if (enable) { rsc_cfg.inline_rotate_prefill = Loading @@ -1668,22 +1666,6 @@ static void _sde_encoder_resource_control_rsc_update( _sde_encoder_update_rsc_client(drm_enc, &rsc_cfg, true); } else { _sde_encoder_update_rsc_client(drm_enc, NULL, false); /** * disable the vsync source after updating the rsc state. rsc * state update might have vsync wait and vsync source must be * disabled after it. It will avoid generating any vsync from * this point till mode-2 entry. It is SW workaround for * HW limitation and should not be removed without checking the * updated design. */ for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys && phys->ops.prepare_idle_pc) phys->ops.prepare_idle_pc(phys); } } } Loading Loading @@ -2194,6 +2176,30 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, SDE_ENC_RC_EVENT_POST_MODESET); } void sde_encoder_control_te(struct drm_encoder *drm_enc, bool enable) { struct sde_encoder_virt *sde_enc; struct sde_encoder_phys *phys; int i; if (!drm_enc) { SDE_ERROR("invalid parameters\n"); return; } sde_enc = to_sde_encoder_virt(drm_enc); if (!sde_enc) { SDE_ERROR("invalid sde encoder\n"); return; } for (i = 0; i < sde_enc->num_phys_encs; i++) { phys = sde_enc->phys_encs[i]; if (phys && phys->ops.control_te) phys->ops.control_te(phys, enable); } } static void _sde_encoder_virt_enable_helper(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; Loading Loading @@ -2231,6 +2237,7 @@ static void _sde_encoder_virt_enable_helper(struct drm_encoder *drm_enc) sde_kms->catalog); _sde_encoder_update_vsync_source(sde_enc, &sde_enc->disp_info, false); sde_encoder_control_te(drm_enc, true); memset(&sde_enc->prv_conn_roi, 0, sizeof(sde_enc->prv_conn_roi)); memset(&sde_enc->cur_conn_roi, 0, sizeof(sde_enc->cur_conn_roi)); Loading
drivers/gpu/drm/msm/sde/sde_encoder.h +7 −0 Original line number Diff line number Diff line Loading @@ -162,6 +162,13 @@ int sde_encoder_wait_for_event(struct drm_encoder *drm_encoder, */ enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder); /** * sde_encoder_control_te - control enabling/disabling VSYNC_IN_EN * @encoder: encoder pointer * @enable: boolean to indicate enable/disable */ void sde_encoder_control_te(struct drm_encoder *encoder, bool enable); /** * sde_encoder_virt_restore - restore the encoder configs * @encoder: encoder pointer Loading
drivers/gpu/drm/msm/sde/sde_encoder_phys.h +2 −3 Original line number Diff line number Diff line Loading @@ -128,8 +128,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 * @prepare_idle_pc: phys encoder can update the vsync_enable status * on idle power collapse prepare * @control_te: Interface to control the vsync_enable status * @restore: Restore all the encoder configs. * @is_autorefresh_enabled: provides the autorefresh current * enable/disable state. Loading Loading @@ -178,7 +177,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 (*prepare_idle_pc)(struct sde_encoder_phys *phys_enc); void (*control_te)(struct sde_encoder_phys *phys_enc, bool enable); void (*restore)(struct sde_encoder_phys *phys); bool (*is_autorefresh_enabled)(struct sde_encoder_phys *phys); int (*get_line_count)(struct sde_encoder_phys *phys); Loading
drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c +2 −22 Original line number Diff line number Diff line Loading @@ -906,7 +906,7 @@ static bool sde_encoder_phys_cmd_is_autorefresh_enabled( return cfg.enable; } static void _sde_encoder_phys_cmd_connect_te( static void sde_encoder_phys_cmd_connect_te( struct sde_encoder_phys *phys_enc, bool enable) { if (!phys_enc || !phys_enc->hw_pp || Loading @@ -917,12 +917,6 @@ static void _sde_encoder_phys_cmd_connect_te( phys_enc->hw_pp->ops.connect_external_te(phys_enc->hw_pp, enable); } static void sde_encoder_phys_cmd_prepare_idle_pc( struct sde_encoder_phys *phys_enc) { _sde_encoder_phys_cmd_connect_te(phys_enc, false); } static int sde_encoder_phys_cmd_get_line_count( struct sde_encoder_phys *phys_enc) { Loading Loading @@ -1229,19 +1223,6 @@ static void sde_encoder_phys_cmd_prepare_commit( SDE_DEBUG_CMDENC(cmd_enc, "disabled autorefresh\n"); } static void sde_encoder_phys_cmd_handle_post_kickoff( struct sde_encoder_phys *phys_enc) { if (!phys_enc) return; /** * re-enable external TE, either for the first time after enabling * or if disabled for Autorefresh */ _sde_encoder_phys_cmd_connect_te(phys_enc, true); } static void sde_encoder_phys_cmd_trigger_start( struct sde_encoder_phys *phys_enc) { Loading Loading @@ -1286,10 +1267,9 @@ static void sde_encoder_phys_cmd_init_ops( ops->irq_control = sde_encoder_phys_cmd_irq_control; ops->update_split_role = sde_encoder_phys_cmd_update_split_role; ops->restore = sde_encoder_phys_cmd_enable_helper; ops->prepare_idle_pc = sde_encoder_phys_cmd_prepare_idle_pc; ops->control_te = sde_encoder_phys_cmd_connect_te; ops->is_autorefresh_enabled = sde_encoder_phys_cmd_is_autorefresh_enabled; ops->handle_post_kickoff = sde_encoder_phys_cmd_handle_post_kickoff; ops->get_line_count = sde_encoder_phys_cmd_get_line_count; } Loading