Loading drivers/gpu/drm/msm/msm_drv.h +2 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,8 @@ enum msm_mdp_crtc_property { CRTC_PROP_DEST_SCALER, CRTC_PROP_CAPTURE_OUTPUT, 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 @@ -3698,6 +3698,7 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc, struct sde_crtc_state *cstate; bool is_error, reset_req, recovery_events; unsigned long flags; enum sde_crtc_idle_pc_state idle_pc_state; if (!crtc) { SDE_ERROR("invalid argument\n"); Loading Loading @@ -3728,6 +3729,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 @@ -3746,6 +3749,10 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc, recovery_events = sde_encoder_recovery_events_enabled(encoder); if (idle_pc_state != IDLE_PC_NONE) sde_encoder_control_idle_pc(encoder, (idle_pc_state == IDLE_PC_ENABLE) ? true : false); } /* Loading Loading @@ -4257,6 +4264,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 @@ -5000,6 +5014,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 @@ -5075,6 +5095,12 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, "idle_time", 0, 0, U64_MAX, 0, CRTC_PROP_IDLE_TIMEOUT); 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 +29 −9 Original line number Diff line number Diff line Loading @@ -199,7 +199,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 @@ -251,7 +252,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 @@ -2113,6 +2114,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 @@ -2139,7 +2159,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 @@ -2147,9 +2167,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 @@ -2545,7 +2565,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 @@ -4629,7 +4649,7 @@ static int _sde_encoder_init_debugfs(struct drm_encoder *drm_enc) sde_enc->debugfs_root, sde_enc, &debugfs_misr_fops); debugfs_create_bool("idle_power_collapse", 0600, sde_enc->debugfs_root, &sde_enc->idle_pc_supported); &sde_enc->idle_pc_enabled); for (i = 0; i < sde_enc->num_phys_encs; i++) if (sde_enc->phys_encs[i] && Loading Loading @@ -4812,7 +4832,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 @@ -277,4 +277,11 @@ void sde_encoder_recovery_events_handler(struct drm_encoder *encoder, */ 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 +2 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,8 @@ enum msm_mdp_crtc_property { CRTC_PROP_DEST_SCALER, CRTC_PROP_CAPTURE_OUTPUT, 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 @@ -3698,6 +3698,7 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc, struct sde_crtc_state *cstate; bool is_error, reset_req, recovery_events; unsigned long flags; enum sde_crtc_idle_pc_state idle_pc_state; if (!crtc) { SDE_ERROR("invalid argument\n"); Loading Loading @@ -3728,6 +3729,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 @@ -3746,6 +3749,10 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc, recovery_events = sde_encoder_recovery_events_enabled(encoder); if (idle_pc_state != IDLE_PC_NONE) sde_encoder_control_idle_pc(encoder, (idle_pc_state == IDLE_PC_ENABLE) ? true : false); } /* Loading Loading @@ -4257,6 +4264,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 @@ -5000,6 +5014,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 @@ -5075,6 +5095,12 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, "idle_time", 0, 0, U64_MAX, 0, CRTC_PROP_IDLE_TIMEOUT); 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 +29 −9 Original line number Diff line number Diff line Loading @@ -199,7 +199,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 @@ -251,7 +252,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 @@ -2113,6 +2114,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 @@ -2139,7 +2159,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 @@ -2147,9 +2167,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 @@ -2545,7 +2565,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 @@ -4629,7 +4649,7 @@ static int _sde_encoder_init_debugfs(struct drm_encoder *drm_enc) sde_enc->debugfs_root, sde_enc, &debugfs_misr_fops); debugfs_create_bool("idle_power_collapse", 0600, sde_enc->debugfs_root, &sde_enc->idle_pc_supported); &sde_enc->idle_pc_enabled); for (i = 0; i < sde_enc->num_phys_encs; i++) if (sde_enc->phys_encs[i] && Loading Loading @@ -4812,7 +4832,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 @@ -277,4 +277,11 @@ void sde_encoder_recovery_events_handler(struct drm_encoder *encoder, */ 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__ */