Forráskód Böngészése

Merge "disp: msm: dsi: avoid DSI PHY shutdown during idle"

qctecmdr 2 éve
szülő
commit
c1d1e0a6ff

+ 2 - 1
msm/dsi/dsi_catalog.h

@@ -314,7 +314,8 @@ void dsi_phy_hw_v5_0_dyn_refresh_pipe_delay(struct dsi_phy_hw *phy,
 
 int dsi_phy_hw_v5_0_cache_phy_timings(struct dsi_phy_per_lane_cfgs *timings,
 				      u32 *dst, u32 size);
-void dsi_phy_hw_v5_0_phy_idle_off(struct dsi_phy_hw *phy);
+void dsi_phy_hw_v5_0_phy_idle_off(struct dsi_phy_hw *phy,
+				struct dsi_phy_cfg *cfg);
 void dsi_ctrl_hw_22_configure_cmddma_window(struct dsi_ctrl_hw *ctrl,
 		struct dsi_ctrl_cmd_dma_info *cmd,
 		u32 line_no, u32 window);

+ 1 - 4
msm/dsi/dsi_phy.c

@@ -1167,11 +1167,8 @@ int dsi_phy_idle_ctrl(struct msm_dsi_phy *phy, bool enable)
 	} else {
 		phy->dsi_phy_state = DSI_PHY_ENGINE_OFF;
 
-		if (phy->hw.ops.disable)
-			phy->hw.ops.disable(&phy->hw, &phy->cfg);
-
 		if (phy->hw.ops.phy_idle_off)
-			phy->hw.ops.phy_idle_off(&phy->hw);
+			phy->hw.ops.phy_idle_off(&phy->hw, &phy->cfg);
 	}
 	mutex_unlock(&phy->phy_lock);
 

+ 3 - 1
msm/dsi/dsi_phy_hw.h

@@ -291,8 +291,10 @@ struct dsi_phy_hw_ops {
 	/**
 	 * phy_idle_off() - Disable PHY hardware when exiting idle screen
 	 * @phy:      Pointer to DSI PHY hardware object.
+	 * @cfg:      Per lane configurations for timing, strength and lane
+	 *	      configurations.
 	 */
-	void (*phy_idle_off)(struct dsi_phy_hw *phy);
+	void (*phy_idle_off)(struct dsi_phy_hw *phy, struct dsi_phy_cfg *cfg);
 
 	/**
 	 * calculate_timing_params() - calculates timing parameters.

+ 14 - 1
msm/dsi/dsi_phy_hw_v5_0.c

@@ -880,10 +880,23 @@ void dsi_phy_hw_v5_0_set_continuous_clk(struct dsi_phy_hw *phy, bool enable)
 	wmb(); /* make sure request is set */
 }
 
-void dsi_phy_hw_v5_0_phy_idle_off(struct dsi_phy_hw *phy)
+void dsi_phy_hw_v5_0_phy_idle_off(struct dsi_phy_hw *phy,
+					struct dsi_phy_cfg *cfg)
 {
+	if (dsi_phy_hw_v5_0_is_pll_on(phy))
+		DSI_PHY_WARN(phy, "Turning OFF PHY while PLL is on\n");
+
 	/* enable clamping of PADS */
 	DSI_W32(phy, DSIPHY_CMN_CTRL_4, 0x1);
 	DSI_W32(phy, DSIPHY_CMN_CTRL_3, 0x0);
 	wmb();
+
+	dsi_phy_hw_v5_0_config_lpcdrx(phy, cfg, false);
+
+	/* Turn off REFGEN Vote */
+	DSI_W32(phy, DSIPHY_CMN_GLBL_DIGTOP_SPARE10, 0x0);
+	/* make sure request is set */
+	wmb();
+	/* Delay to ensure HW removes vote*/
+	udelay(2);
 }

+ 44 - 12
msm/dsi/dsi_pll_4nm.c

@@ -597,11 +597,11 @@ static void dsi_pll_enable_global_clk(struct dsi_pll_resource *rsc)
 	DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_CLK_CFG1, (data | BIT(5) | BIT(4)));
 }
 
-static void dsi_pll_phy_dig_reset(struct dsi_pll_resource *rsc)
+static void dsi_pll_phy_analog_reset(struct dsi_pll_resource *rsc)
 {
 	/*
-	 * Reset the PHY digital domain. This would be needed when
-	 * coming out of a CX or analog rail power collapse while
+	 * Reset the PHY analog domain. This would be needed when
+	 * coming out of a 0p9 power collapse while
 	 * ensuring that the pads maintain LP00 or LP11 state
 	 */
 	DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0));
@@ -1391,15 +1391,6 @@ static int dsi_pll_4nm_enable(struct dsi_pll_resource *rsc)
 		goto error;
 	}
 
-	/*
-	 * assert power on reset for PHY digital in case the PLL is
-	 * enabled after CX of analog domain power collapse. This needs
-	 * to be done before enabling the global clk.
-	 */
-	dsi_pll_phy_dig_reset(rsc);
-	if (rsc->slave)
-		dsi_pll_phy_dig_reset(rsc->slave);
-
 	dsi_pll_enable_global_clk(rsc);
 	if (rsc->slave)
 		dsi_pll_enable_global_clk(rsc->slave);
@@ -1436,12 +1427,53 @@ static int dsi_pll_4nm_disable(struct dsi_pll_resource *rsc)
 	return rc;
 }
 
+void dsi_pll_assert_pll_reset(struct dsi_pll_resource *rsc)
+{
+	u32 data = 0;
+
+	DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_1, data | BIT(7));
+
+	/* Ensure Assert is through */
+	wmb();
+
+	DSI_PLL_REG_W(rsc->phy_base, PHY_CMN_CTRL_1, data & ~BIT(7));
+
+	/* Ensure deassert is through */
+	wmb();
+}
+
+void dsi_pll_4nm_trigger_resets_pre_enable(struct dsi_pll_resource *rsc)
+{
+	/*
+	 * Assert power on reset on DSI PHY Analog immeditately
+	 * after 0P9 resume to make sure PHY starts in a
+	 * clean state
+	 */
+	dsi_pll_phy_analog_reset(rsc);
+	if (rsc->slave)
+		dsi_pll_phy_analog_reset(rsc->slave);
+
+	/*
+	 * Trigger PLL reset as well to clear out any jitter
+	 * introduced as result of 0p9 collapse
+	 */
+	dsi_pll_assert_pll_reset(rsc);
+	if (rsc->slave)
+		dsi_pll_assert_pll_reset(rsc->slave);
+}
+
 int dsi_pll_4nm_configure(void *pll, bool commit)
 {
 
 	int rc = 0;
 	struct dsi_pll_resource *rsc = (struct dsi_pll_resource *)pll;
 
+	/* These resets are needed for resetting Analog and PLL portions
+	 * of DSI PHY before PLL is enabled and locked
+	 */
+	if (commit)
+		dsi_pll_4nm_trigger_resets_pre_enable(rsc);
+
 	dsi_pll_config_slave(rsc);
 
 	/* PLL power needs to be enabled before accessing PLL registers */

+ 1 - 0
msm/dsi/dsi_pll_4nm.h

@@ -167,6 +167,7 @@
 #define PHY_CMN_GLBL_CTRL	0x018
 #define PHY_CMN_RBUF_CTRL	0x01C
 #define PHY_CMN_CTRL_0		0x024
+#define PHY_CMN_CTRL_1          0x028
 #define PHY_CMN_CTRL_2		0x02C
 #define PHY_CMN_CTRL_3		0x030
 #define PHY_CMN_PLL_CNTRL	0x03C