Loading drivers/gpu/drm/msm/msm_drv.h +1 −0 Original line number Diff line number Diff line Loading @@ -158,6 +158,7 @@ enum msm_mdp_crtc_property { CRTC_PROP_CAPTURE_OUTPUT, CRTC_PROP_ENABLE_SUI_ENHANCEMENT, CRTC_PROP_IDLE_PC_STATE, /* total # of properties */ CRTC_PROP_COUNT Loading drivers/gpu/drm/msm/sde/sde_crtc.c +26 −0 Original line number Diff line number Diff line Loading @@ -3689,6 +3689,7 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc, struct sde_kms *sde_kms; struct sde_crtc_state *cstate; bool is_error, reset_req; enum sde_crtc_idle_pc_state idle_pc_state; if (!crtc) { SDE_ERROR("invalid argument\n"); Loading Loading @@ -3719,6 +3720,8 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc, is_error = _sde_crtc_prepare_for_kickoff_rot(dev, crtc); idle_pc_state = sde_crtc_get_property(cstate, CRTC_PROP_IDLE_PC_STATE); list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { struct sde_encoder_kickoff_params params = { 0 }; Loading @@ -3734,6 +3737,10 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc, crtc->state); if (sde_encoder_prepare_for_kickoff(encoder, ¶ms)) reset_req = true; if (idle_pc_state != IDLE_PC_NONE) sde_encoder_control_idle_pc(encoder, (idle_pc_state == IDLE_PC_ENABLE) ? true : false); } /* Loading Loading @@ -4233,6 +4240,13 @@ static void sde_crtc_disable(struct drm_crtc *crtc) sde_encoder_register_frame_event_callback(encoder, NULL, NULL); cstate->rsc_client = NULL; cstate->rsc_update = false; /* * reset idle power-collapse to original state during suspend; * user-mode will change the state on resume, if required */ if (sde_kms->catalog->has_idle_pc) sde_encoder_control_idle_pc(encoder, true); } if (sde_crtc->power_event) Loading Loading @@ -4976,6 +4990,12 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, {CAPTURE_DSPP_OUT, "capture_pp_out"}, }; static const struct drm_prop_enum_list e_idle_pc_state[] = { {IDLE_PC_NONE, "idle_pc_none"}, {IDLE_PC_ENABLE, "idle_pc_enable"}, {IDLE_PC_DISABLE, "idle_pc_disable"}, }; SDE_DEBUG("\n"); if (!crtc || !catalog) { Loading Loading @@ -5055,6 +5075,12 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, "enable_sui_enhancement", 0, 0, U64_MAX, 0, CRTC_PROP_ENABLE_SUI_ENHANCEMENT); if (catalog->has_idle_pc) msm_property_install_enum(&sde_crtc->property_info, "idle_pc_state", 0x0, 0, e_idle_pc_state, ARRAY_SIZE(e_idle_pc_state), CRTC_PROP_IDLE_PC_STATE); if (catalog->has_cwb_support) msm_property_install_enum(&sde_crtc->property_info, "capture_mode", 0, 0, e_cwb_data_points, Loading drivers/gpu/drm/msm/sde/sde_crtc.h +12 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,18 @@ enum sde_crtc_output_capture_point { CAPTURE_DSPP_OUT }; /** * enum sde_crtc_idle_pc_state: states of idle power collapse * @IDLE_PC_NONE: no-op * @IDLE_PC_ENABLE: enable idle power-collapse * @IDLE_PC_DISABLE: disable idle power-collapse */ enum sde_crtc_idle_pc_state { IDLE_PC_NONE, IDLE_PC_ENABLE, IDLE_PC_DISABLE, }; /** * @connectors : Currently associated drm connectors for retire event * @num_connectors: Number of associated drm connectors for retire event Loading drivers/gpu/drm/msm/sde/sde_encoder.c +28 −8 Original line number Diff line number Diff line Loading @@ -200,7 +200,8 @@ enum sde_enc_rc_states { * @disp_info: local copy of msm_display_info struct * @misr_enable: misr enable/disable status * @misr_frame_count: misr frame count before start capturing the data * @idle_pc_supported: indicate if idle power collaps is supported * @idle_pc_enabled: indicate if idle power collapse is enabled * currently. This can be controlled by user-mode * @rc_lock: resource control mutex lock to protect * virt encoder over various state changes * @rc_state: resource controller state Loading Loading @@ -250,7 +251,7 @@ struct sde_encoder_virt { bool misr_enable; u32 misr_frame_count; bool idle_pc_supported; bool idle_pc_enabled; struct mutex rc_lock; enum sde_enc_rc_states rc_state; struct kthread_delayed_work delayed_off_work; Loading Loading @@ -1922,6 +1923,25 @@ static void sde_encoder_input_event_handler(struct input_handle *handle, &sde_enc->input_event_work); } void sde_encoder_control_idle_pc(struct drm_encoder *drm_enc, bool enable) { struct sde_encoder_virt *sde_enc; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); return; } sde_enc = to_sde_encoder_virt(drm_enc); /* return early if there is no state change */ if (sde_enc->idle_pc_enabled == enable) return; sde_enc->idle_pc_enabled = enable; SDE_DEBUG("idle-pc state:%d\n", sde_enc->idle_pc_enabled); SDE_EVT32(sde_enc->idle_pc_enabled); } static int sde_encoder_resource_control(struct drm_encoder *drm_enc, u32 sw_event) Loading @@ -1948,7 +1968,7 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc, * when idle_pc is not supported, process only KICKOFF, STOP and MODESET * events and return early for other events (ie wb display). */ if (!sde_enc->idle_pc_supported && if (!sde_enc->idle_pc_enabled && (sw_event != SDE_ENC_RC_EVENT_KICKOFF && sw_event != SDE_ENC_RC_EVENT_PRE_MODESET && sw_event != SDE_ENC_RC_EVENT_POST_MODESET && Loading @@ -1956,9 +1976,9 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc, sw_event != SDE_ENC_RC_EVENT_PRE_STOP)) return 0; SDE_DEBUG_ENC(sde_enc, "sw_event:%d, idle_pc_supported:%d\n", sw_event, sde_enc->idle_pc_supported); SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_supported, SDE_DEBUG_ENC(sde_enc, "sw_event:%d, idle_pc:%d\n", sw_event, sde_enc->idle_pc_enabled); SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_enabled, sde_enc->rc_state, SDE_EVTLOG_FUNC_ENTRY); switch (sw_event) { Loading Loading @@ -2348,7 +2368,7 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc, break; } SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_supported, SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_enabled, sde_enc->rc_state, SDE_EVTLOG_FUNC_EXIT); return 0; } Loading Loading @@ -4483,7 +4503,7 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, if ((disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) || (disp_info->capabilities & MSM_DISPLAY_CAP_VID_MODE)) sde_enc->idle_pc_supported = sde_kms->catalog->has_idle_pc; sde_enc->idle_pc_enabled = sde_kms->catalog->has_idle_pc; mutex_lock(&sde_enc->enc_lock); for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) { Loading drivers/gpu/drm/msm/sde/sde_encoder.h +7 −0 Original line number Diff line number Diff line Loading @@ -257,4 +257,11 @@ int sde_encoder_display_failure_notification(struct drm_encoder *enc); */ int sde_encoder_in_clone_mode(struct drm_encoder *enc); /** * sde_encoder_control_idle_pc - control enable/disable of idle power collapse * @drm_enc: Pointer to drm encoder structure * @enable: enable/disable flag */ void sde_encoder_control_idle_pc(struct drm_encoder *enc, bool enable); #endif /* __SDE_ENCODER_H__ */ Loading
drivers/gpu/drm/msm/msm_drv.h +1 −0 Original line number Diff line number Diff line Loading @@ -158,6 +158,7 @@ enum msm_mdp_crtc_property { CRTC_PROP_CAPTURE_OUTPUT, CRTC_PROP_ENABLE_SUI_ENHANCEMENT, CRTC_PROP_IDLE_PC_STATE, /* total # of properties */ CRTC_PROP_COUNT Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +26 −0 Original line number Diff line number Diff line Loading @@ -3689,6 +3689,7 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc, struct sde_kms *sde_kms; struct sde_crtc_state *cstate; bool is_error, reset_req; enum sde_crtc_idle_pc_state idle_pc_state; if (!crtc) { SDE_ERROR("invalid argument\n"); Loading Loading @@ -3719,6 +3720,8 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc, is_error = _sde_crtc_prepare_for_kickoff_rot(dev, crtc); idle_pc_state = sde_crtc_get_property(cstate, CRTC_PROP_IDLE_PC_STATE); list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { struct sde_encoder_kickoff_params params = { 0 }; Loading @@ -3734,6 +3737,10 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc, crtc->state); if (sde_encoder_prepare_for_kickoff(encoder, ¶ms)) reset_req = true; if (idle_pc_state != IDLE_PC_NONE) sde_encoder_control_idle_pc(encoder, (idle_pc_state == IDLE_PC_ENABLE) ? true : false); } /* Loading Loading @@ -4233,6 +4240,13 @@ static void sde_crtc_disable(struct drm_crtc *crtc) sde_encoder_register_frame_event_callback(encoder, NULL, NULL); cstate->rsc_client = NULL; cstate->rsc_update = false; /* * reset idle power-collapse to original state during suspend; * user-mode will change the state on resume, if required */ if (sde_kms->catalog->has_idle_pc) sde_encoder_control_idle_pc(encoder, true); } if (sde_crtc->power_event) Loading Loading @@ -4976,6 +4990,12 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, {CAPTURE_DSPP_OUT, "capture_pp_out"}, }; static const struct drm_prop_enum_list e_idle_pc_state[] = { {IDLE_PC_NONE, "idle_pc_none"}, {IDLE_PC_ENABLE, "idle_pc_enable"}, {IDLE_PC_DISABLE, "idle_pc_disable"}, }; SDE_DEBUG("\n"); if (!crtc || !catalog) { Loading Loading @@ -5055,6 +5075,12 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, "enable_sui_enhancement", 0, 0, U64_MAX, 0, CRTC_PROP_ENABLE_SUI_ENHANCEMENT); if (catalog->has_idle_pc) msm_property_install_enum(&sde_crtc->property_info, "idle_pc_state", 0x0, 0, e_idle_pc_state, ARRAY_SIZE(e_idle_pc_state), CRTC_PROP_IDLE_PC_STATE); if (catalog->has_cwb_support) msm_property_install_enum(&sde_crtc->property_info, "capture_mode", 0, 0, e_cwb_data_points, Loading
drivers/gpu/drm/msm/sde/sde_crtc.h +12 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,18 @@ enum sde_crtc_output_capture_point { CAPTURE_DSPP_OUT }; /** * enum sde_crtc_idle_pc_state: states of idle power collapse * @IDLE_PC_NONE: no-op * @IDLE_PC_ENABLE: enable idle power-collapse * @IDLE_PC_DISABLE: disable idle power-collapse */ enum sde_crtc_idle_pc_state { IDLE_PC_NONE, IDLE_PC_ENABLE, IDLE_PC_DISABLE, }; /** * @connectors : Currently associated drm connectors for retire event * @num_connectors: Number of associated drm connectors for retire event Loading
drivers/gpu/drm/msm/sde/sde_encoder.c +28 −8 Original line number Diff line number Diff line Loading @@ -200,7 +200,8 @@ enum sde_enc_rc_states { * @disp_info: local copy of msm_display_info struct * @misr_enable: misr enable/disable status * @misr_frame_count: misr frame count before start capturing the data * @idle_pc_supported: indicate if idle power collaps is supported * @idle_pc_enabled: indicate if idle power collapse is enabled * currently. This can be controlled by user-mode * @rc_lock: resource control mutex lock to protect * virt encoder over various state changes * @rc_state: resource controller state Loading Loading @@ -250,7 +251,7 @@ struct sde_encoder_virt { bool misr_enable; u32 misr_frame_count; bool idle_pc_supported; bool idle_pc_enabled; struct mutex rc_lock; enum sde_enc_rc_states rc_state; struct kthread_delayed_work delayed_off_work; Loading Loading @@ -1922,6 +1923,25 @@ static void sde_encoder_input_event_handler(struct input_handle *handle, &sde_enc->input_event_work); } void sde_encoder_control_idle_pc(struct drm_encoder *drm_enc, bool enable) { struct sde_encoder_virt *sde_enc; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); return; } sde_enc = to_sde_encoder_virt(drm_enc); /* return early if there is no state change */ if (sde_enc->idle_pc_enabled == enable) return; sde_enc->idle_pc_enabled = enable; SDE_DEBUG("idle-pc state:%d\n", sde_enc->idle_pc_enabled); SDE_EVT32(sde_enc->idle_pc_enabled); } static int sde_encoder_resource_control(struct drm_encoder *drm_enc, u32 sw_event) Loading @@ -1948,7 +1968,7 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc, * when idle_pc is not supported, process only KICKOFF, STOP and MODESET * events and return early for other events (ie wb display). */ if (!sde_enc->idle_pc_supported && if (!sde_enc->idle_pc_enabled && (sw_event != SDE_ENC_RC_EVENT_KICKOFF && sw_event != SDE_ENC_RC_EVENT_PRE_MODESET && sw_event != SDE_ENC_RC_EVENT_POST_MODESET && Loading @@ -1956,9 +1976,9 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc, sw_event != SDE_ENC_RC_EVENT_PRE_STOP)) return 0; SDE_DEBUG_ENC(sde_enc, "sw_event:%d, idle_pc_supported:%d\n", sw_event, sde_enc->idle_pc_supported); SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_supported, SDE_DEBUG_ENC(sde_enc, "sw_event:%d, idle_pc:%d\n", sw_event, sde_enc->idle_pc_enabled); SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_enabled, sde_enc->rc_state, SDE_EVTLOG_FUNC_ENTRY); switch (sw_event) { Loading Loading @@ -2348,7 +2368,7 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc, break; } SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_supported, SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_enabled, sde_enc->rc_state, SDE_EVTLOG_FUNC_EXIT); return 0; } Loading Loading @@ -4483,7 +4503,7 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, if ((disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) || (disp_info->capabilities & MSM_DISPLAY_CAP_VID_MODE)) sde_enc->idle_pc_supported = sde_kms->catalog->has_idle_pc; sde_enc->idle_pc_enabled = sde_kms->catalog->has_idle_pc; mutex_lock(&sde_enc->enc_lock); for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) { Loading
drivers/gpu/drm/msm/sde/sde_encoder.h +7 −0 Original line number Diff line number Diff line Loading @@ -257,4 +257,11 @@ int sde_encoder_display_failure_notification(struct drm_encoder *enc); */ int sde_encoder_in_clone_mode(struct drm_encoder *enc); /** * sde_encoder_control_idle_pc - control enable/disable of idle power collapse * @drm_enc: Pointer to drm encoder structure * @enable: enable/disable flag */ void sde_encoder_control_idle_pc(struct drm_encoder *enc, bool enable); #endif /* __SDE_ENCODER_H__ */