Loading msm/sde/sde_color_processing.c +1 −1 Original line number Diff line number Diff line Loading @@ -4132,7 +4132,7 @@ int sde_cp_ltm_off_event_handler(struct drm_crtc *crtc_drm, bool en, return 0; } void sde_cp_mode_switch_prop_dirty(struct drm_crtc *crtc_drm) void sde_cp_crtc_res_change(struct drm_crtc *crtc_drm) { struct sde_cp_node *prop_node = NULL, *n = NULL; struct sde_crtc *crtc; Loading msm/sde/sde_color_processing.h +2 −2 Original line number Diff line number Diff line Loading @@ -201,10 +201,10 @@ int sde_cp_ltm_off_event_handler(struct drm_crtc *crtc_drm, bool en, struct sde_irq_callback *hist_irq); /** * sde_cp_mode_switch_prop_dirty: API marks mode dependent features as dirty * sde_cp_crtc_res_change: API to handle LM resolution changes * @crtc_drm: Pointer to crtc. */ void sde_cp_mode_switch_prop_dirty(struct drm_crtc *crtc_drm); void sde_cp_crtc_res_change(struct drm_crtc *crtc_drm); /** * sde_cp_crtc_vm_primary_handoff: Properly handoff CRTC color mode features Loading msm/sde/sde_crtc.c +81 −47 Original line number Diff line number Diff line Loading @@ -433,7 +433,6 @@ static bool sde_crtc_mode_fixup(struct drm_crtc *crtc, { SDE_DEBUG("\n"); sde_cp_mode_switch_prop_dirty(crtc); if ((msm_is_mode_seamless(adjusted_mode) || (msm_is_mode_seamless_vrr(adjusted_mode) || msm_is_mode_seamless_dyn_clk(adjusted_mode))) && Loading Loading @@ -1113,30 +1112,30 @@ static int _sde_crtc_check_rois(struct drm_crtc *crtc, static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc; struct sde_crtc_state *crtc_state; struct sde_crtc_state *cstate; const struct sde_rect *lm_roi; struct sde_hw_mixer *hw_lm; bool right_mixer = false; bool lm_updated = false; int lm_idx; if (!crtc) return; sde_crtc = to_sde_crtc(crtc); crtc_state = to_sde_crtc_state(crtc->state); cstate = to_sde_crtc_state(crtc->state); for (lm_idx = 0; lm_idx < sde_crtc->num_mixers; lm_idx++) { struct sde_hw_mixer_cfg cfg; lm_roi = &crtc_state->lm_roi[lm_idx]; lm_roi = &cstate->lm_roi[lm_idx]; hw_lm = sde_crtc->mixers[lm_idx].hw_lm; if (!sde_crtc->mixers_swapped) right_mixer = lm_idx % MAX_MIXERS_PER_LAYOUT; SDE_EVT32(DRMID(crtc_state->base.crtc), lm_idx, lm_roi->x, lm_roi->y, lm_roi->w, lm_roi->h, right_mixer); if (lm_roi->w != hw_lm->cfg.out_width || lm_roi->h != hw_lm->cfg.out_height || right_mixer != hw_lm->cfg.right_mixer) { hw_lm->cfg.out_width = lm_roi->w; hw_lm->cfg.out_height = lm_roi->h; hw_lm->cfg.right_mixer = right_mixer; Loading @@ -1145,8 +1144,17 @@ static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc) cfg.out_height = lm_roi->h; cfg.right_mixer = right_mixer; cfg.flags = 0; hw_lm->ops.setup_mixer_out(hw_lm, &cfg); lm_updated = true; } SDE_EVT32(DRMID(crtc), lm_idx, lm_roi->x, lm_roi->y, lm_roi->w, lm_roi->h, right_mixer, lm_updated); } if (lm_updated) sde_cp_crtc_res_change(crtc); } struct plane_state { Loading Loading @@ -1533,8 +1541,6 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, } } _sde_crtc_program_lm_output_roi(crtc); end: kfree(pstates); } Loading Loading @@ -2165,8 +2171,6 @@ static void _sde_crtc_dest_scaler_setup(struct drm_crtc *crtc) hw_ctl->ops.update_bitmask_mixer( hw_ctl, hw_lm->idx, 1); } sde_cp_mode_switch_prop_dirty(crtc); } } Loading Loading @@ -3901,12 +3905,63 @@ static void sde_crtc_reset(struct drm_crtc *crtc) crtc->state = &cstate->base; } static void sde_crtc_clear_cached_mixer_cfg(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_hw_mixer *hw_lm; int lm_idx; /* clearing lm cfg marks it dirty to force reprogramming next update */ for (lm_idx = 0; lm_idx < sde_crtc->num_mixers; lm_idx++) { hw_lm = sde_crtc->mixers[lm_idx].hw_lm; hw_lm->cfg.out_width = 0; hw_lm->cfg.out_height = 0; } SDE_EVT32(DRMID(crtc)); } static void sde_crtc_reset_sw_state_for_ipc(struct drm_crtc *crtc) { struct sde_crtc_state *cstate = to_sde_crtc_state(crtc->state); struct drm_plane *plane; /* mark planes, mixers, and other blocks dirty for next update */ drm_atomic_crtc_for_each_plane(plane, crtc) sde_plane_set_revalidate(plane, true); /* mark mixers dirty for next update */ sde_crtc_clear_cached_mixer_cfg(crtc); /* mark other properties which need to be dirty for next update */ set_bit(SDE_CRTC_DIRTY_DIM_LAYERS, cstate->dirty); if (cstate->num_ds_enabled) set_bit(SDE_CRTC_DIRTY_DEST_SCALER, cstate->dirty); } static void sde_crtc_post_ipc(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; struct drm_encoder *encoder; sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(crtc->state); /* restore encoder; crtc will be programmed during commit */ drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) sde_encoder_virt_restore(encoder); /* restore UIDLE */ sde_core_perf_crtc_update_uidle(crtc, true); sde_cp_crtc_post_ipc(crtc); } static void sde_crtc_handle_power_event(u32 event_type, void *arg) { struct drm_crtc *crtc = arg; struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; struct drm_plane *plane; struct drm_encoder *encoder; u32 power_on; unsigned long flags; Loading @@ -3919,7 +3974,6 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg) return; } sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(crtc->state); mutex_lock(&sde_crtc->crtc_lock); Loading @@ -3927,15 +3981,6 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg) switch (event_type) { case SDE_POWER_EVENT_POST_ENABLE: /* restore encoder; crtc will be programmed during commit */ drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) { sde_encoder_virt_restore(encoder); } /* restore UIDLE */ sde_core_perf_crtc_update_uidle(crtc, true); spin_lock_irqsave(&sde_crtc->spin_lock, flags); list_for_each_entry(node, &sde_crtc->user_event_list, list) { ret = 0; Loading @@ -3947,10 +3992,9 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg) } spin_unlock_irqrestore(&sde_crtc->spin_lock, flags); sde_cp_crtc_post_ipc(crtc); sde_crtc_post_ipc(crtc); break; case SDE_POWER_EVENT_PRE_DISABLE: drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) { /* Loading Loading @@ -3980,21 +4024,8 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg) sde_cp_crtc_pre_ipc(crtc); break; case SDE_POWER_EVENT_POST_DISABLE: /* * 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); sde_crtc_reset_sw_state_for_ipc(crtc); sde_cp_crtc_suspend(crtc); /* reconfigure everything on next frame update */ set_bit(SDE_CRTC_DIRTY_DIM_LAYERS, cstate->dirty); if (cstate->num_ds_enabled) set_bit(SDE_CRTC_DIRTY_DEST_SCALER, cstate->dirty); event.type = DRM_EVENT_SDE_POWER; event.length = sizeof(power_on); power_on = 0; Loading @@ -4014,6 +4045,9 @@ static void _sde_crtc_reset(struct drm_crtc *crtc) struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_crtc_state *cstate = to_sde_crtc_state(crtc->state); /* mark mixer cfgs dirty before wiping them */ sde_crtc_clear_cached_mixer_cfg(crtc); memset(sde_crtc->mixers, 0, sizeof(sde_crtc->mixers)); sde_crtc->num_mixers = 0; sde_crtc->mixers_swapped = false; Loading Loading
msm/sde/sde_color_processing.c +1 −1 Original line number Diff line number Diff line Loading @@ -4132,7 +4132,7 @@ int sde_cp_ltm_off_event_handler(struct drm_crtc *crtc_drm, bool en, return 0; } void sde_cp_mode_switch_prop_dirty(struct drm_crtc *crtc_drm) void sde_cp_crtc_res_change(struct drm_crtc *crtc_drm) { struct sde_cp_node *prop_node = NULL, *n = NULL; struct sde_crtc *crtc; Loading
msm/sde/sde_color_processing.h +2 −2 Original line number Diff line number Diff line Loading @@ -201,10 +201,10 @@ int sde_cp_ltm_off_event_handler(struct drm_crtc *crtc_drm, bool en, struct sde_irq_callback *hist_irq); /** * sde_cp_mode_switch_prop_dirty: API marks mode dependent features as dirty * sde_cp_crtc_res_change: API to handle LM resolution changes * @crtc_drm: Pointer to crtc. */ void sde_cp_mode_switch_prop_dirty(struct drm_crtc *crtc_drm); void sde_cp_crtc_res_change(struct drm_crtc *crtc_drm); /** * sde_cp_crtc_vm_primary_handoff: Properly handoff CRTC color mode features Loading
msm/sde/sde_crtc.c +81 −47 Original line number Diff line number Diff line Loading @@ -433,7 +433,6 @@ static bool sde_crtc_mode_fixup(struct drm_crtc *crtc, { SDE_DEBUG("\n"); sde_cp_mode_switch_prop_dirty(crtc); if ((msm_is_mode_seamless(adjusted_mode) || (msm_is_mode_seamless_vrr(adjusted_mode) || msm_is_mode_seamless_dyn_clk(adjusted_mode))) && Loading Loading @@ -1113,30 +1112,30 @@ static int _sde_crtc_check_rois(struct drm_crtc *crtc, static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc; struct sde_crtc_state *crtc_state; struct sde_crtc_state *cstate; const struct sde_rect *lm_roi; struct sde_hw_mixer *hw_lm; bool right_mixer = false; bool lm_updated = false; int lm_idx; if (!crtc) return; sde_crtc = to_sde_crtc(crtc); crtc_state = to_sde_crtc_state(crtc->state); cstate = to_sde_crtc_state(crtc->state); for (lm_idx = 0; lm_idx < sde_crtc->num_mixers; lm_idx++) { struct sde_hw_mixer_cfg cfg; lm_roi = &crtc_state->lm_roi[lm_idx]; lm_roi = &cstate->lm_roi[lm_idx]; hw_lm = sde_crtc->mixers[lm_idx].hw_lm; if (!sde_crtc->mixers_swapped) right_mixer = lm_idx % MAX_MIXERS_PER_LAYOUT; SDE_EVT32(DRMID(crtc_state->base.crtc), lm_idx, lm_roi->x, lm_roi->y, lm_roi->w, lm_roi->h, right_mixer); if (lm_roi->w != hw_lm->cfg.out_width || lm_roi->h != hw_lm->cfg.out_height || right_mixer != hw_lm->cfg.right_mixer) { hw_lm->cfg.out_width = lm_roi->w; hw_lm->cfg.out_height = lm_roi->h; hw_lm->cfg.right_mixer = right_mixer; Loading @@ -1145,8 +1144,17 @@ static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc) cfg.out_height = lm_roi->h; cfg.right_mixer = right_mixer; cfg.flags = 0; hw_lm->ops.setup_mixer_out(hw_lm, &cfg); lm_updated = true; } SDE_EVT32(DRMID(crtc), lm_idx, lm_roi->x, lm_roi->y, lm_roi->w, lm_roi->h, right_mixer, lm_updated); } if (lm_updated) sde_cp_crtc_res_change(crtc); } struct plane_state { Loading Loading @@ -1533,8 +1541,6 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, } } _sde_crtc_program_lm_output_roi(crtc); end: kfree(pstates); } Loading Loading @@ -2165,8 +2171,6 @@ static void _sde_crtc_dest_scaler_setup(struct drm_crtc *crtc) hw_ctl->ops.update_bitmask_mixer( hw_ctl, hw_lm->idx, 1); } sde_cp_mode_switch_prop_dirty(crtc); } } Loading Loading @@ -3901,12 +3905,63 @@ static void sde_crtc_reset(struct drm_crtc *crtc) crtc->state = &cstate->base; } static void sde_crtc_clear_cached_mixer_cfg(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_hw_mixer *hw_lm; int lm_idx; /* clearing lm cfg marks it dirty to force reprogramming next update */ for (lm_idx = 0; lm_idx < sde_crtc->num_mixers; lm_idx++) { hw_lm = sde_crtc->mixers[lm_idx].hw_lm; hw_lm->cfg.out_width = 0; hw_lm->cfg.out_height = 0; } SDE_EVT32(DRMID(crtc)); } static void sde_crtc_reset_sw_state_for_ipc(struct drm_crtc *crtc) { struct sde_crtc_state *cstate = to_sde_crtc_state(crtc->state); struct drm_plane *plane; /* mark planes, mixers, and other blocks dirty for next update */ drm_atomic_crtc_for_each_plane(plane, crtc) sde_plane_set_revalidate(plane, true); /* mark mixers dirty for next update */ sde_crtc_clear_cached_mixer_cfg(crtc); /* mark other properties which need to be dirty for next update */ set_bit(SDE_CRTC_DIRTY_DIM_LAYERS, cstate->dirty); if (cstate->num_ds_enabled) set_bit(SDE_CRTC_DIRTY_DEST_SCALER, cstate->dirty); } static void sde_crtc_post_ipc(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; struct drm_encoder *encoder; sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(crtc->state); /* restore encoder; crtc will be programmed during commit */ drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) sde_encoder_virt_restore(encoder); /* restore UIDLE */ sde_core_perf_crtc_update_uidle(crtc, true); sde_cp_crtc_post_ipc(crtc); } static void sde_crtc_handle_power_event(u32 event_type, void *arg) { struct drm_crtc *crtc = arg; struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; struct drm_plane *plane; struct drm_encoder *encoder; u32 power_on; unsigned long flags; Loading @@ -3919,7 +3974,6 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg) return; } sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(crtc->state); mutex_lock(&sde_crtc->crtc_lock); Loading @@ -3927,15 +3981,6 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg) switch (event_type) { case SDE_POWER_EVENT_POST_ENABLE: /* restore encoder; crtc will be programmed during commit */ drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) { sde_encoder_virt_restore(encoder); } /* restore UIDLE */ sde_core_perf_crtc_update_uidle(crtc, true); spin_lock_irqsave(&sde_crtc->spin_lock, flags); list_for_each_entry(node, &sde_crtc->user_event_list, list) { ret = 0; Loading @@ -3947,10 +3992,9 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg) } spin_unlock_irqrestore(&sde_crtc->spin_lock, flags); sde_cp_crtc_post_ipc(crtc); sde_crtc_post_ipc(crtc); break; case SDE_POWER_EVENT_PRE_DISABLE: drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) { /* Loading Loading @@ -3980,21 +4024,8 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg) sde_cp_crtc_pre_ipc(crtc); break; case SDE_POWER_EVENT_POST_DISABLE: /* * 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); sde_crtc_reset_sw_state_for_ipc(crtc); sde_cp_crtc_suspend(crtc); /* reconfigure everything on next frame update */ set_bit(SDE_CRTC_DIRTY_DIM_LAYERS, cstate->dirty); if (cstate->num_ds_enabled) set_bit(SDE_CRTC_DIRTY_DEST_SCALER, cstate->dirty); event.type = DRM_EVENT_SDE_POWER; event.length = sizeof(power_on); power_on = 0; Loading @@ -4014,6 +4045,9 @@ static void _sde_crtc_reset(struct drm_crtc *crtc) struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_crtc_state *cstate = to_sde_crtc_state(crtc->state); /* mark mixer cfgs dirty before wiping them */ sde_crtc_clear_cached_mixer_cfg(crtc); memset(sde_crtc->mixers, 0, sizeof(sde_crtc->mixers)); sde_crtc->num_mixers = 0; sde_crtc->mixers_swapped = false; Loading