Browse Source

Merge "disp: msm: dp: fix disp_cc offsets for pixel clk dividers"

qctecmdr 4 years ago
parent
commit
1269ba8e88
8 changed files with 121 additions and 39 deletions
  1. 21 1
      msm/dp/dp_catalog.c
  2. 2 1
      msm/dp/dp_catalog.h
  3. 30 6
      msm/dp/dp_catalog_v420.c
  4. 1 0
      msm/dp/dp_display.c
  5. 30 1
      msm/dp/dp_pll.c
  6. 3 0
      msm/dp/dp_pll.h
  7. 33 25
      msm/dp/dp_pll_5nm.c
  8. 1 5
      msm/dp/dp_reg.h

+ 21 - 1
msm/dp/dp_catalog.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
 
@@ -123,6 +123,7 @@ struct dp_catalog_private {
 	struct dp_catalog dp_catalog;
 
 	char exe_mode[SZ_4];
+	u32 dp_core_version;
 };
 
 static u32 dp_read_sw(struct dp_catalog_private *catalog,
@@ -1938,6 +1939,25 @@ static void dp_catalog_ctrl_fec_config(struct dp_catalog_ctrl *ctrl,
 	wmb();
 }
 
+u32 dp_catalog_get_dp_core_version(struct dp_catalog *dp_catalog)
+{
+	struct dp_catalog_private *catalog;
+	struct dp_io_data *io_data;
+
+	if (!dp_catalog) {
+		DP_ERR("invalid input\n");
+		return 0;
+	}
+
+	catalog = container_of(dp_catalog, struct dp_catalog_private, dp_catalog);
+	if (catalog->dp_core_version)
+		return catalog->dp_core_version;
+
+	io_data = catalog->io.dp_ahb;
+
+	return dp_read(DP_HW_VERSION);
+}
+
 static int dp_catalog_reg_dump(struct dp_catalog *dp_catalog,
 		char *name, u8 **out_buf, u32 *out_buf_len)
 {

+ 2 - 1
msm/dp/dp_catalog.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _DP_CATALOG_H_
@@ -336,4 +336,5 @@ struct dp_catalog_sub *dp_catalog_get_v420(struct device *dev,
 struct dp_catalog_sub *dp_catalog_get_v200(struct device *dev,
 			struct dp_catalog *catalog, struct dp_catalog_io *io);
 
+u32 dp_catalog_get_dp_core_version(struct dp_catalog *dp_catalog);
 #endif /* _DP_CATALOG_H_ */

+ 30 - 6
msm/dp/dp_catalog_v420.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
 
@@ -8,6 +8,15 @@
 #include "dp_reg.h"
 #include "dp_debug.h"
 
+#define MMSS_DP_PIXEL_BASE_V130			(0x1A8)
+#define MMSS_DP_PIXEL1_BASE_V130		(0x1C0)
+
+#define MMSS_DP_PIXEL_BASE_V140			(0x1BC)
+#define MMSS_DP_PIXEL1_BASE_V140		(0x1D4)
+
+#define MMSS_DP_M_OFF				(0x8)
+#define MMSS_DP_N_OFF				(0xC)
+
 #define dp_catalog_get_priv_v420(x) ({ \
 	struct dp_catalog *catalog; \
 	catalog = container_of(x, struct dp_catalog, x); \
@@ -146,8 +155,10 @@ static void dp_catalog_panel_config_msa_v420(struct dp_catalog_panel *panel,
 	u32 const nvid_fixed = 0x8000;
 	u32 const link_rate_hbr2 = 540000;
 	u32 const link_rate_hbr3 = 810000;
+	struct dp_catalog *dp_catalog;
 	struct dp_catalog_private_v420 *catalog;
 	struct dp_io_data *io_data;
+	u32 version;
 
 	if (!panel || !rate) {
 		DP_ERR("invalid input\n");
@@ -159,14 +170,27 @@ static void dp_catalog_panel_config_msa_v420(struct dp_catalog_panel *panel,
 		return;
 	}
 
-	catalog = dp_catalog_get_priv_v420(panel);
+	dp_catalog = container_of(panel, struct dp_catalog, panel);
+	catalog = container_of(dp_catalog->sub, struct dp_catalog_private_v420, sub);
+
+	version = dp_catalog_get_dp_core_version(dp_catalog);
 	io_data = catalog->io->dp_mmss_cc;
 
-	if (panel->stream_id == DP_STREAM_1)
-		reg_off = MMSS_DP_PIXEL1_M_V420 - MMSS_DP_PIXEL_M_V420;
+	if (version >= 0x10040000) {
+		if (panel->stream_id == DP_STREAM_1)
+			reg_off = MMSS_DP_PIXEL1_BASE_V140;
+		else
+			reg_off = MMSS_DP_PIXEL_BASE_V140;
+	} else {
+		if (panel->stream_id == DP_STREAM_1)
+			reg_off = MMSS_DP_PIXEL1_BASE_V130;
+		else
+			reg_off = MMSS_DP_PIXEL_BASE_V130;
+	}
+
 
-	pixel_m = dp_read(MMSS_DP_PIXEL_M_V420 + reg_off);
-	pixel_n = dp_read(MMSS_DP_PIXEL_N_V420 + reg_off);
+	pixel_m = dp_read(reg_off + MMSS_DP_M_OFF);
+	pixel_n = dp_read(reg_off + MMSS_DP_N_OFF);
 	DP_DEBUG("pixel_m=0x%x, pixel_n=0x%x\n", pixel_m, pixel_n);
 
 	mvid = (pixel_m & 0xFFFF) * 5;

+ 1 - 0
msm/dp/dp_display.c

@@ -1950,6 +1950,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
 
 	pll_in.aux = dp->aux;
 	pll_in.parser = dp->parser;
+	pll_in.dp_core_revision = dp_catalog_get_dp_core_version(dp->catalog);
 
 	dp->pll = dp_pll_get(&pll_in);
 	if (IS_ERR(dp->pll)) {

+ 30 - 1
msm/dp/dp_pll.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/err.h>
@@ -74,6 +74,34 @@ static void dp_pll_clock_unregister(struct dp_pll *pll)
 	}
 }
 
+int dp_pll_clock_register_helper(struct dp_pll *pll, struct dp_pll_vco_clk *clks, int num_clks)
+{
+	int rc = 0, i = 0;
+	struct platform_device *pdev;
+	struct clk *clk;
+
+	if (!pll || !clks) {
+		DP_ERR("input not initialized\n");
+		return -EINVAL;
+	}
+
+	pdev = pll->pdev;
+
+	for (i = 0; i < num_clks; i++) {
+		clks[i].priv = pll;
+
+		clk = clk_register(&pdev->dev, &clks[i].hw);
+		if (IS_ERR(clk)) {
+			DP_ERR("%s registration failed for DP: %d\n",
+			clk_hw_get_name(&clks[i].hw), pll->index);
+			return -EINVAL;
+		}
+		pll->clk_data->clks[i] = clk;
+	}
+
+	return rc;
+}
+
 struct dp_pll *dp_pll_get(struct dp_pll_in *in)
 {
 	int rc = 0;
@@ -93,6 +121,7 @@ struct dp_pll *dp_pll_get(struct dp_pll_in *in)
 	pll->pdev = in->pdev;
 	pll->parser = in->parser;
 	pll->aux = in->aux;
+	pll->dp_core_revision = in->dp_core_revision;
 	parser = pll->parser;
 	pdev = pll->pdev;
 

+ 3 - 0
msm/dp/dp_pll.h

@@ -80,6 +80,7 @@ struct dp_pll {
 	struct dp_aux *aux;
 	struct dp_pll_io io;
 	struct clk_onecell_data *clk_data;
+	u32 dp_core_revision;
 
 	int (*pll_cfg)(struct dp_pll *pll, unsigned long rate);
 	int (*pll_prepare)(struct dp_pll *pll);
@@ -128,8 +129,10 @@ struct dp_pll_in {
 	struct platform_device *pdev;
 	struct dp_aux *aux;
 	struct dp_parser *parser;
+	u32 dp_core_revision;
 };
 
+int dp_pll_clock_register_helper(struct dp_pll *pll, struct dp_pll_vco_clk *clks, int num_clks);
 struct dp_pll *dp_pll_get(struct dp_pll_in *in);
 void dp_pll_put(struct dp_pll *pll);
 #endif /* __DP_PLL_H */

+ 33 - 25
msm/dp/dp_pll_5nm.c

@@ -121,6 +121,8 @@
 #define DP_VCO_RATE_9720MHZDIV1000		9720000UL
 #define DP_VCO_RATE_10800MHZDIV1000		10800000UL
 
+#define DP_PLL_NUM_CLKS				2
+
 #define DP_5NM_C_READY		BIT(0)
 #define DP_5NM_FREQ_DONE	BIT(0)
 #define DP_5NM_PLL_LOCKED	BIT(1)
@@ -826,17 +828,33 @@ static const struct clk_ops pll_vco_div_clk_ops = {
 	.set_rate = dp_pll_vco_div_clk_set_rate,
 };
 
-static struct dp_pll_vco_clk dp_phy_pll_link_clk = {
+static struct dp_pll_vco_clk dp0_phy_pll_clks[DP_PLL_NUM_CLKS] = {
+	{
 	.hw.init = &(struct clk_init_data) {
-		.name = "dp_phy_pll_link_clk",
+		.name = "dp0_phy_pll_link_clk",
 		.ops = &pll_link_clk_ops,
+		},
+	},
+	{
+	.hw.init = &(struct clk_init_data) {
+		.name = "dp0_phy_pll_vco_div_clk",
+		.ops = &pll_vco_div_clk_ops,
+		},
 	},
 };
 
-static struct dp_pll_vco_clk dp_phy_pll_vco_div_clk = {
+static struct dp_pll_vco_clk dp_phy_pll_clks[DP_PLL_NUM_CLKS] = {
+	{
+	.hw.init = &(struct clk_init_data) {
+		.name = "dp_phy_pll_link_clk",
+		.ops = &pll_link_clk_ops,
+		},
+	},
+	{
 	.hw.init = &(struct clk_init_data) {
 		.name = "dp_phy_pll_vco_div_clk",
 		.ops = &pll_vco_div_clk_ops,
+		},
 	},
 };
 
@@ -844,9 +862,9 @@ static struct dp_pll_db dp_pdb;
 
 int dp_pll_clock_register_5nm(struct dp_pll *pll)
 {
-	int rc = 0, num_clks = 2;
+	int rc = 0;
 	struct platform_device *pdev;
-	struct clk *clk;
+	struct dp_pll_vco_clk *pll_clks;
 
 	if (!pll) {
 		DP_ERR("pll data not initialized\n");
@@ -858,46 +876,36 @@ int dp_pll_clock_register_5nm(struct dp_pll *pll)
 	if (!pll->clk_data)
 		return -ENOMEM;
 
-	pll->clk_data->clks = kcalloc(num_clks, sizeof(struct clk *),
+	pll->clk_data->clks = kcalloc(DP_PLL_NUM_CLKS, sizeof(struct clk *),
 			GFP_KERNEL);
 	if (!pll->clk_data->clks) {
 		kfree(pll->clk_data);
 		return -ENOMEM;
 	}
 
-	pll->clk_data->clk_num = num_clks;
+	pll->clk_data->clk_num = DP_PLL_NUM_CLKS;
 	pll->priv = &dp_pdb;
 	dp_pdb.pll = pll;
 
-	dp_phy_pll_link_clk.priv = pll;
-	dp_phy_pll_vco_div_clk.priv = pll;
-
 	pll->pll_cfg = dp_pll_configure;
 	pll->pll_prepare = dp_pll_prepare;
 	pll->pll_unprepare = dp_pll_unprepare;
 
-	clk = clk_register(&pdev->dev, &dp_phy_pll_link_clk.hw);
-	if (IS_ERR(clk)) {
-		DP_ERR("%s registration failed for DP: %d\n",
-		       clk_hw_get_name(&dp_phy_pll_link_clk.hw), pll->index);
-		rc = -EINVAL;
-		goto clk_reg_fail;
-	}
-	pll->clk_data->clks[0] = clk;
+	if (pll->dp_core_revision >= 0x10040000)
+		pll_clks = dp0_phy_pll_clks;
+	else
+		pll_clks = dp_phy_pll_clks;
 
-	clk = clk_register(&pdev->dev, &dp_phy_pll_vco_div_clk.hw);
-	if (IS_ERR(clk)) {
-		DP_ERR("%s registration failed for DP: %d\n",
-		       clk_hw_get_name(&dp_phy_pll_vco_div_clk.hw), pll->index);
-		rc = -EINVAL;
+	rc = dp_pll_clock_register_helper(pll, pll_clks, DP_PLL_NUM_CLKS);
+	if (rc) {
+		DP_ERR("Clock register failed rc=%d\n", rc);
 		goto clk_reg_fail;
 	}
-	pll->clk_data->clks[1] = clk;
 
 	rc = of_clk_add_provider(pdev->dev.of_node,
 			of_clk_src_onecell_get, pll->clk_data);
 	if (rc) {
-		DP_ERR("Clock register failed rc=%d\n", rc);
+		DP_ERR("Clock add provider failed rc=%d\n", rc);
 		goto clk_reg_fail;
 	}
 

+ 1 - 5
msm/dp/dp_reg.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _DP_REG_H_
@@ -398,10 +398,6 @@
 #define MMSS_DP_PIXEL_N_V200			(0x0134)
 #define MMSS_DP_PIXEL1_M_V200			(0x0148)
 #define MMSS_DP_PIXEL1_N_V200			(0x014C)
-#define MMSS_DP_PIXEL_M_V420			(0x01B0)
-#define MMSS_DP_PIXEL_N_V420			(0x01B4)
-#define MMSS_DP_PIXEL1_M_V420			(0x01C8)
-#define MMSS_DP_PIXEL1_N_V420			(0x01CC)
 
 /* DP HDCP 1.3 registers */
 #define DP_HDCP_CTRL                                   (0x0A0)