Browse Source

disp: msm: add support for splitlink in sde drm

Change adds support for splitlink and disables
dsc merge or 3dmerge which is not needed for splitlink.

Change-Id: I77a794d3ea6f53988f493a7af792add81abb22f0
Signed-off-by: Vara Reddy <[email protected]>
Vara Reddy 4 years ago
parent
commit
02a4648999
5 changed files with 32 additions and 10 deletions
  1. 14 0
      msm/sde/sde_encoder.c
  2. 10 3
      msm/sde/sde_encoder_dce.c
  3. 3 0
      msm/sde/sde_encoder_phys.h
  4. 3 2
      msm/sde/sde_hw_intf.c
  5. 2 5
      msm/sde/sde_hw_top.c

+ 14 - 0
msm/sde/sde_encoder.c

@@ -1007,6 +1007,8 @@ static int sde_encoder_virt_atomic_check(
 	struct sde_connector_state *sde_conn_state = NULL;
 	struct sde_crtc_state *sde_crtc_state = NULL;
 	enum sde_rm_topology_name old_top;
+	enum sde_rm_topology_name top_name;
+	struct msm_display_info *disp_info;
 	int ret = 0;
 	bool qsync_dirty = false, has_modeset = false;
 
@@ -1017,6 +1019,7 @@ static int sde_encoder_virt_atomic_check(
 	}
 
 	sde_enc = to_sde_encoder_virt(drm_enc);
+	disp_info = &sde_enc->disp_info;
 	SDE_DEBUG_ENC(sde_enc, "\n");
 
 	sde_kms = sde_encoder_get_kms(drm_enc);
@@ -1060,6 +1063,17 @@ static int sde_encoder_virt_atomic_check(
 	if (ret)
 		return ret;
 
+	top_name  = sde_connector_get_property(conn_state,
+				CONNECTOR_PROP_TOPOLOGY_NAME);
+	if ((disp_info->capabilities & MSM_DISPLAY_SPLIT_LINK) && crtc_state->active) {
+		if ((top_name != SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE) &&
+			       (top_name != SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE)) {
+			SDE_ERROR_ENC(sde_enc, "Splitlink check failed, top_name:%d",
+					 top_name);
+			return -EINVAL;
+		}
+	}
+
 	ret = sde_connector_roi_v1_check_roi(conn_state);
 	if (ret) {
 		SDE_ERROR_ENC(sde_enc, "connector roi check failed, rc: %d",

+ 10 - 3
msm/sde/sde_encoder_dce.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
  */
 
 #include <linux/kthread.h>
@@ -38,6 +38,7 @@ bool sde_encoder_is_dsc_merge(struct drm_encoder *drm_enc)
 	enum sde_rm_topology_name topology;
 	struct sde_encoder_virt *sde_enc;
 	struct drm_connector *drm_conn;
+	struct sde_encoder_phys *phys_enc;
 
 	if (!drm_enc)
 		return false;
@@ -50,6 +51,10 @@ bool sde_encoder_is_dsc_merge(struct drm_encoder *drm_enc)
 	if (!drm_conn)
 		return false;
 
+	phys_enc = sde_enc->phys_encs[0];
+	if (phys_enc->hw_intf->cfg.split_link_en)
+		return false;
+
 	topology = sde_connector_get_topology_name(drm_conn);
 	if (topology == SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE)
 		return true;
@@ -427,10 +432,12 @@ static int _dce_dsc_setup_helper(struct sde_encoder_virt *sde_enc,
 	num_dsc = def->num_comp_enc;
 	num_intf = def->num_intf;
 	mode_3d = (num_lm > num_dsc) ? BLEND_3D_H_ROW_INT : BLEND_3D_NONE;
-	merge_3d = (mode_3d != BLEND_3D_NONE) ? true : false;
+	merge_3d = ((mode_3d != BLEND_3D_NONE) && !(enc_master->hw_intf->cfg.split_link_en)) ?
+		true : false;
 
 	dsc->half_panel_pu = _dce_check_half_panel_update(num_lm, sde_enc);
-	dsc_merge = ((num_dsc > num_intf) && !dsc->half_panel_pu) ?
+	dsc_merge = ((num_dsc > num_intf) && !dsc->half_panel_pu &&
+			!(enc_master->hw_intf->cfg.split_link_en)) ?
 			true : false;
 	disable_merge_3d = (merge_3d && dsc->half_panel_pu) ?
 			false : true;

+ 3 - 0
msm/sde/sde_encoder_phys.h

@@ -620,6 +620,9 @@ static inline enum sde_3d_blend_mode sde_encoder_helper_get_3d_blend_mode(
 	if (ret)
 		return BLEND_3D_NONE;
 
+	if (phys_enc->hw_intf->cfg.split_link_en)
+		return BLEND_3D_NONE;
+
 	num_lm = def.num_lm;
 	mode_3d = (num_lm > def.num_enc) ? true : false;
 	split_role = phys_enc->split_role;

+ 3 - 2
msm/sde/sde_hw_intf.c

@@ -464,12 +464,13 @@ static void sde_hw_intf_bind_pingpong_blk(
 	c = &intf->hw;
 
 	mux_cfg = SDE_REG_READ(c, INTF_MUX);
-	mux_cfg &= ~0xf;
+	mux_cfg &= ~0xf000f;
 
 	if (enable) {
 		mux_cfg |= (pp - PINGPONG_0) & 0x7;
+		/* Splitlink case, pp0->sublink0, pp1->sublink1 */
 		if (intf->cfg.split_link_en)
-			mux_cfg = 0x60000;
+			mux_cfg = 0x10000;
 	} else {
 		mux_cfg = 0xf000f;
 	}

+ 2 - 5
msm/sde/sde_hw_top.c

@@ -140,16 +140,13 @@ static void sde_hw_setup_pp_split(struct sde_hw_mdp *mdp,
 	if (!mdp || !cfg)
 		return;
 
-	if (cfg->split_link_en) {
-		ppb_config |= BIT(16); /* split enable */
-		ppb_control = BIT(5); /* horz split*/
-	} else if (cfg->en && cfg->pp_split_slave != INTF_MAX) {
+	if (cfg->en && cfg->pp_split_slave != INTF_MAX) {
 		ppb_config |= (cfg->pp_split_slave - INTF_0 + 1) << 20;
 		ppb_config |= BIT(16); /* split enable */
 		ppb_control = BIT(5); /* horz split*/
 	}
 
-	if (cfg->pp_split_index && !cfg->split_link_en) {
+	if (cfg->pp_split_index) {
 		SDE_REG_WRITE(&mdp->hw, PPB0_CONFIG, 0x0);
 		SDE_REG_WRITE(&mdp->hw, PPB0_CNTL, 0x0);
 		SDE_REG_WRITE(&mdp->hw, PPB1_CONFIG, ppb_config);