From a28797563b8c97c9abced82e0cf89302fcd2bf37 Mon Sep 17 00:00:00 2001
From: Ziyang Huang <hzyitc@outlook.com>
Date: Sun, 8 Sep 2024 16:40:11 +0800
Subject: [PATCH 1/2] clk: qcom: cmn-pll: add IPQ5018 support

Add support for IPQ5018 (and removing dependency on the IPQ9574 platform).
The common network block in IPQ5018 must be enabled first through a 
specific register at a fixed offset in the TCSR area, set in the DTS.

Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
 drivers/clk/qcom/Kconfig           |  1 -
 drivers/clk/qcom/clk-ipq-cmn-pll.c | 29 +++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)

--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -192,7 +192,6 @@ config IPQ_APSS_6018
 
 config IPQ_CMN_PLL
 	tristate "IPQ CMN PLL Clock Controller"
-	depends on IPQ_GCC_9574
 	help
 	  Support for CMN PLL clock controller on IPQ platform. The
 	  CMN PLL feeds the reference clocks to the Ethernet devices
--- a/drivers/clk/qcom/clk-ipq-cmn-pll.c
+++ b/drivers/clk/qcom/clk-ipq-cmn-pll.c
@@ -42,6 +42,9 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
+#define TCSR_ETH_CMN				0x0
+#define  TCSR_ETH_CMN_ENABLE			BIT(0)
+
 #define CMN_PLL_REFCLK_SRC_SELECTION		0x28
 #define CMN_PLL_REFCLK_SRC_DIV			GENMASK(9, 8)
 
@@ -79,6 +82,28 @@ static const struct cmn_pll_fixed_output
 	CLK_PLL_OUTPUT(ETH_25MHZ_CLK, "eth-25mhz", 25000000UL),
 };
 
+static int ipq_cmn_pll_tcsr_enable(struct platform_device *pdev)
+{
+	struct resource *res;
+	void __iomem *tcsr_base;
+	u32 val;
+
+	/* For IPQ50xx, tcsr is necessary to enable cmn block */
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tcsr");
+	if (!res)
+		return 0;
+
+	tcsr_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR_OR_NULL(tcsr_base))
+		return PTR_ERR(tcsr_base);
+
+	val = readl(tcsr_base + TCSR_ETH_CMN);
+	val |= TCSR_ETH_CMN_ENABLE;
+	writel(val, (tcsr_base + TCSR_ETH_CMN));
+
+	return 0;
+}
+
 static int ipq_cmn_pll_config(struct device *dev, unsigned long parent_rate)
 {
 	void __iomem *base;
@@ -181,6 +206,10 @@ static int ipq_cmn_pll_clk_probe(struct
 	struct clk *clk;
 	int ret;
 
+	ret = ipq_cmn_pll_tcsr_enable(pdev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Enable CMN PLL failed\n");
+
 	/*
 	 * To access the CMN PLL registers, the GCC AHB & SYSY clocks
 	 * for CMN PLL block need to be enabled.
