From 1834bd53befc8897a675267a67b247690f7c7feb Mon Sep 17 00:00:00 2001 From: Jayaprakash Madisetty Date: Sat, 22 May 2021 17:16:25 +0530 Subject: [PATCH] disp: msm: sde: set ctl preference for built in displays Add changes to set CTL id preference for primary and secondary builtin displays. This change check for preference if already set from DT. If not preference will be set during connector init. This avoids CTL datapath switches on secondary when there is dual display usecase running concurrently with dp connect/disconnect. In current issue scenario, due to the secondary ctl datapath switch CTL_LAYER programming is happened on CTL_2 but CTL_FLUSH is happened on CTL_1 causing pp_done timeout issues. Change-Id: I5f1f52b7673740c48b249ab4d36e80b7a1d3db96 Signed-off-by: Jayaprakash Madisetty --- msm/sde/sde_connector.c | 3 +++ msm/sde/sde_hw_catalog.c | 39 +++++++++++++++++++++++++++++++++++++++ msm/sde/sde_hw_catalog.h | 8 ++++++++ msm/sde/sde_rm.c | 21 +++++++++++++++------ 4 files changed, 65 insertions(+), 6 deletions(-) diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index eeda022f1da7..a6de23aab43b 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -2994,6 +2994,9 @@ struct drm_connector *sde_connector_init(struct drm_device *dev, _sde_connector_lm_preference(c_conn, sde_kms, display_info.display_type); + sde_hw_ctl_set_preference(sde_kms->catalog, + display_info.display_type); + SDE_DEBUG("connector %d attach encoder %d\n", c_conn->base.base.id, encoder->base.id); diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 74896a8edb2c..ce5caac2a667 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -1919,6 +1919,8 @@ static int sde_ctl_parse_dt(struct device_node *np, ctl_prop[HW_DISP].prop_name, i, &disp_pref); if (disp_pref && !strcmp(disp_pref, "primary")) set_bit(SDE_CTL_PRIMARY_PREF, &ctl->features); + if (disp_pref && !strcmp(disp_pref, "secondary")) + set_bit(SDE_CTL_SECONDARY_PREF, &ctl->features); if ((i < MAX_SPLIT_DISPLAY_CTL) && !(IS_SDE_CTL_REV_100(sde_cfg->ctl_rev))) set_bit(SDE_CTL_SPLIT_DISPLAY, &ctl->features); @@ -1937,6 +1939,43 @@ static int sde_ctl_parse_dt(struct device_node *np, return 0; } +void sde_hw_ctl_set_preference(struct sde_mdss_cfg *sde_cfg, + uint32_t disp_type) +{ + u32 i; + + if (!IS_SDE_CTL_REV_100(sde_cfg->ctl_rev)) + return; + + if (disp_type == SDE_CONNECTOR_PRIMARY) { + for (i = 0; i < sde_cfg->ctl_count; i++) { + /* Exit if already set in dt file*/ + if (sde_cfg->ctl[i].features & BIT(SDE_CTL_PRIMARY_PREF)) + return; + } + for (i = 0; i < sde_cfg->ctl_count; i++) { + /* Set preference here*/ + if (!(sde_cfg->ctl[i].features & BIT(SDE_CTL_SECONDARY_PREF))) { + set_bit(SDE_CTL_PRIMARY_PREF, &sde_cfg->ctl[i].features); + return; + } + } + } else if (disp_type == SDE_CONNECTOR_SECONDARY) { + for (i = 0; i < sde_cfg->ctl_count; i++) { + /* Exit if already set in dt file*/ + if (sde_cfg->ctl[i].features & BIT(SDE_CTL_SECONDARY_PREF)) + return; + } + for (i = 0; i < sde_cfg->ctl_count; i++) { + /* Set preference here*/ + if (!(sde_cfg->ctl[i].features & BIT(SDE_CTL_PRIMARY_PREF))) { + set_bit(SDE_CTL_SECONDARY_PREF, &sde_cfg->ctl[i].features); + return; + } + } + } +} + void sde_hw_mixer_set_preference(struct sde_mdss_cfg *sde_cfg, u32 num_lm, uint32_t disp_type) { diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index 6bfaf2bf5080..dd9d93d9f01f 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -465,6 +465,7 @@ enum { SDE_CTL_SPLIT_DISPLAY = 0x1, SDE_CTL_PINGPONG_SPLIT, SDE_CTL_PRIMARY_PREF, + SDE_CTL_SECONDARY_PREF, SDE_CTL_ACTIVE_CFG, SDE_CTL_UIDLE, SDE_CTL_UNIFIED_DSPP_FLUSH, @@ -1657,6 +1658,13 @@ struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev); */ void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg); +/** + * sde_hw_ctl_set_preference - set CTL preference for display + * @sde_cfg: pointer to mdss cfg + * @disp_type: type of display primary/secondary + */ +void sde_hw_ctl_set_preference(struct sde_mdss_cfg *sde_cfg, + uint32_t disp_type); /** * sde_hw_catalog_irq_offset_list_delete - delete the irq_offset_list * maintained by the catalog diff --git a/msm/sde/sde_rm.c b/msm/sde/sde_rm.c index f5221aae3f26..5314b3c28fdd 100644 --- a/msm/sde/sde_rm.c +++ b/msm/sde/sde_rm.c @@ -1227,7 +1227,8 @@ static int _sde_rm_reserve_ctls( while (_sde_rm_get_hw_locked(rm, &iter)) { const struct sde_hw_ctl *ctl = to_sde_hw_ctl(iter.blk->hw); unsigned long features = ctl->caps->features; - bool has_split_display, has_ppsplit, primary_pref; + bool has_split_display, has_ppsplit, primary_pref, secondary_pref; + bool is_conn_primary, is_conn_secondary; if (RESERVED_BY_OTHER(iter.blk, rsvp)) continue; @@ -1235,6 +1236,11 @@ static int _sde_rm_reserve_ctls( has_split_display = BIT(SDE_CTL_SPLIT_DISPLAY) & features; has_ppsplit = BIT(SDE_CTL_PINGPONG_SPLIT) & features; primary_pref = BIT(SDE_CTL_PRIMARY_PREF) & features; + secondary_pref = BIT(SDE_CTL_SECONDARY_PREF) & features; + is_conn_primary = (reqs->hw_res.display_type == + SDE_CONNECTOR_PRIMARY) ? true : false; + is_conn_secondary = (reqs->hw_res.display_type == + SDE_CONNECTOR_SECONDARY) ? true : false; SDE_DEBUG("ctl %d caps 0x%lX\n", iter.blk->id, features); @@ -1242,18 +1248,21 @@ static int _sde_rm_reserve_ctls( * bypass rest feature checks on finding CTL preferred * for primary displays. */ - if (!primary_pref && !_ctl_ids) { + if (!primary_pref && !secondary_pref && !_ctl_ids) { if (top->needs_split_display != has_split_display) continue; if (top->top_name == SDE_RM_TOPOLOGY_PPSPLIT && !has_ppsplit) continue; - } else if (!(reqs->hw_res.display_type == - SDE_CONNECTOR_PRIMARY && primary_pref) && !_ctl_ids) { + + if (is_conn_primary || is_conn_secondary) + continue; + } else if (!((is_conn_primary && primary_pref) || + (is_conn_secondary && secondary_pref)) && !_ctl_ids) { SDE_DEBUG( - "display pref not met. display_type: %d primary_pref: %d\n", - reqs->hw_res.display_type, primary_pref); + "display pref not met. display_type: %d features: 0x%lX\n", + reqs->hw_res.display_type, features); continue; }