disp: msm: sde: add kickoff_in_progress flag in sde crtc
In dual display usecases, during pm suspend/resume, commit is scheduled only on primary crtc thread. If idle timeout value is very short such as in LP2 mode, it might result in race condition due to idle pc off work getting scheduled on its crtc thread. This change adds kickoff in progress flag to handle such cases as crtc frame pending count is only updated after rc kickoff. Change-Id: Iebb331d914b23cc5eeadfeb2a488891e88b3202a Signed-off-by: Yashwanth <yvulapu@codeaurora.org>
This commit is contained in:

committed by
Nilaan Gunabalachandran

parent
4f8792dfc6
commit
75f3403326
@@ -3998,6 +3998,7 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
|
|||||||
|
|
||||||
idle_pc_state = sde_crtc_get_property(cstate, CRTC_PROP_IDLE_PC_STATE);
|
idle_pc_state = sde_crtc_get_property(cstate, CRTC_PROP_IDLE_PC_STATE);
|
||||||
|
|
||||||
|
sde_crtc->kickoff_in_progress = true;
|
||||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||||
if (encoder->crtc != crtc)
|
if (encoder->crtc != crtc)
|
||||||
continue;
|
continue;
|
||||||
@@ -4059,6 +4060,7 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
|
|||||||
|
|
||||||
sde_encoder_kickoff(encoder, false, true);
|
sde_encoder_kickoff(encoder, false, true);
|
||||||
}
|
}
|
||||||
|
sde_crtc->kickoff_in_progress = false;
|
||||||
|
|
||||||
/* store the event after frame trigger */
|
/* store the event after frame trigger */
|
||||||
if (sde_crtc->event) {
|
if (sde_crtc->event) {
|
||||||
@@ -7092,6 +7094,7 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_plane *plane)
|
|||||||
atomic_set(&sde_crtc->frame_pending, 0);
|
atomic_set(&sde_crtc->frame_pending, 0);
|
||||||
|
|
||||||
sde_crtc->enabled = false;
|
sde_crtc->enabled = false;
|
||||||
|
sde_crtc->kickoff_in_progress = false;
|
||||||
|
|
||||||
/* Below parameters are for fps calculation for sysfs node */
|
/* Below parameters are for fps calculation for sysfs node */
|
||||||
sde_crtc->fps_info.fps_periodic_duration = DEFAULT_FPS_PERIOD_1_SEC;
|
sde_crtc->fps_info.fps_periodic_duration = DEFAULT_FPS_PERIOD_1_SEC;
|
||||||
|
@@ -286,6 +286,7 @@ struct sde_frame_data {
|
|||||||
* @ad_active : list containing ad properties that are active
|
* @ad_active : list containing ad properties that are active
|
||||||
* @crtc_lock : crtc lock around create, destroy and access.
|
* @crtc_lock : crtc lock around create, destroy and access.
|
||||||
* @frame_pending : Whether or not an update is pending
|
* @frame_pending : Whether or not an update is pending
|
||||||
|
* @kickoff_in_progress : boolean entry to check if kickoff is in progress
|
||||||
* @frame_events : static allocation of in-flight frame events
|
* @frame_events : static allocation of in-flight frame events
|
||||||
* @frame_event_list : available frame event list
|
* @frame_event_list : available frame event list
|
||||||
* @spin_lock : spin lock for transaction status, etc...
|
* @spin_lock : spin lock for transaction status, etc...
|
||||||
@@ -379,6 +380,7 @@ struct sde_crtc {
|
|||||||
struct list_head frame_event_list;
|
struct list_head frame_event_list;
|
||||||
spinlock_t spin_lock;
|
spinlock_t spin_lock;
|
||||||
spinlock_t fevent_spin_lock;
|
spinlock_t fevent_spin_lock;
|
||||||
|
bool kickoff_in_progress;
|
||||||
|
|
||||||
/* for handling internal event thread */
|
/* for handling internal event thread */
|
||||||
struct sde_crtc_event event_cache[SDE_CRTC_MAX_EVENT_COUNT];
|
struct sde_crtc_event event_cache[SDE_CRTC_MAX_EVENT_COUNT];
|
||||||
|
@@ -2091,7 +2091,8 @@ static int _sde_encoder_rc_idle(struct drm_encoder *drm_enc,
|
|||||||
sw_event, sde_enc->rc_state);
|
sw_event, sde_enc->rc_state);
|
||||||
SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state, SDE_EVTLOG_ERROR);
|
SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state, SDE_EVTLOG_ERROR);
|
||||||
goto end;
|
goto end;
|
||||||
} else if (sde_crtc_frame_pending(sde_enc->crtc)) {
|
} else if (sde_crtc_frame_pending(sde_enc->crtc) ||
|
||||||
|
sde_crtc->kickoff_in_progress) {
|
||||||
SDE_DEBUG_ENC(sde_enc, "skip idle entry");
|
SDE_DEBUG_ENC(sde_enc, "skip idle entry");
|
||||||
SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
|
SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
|
||||||
sde_crtc_frame_pending(sde_enc->crtc), SDE_EVTLOG_ERROR);
|
sde_crtc_frame_pending(sde_enc->crtc), SDE_EVTLOG_ERROR);
|
||||||
|
Reference in New Issue
Block a user