From 5d729f96299321af2c132fae4b56306e19a3f52b Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 7 Sep 2020 17:46:38 +0300 Subject: [PATCH] clk: at91: pmc: add helpers for clock drivers Add helper for clock drivers. These will be used by following commits in the process of switching AT91 clock drivers to CCF. Signed-off-by: Claudiu Beznea --- drivers/clk/at91/pmc.c | 91 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/at91/pmc.h | 13 ++++++ 2 files changed, 104 insertions(+) diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index ca90abef2d..e403baea0e 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -120,3 +120,94 @@ int at91_clk_probe(struct udevice *dev) return 0; } + +/** + * pmc_read() - read content at address base + off into val + * + * @base: base address + * @off: offset to read from + * @val: where the content of base + off is stored + * + * @return: void + */ +void pmc_read(void __iomem *base, unsigned int off, unsigned int *val) +{ + *val = readl(base + off); +} + +/** + * pmc_write() - write content of val at address base + off + * + * @base: base address + * @off: offset to write to + * @val: content to be written at base + off + * + * @return: void + */ +void pmc_write(void __iomem *base, unsigned int off, unsigned int val) +{ + writel(val, base + off); +} + +/** + * pmc_update_bits() - update a set of bits at address base + off + * + * @base: base address + * @off: offset to be updated + * @mask: mask of bits to be updated + * @bits: the new value to be updated + * + * @return: void + */ +void pmc_update_bits(void __iomem *base, unsigned int off, + unsigned int mask, unsigned int bits) +{ + unsigned int tmp; + + tmp = readl(base + off); + tmp &= ~mask; + writel(tmp | (bits & mask), base + off); +} + +/** + * at91_clk_mux_val_to_index() - get parent index in mux table + * + * @table: clock mux table + * @num_parents: clock number of parents + * @val: clock id who's mux index should be retrieved + * + * @return: clock index in mux table or a negative error number in case of + * failure + */ +int at91_clk_mux_val_to_index(const u32 *table, u32 num_parents, u32 val) +{ + int i; + + if (!table || !num_parents) + return -EINVAL; + + for (i = 0; i < num_parents; i++) { + if (table[i] == val) + return i; + } + + return -EINVAL; +} + +/** + * at91_clk_mux_index_to_val() - get parent ID corresponding to an entry in + * clock's mux table + * + * @table: clock's mux table + * @num_parents: clock's number of parents + * @index: index in mux table which clock's ID should be retrieved + * + * @return: clock ID or a negative error number in case of failure + */ +int at91_clk_mux_index_to_val(const u32 *table, u32 num_parents, u32 index) +{ + if (!table || !num_parents || index < 0 || index > num_parents) + return -EINVAL; + + return table[index]; +} diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 517ba1d6b4..b1ab0a95c8 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -8,6 +8,12 @@ #define __AT91_PMC_H__ #include +#include +#include + +/* Keep a range of 256 available clocks for every clock type. */ +#define AT91_TO_CLK_ID(_t, _i) (((_t) << 8) | ((_i) & 0xff)) +#define AT91_CLK_ID_TO_DID(_i) ((_i) & 0xff) struct pmc_platdata { struct at91_pmc *reg_base; @@ -20,4 +26,11 @@ int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name); int at91_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args); int at91_clk_probe(struct udevice *dev); +int at91_clk_mux_val_to_index(const u32 *table, u32 num_parents, u32 val); +int at91_clk_mux_index_to_val(const u32 *table, u32 num_parents, u32 index); + +void pmc_read(void __iomem *base, unsigned int off, unsigned int *val); +void pmc_write(void __iomem *base, unsigned int off, unsigned int val); +void pmc_update_bits(void __iomem *base, unsigned int off, unsigned int mask, + unsigned int bits); #endif