diff mbox series

[03/14] clocks: qcs404: Add support for ethernet clocks

Message ID 20230120071719.623661-4-sumit.garg@linaro.org
State Superseded
Headers show
Series QCS404: Add ethernet and I2C drivers | expand

Commit Message

Sumit Garg Jan. 20, 2023, 7:17 a.m. UTC
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
---
 arch/arm/mach-snapdragon/clock-qcs404.c       | 60 +++++++++++++++++++
 .../include/mach/sysmap-qcs404.h              | 14 +++++
 2 files changed, 74 insertions(+)
diff mbox series

Patch

diff --git a/arch/arm/mach-snapdragon/clock-qcs404.c b/arch/arm/mach-snapdragon/clock-qcs404.c
index 6fe92afe8d..b8f5691aae 100644
--- a/arch/arm/mach-snapdragon/clock-qcs404.c
+++ b/arch/arm/mach-snapdragon/clock-qcs404.c
@@ -18,6 +18,9 @@ 
 /* GPLL0 clock control registers */
 #define GPLL0_STATUS_ACTIVE BIT(31)
 
+#define CFG_CLK_SRC_GPLL1	BIT(8)
+#define GPLL1_STATUS_ACTIVE	BIT(31)
+
 static struct vote_clk gcc_blsp1_ahb_clk = {
 	.cbcr_reg = BLSP1_AHB_CBCR,
 	.ena_vote = APCS_CLOCK_BRANCH_ENA_VOTE,
@@ -47,6 +50,13 @@  static struct pll_vote_clk gpll0_vote_clk = {
 	.vote_bit = BIT(0),
 };
 
+static struct pll_vote_clk gpll1_vote_clk = {
+	.status = GPLL1_STATUS,
+	.status_bit = GPLL1_STATUS_ACTIVE,
+	.ena_vote = APCS_GPLL_ENA_VOTE,
+	.vote_bit = BIT(1),
+};
+
 static const struct bcr_regs usb30_master_regs = {
 	.cfg_rcgr = USB30_MASTER_CFG_RCGR,
 	.cmd_rcgr = USB30_MASTER_CMD_RCGR,
@@ -55,6 +65,22 @@  static const struct bcr_regs usb30_master_regs = {
 	.D = USB30_MASTER_D,
 };
 
+static const struct bcr_regs emac_regs = {
+	.cfg_rcgr = EMAC_CFG_RCGR,
+	.cmd_rcgr = EMAC_CMD_RCGR,
+	.M = EMAC_M,
+	.N = EMAC_N,
+	.D = EMAC_D,
+};
+
+static const struct bcr_regs emac_ptp_regs = {
+	.cfg_rcgr = EMAC_PTP_CFG_RCGR,
+	.cmd_rcgr = EMAC_PTP_CMD_RCGR,
+	.M = EMAC_M,
+	.N = EMAC_N,
+	.D = EMAC_D,
+};
+
 ulong msm_set_rate(struct clk *clk, ulong rate)
 {
 	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
@@ -79,6 +105,20 @@  ulong msm_set_rate(struct clk *clk, ulong rate)
 	case GCC_SDCC1_AHB_CLK:
 		clk_enable_cbc(priv->base + SDCC_AHB_CBCR(1));
 		break;
+	case GCC_ETH_RGMII_CLK:
+		if (rate == 250000000)
+			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0,
+					     CFG_CLK_SRC_GPLL1);
+		else if (rate == 125000000)
+			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 4, 0, 0,
+					     CFG_CLK_SRC_GPLL1);
+		else if (rate == 50000000)
+			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 10, 0, 0,
+					     CFG_CLK_SRC_GPLL1);
+		else if (rate == 5000000)
+			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 1, 50,
+					     CFG_CLK_SRC_GPLL1);
+		break;
 	default:
 		return 0;
 	}
@@ -111,6 +151,26 @@  int msm_enable(struct clk *clk)
 	case GCC_USB2A_PHY_SLEEP_CLK:
 		clk_enable_cbc(priv->base + USB_HS_PHY_CFG_AHB_CBCR);
 		break;
+	case GCC_ETH_PTP_CLK:
+		/* SPEED_1000: freq -> 250MHz */
+		clk_enable_cbc(priv->base + ETH_PTP_CBCR);
+		clk_enable_gpll0(priv->base, &gpll1_vote_clk);
+		clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 2, 0, 0,
+				     CFG_CLK_SRC_GPLL1);
+		break;
+	case GCC_ETH_RGMII_CLK:
+		/* SPEED_1000: freq -> 250MHz */
+		clk_enable_cbc(priv->base + ETH_RGMII_CBCR);
+		clk_enable_gpll0(priv->base, &gpll1_vote_clk);
+		clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0,
+				     CFG_CLK_SRC_GPLL1);
+		break;
+	case GCC_ETH_SLAVE_AHB_CLK:
+		clk_enable_cbc(priv->base + ETH_SLAVE_AHB_CBCR);
+		break;
+	case GCC_ETH_AXI_CLK:
+		clk_enable_cbc(priv->base + ETH_AXI_CBCR);
+		break;
 	default:
 		return 0;
 	}
diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h b/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h
index e448faad2d..8920c4ee8f 100644
--- a/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h
+++ b/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h
@@ -12,6 +12,7 @@ 
 
 /* Clocks: (from CLK_CTL_BASE)  */
 #define GPLL0_STATUS			(0x21000)
+#define GPLL1_STATUS			(0x20000)
 #define APCS_GPLL_ENA_VOTE		(0x45000)
 #define APCS_CLOCK_BRANCH_ENA_VOTE	(0x45004)
 
@@ -54,4 +55,17 @@ 
 #define USB2A_PHY_SLEEP_CBCR		(0x4102C)
 #define USB_HS_PHY_CFG_AHB_CBCR		(0x41030)
 
+/* ETH controller clock control registers */
+#define ETH_PTP_CBCR			(0x4e004)
+#define ETH_RGMII_CBCR			(0x4e008)
+#define ETH_SLAVE_AHB_CBCR		(0x4e00c)
+#define ETH_AXI_CBCR			(0x4e010)
+#define EMAC_PTP_CMD_RCGR		(0x4e014)
+#define EMAC_PTP_CFG_RCGR		(0x4e018)
+#define EMAC_CMD_RCGR			(0x4e01c)
+#define EMAC_CFG_RCGR			(0x4e020)
+#define EMAC_M				(0x4e024)
+#define EMAC_N				(0x4e028)
+#define EMAC_D				(0x4e02c)
+
 #endif