diff options
author | Tom Rini <trini@konsulko.com> | 2021-01-18 08:04:28 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-01-18 08:04:28 -0500 |
commit | 59e4e391df8c254299b1342c3cfa3390e9f1e895 (patch) | |
tree | 2dcb7f6fc8b1caab173f2abdbe78f368d254d08c /drivers/clk/microchip/mpfs_clk.c | |
parent | b5b0237d0216db34605ca54b83588fcfcf5e63a8 (diff) | |
parent | 9e550e18305fb31af83bfb72d16e86d8c054fb65 (diff) | |
download | u-boot-59e4e391df8c254299b1342c3cfa3390e9f1e895.tar.gz |
Merge https://gitlab.denx.de/u-boot/custodians/u-boot-riscvWIP/18Jan2021
- Update qemu-riscv.rst build instructions.
- Add support for SPI on Kendryte K210.
- Add Microchip PolarFire SoC Icicle Kit support.
- Add support for an early timer.
- Select TIMER_EARLY to avoid infinite recursion for Trace.
Diffstat (limited to 'drivers/clk/microchip/mpfs_clk.c')
-rw-r--r-- | drivers/clk/microchip/mpfs_clk.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/drivers/clk/microchip/mpfs_clk.c b/drivers/clk/microchip/mpfs_clk.c new file mode 100644 index 0000000000..722c79b7c0 --- /dev/null +++ b/drivers/clk/microchip/mpfs_clk.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Microchip Technology Inc. + * Padmarao Begari <padmarao.begari@microchip.com> + */ +#include <common.h> +#include <clk.h> +#include <clk-uclass.h> +#include <dm.h> +#include <log.h> +#include <dm/device.h> +#include <dm/devres.h> +#include <dm/uclass.h> +#include <linux/err.h> + +#include "mpfs_clk.h" + +/* All methods are delegated to CCF clocks */ + +static ulong mpfs_clk_get_rate(struct clk *clk) +{ + struct clk *c; + int err = clk_get_by_id(clk->id, &c); + + if (err) + return err; + return clk_get_rate(c); +} + +static ulong mpfs_clk_set_rate(struct clk *clk, unsigned long rate) +{ + struct clk *c; + int err = clk_get_by_id(clk->id, &c); + + if (err) + return err; + return clk_set_rate(c, rate); +} + +static int mpfs_clk_set_parent(struct clk *clk, struct clk *parent) +{ + struct clk *c, *p; + int err = clk_get_by_id(clk->id, &c); + + if (err) + return err; + + err = clk_get_by_id(parent->id, &p); + if (err) + return err; + + return clk_set_parent(c, p); +} + +static int mpfs_clk_endisable(struct clk *clk, bool enable) +{ + struct clk *c; + int err = clk_get_by_id(clk->id, &c); + + if (err) + return err; + return enable ? clk_enable(c) : clk_disable(c); +} + +static int mpfs_clk_enable(struct clk *clk) +{ + return mpfs_clk_endisable(clk, true); +} + +static int mpfs_clk_disable(struct clk *clk) +{ + return mpfs_clk_endisable(clk, false); +} + +static int mpfs_clk_probe(struct udevice *dev) +{ + int ret; + void __iomem *base; + u32 clk_rate; + const char *parent_clk_name; + struct clk *clk = dev_get_priv(dev); + + base = dev_read_addr_ptr(dev); + if (!base) + return -EINVAL; + + ret = clk_get_by_index(dev, 0, 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); + if (ret) + return ret; + + ret = mpfs_clk_register_periphs(base, clk_rate, "clk_ahb"); + + return ret; +} + +static const struct clk_ops mpfs_clk_ops = { + .set_rate = mpfs_clk_set_rate, + .get_rate = mpfs_clk_get_rate, + .set_parent = mpfs_clk_set_parent, + .enable = mpfs_clk_enable, + .disable = mpfs_clk_disable, +}; + +static const struct udevice_id mpfs_of_match[] = { + { .compatible = "microchip,mpfs-clkcfg" }, + { } +}; + +U_BOOT_DRIVER(mpfs_clk) = { + .name = "mpfs_clk", + .id = UCLASS_CLK, + .of_match = mpfs_of_match, + .ops = &mpfs_clk_ops, + .probe = mpfs_clk_probe, + .priv_auto = sizeof(struct clk), +}; |