浏览代码

Merge "disp: msm: dsi: add dsiclk_sel support for DPHY and CPHY as per HPG"

qctecmdr 2 年之前
父节点
当前提交
bb09525fc6
共有 2 个文件被更改,包括 97 次插入49 次删除
  1. 85 37
      msm/dsi/dsi_pll_4nm.c
  2. 12 12
      msm/dsi/dsi_pll_5nm.c

+ 85 - 37
msm/dsi/dsi_pll_4nm.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/kernel.h>
@@ -123,23 +123,23 @@ static inline int dsi_pll_get_phy_post_div(struct dsi_pll_resource *pll)
 }
 
 
-static inline void dsi_pll_set_dsi_clk(struct dsi_pll_resource *pll, u32 dsi_clk)
+static inline void dsi_pll_set_dsiclk_sel(struct dsi_pll_resource *pll, u32 dsiclk_sel)
 {
 	u32 reg_val = 0;
 
 	reg_val = DSI_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG1);
 	reg_val &= ~0x3;
-	reg_val |= dsi_clk;
+	reg_val |= dsiclk_sel;
 	DSI_PLL_REG_W(pll->phy_base, PHY_CMN_CLK_CFG1, reg_val);
 	if (pll->slave) {
 		reg_val = DSI_PLL_REG_R(pll->slave->phy_base, PHY_CMN_CLK_CFG1);
 		reg_val &= ~0x3;
-		reg_val |= dsi_clk;
+		reg_val |= dsiclk_sel;
 		DSI_PLL_REG_W(pll->slave->phy_base, PHY_CMN_CLK_CFG1, reg_val);
 	}
 }
 
-static inline int dsi_pll_get_dsi_clk(struct dsi_pll_resource *pll)
+static inline int dsi_pll_get_dsiclk_sel(struct dsi_pll_resource *pll)
 {
 	u32 reg_val;
 
@@ -738,7 +738,7 @@ static unsigned long dsi_pll_pclk_recalc_rate(struct clk_hw *hw, unsigned long p
 	struct dsi_pll_resource *pll = NULL;
 	u64 vco_rate = 0;
 	u64 pclk_rate = 0;
-	u32 phy_post_div, pclk_div;
+	u32 phy_post_div, pclk_div, dsiclk_sel;
 
 	if (!pix_pll->priv) {
 		DSI_PLL_INFO(pll, "pll priv is null\n");
@@ -760,19 +760,22 @@ static unsigned long dsi_pll_pclk_recalc_rate(struct clk_hw *hw, unsigned long p
 
 	vco_rate = dsi_pll_vco_recalc_rate(pll);
 
-	if (pll->type == DSI_PHY_TYPE_DPHY) {
-		phy_post_div = dsi_pll_get_phy_post_div(pll);
+	phy_post_div = dsi_pll_get_phy_post_div(pll);
+	dsiclk_sel = dsi_pll_get_dsiclk_sel(pll);
+
+	if (dsiclk_sel == 0) {
+		pclk_rate = div_u64(vco_rate, phy_post_div);
+	} else if (dsiclk_sel == 1) {
 		pclk_rate = div_u64(vco_rate, phy_post_div);
 		pclk_rate = div_u64(pclk_rate, 2);
-		pclk_div = dsi_pll_get_pclk_div(pll);
-		pclk_rate = div_u64(pclk_rate, pclk_div);
-	} else {
+	} else if (dsiclk_sel == 3 && pll->type == DSI_PHY_TYPE_CPHY) {
 		pclk_rate = vco_rate * 2;
 		pclk_rate = div_u64(pclk_rate, 7);
-		pclk_div = dsi_pll_get_pclk_div(pll);
-		pclk_rate = div_u64(pclk_rate, pclk_div);
 	}
 
+	pclk_div = dsi_pll_get_pclk_div(pll);
+	pclk_rate = div_u64(pclk_rate, pclk_div);
+
 	return pclk_rate;
 }
 
@@ -985,7 +988,7 @@ static int dsi_pll_4nm_set_byteclk_div(struct dsi_pll_resource *pll, bool commit
 static int dsi_pll_calc_dphy_pclk_div(struct dsi_pll_resource *pll)
 {
 	u32 m_val, n_val; /* M and N values of MND trio */
-	u32 pclk_div;
+	u32 dsiclk_sel, pclk_div;
 
 	if (pll->bpp == 30 && pll->lanes == 4) {
 		/* RGB101010 */
@@ -1008,14 +1011,15 @@ static int dsi_pll_calc_dphy_pclk_div(struct dsi_pll_resource *pll)
 		n_val = 1;
 	}
 
-	/* Calculating pclk_div assuming dsiclk_sel to be 1 */
+	dsiclk_sel = dsi_pll_get_dsiclk_sel(pll);
 	pclk_div = pll->bpp;
 	pclk_div = mult_frac(pclk_div, m_val, n_val);
-	do_div(pclk_div, 2);
+	if (dsiclk_sel == 1)
+		do_div(pclk_div, 2);
 	do_div(pclk_div, pll->lanes);
 
-	DSI_PLL_DBG(pll, "bpp: %d, lanes: %d, m_val: %u, n_val: %u, pclk_div: %u\n",
-                          pll->bpp, pll->lanes, m_val, n_val, pclk_div);
+	DSI_PLL_DBG(pll, "bpp:%d lanes:%d m_val:%u n_val:%u dsiclk_sel:%u pclk_div: %u\n",
+			pll->bpp, pll->lanes, m_val, n_val, dsiclk_sel, pclk_div);
 
 	return pclk_div;
 }
@@ -1023,7 +1027,7 @@ static int dsi_pll_calc_dphy_pclk_div(struct dsi_pll_resource *pll)
 static int dsi_pll_calc_cphy_pclk_div(struct dsi_pll_resource *pll)
 {
 	u32 m_val, n_val; /* M and N values of MND trio */
-	u32 pclk_div;
+	u32 dsiclk_sel, pclk_div, num, den;
 	u32 phy_post_div = dsi_pll_get_phy_post_div(pll);
 
 	if (pll->bpp == 24 && pll->lanes == 2) {
@@ -1066,48 +1070,92 @@ static int dsi_pll_calc_cphy_pclk_div(struct dsi_pll_resource *pll)
 		n_val = 1;
 	}
 
-	/* Calculating pclk_div assuming dsiclk_sel to be 3 */
-	pclk_div =  pll->bpp * phy_post_div;
-	pclk_div = mult_frac(pclk_div, m_val, n_val);
-	do_div(pclk_div, 8);
-	do_div(pclk_div, pll->lanes);
+	dsiclk_sel = dsi_pll_get_dsiclk_sel(pll);
+	num = m_val * pll->bpp;
+	den = n_val * pll->lanes;
+
+	if (dsiclk_sel == 3) {
+		num *= phy_post_div;
+		den *= 8;
+	} else if (dsiclk_sel == 2) {
+		num *= (7 * phy_post_div);
+		den *= 16;
+	} else if (dsiclk_sel == 0) {
+		num *= 7;
+		den *= 16;
+	}
 
-	DSI_PLL_DBG(pll, "bpp: %d, lanes: %d, m_val: %u, n_val: %u, phy_post_div: %u pclk_div: %u\n",
-                          pll->bpp, pll->lanes, m_val, n_val, phy_post_div, pclk_div);
+	pclk_div = mult_frac(1, num, den);
+
+	DSI_PLL_DBG(pll,
+		"bpp:%d lanes:%d m_val:%u n_val:%u phy_post_div:%u dsiclk_sel:%u pclk_div:%u\n",
+		pll->bpp, pll->lanes, m_val, n_val, phy_post_div, dsiclk_sel, pclk_div);
 
 	return pclk_div;
 }
 
+static int dsi_pll_calc_dsiclk_sel(struct dsi_pll_resource *pll)
+{
+	u32 dsiclk_sel;
+
+	if (pll->type == DSI_PHY_TYPE_DPHY) {
+		if (pll->bpp == 30 && (pll->lanes == 2 || pll->lanes == 4)) {
+			dsiclk_sel = 0;
+		} else if (pll->bpp == 3 && pll->lanes >= 3) {
+			dsiclk_sel = 0;
+		} else {
+			dsiclk_sel = 1;
+		}
+	} else {
+		if (pll->bpp == 24 || (pll->bpp == 16 && pll->lanes == 2)
+				|| (pll->bpp == 30 && pll->lanes == 1)) {
+			dsiclk_sel = 3;
+		} else if (pll->bpp == 3 && pll->lanes >= 2) {
+			dsiclk_sel = 2;
+		} else {
+			dsiclk_sel = 0;
+		}
+	}
+
+	return dsiclk_sel;
+}
+
 static int dsi_pll_4nm_set_pclk_div(struct dsi_pll_resource *pll, bool commit)
 {
 
-	int dsi_clk = 0, pclk_div = 0;
+	int dsiclk_sel = 0, pclk_div = 0;
 	u64 pclk_src_rate;
 	u32 pll_post_div;
 	u32 phy_post_div;
 
 	pll_post_div = dsi_pll_get_pll_post_div(pll);
 	pclk_src_rate = div_u64(pll->vco_rate, pll_post_div);
-	if (pll->type == DSI_PHY_TYPE_DPHY) {
-		dsi_clk = 0x1;
-		phy_post_div = dsi_pll_get_phy_post_div(pll);
+	phy_post_div = dsi_pll_get_phy_post_div(pll);
+	dsiclk_sel = dsi_pll_calc_dsiclk_sel(pll);
+
+	dsi_pll_set_dsiclk_sel(pll, dsiclk_sel);
+
+	if (dsiclk_sel == 0) {
+		pclk_src_rate = div_u64(pclk_src_rate, phy_post_div);
+	} else if (dsiclk_sel == 1) {
 		pclk_src_rate = div_u64(pclk_src_rate, phy_post_div);
 		pclk_src_rate = div_u64(pclk_src_rate, 2);
-		pclk_div = dsi_pll_calc_dphy_pclk_div(pll);
-	} else {
-		dsi_clk = 0x3;
+	} else if (dsiclk_sel == 3 && pll->type == DSI_PHY_TYPE_CPHY) {
 		pclk_src_rate *= 2;
 		pclk_src_rate = div_u64(pclk_src_rate, 7);
-		pclk_div = dsi_pll_calc_cphy_pclk_div(pll);
 	}
 
+	if (pll->type == DSI_PHY_TYPE_DPHY)
+		pclk_div = dsi_pll_calc_dphy_pclk_div(pll);
+	else
+		pclk_div = dsi_pll_calc_cphy_pclk_div(pll);
+
 	pll->pclk_rate = div_u64(pclk_src_rate, pclk_div);
 
-	DSI_PLL_DBG(pll, "pclk rate: %llu, dsi_clk: %d, pclk_div: %d\n",
-			pll->pclk_rate, dsi_clk, pclk_div);
+	DSI_PLL_DBG(pll, "pclk rate: %llu, dsiclk_sel: %d, pclk_div: %d\n",
+			pll->pclk_rate, dsiclk_sel, pclk_div);
 
 	if (commit) {
-		dsi_pll_set_dsi_clk(pll, dsi_clk);
 		dsi_pll_set_pclk_div(pll, pclk_div);
 	}
 

+ 12 - 12
msm/dsi/dsi_pll_5nm.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/kernel.h>
@@ -128,24 +128,24 @@ static inline int dsi_pll_get_phy_post_div(struct dsi_pll_resource *pll)
 }
 
 
-static inline void dsi_pll_set_dsi_clk(struct dsi_pll_resource *pll, u32
-		dsi_clk)
+static inline void dsi_pll_set_dsiclk_sel(struct dsi_pll_resource *pll, u32
+		dsiclk_sel)
 {
 	u32 reg_val = 0;
 
 	reg_val = DSI_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG1);
 	reg_val &= ~0x3;
-	reg_val |= dsi_clk;
+	reg_val |= dsiclk_sel;
 	DSI_PLL_REG_W(pll->phy_base, PHY_CMN_CLK_CFG1, reg_val);
 	if (pll->slave) {
 		reg_val = DSI_PLL_REG_R(pll->slave->phy_base, PHY_CMN_CLK_CFG1);
 		reg_val &= ~0x3;
-		reg_val |= dsi_clk;
+		reg_val |= dsiclk_sel;
 		DSI_PLL_REG_W(pll->slave->phy_base, PHY_CMN_CLK_CFG1, reg_val);
 	}
 }
 
-static inline int dsi_pll_get_dsi_clk(struct dsi_pll_resource *pll)
+static inline int dsi_pll_get_dsiclk_sel(struct dsi_pll_resource *pll)
 {
 	u32 reg_val;
 
@@ -1151,7 +1151,7 @@ static int dsi_pll_calc_cphy_pclk_div(struct dsi_pll_resource *pll)
 static int dsi_pll_5nm_set_pclk_div(struct dsi_pll_resource *pll, bool commit)
 {
 
-	int dsi_clk = 0, pclk_div = 0;
+	int dsiclk_sel = 0, pclk_div = 0;
 	u64 pclk_src_rate;
 	u32 pll_post_div;
 	u32 phy_post_div;
@@ -1159,13 +1159,13 @@ static int dsi_pll_5nm_set_pclk_div(struct dsi_pll_resource *pll, bool commit)
 	pll_post_div = dsi_pll_get_pll_post_div(pll);
 	pclk_src_rate = div_u64(pll->vco_rate, pll_post_div);
 	if (pll->type == DSI_PHY_TYPE_DPHY) {
-		dsi_clk = 0x1;
+		dsiclk_sel = 0x1;
 		phy_post_div = dsi_pll_get_phy_post_div(pll);
 		pclk_src_rate = div_u64(pclk_src_rate, phy_post_div);
 		pclk_src_rate = div_u64(pclk_src_rate, 2);
 		pclk_div = dsi_pll_calc_dphy_pclk_div(pll);
 	} else {
-		dsi_clk = 0x3;
+		dsiclk_sel = 0x3;
 		pclk_src_rate *= 2;
 		pclk_src_rate = div_u64(pclk_src_rate, 7);
 		pclk_div = dsi_pll_calc_cphy_pclk_div(pll);
@@ -1173,11 +1173,11 @@ static int dsi_pll_5nm_set_pclk_div(struct dsi_pll_resource *pll, bool commit)
 
 	pll->pclk_rate = div_u64(pclk_src_rate, pclk_div);
 
-	DSI_PLL_DBG(pll, "pclk rate: %llu, dsi_clk: %d, pclk_div: %d\n",
-			pll->pclk_rate, dsi_clk, pclk_div);
+	DSI_PLL_DBG(pll, "pclk rate: %llu, dsiclk_sel: %d, pclk_div: %d\n",
+			pll->pclk_rate, dsiclk_sel, pclk_div);
 
 	if (commit) {
-		dsi_pll_set_dsi_clk(pll, dsi_clk);
+		dsi_pll_set_dsiclk_sel(pll, dsiclk_sel);
 		dsi_pll_set_pclk_div(pll, pclk_div);
 	}