Commit 0099dc44 authored by Omri Itach's avatar Omri Itach Committed by Stephen Boyd

clk: mvebu: ap806: add AP-DCLK (hclk) to system controller driver

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: default avatarOmri Itach <omrii@marvell.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Link: https://lkml.kernel.org/r/20190805100310.29048-7-miquel.raynal@bootlin.comSigned-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent cd016cb0
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#define AP806_SAR_REG 0x400 #define AP806_SAR_REG 0x400
#define AP806_SAR_CLKFREQ_MODE_MASK 0x1f #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]; static struct clk *ap806_clks[AP806_CLK_NUM];
...@@ -33,7 +33,7 @@ static struct clk_onecell_data ap806_clk_data = { ...@@ -33,7 +33,7 @@ static struct clk_onecell_data ap806_clk_data = {
static int ap806_syscon_common_probe(struct platform_device *pdev, static int ap806_syscon_common_probe(struct platform_device *pdev,
struct device_node *syscon_node) struct device_node *syscon_node)
{ {
unsigned int freq_mode, cpuclk_freq; unsigned int freq_mode, cpuclk_freq, dclk_freq;
const char *name, *fixedclk_name; const char *name, *fixedclk_name;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
...@@ -93,8 +93,42 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, ...@@ -93,8 +93,42 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
return -EINVAL; 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 */ /* Convert to hertz */
cpuclk_freq *= 1000 * 1000; cpuclk_freq *= 1000 * 1000;
dclk_freq *= 1000 * 1000;
/* CPU clocks depend on the Sample At Reset configuration */ /* CPU clocks depend on the Sample At Reset configuration */
name = ap_cp_unique_name(dev, syscon_node, "pll-cluster-0"); 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, ...@@ -141,6 +175,14 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
goto fail4; 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); ret = of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data);
if (ret) if (ret)
goto fail_clk_add; goto fail_clk_add;
...@@ -148,6 +190,8 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, ...@@ -148,6 +190,8 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
return 0; return 0;
fail_clk_add: fail_clk_add:
clk_unregister_fixed_factor(ap806_clks[5]);
fail5:
clk_unregister_fixed_factor(ap806_clks[4]); clk_unregister_fixed_factor(ap806_clks[4]);
fail4: fail4:
clk_unregister_fixed_factor(ap806_clks[3]); clk_unregister_fixed_factor(ap806_clks[3]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment