-obj-y += mpfs_clk.o mpfs_clk_cfg.o mpfs_clk_periph.o
+obj-y += mpfs_clk.o mpfs_clk_cfg.o mpfs_clk_periph.o mpfs_clk_msspll.o
#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_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;
}
* mpfs_clk_register_cfgs() - register configuration clocks
*
* @base: base address of the mpfs system register.
- * @clk_rate: the mpfs pll clock rate.
- * @parent_name: a pointer to parent clock name.
+ * @parent: a pointer to parent clock.
* Return: zero on success, or a negative error code.
*/
-int mpfs_clk_register_cfgs(void __iomem *base, u32 clk_rate,
- const char *parent_name);
+int mpfs_clk_register_cfgs(void __iomem *base, struct clk *parent);
/**
* mpfs_clk_register_periphs() - register peripheral clocks
*
* @base: base address of the mpfs system register.
- * @clk_rate: the mpfs pll clock rate.
- * @parent_name: a pointer to parent clock name.
+ * @parent: a pointer to parent clock.
* Return: zero on success, or a negative error code.
*/
-int mpfs_clk_register_periphs(void __iomem *base, u32 clk_rate,
- const char *parent_name);
+int mpfs_clk_register_periphs(void __iomem *base, struct clk *parent);
/**
* divider_get_val() - get the clock divider value
*
CLK_CFG(CLK_AHB, "clk_ahb", 4, 2, mpfs_div_ahb_table, 0),
};
-int mpfs_clk_register_cfgs(void __iomem *base, u32 clk_rate,
- const char *parent_name)
+int mpfs_clk_register_cfgs(void __iomem *base, struct clk *parent)
{
int ret;
int i, id, num_clks;
for (i = 0; i < num_clks; i++) {
hw = &mpfs_cfg_clks[i].hw;
mpfs_cfg_clks[i].sys_base = base;
- mpfs_cfg_clks[i].prate = clk_rate;
+ mpfs_cfg_clks[i].prate = clk_get_rate(parent);
name = mpfs_cfg_clks[i].cfg.name;
- ret = clk_register(hw, MPFS_CFG_CLOCK, name, parent_name);
+ ret = clk_register(hw, MPFS_CFG_CLOCK, name, parent->dev->name);
if (ret)
ERR_PTR(ret);
id = mpfs_cfg_clks[i].cfg.id;
static ulong mpfs_periph_clk_recalc_rate(struct clk *hw)
{
struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
- void __iomem *base_addr = periph_hw->sys_base;
- unsigned long rate;
- u32 val;
- val = readl(base_addr + REG_CLOCK_CONFIG_CR) >> CFG_AHB_SHIFT;
- val &= clk_div_mask(CFG_WIDTH);
- rate = periph_hw->prate / (1u << val);
- hw->rate = rate;
+ return periph_hw->prate;
- return rate;
}
#define CLK_PERIPH(_id, _name, _shift, _flags) { \
CLK_PERIPH(CLK_CFM, "clk_periph_cfm", 29, 0),
};
-int mpfs_clk_register_periphs(void __iomem *base, u32 clk_rate,
- const char *parent_name)
+int mpfs_clk_register_periphs(void __iomem *base, struct clk *parent)
{
int ret;
int i, id, num_clks;
for (i = 0; i < num_clks; i++) {
hw = &mpfs_periph_clks[i].hw;
mpfs_periph_clks[i].sys_base = base;
- mpfs_periph_clks[i].prate = clk_rate;
+ mpfs_periph_clks[i].prate = clk_get_rate(parent);
name = mpfs_periph_clks[i].periph.name;
- ret = clk_register(hw, MPFS_PERIPH_CLOCK, name, parent_name);
+ ret = clk_register(hw, MPFS_PERIPH_CLOCK, name, parent->dev->name);
if (ret)
ERR_PTR(ret);
id = mpfs_periph_clks[i].periph.id;