From fb103971feb637809a96fe739d81fe2f887cf3ac Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Tue, 25 Oct 2022 08:58:45 +0100 Subject: clk: microchip: mpfs: convert parent rate acquistion to get_get_rate() Currently the clock driver for PolarFire SoC takes a very naive approach to the relationship between clocks. It reads the dt to get an input clock, assumes that that is fixed frequency, reads the "clock-frequency" property & uses that to set up both the "cfg" and "periph" clocks. Simplifying for the sake of incremental fixes, the "correct" parentage for the clocks currently supported in U-Boot is that the "cfg" clocks should be children of the fixed frequency clock in the dt. The AHB clock is one of these "cfg" clocks and is the parent of the "periph" clocks. Instead of passing the clock rate of the fixed-frequency clock to the "cfg" and "periph" registration functions and the name of the parents, pass their actual parents & use clk_get_rate() to determine their parents rates. The "periph" clocks are purely gate clocks and should not be reading the AHB clocks registers to determine their rates, as they can simply report the output of clk_get_rate() on their parent. Signed-off-by: Conor Dooley Reviewed-by: Leo Yu-Chi Liang Reviewed-by: Padmarao Begari --- drivers/clk/microchip/mpfs_clk.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers/clk/microchip/mpfs_clk.c') diff --git a/drivers/clk/microchip/mpfs_clk.c b/drivers/clk/microchip/mpfs_clk.c index 67828c9bf40..7ba1218b56e 100644 --- a/drivers/clk/microchip/mpfs_clk.c +++ b/drivers/clk/microchip/mpfs_clk.c @@ -11,34 +11,32 @@ #include #include #include +#include #include #include "mpfs_clk.h" static int mpfs_clk_probe(struct udevice *dev) { - int ret; + struct clk *parent_clk = dev_get_priv(dev); + struct clk clk_ahb = { .id = CLK_AHB }; void __iomem *base; - u32 clk_rate; - const char *parent_clk_name; - struct clk *clk = dev_get_priv(dev); + int ret; base = dev_read_addr_ptr(dev); if (!base) return -EINVAL; - ret = clk_get_by_index(dev, 0, clk); + ret = clk_get_by_index(dev, 0, parent_clk); if (ret) return ret; - dev_read_u32(clk->dev, "clock-frequency", &clk_rate); - parent_clk_name = clk->dev->name; - - ret = mpfs_clk_register_cfgs(base, clk_rate, parent_clk_name); + ret = mpfs_clk_register_cfgs(base, parent_clk); if (ret) return ret; - ret = mpfs_clk_register_periphs(base, clk_rate, "clk_ahb"); + clk_request(dev, &clk_ahb); + ret = mpfs_clk_register_periphs(base, &clk_ahb); return ret; } -- cgit v1.2.3 From 32cfdd51630506393ca078aa36fa70248d549109 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Tue, 25 Oct 2022 08:58:46 +0100 Subject: clk: microchip: mpfs: fix reference clock handling The original devicetrees for PolarFire SoC messed up & defined the msspll's output as a fixed-frequency, 600 MHz clock & used that as the input for the clock controller node. The msspll is not a fixed frequency clock and later devicetrees handled this properly. Check the devicetree & if it is one of the fixed ones, register the msspll. Otherwise, skip registering it & pass the reference clock directly to the cfg clock registration function so that existing devicetrees are not broken by this change. As the MSS PLL is not a "cfg" or a "periph" clock, add a new driver for it, based on the one in Linux. Fixes: 2f27c9219e ("clk: Add Microchip PolarFire SoC clock driver") Signed-off-by: Conor Dooley Reviewed-by: Leo Yu-Chi Liang Reviewed-by: Padmarao Begari Tested-by: Padmarao Begari --- drivers/clk/microchip/mpfs_clk.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers/clk/microchip/mpfs_clk.c') diff --git a/drivers/clk/microchip/mpfs_clk.c b/drivers/clk/microchip/mpfs_clk.c index 7ba1218b56e..f16f716f00e 100644 --- a/drivers/clk/microchip/mpfs_clk.c +++ b/drivers/clk/microchip/mpfs_clk.c @@ -20,10 +20,12 @@ static int mpfs_clk_probe(struct udevice *dev) { struct clk *parent_clk = dev_get_priv(dev); struct clk clk_ahb = { .id = CLK_AHB }; + struct clk clk_msspll = { .id = CLK_MSSPLL }; void __iomem *base; + void __iomem *msspll_base; int ret; - base = dev_read_addr_ptr(dev); + base = dev_read_addr_index_ptr(dev, 0); if (!base) return -EINVAL; @@ -31,6 +33,25 @@ static int mpfs_clk_probe(struct udevice *dev) if (ret) return ret; + /* + * The original devicetrees for mpfs messed up & defined the msspll's + * output as a fixed-frequency, 600 MHz clock & used that as the input + * for the clock controller node. The msspll is however not a fixed + * frequency clock and later devicetrees handled this properly. Check + * the devicetree & if it is one of the fixed ones, register the msspll. + * Otherwise, skip registering it & pass the reference clock directly + * to the cfg clock registration function. + */ + msspll_base = dev_read_addr_index_ptr(dev, 1); + if (msspll_base) { + ret = mpfs_clk_register_msspll(msspll_base, parent_clk); + if (ret) + return ret; + + clk_request(dev, &clk_msspll); + parent_clk = &clk_msspll; + } + ret = mpfs_clk_register_cfgs(base, parent_clk); if (ret) return ret; -- cgit v1.2.3 From 88b697fb37432b95bd87525e718726607bdb2123 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Tue, 25 Oct 2022 08:58:47 +0100 Subject: clk: microchip: mpfs: fix periph clk parentage Not all "periph" clocks are children of the AHB clock, some have the AXI clock as their parent & the mtimer clock is derived from the external reference clock directly. Stop assuming the AHB clock to be the parent of all "periph" clocks and define their correct parents instead. Fixes: 2f27c9219e ("clk: Add Microchip PolarFire SoC clock driver") Signed-off-by: Conor Dooley Reviewed-by: Leo Yu-Chi Liang Reviewed-by: Padmarao Begari Tested-by: Padmarao Begari --- drivers/clk/microchip/mpfs_clk.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/clk/microchip/mpfs_clk.c') diff --git a/drivers/clk/microchip/mpfs_clk.c b/drivers/clk/microchip/mpfs_clk.c index f16f716f00e..08f8bfcecbe 100644 --- a/drivers/clk/microchip/mpfs_clk.c +++ b/drivers/clk/microchip/mpfs_clk.c @@ -19,7 +19,6 @@ static int mpfs_clk_probe(struct udevice *dev) { struct clk *parent_clk = dev_get_priv(dev); - struct clk clk_ahb = { .id = CLK_AHB }; struct clk clk_msspll = { .id = CLK_MSSPLL }; void __iomem *base; void __iomem *msspll_base; @@ -56,8 +55,7 @@ static int mpfs_clk_probe(struct udevice *dev) if (ret) return ret; - clk_request(dev, &clk_ahb); - ret = mpfs_clk_register_periphs(base, &clk_ahb); + ret = mpfs_clk_register_periphs(base, dev); return ret; } -- cgit v1.2.3