From 4ecdf5cbbd5f47b1847a0f2213662773f21cb725 Mon Sep 17 00:00:00 2001 From: Shubhashree Dhar Date: Fri, 12 Jul 2019 19:12:34 +0530 Subject: [PATCH] drm/msm/sde: check for ppsplit topology from current state During pm suspend-resume cases, topology is reset and ppsplit flag is set to false based on previous connector state. This leads to incorrect interface config resulting in pptimeout. Made changes to update the ppsplit flag based on current connector state to avoid this. Change-Id: Id42313036eda98e5109083b0d57a778f1262f3fd Signed-off-by: Shubhashree Dhar --- drivers/gpu/drm/msm/sde/sde_crtc.c | 12 +++++++++++- drivers/gpu/drm/msm/sde/sde_encoder.c | 18 ++++++++++++++++++ drivers/gpu/drm/msm/sde/sde_encoder.h | 8 ++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index a82ca1a73e986..71100d5c2b75e 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -1391,14 +1391,24 @@ static u32 _sde_crtc_get_displays_affected(struct drm_crtc *crtc, { struct sde_crtc *sde_crtc; struct sde_crtc_state *crtc_state; + struct drm_encoder *encoder; u32 disp_bitmask = 0; int i; + bool is_ppsplit = false; sde_crtc = to_sde_crtc(crtc); crtc_state = to_sde_crtc_state(state); + list_for_each_entry(encoder, + &crtc->dev->mode_config.encoder_list, head) { + if (encoder->crtc != state->crtc) + continue; + + is_ppsplit |= sde_encoder_is_topology_ppsplit(encoder); + } + /* pingpong split: one ROI, one LM, two physical displays */ - if (crtc_state->is_ppsplit) { + if (is_ppsplit) { u32 lm_split_width = crtc_state->lm_bounds[0].w / 2; struct sde_rect *roi = &crtc_state->lm_roi[0]; diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c index 8be253ddd3988..8e397029dd5fc 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder.c @@ -943,6 +943,24 @@ bool sde_encoder_in_clone_mode(struct drm_encoder *drm_enc) return false; } +bool sde_encoder_is_topology_ppsplit(struct drm_encoder *drm_enc) +{ + struct sde_encoder_virt *sde_enc; + struct sde_encoder_phys *master; + + if (!drm_enc) + return false; + + sde_enc = to_sde_encoder_virt(drm_enc); + master = sde_enc->cur_master; + + if (!master || !master->connector) + return false; + + return (sde_connector_get_topology_name(master->connector) + == SDE_RM_TOPOLOGY_PPSPLIT); +} + static int sde_encoder_virt_atomic_check( struct drm_encoder *drm_enc, struct drm_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.h b/drivers/gpu/drm/msm/sde/sde_encoder.h index 83b207236cfcf..74f26d40e08a6 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.h +++ b/drivers/gpu/drm/msm/sde/sde_encoder.h @@ -284,6 +284,14 @@ void sde_encoder_recovery_events_handler(struct drm_encoder *encoder, */ bool sde_encoder_in_clone_mode(struct drm_encoder *enc); +/** + *sde_encoder_is_topology_ppsplit - checks if the current encoder is in + ppsplit topology. + *@drm_enc: Pointer to drm encoder structure + *@Return: true if the present topology is ppsplit + */ +bool sde_encoder_is_topology_ppsplit(struct drm_encoder *drm_enc); + /** * sde_encoder_is_primary_display - checks if underlying display is primary * display or not.