Browse Source

disp: msm: dsi: add HW programming for split link clock ctrl

There is a new clock lane that is used for the sublink when
split link is enabled. The following change adds programming
to control the sublink clock lane.

Change-Id: I1af370cd39e02130569815766fb748ae6bad72d0
Signed-off-by: Satya Rama Aditya Pinapala <[email protected]>
Satya Rama Aditya Pinapala 4 years ago
parent
commit
d575e0cb37
1 changed files with 44 additions and 6 deletions
  1. 44 6
      msm/dsi/dsi_phy_hw_v4_0.c

+ 44 - 6
msm/dsi/dsi_phy_hw_v4_0.c

@@ -62,7 +62,7 @@
 #define DSIPHY_CMN_LANE_STATUS0						0x148
 #define DSIPHY_CMN_LANE_STATUS0						0x148
 #define DSIPHY_CMN_LANE_STATUS1						0x14C
 #define DSIPHY_CMN_LANE_STATUS1						0x14C
 #define DSIPHY_CMN_GLBL_DIGTOP_SPARE10                                  0x1AC
 #define DSIPHY_CMN_GLBL_DIGTOP_SPARE10                                  0x1AC
-#define DSIPHY_CMN_CMN_SL_DSI_LANE_CTRL1                                0x1B4
+#define DSIPHY_CMN_SL_DSI_LANE_CTRL1                                0x1B4
 
 
 /* n = 0..3 for data lanes and n = 4 for clock lane */
 /* n = 0..3 for data lanes and n = 4 for clock lane */
 #define DSIPHY_LNX_CFG0(n)                         (0x200 + (0x80 * (n)))
 #define DSIPHY_LNX_CFG0(n)                         (0x200 + (0x80 * (n)))
@@ -123,6 +123,15 @@ static int dsi_phy_hw_v4_0_is_pll_on(struct dsi_phy_hw *phy)
 	return (data & BIT(0));
 	return (data & BIT(0));
 }
 }
 
 
+static bool dsi_phy_hw_v4_0_is_split_link_enabled(struct dsi_phy_hw *phy)
+{
+	u32 reg = 0;
+
+	reg = DSI_R32(phy, DSIPHY_CMN_GLBL_CTRL);
+	mb(); /*make sure read happened */
+	return (reg & BIT(5));
+}
+
 static void dsi_phy_hw_v4_0_config_lpcdrx(struct dsi_phy_hw *phy,
 static void dsi_phy_hw_v4_0_config_lpcdrx(struct dsi_phy_hw *phy,
 	struct dsi_phy_cfg *cfg, bool enable)
 	struct dsi_phy_cfg *cfg, bool enable)
 {
 {
@@ -432,7 +441,7 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy,
 			DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, 0x3F);
 			DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, 0x3F);
 		}
 		}
 
 
-		DSI_W32(phy, DSIPHY_CMN_CMN_SL_DSI_LANE_CTRL1, 0x03);
+		DSI_W32(phy, DSIPHY_CMN_SL_DSI_LANE_CTRL1, 0x03);
 	} else {
 	} else {
 		/* Remove power down from all blocks */
 		/* Remove power down from all blocks */
 		DSI_W32(phy, DSIPHY_CMN_CTRL_0, 0x7f);
 		DSI_W32(phy, DSIPHY_CMN_CTRL_0, 0x7f);
@@ -558,8 +567,11 @@ int dsi_phy_hw_v4_0_wait_for_lane_idle(
 	u32 stop_state_mask = 0;
 	u32 stop_state_mask = 0;
 	u32 const sleep_us = 10;
 	u32 const sleep_us = 10;
 	u32 const timeout_us = 100;
 	u32 const timeout_us = 100;
+	bool split_link_enabled = dsi_phy_hw_v4_0_is_split_link_enabled(phy);
 
 
 	stop_state_mask = BIT(4); /* clock lane */
 	stop_state_mask = BIT(4); /* clock lane */
+	if (split_link_enabled)
+		stop_state_mask |= BIT(5);
 	if (lanes & DSI_DATA_LANE_0)
 	if (lanes & DSI_DATA_LANE_0)
 		stop_state_mask |= BIT(0);
 		stop_state_mask |= BIT(0);
 	if (lanes & DSI_DATA_LANE_1)
 	if (lanes & DSI_DATA_LANE_1)
@@ -586,7 +598,7 @@ int dsi_phy_hw_v4_0_wait_for_lane_idle(
 void dsi_phy_hw_v4_0_ulps_request(struct dsi_phy_hw *phy,
 void dsi_phy_hw_v4_0_ulps_request(struct dsi_phy_hw *phy,
 		struct dsi_phy_cfg *cfg, u32 lanes)
 		struct dsi_phy_cfg *cfg, u32 lanes)
 {
 {
-	u32 reg = 0;
+	u32 reg = 0, sl_lane_ctrl1 = 0;
 
 
 	if (lanes & DSI_CLOCK_LANE)
 	if (lanes & DSI_CLOCK_LANE)
 		reg = BIT(4);
 		reg = BIT(4);
@@ -598,9 +610,17 @@ void dsi_phy_hw_v4_0_ulps_request(struct dsi_phy_hw *phy,
 		reg |= BIT(2);
 		reg |= BIT(2);
 	if (lanes & DSI_DATA_LANE_3)
 	if (lanes & DSI_DATA_LANE_3)
 		reg |= BIT(3);
 		reg |= BIT(3);
+	if (cfg->split_link.enabled)
+		reg |= BIT(7);
 
 
-	if (cfg->force_clk_lane_hs)
+	if (cfg->force_clk_lane_hs) {
 		reg |= BIT(5) | BIT(6);
 		reg |= BIT(5) | BIT(6);
+		if (cfg->split_link.enabled) {
+			sl_lane_ctrl1 = DSI_R32(phy, DSIPHY_CMN_SL_DSI_LANE_CTRL1);
+			sl_lane_ctrl1 |= BIT(2);
+			DSI_W32(phy, DSIPHY_CMN_SL_DSI_LANE_CTRL1, sl_lane_ctrl1);
+		}
+	}
 
 
 	/*
 	/*
 	 * ULPS entry request. Wait for short time to make sure
 	 * ULPS entry request. Wait for short time to make sure
@@ -641,7 +661,7 @@ int dsi_phy_hw_v4_0_lane_reset(struct dsi_phy_hw *phy)
 void dsi_phy_hw_v4_0_ulps_exit(struct dsi_phy_hw *phy,
 void dsi_phy_hw_v4_0_ulps_exit(struct dsi_phy_hw *phy,
 			struct dsi_phy_cfg *cfg, u32 lanes)
 			struct dsi_phy_cfg *cfg, u32 lanes)
 {
 {
-	u32 reg = 0;
+	u32 reg = 0, sl_lane_ctrl1 = 0;
 
 
 	if (lanes & DSI_CLOCK_LANE)
 	if (lanes & DSI_CLOCK_LANE)
 		reg = BIT(4);
 		reg = BIT(4);
@@ -653,6 +673,8 @@ void dsi_phy_hw_v4_0_ulps_exit(struct dsi_phy_hw *phy,
 		reg |= BIT(2);
 		reg |= BIT(2);
 	if (lanes & DSI_DATA_LANE_3)
 	if (lanes & DSI_DATA_LANE_3)
 		reg |= BIT(3);
 		reg |= BIT(3);
+	if (cfg->split_link.enabled)
+		reg |= BIT(5);
 
 
 	/* enable LPRX and CDRX */
 	/* enable LPRX and CDRX */
 	dsi_phy_hw_v4_0_config_lpcdrx(phy, cfg, true);
 	dsi_phy_hw_v4_0_config_lpcdrx(phy, cfg, true);
@@ -679,6 +701,11 @@ void dsi_phy_hw_v4_0_ulps_exit(struct dsi_phy_hw *phy,
 	if (cfg->force_clk_lane_hs) {
 	if (cfg->force_clk_lane_hs) {
 		reg = BIT(5) | BIT(6);
 		reg = BIT(5) | BIT(6);
 		DSI_W32(phy, DSIPHY_CMN_LANE_CTRL1, reg);
 		DSI_W32(phy, DSIPHY_CMN_LANE_CTRL1, reg);
+		if (cfg->split_link.enabled) {
+			sl_lane_ctrl1 = DSI_R32(phy, DSIPHY_CMN_SL_DSI_LANE_CTRL1);
+			sl_lane_ctrl1 |= BIT(2);
+			DSI_W32(phy, DSIPHY_CMN_SL_DSI_LANE_CTRL1, sl_lane_ctrl1);
+		}
 	}
 	}
 }
 }
 
 
@@ -897,7 +924,8 @@ int dsi_phy_hw_v4_0_cache_phy_timings(struct dsi_phy_per_lane_cfgs *timings,
 
 
 void dsi_phy_hw_v4_0_set_continuous_clk(struct dsi_phy_hw *phy, bool enable)
 void dsi_phy_hw_v4_0_set_continuous_clk(struct dsi_phy_hw *phy, bool enable)
 {
 {
-	u32 reg = 0;
+	u32 reg = 0, sl_lane_ctrl1 = 0;
+	bool is_split_link_enabled = dsi_phy_hw_v4_0_is_split_link_enabled(phy);
 
 
 	reg = DSI_R32(phy, DSIPHY_CMN_LANE_CTRL1);
 	reg = DSI_R32(phy, DSIPHY_CMN_LANE_CTRL1);
 
 
@@ -907,5 +935,15 @@ void dsi_phy_hw_v4_0_set_continuous_clk(struct dsi_phy_hw *phy, bool enable)
 		reg &= ~(BIT(5) | BIT(6));
 		reg &= ~(BIT(5) | BIT(6));
 
 
 	DSI_W32(phy, DSIPHY_CMN_LANE_CTRL1, reg);
 	DSI_W32(phy, DSIPHY_CMN_LANE_CTRL1, reg);
+
+	if (is_split_link_enabled) {
+		sl_lane_ctrl1 = DSI_R32(phy, DSIPHY_CMN_SL_DSI_LANE_CTRL1);
+		if (enable)
+			sl_lane_ctrl1 |= BIT(2);
+		else
+			sl_lane_ctrl1 &= ~BIT(2);
+		DSI_W32(phy, DSIPHY_CMN_SL_DSI_LANE_CTRL1, sl_lane_ctrl1);
+	}
+
 	wmb(); /* make sure request is set */
 	wmb(); /* make sure request is set */
 }
 }