diff mbox series

[6/8] clk: mvebu: ap806: add AP-DCLK (hclk) to system controller driver

Message ID 20190805100310.29048-7-miquel.raynal@bootlin.com (mailing list archive)
State Accepted, archived
Headers show
Series AP807 clocks support | expand

Commit Message

Miquel Raynal Aug. 5, 2019, 10:03 a.m. UTC
From: Omri Itach <omrii@marvell.com>

Add dynamic AP-DCLK clock (hclk) to system controller driver. AP-DCLK
is half the rate of DDR clock, so its derrived from Sample At Reset
configuration. The clock frequency is required for AP806 AXI monitor
profiling feature.

Signed-off-by: Omri Itach <omrii@marvell.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/clk/mvebu/ap806-system-controller.c | 48 ++++++++++++++++++++-
 1 file changed, 46 insertions(+), 2 deletions(-)

Comments

Stephen Boyd Sept. 18, 2019, 5:08 a.m. UTC | #1
Quoting Miquel Raynal (2019-08-05 03:03:08)
> From: Omri Itach <omrii@marvell.com>
> 
> Add dynamic AP-DCLK clock (hclk) to system controller driver. AP-DCLK
> is half the rate of DDR clock, so its derrived from Sample At Reset
> configuration. The clock frequency is required for AP806 AXI monitor
> profiling feature.
> 
> Signed-off-by: Omri Itach <omrii@marvell.com>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---

Applied to clk-next
diff mbox series

Patch

diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c
index 2cf874f01394..bc43adff02e0 100644
--- a/drivers/clk/mvebu/ap806-system-controller.c
+++ b/drivers/clk/mvebu/ap806-system-controller.c
@@ -21,7 +21,7 @@ 
 #define AP806_SAR_REG			0x400
 #define AP806_SAR_CLKFREQ_MODE_MASK	0x1f
 
-#define AP806_CLK_NUM			5
+#define AP806_CLK_NUM			6
 
 static struct clk *ap806_clks[AP806_CLK_NUM];
 
@@ -33,7 +33,7 @@  static struct clk_onecell_data ap806_clk_data = {
 static int ap806_syscon_common_probe(struct platform_device *pdev,
 				     struct device_node *syscon_node)
 {
-	unsigned int freq_mode, cpuclk_freq;
+	unsigned int freq_mode, cpuclk_freq, dclk_freq;
 	const char *name, *fixedclk_name;
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
@@ -93,8 +93,42 @@  static int ap806_syscon_common_probe(struct platform_device *pdev,
 		return -EINVAL;
 	}
 
+	/* Get DCLK frequency (DCLK = DDR_CLK / 2) */
+	switch (freq_mode) {
+	case 0x0:
+	case 0x6:
+		/* DDR_CLK = 1200Mhz */
+		dclk_freq = 600;
+		break;
+	case 0x1:
+	case 0x7:
+	case 0xD:
+		/* DDR_CLK = 1050Mhz */
+		dclk_freq = 525;
+		break;
+	case 0x13:
+	case 0x17:
+		/* DDR_CLK = 650Mhz */
+		dclk_freq = 325;
+		break;
+	case 0x4:
+	case 0x14:
+	case 0x19:
+	case 0x1A:
+	case 0x1B:
+	case 0x1C:
+	case 0x1D:
+		/* DDR_CLK = 800Mhz */
+		dclk_freq = 400;
+		break;
+	default:
+		dclk_freq = 0;
+		dev_err(dev, "invalid Sample at Reset value\n");
+	}
+
 	/* Convert to hertz */
 	cpuclk_freq *= 1000 * 1000;
+	dclk_freq *= 1000 * 1000;
 
 	/* CPU clocks depend on the Sample At Reset configuration */
 	name = ap_cp_unique_name(dev, syscon_node, "pll-cluster-0");
@@ -141,6 +175,14 @@  static int ap806_syscon_common_probe(struct platform_device *pdev,
 		goto fail4;
 	}
 
+	/* AP-DCLK(HCLK) Clock is DDR clock divided by 2 */
+	name = ap_cp_unique_name(dev, syscon_node, "ap-dclk");
+	ap806_clks[5] = clk_register_fixed_rate(dev, name, NULL, 0, dclk_freq);
+	if (IS_ERR(ap806_clks[5])) {
+		ret = PTR_ERR(ap806_clks[5]);
+		goto fail5;
+	}
+
 	ret = of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data);
 	if (ret)
 		goto fail_clk_add;
@@ -148,6 +190,8 @@  static int ap806_syscon_common_probe(struct platform_device *pdev,
 	return 0;
 
 fail_clk_add:
+	clk_unregister_fixed_factor(ap806_clks[5]);
+fail5:
 	clk_unregister_fixed_factor(ap806_clks[4]);
 fail4:
 	clk_unregister_fixed_factor(ap806_clks[3]);