diff options
Diffstat (limited to 'drivers/clk/microchip/mpfs_clk.c')
-rw-r--r-- | drivers/clk/microchip/mpfs_clk.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/clk/microchip/mpfs_clk.c b/drivers/clk/microchip/mpfs_clk.c index 67828c9bf40..08f8bfcecbe 100644 --- a/drivers/clk/microchip/mpfs_clk.c +++ b/drivers/clk/microchip/mpfs_clk.c @@ -11,34 +11,51 @@ #include <dm/device.h> #include <dm/devres.h> #include <dm/uclass.h> +#include <dt-bindings/clock/microchip-mpfs-clock.h> #include <linux/err.h> #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_msspll = { .id = CLK_MSSPLL }; void __iomem *base; - u32 clk_rate; - const char *parent_clk_name; - struct clk *clk = dev_get_priv(dev); + void __iomem *msspll_base; + int ret; - base = dev_read_addr_ptr(dev); + base = dev_read_addr_index_ptr(dev, 0); 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; + /* + * 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, 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"); + ret = mpfs_clk_register_periphs(base, dev); return ret; } |