[PATCH 1/2] clk: Check that composite clock's div has set_rate()
It's possible for composite clocks to have a divider that does not implement set_rate() operation. For example, sandbox_clk_composite() registers composite clock with a divider that only has get_rate(). Currently clk_composite_set_rate() only checks thate rate_ops are present, so for sandbox it will cause NULL dereference during clk_set_rate(). This patch adds rate_ops->set_rate check tp clk_composite_set_rate(). Signed-off-by: Igor Prusov --- drivers/clk/clk-composite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 6eb2b8133a..d2e5a1ae40 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -66,7 +66,7 @@ static ulong clk_composite_set_rate(struct clk *clk, unsigned long rate) const struct clk_ops *rate_ops = composite->rate_ops; struct clk *clk_rate = composite->rate; - if (rate && rate_ops) + if (rate && rate_ops && rate_ops->set_rate) return rate_ops->set_rate(clk_rate, rate); else return clk_get_rate(clk); -- 2.34.1
[PATCH 2/2] dm: test: clk: Add test for ccf clk_set_rate()
Add a simple test case which sets clock rate to its current value. Signed-off-by: Igor Prusov --- test/dm/clk_ccf.c | 9 + 1 file changed, 9 insertions(+) diff --git a/test/dm/clk_ccf.c b/test/dm/clk_ccf.c index e4ebb93cda..3b23982541 100644 --- a/test/dm/clk_ccf.c +++ b/test/dm/clk_ccf.c @@ -63,6 +63,9 @@ static int dm_test_clk_ccf(struct unit_test_state *uts) rate = clk_get_parent_rate(clk); ut_asserteq(rate, 6000); + rate = clk_set_rate(clk, 6000); + ut_asserteq(rate, -ENOSYS); + rate = clk_get_rate(clk); ut_asserteq(rate, 6000); @@ -87,6 +90,9 @@ static int dm_test_clk_ccf(struct unit_test_state *uts) ut_asserteq_str("pll3_80m", pclk->dev->name); ut_asserteq(CLK_SET_RATE_PARENT, pclk->flags); + rate = clk_set_rate(clk, 8000); + ut_asserteq(rate, -ENOSYS); + rate = clk_get_rate(clk); ut_asserteq(rate, 8000); @@ -108,6 +114,9 @@ static int dm_test_clk_ccf(struct unit_test_state *uts) rate = clk_get_rate(clk); ut_asserteq(rate, 6000); + rate = clk_set_rate(clk, 6000); + ut_asserteq(rate, 6000); + #if CONFIG_IS_ENABLED(CLK_CCF) /* Test clk tree enable/disable */ ret = clk_get_by_id(SANDBOX_CLK_I2C_ROOT, &clk); -- 2.34.1
[PATCH 0/2] Fix NULL dereference in clk_composite_set_rate()
On sandbox it's possible to trigger NULL dereference when setting rate of a composite clock. It happens because sandbox composite divider does not implement set_rate() operation. This series adds NULL check and a test cases for clk_set_rate(). Igor Prusov (2): clk: Check that composite clock's div has set_rate() dm: test: clk: Add test for ccf clk_set_rate() drivers/clk/clk-composite.c | 2 +- test/dm/clk_ccf.c | 9 + 2 files changed, 10 insertions(+), 1 deletion(-) -- 2.34.1
[PATCH 00/13] Import "string" I/O functions from Linux
This series imports generic versions of ioread_rep/iowrite_rep and reads/writes from Linux. Some cleanup is done to make sure that all platforms have proper defines for implemented functions and there are no redefinitions. Igor Prusov (13): sandbox: move asm-generic include to the end of file x86: Add defines for ins/outs functions mips: io.h: Add const to reads functions params mips: io.h: Add defines for read/write/in/out functions riscv: io.h: Add defines for reads/writes functions riscv: io.h: Fix signatures of reads/writes functions nios2: io.h: Add defines for ins/outs functions powerpc: io.h: Add defines for __raw_{read,write} functions xtensa: io.h: Add defines for ins/outs functions asm-generic: Import functions from Linux spi: meson_spifc_a1: Switch to io{read,write}32_rep() treewide: Include linux/io.h instead of asm-generic/io.h musb-new: Remove implementation of io.h functions arch/mips/include/asm/io.h | 35 +- arch/nios2/include/asm/io.h | 6 + arch/powerpc/include/asm/io.h| 11 + arch/riscv/include/asm/io.h | 26 +- arch/sandbox/include/asm/io.h| 28 +- arch/x86/include/asm/io.h| 6 + arch/xtensa/include/asm/io.h | 6 + drivers/mtd/nand/raw/atmel/nand-controller.c | 34 -- drivers/mtd/nand/raw/nand_base.c | 33 -- drivers/spi/cadence_qspi.c | 2 +- drivers/spi/meson_spifc_a1.c | 4 +- drivers/usb/cdns3/cdns3-ti.c | 1 - drivers/usb/dwc3/dwc3-meson-g12a.c | 2 +- drivers/usb/dwc3/dwc3-meson-gxl.c| 2 +- drivers/usb/musb-new/musb_io.h | 24 -- include/asm-generic/io.h | 348 +++ 16 files changed, 450 insertions(+), 118 deletions(-) -- 2.34.1
[PATCH 13/13] musb-new: Remove implementation of io.h functions
Since {read,write}s{l, w, b}() functions are now supported in linux/io.h there is no need to add custom implementation to driver. Signed-off-by: Igor Prusov --- drivers/usb/musb-new/musb_io.h | 24 1 file changed, 24 deletions(-) diff --git a/drivers/usb/musb-new/musb_io.h b/drivers/usb/musb-new/musb_io.h index 72a5365632..19b12f36a5 100644 --- a/drivers/usb/musb-new/musb_io.h +++ b/drivers/usb/musb-new/musb_io.h @@ -14,31 +14,7 @@ #ifndef __MUSB_LINUX_PLATFORM_ARCH_H__ #define __MUSB_LINUX_PLATFORM_ARCH_H__ -#ifndef __UBOOT__ #include -#else -#include -#endif - -#if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \ - && !defined(CONFIG_PPC32) \ - && !defined(CONFIG_PPC64) && !defined(CONFIG_MIPS) \ - && !defined(CONFIG_M68K) -static inline void readsl(const void __iomem *addr, void *buf, int len) - { insl((unsigned long)addr, buf, len); } -static inline void readsw(const void __iomem *addr, void *buf, int len) - { insw((unsigned long)addr, buf, len); } -static inline void readsb(const void __iomem *addr, void *buf, int len) - { insb((unsigned long)addr, buf, len); } - -static inline void writesl(const void __iomem *addr, const void *buf, int len) - { outsl((unsigned long)addr, buf, len); } -static inline void writesw(const void __iomem *addr, const void *buf, int len) - { outsw((unsigned long)addr, buf, len); } -static inline void writesb(const void __iomem *addr, const void *buf, int len) - { outsb((unsigned long)addr, buf, len); } - -#endif /* NOTE: these offsets are all in bytes */ -- 2.34.1
[PATCH 12/13] treewide: Include linux/io.h instead of asm-generic/io.h
Directly including asm-generic/io.h may break build because it will cause redefenition of generic io macros if linux/io.h gets included later, hence replace it with direct include of linux/io.h Signed-off-by: Igor Prusov --- drivers/spi/cadence_qspi.c | 2 +- drivers/usb/cdns3/cdns3-ti.c | 1 - drivers/usb/dwc3/dwc3-meson-g12a.c | 2 +- drivers/usb/dwc3/dwc3-meson-gxl.c | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index cc3a54f295..23240c1302 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -17,6 +16,7 @@ #include #include #include +#include #include #include #include "cadence_qspi.h" diff --git a/drivers/usb/cdns3/cdns3-ti.c b/drivers/usb/cdns3/cdns3-ti.c index 92a7941ed1..2e44aadea4 100644 --- a/drivers/usb/cdns3/cdns3-ti.c +++ b/drivers/usb/cdns3/cdns3-ti.c @@ -6,7 +6,6 @@ */ #include -#include #include #include #include diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c index e0356e653f..196035215a 100644 --- a/drivers/usb/dwc3/dwc3-meson-g12a.c +++ b/drivers/usb/dwc3/dwc3-meson-g12a.c @@ -8,13 +8,13 @@ #include #include -#include #include #include #include #include #include #include +#include #include #include #include diff --git a/drivers/usb/dwc3/dwc3-meson-gxl.c b/drivers/usb/dwc3/dwc3-meson-gxl.c index d56f2747b6..cbe8aaa005 100644 --- a/drivers/usb/dwc3/dwc3-meson-gxl.c +++ b/drivers/usb/dwc3/dwc3-meson-gxl.c @@ -8,12 +8,12 @@ #define DEBUG #include -#include #include #include #include #include #include +#include #include #include #include -- 2.34.1
[PATCH 11/13] spi: meson_spifc_a1: Switch to io{read,write}32_rep()
Use io{read,write}32_rep() functions to sync code with Linux version. Signed-off-by: Igor Prusov --- drivers/spi/meson_spifc_a1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/meson_spifc_a1.c b/drivers/spi/meson_spifc_a1.c index 099c4c037d..a33b1a3879 100644 --- a/drivers/spi/meson_spifc_a1.c +++ b/drivers/spi/meson_spifc_a1.c @@ -129,7 +129,7 @@ static void amlogic_spifc_a1_drain_buffer(struct amlogic_spifc_a1 *spifc, writel(SPIFC_A1_DBUF_AUTO_UPDATE_ADDR, spifc->base + SPIFC_A1_DBUF_CTRL_REG); - readsl(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); + ioread32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); if (pad) { data = readl(spifc->base + SPIFC_A1_DBUF_DATA_REG); @@ -146,7 +146,7 @@ static void amlogic_spifc_a1_fill_buffer(struct amlogic_spifc_a1 *spifc, writel(SPIFC_A1_DBUF_DIR | SPIFC_A1_DBUF_AUTO_UPDATE_ADDR, spifc->base + SPIFC_A1_DBUF_CTRL_REG); - writesl(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); + iowrite32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); if (pad) { memcpy(&data, buf + len - pad, pad); -- 2.34.1
[PATCH 10/13] asm-generic: Import functions from Linux
Currently {read,write}s{b,w,lq}() functions are available only on some architectures, and there are no io{read,write}{8,16,32,64}_rep() functions in u-boot. This patch adds generic versions that may be used without arch-specific implementation. Since some of added functions were already added locally in some files, remove them to avoid redeclaration errors. Signed-off-by: Igor Prusov --- drivers/mtd/nand/raw/atmel/nand-controller.c | 34 -- drivers/mtd/nand/raw/nand_base.c | 33 -- include/asm-generic/io.h | 348 +++ 3 files changed, 348 insertions(+), 67 deletions(-) diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index fa962ba591..37b0c3a5cd 100644 --- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -352,40 +352,6 @@ static int atmel_nfc_wait(struct atmel_hsmc_nand_controller *nc, bool poll, return ret; } -static void iowrite8_rep(void *addr, const uint8_t *buf, int len) -{ - int i; - - for (i = 0; i < len; i++) - writeb(buf[i], addr); -} - -static void ioread8_rep(void *addr, uint8_t *buf, int len) -{ - int i; - - for (i = 0; i < len; i++) - buf[i] = readb(addr); -} - -static void ioread16_rep(void *addr, void *buf, int len) -{ - int i; - u16 *p = (u16 *)buf; - - for (i = 0; i < len; i++) - p[i] = readw(addr); -} - -static void iowrite16_rep(void *addr, const void *buf, int len) -{ - int i; - u16 *p = (u16 *)buf; - - for (i = 0; i < len; i++) - writew(p[i], addr); -} - static u8 atmel_nand_read_byte(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 6b4adcf6bd..815ddf5d8d 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -245,39 +245,6 @@ static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte) chip->write_buf(mtd, (uint8_t *)&word, 2); } -static void iowrite8_rep(void *addr, const uint8_t *buf, int len) -{ - int i; - - for (i = 0; i < len; i++) - writeb(buf[i], addr); -} -static void ioread8_rep(void *addr, uint8_t *buf, int len) -{ - int i; - - for (i = 0; i < len; i++) - buf[i] = readb(addr); -} - -static void ioread16_rep(void *addr, void *buf, int len) -{ - int i; - u16 *p = (u16 *) buf; - - for (i = 0; i < len; i++) - p[i] = readw(addr); -} - -static void iowrite16_rep(void *addr, void *buf, int len) -{ - int i; -u16 *p = (u16 *) buf; - -for (i = 0; i < len; i++) -writew(p[i], addr); -} - /** * nand_write_buf - [DEFAULT] write buffer to chip * @mtd: MTD device structure diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index 7a2f0dba31..13d99cfb59 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h @@ -105,5 +105,353 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) } #endif +/* + * __raw_{read,write}{b,w,l,q}() access memory in native endianness. + * + * On some architectures memory mapped IO needs to be accessed differently. + * On the simple architectures, we just read/write the memory location + * directly. + */ + +#ifndef __raw_readb +#define __raw_readb __raw_readb +static inline u8 __raw_readb(const volatile void __iomem *addr) +{ + return *(const volatile u8 __force *)addr; +} +#endif + +#ifndef __raw_readw +#define __raw_readw __raw_readw +static inline u16 __raw_readw(const volatile void __iomem *addr) +{ + return *(const volatile u16 __force *)addr; +} +#endif + +#ifndef __raw_readl +#define __raw_readl __raw_readl +static inline u32 __raw_readl(const volatile void __iomem *addr) +{ + return *(const volatile u32 __force *)addr; +} +#endif + +#ifdef CONFIG_64BIT +#ifndef __raw_readq +#define __raw_readq __raw_readq +static inline u64 __raw_readq(const volatile void __iomem *addr) +{ + return *(const volatile u64 __force *)addr; +} +#endif +#endif /* CONFIG_64BIT */ + +#ifndef __raw_writeb +#define __raw_writeb __raw_writeb +static inline void __raw_writeb(u8 value, volatile void __iomem *addr) +{ + *(volatile u8 __force *)addr = value; +} +#endif + +#ifndef __raw_writew +#define __raw_writew __raw_writew +static inline void __raw_writew(u16 value, volatile void __iomem *addr) +{ + *(volatile u16 __force *)addr = value; +} +#endif + +#ifndef __raw_writel +#define __raw_writel __raw_writel +static inline void __raw_writel(u32 value, volatile void __iomem *addr) +{ + *(volatile u32 __force *)addr = value; +} +#endif + +#ifdef CONFIG_64BIT +#ifndef __raw_writeq +#define __raw_writeq __raw_writeq +static inline void __raw_writeq(u64 value, volatile void __iomem *addr) +{ +
[PATCH 09/13] xtensa: io.h: Add defines for ins/outs functions
Add defines for {in,out}s{b,w,l}() functions to make asm-generic/io.h aware of them. Signed-off-by: Igor Prusov --- arch/xtensa/include/asm/io.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h index 76a646e882..87ad9faa29 100644 --- a/arch/xtensa/include/asm/io.h +++ b/arch/xtensa/include/asm/io.h @@ -76,6 +76,12 @@ void insl(unsigned long port, void *dst, unsigned long count); void outsb(unsigned long port, const void *src, unsigned long count); void outsw(unsigned long port, const void *src, unsigned long count); void outsl(unsigned long port, const void *src, unsigned long count); +#define insb insb +#define insw insw +#define insl insl +#define outsb outsb +#define outsw outsw +#define outsl outsl #define IO_SPACE_LIMIT ~0 -- 2.34.1
[PATCH 08/13] powerpc: io.h: Add defines for __raw_{read, write} functions
Add defines for __raw_{read,write}{b,w,l}() functions to make make asm-generic/io.h aware of them. Signed-off-by: Igor Prusov --- arch/powerpc/include/asm/io.h | 11 +++ 1 file changed, 11 insertions(+) diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index f63cae0bc8..2412bb9d7c 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -138,26 +138,37 @@ static inline unsigned char __raw_readb(const volatile void __iomem *addr) { return *(volatile unsigned char *)PCI_FIX_ADDR(addr); } +#define __raw_readb __raw_readb + static inline unsigned short __raw_readw(const volatile void __iomem *addr) { return *(volatile unsigned short *)PCI_FIX_ADDR(addr); } +#define __raw_readw __raw_readw + static inline unsigned int __raw_readl(const volatile void __iomem *addr) { return *(volatile unsigned int *)PCI_FIX_ADDR(addr); } +#define __raw_readl __raw_readl + static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr) { *(volatile unsigned char *)PCI_FIX_ADDR(addr) = v; } +#define __raw_writeb __raw_writeb + static inline void __raw_writew(unsigned short v, volatile void __iomem *addr) { *(volatile unsigned short *)PCI_FIX_ADDR(addr) = v; } +#define __raw_writew __raw_writew + static inline void __raw_writel(unsigned int v, volatile void __iomem *addr) { *(volatile unsigned int *)PCI_FIX_ADDR(addr) = v; } +#define __raw_writel __raw_writel /* * 8, 16 and 32 bit, big and little endian I/O operations, with barrier. -- 2.34.1
[PATCH 07/13] nios2: io.h: Add defines for ins/outs functions
Add defines for {in,out}s{b,w,l} functions to make asm-generic/io.h aware of them. Signed-off-by: Igor Prusov --- arch/nios2/include/asm/io.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/nios2/include/asm/io.h b/arch/nios2/include/asm/io.h index 817cd72e00..321e4fd1ca 100644 --- a/arch/nios2/include/asm/io.h +++ b/arch/nios2/include/asm/io.h @@ -94,6 +94,9 @@ static inline void insl (unsigned long port, void *dst, unsigned long count) unsigned long *p = dst; while (count--) *p++ = inl (port); } +#define insb insb +#define insw insw +#define insl insl static inline void outsb (unsigned long port, const void *src, unsigned long count) { @@ -111,6 +114,9 @@ static inline void outsl (unsigned long port, const void *src, unsigned long cou const unsigned long *p = src; while (count--) outl (*p++, port); } +#define outsb outsb +#define outsw outsw +#define outsl outsl /* * Clear and set bits in one shot. These macros can be used to clear and -- 2.34.1
[PATCH 06/13] riscv: io.h: Fix signatures of reads/writes functions
Change type of address parameter from int* to volatile void* for {read,write}s{b,w,l}() functions and add const qualifier for reads. This is done to keep function signatures in sync with asm-generic/io.h and other platforms. Signed-off-by: Igor Prusov --- arch/riscv/include/asm/io.h | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h index cedd5375d6..da16585803 100644 --- a/arch/riscv/include/asm/io.h +++ b/arch/riscv/include/asm/io.h @@ -218,7 +218,8 @@ static inline u64 readq(const volatile void __iomem *addr) #define insw(p, d, l) readsw(__io(p), d, l) #define insl(p, d, l) readsl(__io(p), d, l) -static inline void readsb(unsigned int *addr, void *data, int bytelen) +static inline void readsb(const volatile void __iomem *addr, void *data, + unsigned int bytelen) { unsigned char *ptr; unsigned char *ptr2; @@ -233,7 +234,8 @@ static inline void readsb(unsigned int *addr, void *data, int bytelen) } } -static inline void readsw(unsigned int *addr, void *data, int wordlen) +static inline void readsw(const volatile void __iomem *addr, void *data, + unsigned int wordlen) { unsigned short *ptr; unsigned short *ptr2; @@ -248,7 +250,8 @@ static inline void readsw(unsigned int *addr, void *data, int wordlen) } } -static inline void readsl(unsigned int *addr, void *data, int longlen) +static inline void readsl(const volatile void __iomem *addr, void *data, + unsigned int longlen) { unsigned int *ptr; unsigned int *ptr2; @@ -263,7 +266,8 @@ static inline void readsl(unsigned int *addr, void *data, int longlen) } } -static inline void writesb(unsigned int *addr, const void *data, int bytelen) +static inline void writesb(volatile void __iomem *addr, const void *data, + unsigned int bytelen) { unsigned char *ptr; unsigned char *ptr2; @@ -278,7 +282,8 @@ static inline void writesb(unsigned int *addr, const void *data, int bytelen) } } -static inline void writesw(unsigned int *addr, const void *data, int wordlen) +static inline void writesw(volatile void __iomem *addr, const void *data, + unsigned int wordlen) { unsigned short *ptr; unsigned short *ptr2; @@ -293,7 +298,8 @@ static inline void writesw(unsigned int *addr, const void *data, int wordlen) } } -static inline void writesl(unsigned int *addr, const void *data, int longlen) +static inline void writesl(volatile void __iomem *addr, const void *data, + unsigned int longlen) { unsigned int *ptr; unsigned int *ptr2; -- 2.34.1
[PATCH 05/13] riscv: io.h: Add defines for reads/writes functions
Add defines for {read,write}s{b,w,l} functions to make asm-generic/io.h aware of them. Signed-off-by: Igor Prusov --- arch/riscv/include/asm/io.h | 8 1 file changed, 8 insertions(+) diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h index 4170877a1a..cedd5375d6 100644 --- a/arch/riscv/include/asm/io.h +++ b/arch/riscv/include/asm/io.h @@ -307,6 +307,14 @@ static inline void writesl(unsigned int *addr, const void *data, int longlen) longlen--; } } + +#define readsb readsb +#define readsw readsw +#define readsl readsl +#define writesb writesb +#define writesw writesw +#define writesl writesl + #endif #define outb_p(val, port) outb((val), (port)) -- 2.34.1
[PATCH 04/13] mips: io.h: Add defines for read/write/in/out functions
Add defines for {read,write}{b,w,l,q}(), {read,write}s{b,w,l,q}() and {in,out}s{b,w,l,q}() functions to make asm-generic/io.h aware of them. Signed-off-by: Igor Prusov --- arch/mips/include/asm/io.h | 32 1 file changed, 32 insertions(+) diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 12595c4334..3774acaadc 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -336,6 +336,22 @@ BUILDIO_MEM(b, u8) BUILDIO_MEM(w, u16) BUILDIO_MEM(l, u32) BUILDIO_MEM(q, u64) +#define __raw_readb __raw_readb +#define __raw_readw __raw_readw +#define __raw_readl __raw_readl +#define __raw_readq __raw_readq +#define __raw_writeb __raw_writeb +#define __raw_writew __raw_writew +#define __raw_writel __raw_writel +#define __raw_writeq __raw_writeq +#define readb readb +#define readw readw +#define readl readl +#define readq readq +#define writeb writeb +#define writew writew +#define writel writel +#define writeq writeq #define __BUILD_IOPORT_PFX(bus, bwlq, type)\ __BUILD_IOPORT_SINGLE(bus, bwlq, type, )\ @@ -449,8 +465,24 @@ __BUILD_IOPORT_STRING(bwlq, type) BUILDSTRING(b, u8) BUILDSTRING(w, u16) BUILDSTRING(l, u32) +#define readsb readsb +#define readsw readsw +#define readsl readsl +#define writesb writesb +#define writesw writesw +#define writesl writesl +#define outsb outsb +#define outsw outsw +#define outsl outsl +#define insb insb +#define insw insw +#define insl insl #ifdef CONFIG_64BIT BUILDSTRING(q, u64) +#define readsq readsq +#define writesq writesq +#define insq insq +#define outsq outsq #endif -- 2.34.1
[PATCH 03/13] mips: io.h: Add const to reads functions params
Currently reads{b,w,l}() functions don't have const qualifier for their address parameter. Since asm-generic/io.h in Linux has const for all read functions, add it here as well to keep signatures in sync. Signed-off-by: Igor Prusov --- arch/mips/include/asm/io.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index d3ad669301..12595c4334 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -405,7 +405,8 @@ static inline void writes##bwlq(volatile void __iomem *mem, \ } \ } \ \ -static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \ +static inline void reads##bwlq(const volatile void __iomem *mem, \ + void *addr, \ unsigned int count) \ { \ volatile type *__addr = addr; \ -- 2.34.1
[PATCH 02/13] x86: Add defines for ins/outs functions
Add defines for {in,out}s{b,w,l}() functions to make sure that they will be used by asm-generic/io.h Signed-off-by: Igor Prusov --- arch/x86/include/asm/io.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 83dc09757e..5efb2e1b21 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -202,10 +202,16 @@ __OUT(l,,int) __INS(b) __INS(w) __INS(l) +#define insb insb +#define insw insw +#define insl insl __OUTS(b) __OUTS(w) __OUTS(l) +#define outsb outsb +#define outsw outsw +#define outsl outsl /* IO space accessors */ #define clrio(type, addr, clear) \ -- 2.34.1
[PATCH 01/13] sandbox: move asm-generic include to the end of file
Generic version of io.h should be included at the end of architecture-specific ones to make sure that arch implementations are used and to avoid redefinitions. Signed-off-by: Igor Prusov --- arch/sandbox/include/asm/io.h | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h index 31ab7289b4..77a02e5f52 100644 --- a/arch/sandbox/include/asm/io.h +++ b/arch/sandbox/include/asm/io.h @@ -28,20 +28,6 @@ void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags); void unmap_physmem(const void *vaddr, unsigned long flags); #define unmap_physmem unmap_physmem -#include - -/* For sandbox, we want addresses to point into our RAM buffer */ -static inline void *map_sysmem(phys_addr_t paddr, unsigned long len) -{ - return map_physmem(paddr, len, MAP_WRBACK); -} - -/* Remove a previous mapping */ -static inline void unmap_sysmem(const void *vaddr) -{ - unmap_physmem(vaddr, MAP_WRBACK); -} - /* Map from a pointer to our RAM buffer */ phys_addr_t map_to_sysmem(const void *ptr); @@ -229,5 +215,19 @@ static inline void memcpy_toio(volatile void *dst, const void *src, int count) #include #include +#include + +/* For sandbox, we want addresses to point into our RAM buffer */ +static inline void *map_sysmem(phys_addr_t paddr, unsigned long len) +{ + return map_physmem(paddr, len, MAP_WRBACK); +} + +/* Remove a previous mapping */ +static inline void unmap_sysmem(const void *vaddr) +{ + unmap_physmem(vaddr, MAP_WRBACK); +} + #endif -- 2.34.1
Re: [PATCH] clk: meson: add Hardware Clock measure driver
_ID(19, "lcd_an_ph2"), > + CLK_MSR_ID(20, "rtc_osc_out"), > + CLK_MSR_ID(21, "lcd_an_ph3"), > + CLK_MSR_ID(22, "eth_phy_ref"), > + CLK_MSR_ID(23, "mpll_50m"), > + CLK_MSR_ID(24, "eth_125m"), > + CLK_MSR_ID(25, "eth_rmii"), > + CLK_MSR_ID(26, "sc_int"), > + CLK_MSR_ID(27, "in_mac"), > + CLK_MSR_ID(28, "sar_adc"), > + CLK_MSR_ID(29, "pcie_inp"), > + CLK_MSR_ID(30, "pcie_inn"), > + CLK_MSR_ID(31, "mpll_test_out"), > + CLK_MSR_ID(32, "vdec"), > + CLK_MSR_ID(34, "eth_mpll_50m"), > + CLK_MSR_ID(35, "mali"), > + CLK_MSR_ID(36, "hdmi_tx_pixel"), > + CLK_MSR_ID(37, "cdac"), > + CLK_MSR_ID(38, "vdin_meas"), > + CLK_MSR_ID(39, "bt656"), > + CLK_MSR_ID(40, "arm_ring_osc_out_4"), > + CLK_MSR_ID(41, "eth_rx_or_rmii"), > + CLK_MSR_ID(42, "mp0_out"), > + CLK_MSR_ID(43, "fclk_div5"), > + CLK_MSR_ID(44, "pwm_b"), > + CLK_MSR_ID(45, "pwm_a"), > + CLK_MSR_ID(46, "vpu"), > + CLK_MSR_ID(47, "ddr_dpll_pt"), > + CLK_MSR_ID(48, "mp1_out"), > + CLK_MSR_ID(49, "mp2_out"), > + CLK_MSR_ID(50, "mp3_out"), > + CLK_MSR_ID(51, "sd_emmc_c"), > + CLK_MSR_ID(52, "sd_emmc_b"), > + CLK_MSR_ID(53, "sd_emmc_a"), > + CLK_MSR_ID(54, "vpu_clkc"), > + CLK_MSR_ID(55, "vid_pll_div_out"), > + CLK_MSR_ID(56, "wave420l_a"), > + CLK_MSR_ID(57, "wave420l_c"), > + CLK_MSR_ID(58, "wave420l_b"), > + CLK_MSR_ID(59, "hcodec"), > + CLK_MSR_ID(60, "arm_ring_osc_out_5"), > + CLK_MSR_ID(61, "gpio_msr"), > + CLK_MSR_ID(62, "hevcb"), > + CLK_MSR_ID(63, "dsi_meas"), > + CLK_MSR_ID(64, "spicc_1"), > + CLK_MSR_ID(65, "spicc_0"), > + CLK_MSR_ID(66, "vid_lock"), > + CLK_MSR_ID(67, "dsi_phy"), > + CLK_MSR_ID(68, "hdcp22_esm"), > + CLK_MSR_ID(69, "hdcp22_skp"), > + CLK_MSR_ID(70, "pwm_f"), > + CLK_MSR_ID(71, "pwm_e"), > + CLK_MSR_ID(72, "pwm_d"), > + CLK_MSR_ID(73, "pwm_c"), > + CLK_MSR_ID(74, "arm_ring_osc_out_6"), > + CLK_MSR_ID(75, "hevcf"), > + CLK_MSR_ID(76, "arm_ring_osc_out_7"), > + CLK_MSR_ID(77, "rng_ring_osc_0"), > + CLK_MSR_ID(78, "rng_ring_osc_1"), > + CLK_MSR_ID(79, "rng_ring_osc_2"), > + CLK_MSR_ID(80, "rng_ring_osc_3"), > + CLK_MSR_ID(81, "vapb"), > + CLK_MSR_ID(82, "ge2d"), > + CLK_MSR_ID(83, "co_rx"), > + CLK_MSR_ID(84, "co_tx"), > + CLK_MSR_ID(85, "arm_ring_osc_out_8"), > + CLK_MSR_ID(86, "arm_ring_osc_out_9"), > + CLK_MSR_ID(87, "mipi_dsi_phy"), > + CLK_MSR_ID(88, "cis2_adapt"), > + CLK_MSR_ID(89, "hdmi_todig"), > + CLK_MSR_ID(90, "hdmitx_sys"), > + CLK_MSR_ID(91, "nna_core"), > + CLK_MSR_ID(92, "nna_axi"), > + CLK_MSR_ID(93, "vad"), > + CLK_MSR_ID(94, "eth_phy_rx"), > + CLK_MSR_ID(95, "eth_phy_pll"), > + CLK_MSR_ID(96, "vpu_b"), > + CLK_MSR_ID(97, "cpu_b_tmp"), > + CLK_MSR_ID(98, "ts"), > + CLK_MSR_ID(99, "arm_ring_osc_out_10"), > + CLK_MSR_ID(100, "arm_ring_osc_out_11"), > + CLK_MSR_ID(101, "arm_ring_osc_out_12"), > + CLK_MSR_ID(102, "arm_ring_osc_out_13"), > + CLK_MSR_ID(103, "arm_ring_osc_out_14"), > + CLK_MSR_ID(104, "arm_ring_osc_out_15"), > + CLK_MSR_ID(105, "arm_ring_osc_out_16"), > + CLK_MSR_ID(106, "ephy_test"), > + CLK_MSR_ID(107, "au_dac_g128x"), > + CLK_MSR_ID(108, "audio_locker_out"), > + CLK_MSR_ID(109, "audio_locker_in"), > + CLK_MSR_ID(110, "audio_tdmout_c_sclk"), > + CLK_MSR_ID(111, "audio_tdmout_b_sclk"), > + CLK_MSR_ID(112, "audio_tdmout_a_sclk"), > + CLK_MSR_ID(113, "audio_tdmin_lb_sclk"), > + CLK_MSR_ID(114, "audio_tdmin_c_sclk"), > + CLK_MSR_ID(115, "audio_tdmin_b_sclk"), > + CLK_MSR_ID(116, "audio_tdmin_a_sclk"), > + CLK_MSR_ID(117, "audio_resample"), > + CLK_MSR_ID(118, "audio_pdm_sys"), > + CLK_MSR_ID(119, "audio_spdifout_b"), > + CLK_MSR_ID(120, "audio_spdifout"), > + CLK_MSR_ID(121, "audio_spdifin"), > + CLK_MSR_ID(122, "audio_pdm_dclk"), > + CLK_MSR_ID(123, "audio_resampled"), > + CLK_MSR_ID(124, "earcrx_pll"), > + CLK_MSR_ID(125, "earcrx_pll_test"), > + CLK_MSR_ID(126, "csi_phy0"), > + CLK_MSR_ID(127, "csi2_data"), > +}; > + > +static int meson_clk_msr_measure_id(struct meson_msr *priv, unsigned int id, > + unsigned int duration) > +{ > + unsigned int val; > + int ret; > + > + regmap_write(priv->regmap, MSR_CLK_REG0, 0); > + > + /* Set measurement duration */ > + regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_DURATION, > +FIELD_PREP(MSR_DURATION, duration - 1)); > + > + /* Set ID */ > + regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_CLK_SRC, > +FIELD_PREP(MSR_CLK_SRC, id)); > + > + /* Enable & Start */ > + regmap_update_bits(priv->regmap, MSR_CLK_REG0, > +MSR_RUN | MSR_ENABLE, > +MSR_RUN | MSR_ENABLE); > + > + ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0, > +val, !(val & MSR_BUSY), 10, 1); > + if (ret) > + return ret; > + > + /* Disable */ > + regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0); > + > + /* Get the value in multiple of gate time counts */ > + regmap_read(priv->regmap, MSR_CLK_REG2, &val); > + > + if (val >= MSR_VAL_MASK) > + return -EINVAL; > + > + return DIV_ROUND_CLOSEST_ULL((val & MSR_VAL_MASK) * 100ULL, > + duration); > +} > + > +static int meson_clk_msr_best_id(struct meson_msr *priv, unsigned int id, > + unsigned int *precision) > +{ > + unsigned int duration = DIV_MAX; > + int ret; > + > + /* Start from max duration and down to min duration */ > + do { > + ret = meson_clk_msr_measure_id(priv, id, duration); > + if (ret >= 0) > + *precision = (2 * 100) / duration; > + else > + duration -= DIV_STEP; > + } while (duration >= DIV_MIN && ret == -EINVAL); > + > + return ret; > +} > + > +static void meson_clk_msr_dump(struct udevice *dev) > +{ > + struct meson_msr *priv = dev_get_priv(dev); > + unsigned int precision = 0; > + int val, i; > + > + printf(" clock rateprecision\n"); > + printf("-\n"); > + > + for (i = 0 ; i < CLK_MSR_MAX ; ++i) { > + if (!priv->msr_table[i].name) > + continue; > + > + val = meson_clk_msr_best_id(priv, i, &precision); > + if (val < 0) > + return; > + > + printf(" %-20s %10d+/-%dHz\n", > +priv->msr_table[i].name, val, precision); > + } > +} > + > +static int meson_clk_msr_xlate(struct clk *clk, struct ofnode_phandle_args > *args) > +{ > + /* This driver doesn't expose any clocks */ > + return -EINVAL; > +} > + > +static int meson_clk_msr_probe(struct udevice *dev) > +{ > + struct meson_msr *priv = dev_get_priv(dev); > + int ret; > + > + priv->msr_table = (struct meson_msr_id *)dev_get_driver_data(dev); > + > + ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap); > + if (ret) > + return ret; > + > + return 0; > +} > + > +static struct clk_ops meson_clk_msr_ops = { > + .of_xlate = meson_clk_msr_xlate, > + .dump = meson_clk_msr_dump, > +}; > + > +static const struct udevice_id meson_clk_msr_ids[] = { > + { > + .compatible = "amlogic,meson-gx-clk-measure", > + .data = (ulong)clk_msr_gx, > + }, > + { > + .compatible = "amlogic,meson8-clk-measure", > + .data = (ulong)clk_msr_m8, > + }, > + { > + .compatible = "amlogic,meson8b-clk-measure", > + .data = (ulong)clk_msr_m8, > + }, > + { > + .compatible = "amlogic,meson-axg-clk-measure", > + .data = (ulong)clk_msr_axg, > + }, > + { > + .compatible = "amlogic,meson-g12a-clk-measure", > + .data = (ulong)clk_msr_g12a, > + }, > + { > + .compatible = "amlogic,meson-sm1-clk-measure", > + .data = (ulong)clk_msr_sm1, > + }, > + { /* sentinel */ } > +}; > + > +U_BOOT_DRIVER(meson_clk_msr) = { > + .name = "meson_clk_msr", > + .id = UCLASS_CLK, > + .of_match = meson_clk_msr_ids, > + .priv_auto = sizeof(struct meson_msr), > + .ops= &meson_clk_msr_ops, > + .probe = meson_clk_msr_probe, > +}; > > --- > base-commit: 3221d10770b4c288ddb7d83350e1cd86c3b6ef55 > change-id: 20231113-uboot-meson-clk-msr-21cf9101278b > > Best regards, > -- > Neil Armstrong > -- Best Regards, Igor Prusov
[PATCH 3/3] treewide: use linux/time.h for time conversion defines
Now that we have time conversion defines from in time.h there is no need for each driver to define their own version. Signed-off-by: Igor Prusov --- board/friendlyarm/nanopi2/onewire.c | 5 + drivers/clk/at91/clk-main.c | 2 +- drivers/i2c/stm32f7_i2c.c| 11 +-- drivers/memory/stm32-fmc2-ebi.c | 5 ++--- drivers/mmc/octeontx_hsmmc.h | 2 -- drivers/mtd/nand/raw/atmel/nand-controller.c | 3 +-- drivers/mtd/nand/raw/mxs_nand.c | 3 +-- drivers/mtd/nand/raw/octeontx_nand.c | 2 +- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 5 ++--- drivers/phy/meson-axg-mipi-dphy.c| 3 +-- drivers/phy/phy-core-mipi-dphy.c | 3 +-- drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c | 3 +-- drivers/pwm/pwm-aspeed.c | 3 +-- drivers/pwm/pwm-at91.c | 2 +- drivers/pwm/pwm-cadence-ttc.c| 3 +-- drivers/pwm/pwm-meson.c | 3 +-- drivers/pwm/pwm-mtk.c| 3 +-- drivers/pwm/pwm-ti-ehrpwm.c | 3 +-- drivers/serial/serial_msm_geni.c | 3 +-- drivers/spi/cadence_qspi.c | 3 +-- drivers/spi/fsl_dspi.c | 4 +--- drivers/ufs/cdns-platform.c | 3 +-- drivers/usb/dwc3/core.c | 3 +-- drivers/video/dw_mipi_dsi.c | 3 +-- drivers/video/rockchip/dw_mipi_dsi_rockchip.c| 3 +-- drivers/video/tegra20/tegra-dsi.c| 4 +--- drivers/watchdog/sunxi_wdt.c | 3 +-- fs/ubifs/ubifs.h | 1 - 28 files changed, 32 insertions(+), 62 deletions(-) diff --git a/board/friendlyarm/nanopi2/onewire.c b/board/friendlyarm/nanopi2/onewire.c index 56f0f2dfce..4f0b1e33c2 100644 --- a/board/friendlyarm/nanopi2/onewire.c +++ b/board/friendlyarm/nanopi2/onewire.c @@ -11,16 +11,13 @@ #include #include #include +#include #include #include #include -#ifndef NSEC_PER_SEC -#define NSEC_PER_SEC 10L -#endif - #define SAMPLE_BPS 9600 #define SAMPLE_IN_US 101 /* (100 / BPS) */ diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c index b52d926f33..025c7a7aa2 100644 --- a/drivers/clk/at91/clk-main.c +++ b/drivers/clk/at91/clk-main.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "pmc.h" #define UBOOT_DM_CLK_AT91_MAIN_RC "at91-main-rc-clk" @@ -25,7 +26,6 @@ #define UBOOT_DM_CLK_AT91_SAM9X5_MAIN "at91-sam9x5-main-clk" #define MOR_KEY_MASK GENMASK(23, 16) -#define USEC_PER_SEC 100UL #define SLOW_CLOCK_FREQ32768 #define clk_main_parent_select(s) (((s) & \ diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c index b6c71789ee..eaa1d69289 100644 --- a/drivers/i2c/stm32f7_i2c.c +++ b/drivers/i2c/stm32f7_i2c.c @@ -20,6 +20,7 @@ #include #include #include +#include /* STM32 I2C registers */ struct stm32_i2c_regs { @@ -121,8 +122,6 @@ struct stm32_i2c_regs { #define STM32_SCLH_MAX BIT(8) #define STM32_SCLL_MAX BIT(8) -#define STM32_NSEC_PER_SEC 10L - /** * struct stm32_i2c_spec - private i2c specification timing * @rate: I2C bus speed (Hz) @@ -591,7 +590,7 @@ static int stm32_i2c_choose_solution(u32 i2cclk, struct stm32_i2c_timings *s) { struct stm32_i2c_timings *v; - u32 i2cbus = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC, + u32 i2cbus = DIV_ROUND_CLOSEST(NSEC_PER_SEC, setup->speed_freq); u32 clk_error_prev = i2cbus; u32 clk_min, clk_max; @@ -607,8 +606,8 @@ static int stm32_i2c_choose_solution(u32 i2cclk, dnf_delay = setup->dnf * i2cclk; tsync = af_delay_min + dnf_delay + (2 * i2cclk); - clk_max = STM32_NSEC_PER_SEC / specs->rate_min; - clk_min = STM32_NSEC_PER_SEC / specs->rate_max; + clk_max = NSEC_PER_SEC / specs->rate_min; + clk_min = NSEC_PER_SEC / specs->rate_max; /* * Among Prescaler possibilities discovered above figures out SCL Low @@ -686,7 +685,7 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, const struct stm32_i2c_spec *specs; struct stm32_i2c_timings *v, *_v; struct list_head solutions; - u32 i2cclk = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC, setup->clock_src); + u32 i2cclk = DIV_ROUND_CLOSEST(NSEC_PER_SEC, setup->clock_src); int ret; specs = get_specs(setup->speed_freq); diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-e
[PATCH 0/3] Add time conversion defines from Linux.
This series imports time conversion defines from Linux, that are currently located in include/vdso/time64.h file. Those defines are almost always used by including linux/time.h so it seems the proper place in U-Boot to place them. Various places where same or similar defines were added on per-driver basis are replaced with time.h include. Igor Prusov (3): linux/time.h: Add Linux time conversion defines spi: meson_spifc_a1: Use define for time interval treewide: use linux/time.h for time conversion defines board/friendlyarm/nanopi2/onewire.c | 5 + drivers/clk/at91/clk-main.c | 2 +- drivers/i2c/stm32f7_i2c.c| 11 +-- drivers/memory/stm32-fmc2-ebi.c | 5 ++--- drivers/mmc/octeontx_hsmmc.h | 2 -- drivers/mtd/nand/raw/atmel/nand-controller.c | 3 +-- drivers/mtd/nand/raw/mxs_nand.c | 3 +-- drivers/mtd/nand/raw/octeontx_nand.c | 2 +- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 5 ++--- drivers/phy/meson-axg-mipi-dphy.c| 3 +-- drivers/phy/phy-core-mipi-dphy.c | 3 +-- drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c | 3 +-- drivers/pwm/pwm-aspeed.c | 3 +-- drivers/pwm/pwm-at91.c | 2 +- drivers/pwm/pwm-cadence-ttc.c| 3 +-- drivers/pwm/pwm-meson.c | 3 +-- drivers/pwm/pwm-mtk.c| 3 +-- drivers/pwm/pwm-ti-ehrpwm.c | 3 +-- drivers/serial/serial_msm_geni.c | 3 +-- drivers/spi/cadence_qspi.c | 3 +-- drivers/spi/fsl_dspi.c | 4 +--- drivers/spi/meson_spifc_a1.c | 3 ++- drivers/ufs/cdns-platform.c | 3 +-- drivers/usb/dwc3/core.c | 3 +-- drivers/video/dw_mipi_dsi.c | 3 +-- drivers/video/rockchip/dw_mipi_dsi_rockchip.c| 3 +-- drivers/video/tegra20/tegra-dsi.c| 4 +--- drivers/watchdog/sunxi_wdt.c | 3 +-- fs/ubifs/ubifs.h | 1 - include/linux/time.h | 9 + 30 files changed, 43 insertions(+), 63 deletions(-) -- 2.34.1
[PATCH 2/3] spi: meson_spifc_a1: Use define for time interval
Use USEC_PER_MSEC define for timeout to sync code with Linux version. Signed-off-by: Igor Prusov --- drivers/spi/meson_spifc_a1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/meson_spifc_a1.c b/drivers/spi/meson_spifc_a1.c index 099c4c037d..418d4d5e10 100644 --- a/drivers/spi/meson_spifc_a1.c +++ b/drivers/spi/meson_spifc_a1.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -117,7 +118,7 @@ static int amlogic_spifc_a1_request(struct amlogic_spifc_a1 *spifc, bool read) return readl_poll_timeout(spifc->base + SPIFC_A1_USER_CTRL0_REG, val, (val & mask) == mask, - 200 * 1000); + 200 * USEC_PER_MSEC); } static void amlogic_spifc_a1_drain_buffer(struct amlogic_spifc_a1 *spifc, -- 2.34.1
[PATCH 1/3] linux/time.h: Add Linux time conversion defines
Currently there are no defines for time conversion in time.h, which leads to drivers declaring those locally or not using defines at all, so add them from Linux. Signed-off-by: Igor Prusov --- include/linux/time.h | 9 + 1 file changed, 9 insertions(+) diff --git a/include/linux/time.h b/include/linux/time.h index 14ff5b6f48..14a144d9c9 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -11,6 +11,15 @@ #define _REENT_ONLY +#define MSEC_PER_SEC 1000L +#define USEC_PER_MSEC 1000L +#define NSEC_PER_USEC 1000L +#define NSEC_PER_MSEC 100L +#define USEC_PER_SEC 100L +#define NSEC_PER_SEC 10L +#define PSEC_PER_SEC 1LL +#define FSEC_PER_SEC 1000LL + #define SECSPERMIN 60L #define MINSPERHOUR60L #define HOURSPERDAY24L -- 2.34.1
[PATCH v7 8/8] cmd: clk: Make soc_clk_dump static
After introducing dump to clk_ops there is no need to override or expose this symbol anymore. Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard Reviewed-by: Sean Anderson Signed-off-by: Igor Prusov --- cmd/clk.c | 4 ++-- include/clk.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cmd/clk.c b/cmd/clk.c index 4b9709d3ff..7bbcbfeda3 100644 --- a/cmd/clk.c +++ b/cmd/clk.c @@ -59,7 +59,7 @@ static void show_clks(struct udevice *dev, int depth, int last_flag) } } -int __weak soc_clk_dump(void) +static int soc_clk_dump(void) { struct udevice *dev; const struct clk_ops *ops; @@ -81,7 +81,7 @@ int __weak soc_clk_dump(void) return 0; } #else -int __weak soc_clk_dump(void) +static int soc_clk_dump(void) { puts("Not implemented\n"); return 1; diff --git a/include/clk.h b/include/clk.h index 249c0e0ab4..3d6394477b 100644 --- a/include/clk.h +++ b/include/clk.h @@ -676,8 +676,6 @@ static inline bool clk_valid(struct clk *clk) return clk && !!clk->dev; } -int soc_clk_dump(void); - #endif #define clk_prepare_enable(clk) clk_enable(clk) -- 2.34.1
[PATCH v7 7/8] clk: treewide: switch to clock dump from clk_ops
Switch to using new dump operation in clock provider drivers instead of overriding soc_clk_dump. Tested-by: Patrice Chotard Reviewed-by: Sean Anderson Signed-off-by: Igor Prusov --- arch/mips/mach-pic32/cpu.c | 23 drivers/clk/aspeed/clk_ast2600.c | 13 + drivers/clk/clk_k210.c | 12 +++-- drivers/clk/clk_pic32.c| 37 ++ drivers/clk/clk_versal.c | 9 --- drivers/clk/clk_zynq.c | 28 --- drivers/clk/clk_zynqmp.c | 22 +++ drivers/clk/imx/clk-imx8.c | 13 +++-- drivers/clk/meson/a1.c | 28 ++- drivers/clk/mvebu/armada-37xx-periph.c | 20 +- drivers/clk/stm32/clk-stm32mp1.c | 31 ++--- 11 files changed, 108 insertions(+), 128 deletions(-) diff --git a/arch/mips/mach-pic32/cpu.c b/arch/mips/mach-pic32/cpu.c index dbf8c9cd22..3181a946a2 100644 --- a/arch/mips/mach-pic32/cpu.c +++ b/arch/mips/mach-pic32/cpu.c @@ -143,26 +143,3 @@ const char *get_core_name(void) return str; } #endif -#ifdef CONFIG_CMD_CLK - -int soc_clk_dump(void) -{ - int i; - - printf("PLL Speed: %lu MHz\n", - CLK_MHZ(rate(PLLCLK))); - - printf("CPU Speed: %lu MHz\n", CLK_MHZ(rate(PB7CLK))); - - printf("MPLL Speed: %lu MHz\n", CLK_MHZ(rate(MPLL))); - - for (i = PB1CLK; i <= PB7CLK; i++) - printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1, - CLK_MHZ(rate(i))); - - for (i = REF1CLK; i <= REF5CLK; i++) - printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1, - CLK_MHZ(rate(i))); - return 0; -} -#endif diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index b3cc8392fa..eecfacd7fc 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -1109,6 +1109,7 @@ struct aspeed_clks { const char *name; }; +#if IS_ENABLED(CONFIG_CMD_CLK) static struct aspeed_clks aspeed_clk_names[] = { { ASPEED_CLK_HPLL, "hpll" }, { ASPEED_CLK_MPLL, "mpll" }, @@ -1123,18 +1124,12 @@ static struct aspeed_clks aspeed_clk_names[] = { { ASPEED_CLK_HUARTX, "huxclk" }, }; -int soc_clk_dump(void) +static void ast2600_clk_dump(struct udevice *dev) { - struct udevice *dev; struct clk clk; unsigned long rate; int i, ret; - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(aspeed_scu), - &dev); - if (ret) - return ret; - printf("Clk\t\tHz\n"); for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) { @@ -1167,11 +1162,15 @@ int soc_clk_dump(void) return 0; } +#endif struct clk_ops ast2600_clk_ops = { .get_rate = ast2600_clk_get_rate, .set_rate = ast2600_clk_set_rate, .enable = ast2600_clk_enable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = ast2600_clk_dump, +#endif }; static int ast2600_clk_probe(struct udevice *dev) diff --git a/drivers/clk/clk_k210.c b/drivers/clk/clk_k210.c index 2f17152021..0d266bd1aa 100644 --- a/drivers/clk/clk_k210.c +++ b/drivers/clk/clk_k210.c @@ -1276,16 +1276,10 @@ static void show_clks(struct k210_clk_priv *priv, int id, int depth) } } -int soc_clk_dump(void) +static void k210_clk_dump(struct udevice *dev) { - int ret; - struct udevice *dev; struct k210_clk_priv *priv; - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(k210_clk), - &dev); - if (ret) - return ret; priv = dev_get_priv(dev); puts(" Rate Enabled Name\n"); @@ -1293,7 +1287,6 @@ int soc_clk_dump(void) printf(" %-9lu %-7c %*s%s\n", clk_get_rate(&priv->in0), 'y', 0, "", priv->in0.dev->name); show_clks(priv, K210_CLK_IN0, 1); - return 0; } #endif @@ -1304,6 +1297,9 @@ static const struct clk_ops k210_clk_ops = { .set_parent = k210_clk_set_parent, .enable = k210_clk_enable, .disable = k210_clk_disable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = k210_clk_dump, +#endif }; static int k210_clk_probe(struct udevice *dev) diff --git a/drivers/clk/clk_pic32.c b/drivers/clk/clk_pic32.c index ef06a7fb9f..a77d0e7419 100644 --- a/drivers/clk/clk_pic32.c +++ b/drivers/clk/clk_pic32.c @@ -20,6 +20,8 @@ DECLARE_GLOBAL_DATA_PTR; +#define CLK_MHZ(x) ((x) / 100) + /* Primary oscillator */ #define SYS_POSC_CLK_HZ2400 @@ -385,9 +387,44 @@ static ulong pic32_set_rate(struct clk *clk, ulong rate) return rate; } +#if IS_ENABLED(CONFIG_CMD_CLK) +static void
[PATCH v7 6/8] cmd: clk: Use dump function from clk_ops
Add another loop to dump additional info from clock providers that implement dump operation. Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard Reviewed-by: Sean Anderson Signed-off-by: Igor Prusov --- cmd/clk.c | 9 + 1 file changed, 9 insertions(+) diff --git a/cmd/clk.c b/cmd/clk.c index c7c379d7a6..4b9709d3ff 100644 --- a/cmd/clk.c +++ b/cmd/clk.c @@ -62,6 +62,7 @@ static void show_clks(struct udevice *dev, int depth, int last_flag) int __weak soc_clk_dump(void) { struct udevice *dev; + const struct clk_ops *ops; printf(" Rate Usecnt Name\n"); printf("--\n"); @@ -69,6 +70,14 @@ int __weak soc_clk_dump(void) uclass_foreach_dev_probe(UCLASS_CLK, dev) show_clks(dev, -1, 0); + uclass_foreach_dev_probe(UCLASS_CLK, dev) { + ops = dev_get_driver_ops(dev); + if (ops && ops->dump) { + printf("\n%s %s:\n", dev->driver->name, dev->name); + ops->dump(dev); + } + } + return 0; } #else -- 2.34.1
[PATCH v7 5/8] clk: Add dump operation to clk_ops
This adds dump function to struct clk_ops which should replace soc_clk_dump. It allows clock drivers to provide custom dump implementation without overriding generic CCF dump function. Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard Reviewed-by: Sean Anderson Signed-off-by: Igor Prusov --- include/clk-uclass.h | 13 + 1 file changed, 13 insertions(+) diff --git a/include/clk-uclass.h b/include/clk-uclass.h index a22f1a5d84..f10dd213ff 100644 --- a/include/clk-uclass.h +++ b/include/clk-uclass.h @@ -25,6 +25,7 @@ struct ofnode_phandle_args; * @set_parent: Set current clock parent * @enable: Enable a clock. * @disable: Disable a clock. + * @dump: Print clock information. * * The individual methods are described more fully below. */ @@ -39,6 +40,9 @@ struct clk_ops { int (*set_parent)(struct clk *clk, struct clk *parent); int (*enable)(struct clk *clk); int (*disable)(struct clk *clk); +#if IS_ENABLED(CONFIG_CMD_CLK) + void (*dump)(struct udevice *dev); +#endif }; #if 0 /* For documentation only */ @@ -135,6 +139,15 @@ int enable(struct clk *clk); * Return: zero on success, or -ve error code. */ int disable(struct clk *clk); + +/** + * dump() - Print clock information. + * @clk: The clock device to dump. + * + * If present, this function is called by "clk dump" command for each + * bound device. + */ +void dump(struct udevice *dev); #endif #endif -- 2.34.1
[PATCH v7 4/8] clk: amlogic: Move driver and ops structs
Move driver and ops structs to avoid forward declaration after switching to dump in clk_ops. Reviewed-by: Neil Armstrong Signed-off-by: Igor Prusov --- drivers/clk/meson/a1.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/clk/meson/a1.c b/drivers/clk/meson/a1.c index d0f5bb3753..c91357ec27 100644 --- a/drivers/clk/meson/a1.c +++ b/drivers/clk/meson/a1.c @@ -607,14 +607,6 @@ static int meson_clk_set_parent(struct clk *clk, struct clk *parent_clk) return meson_mux_set_parent_by_id(clk, parent_clk->id); } -static struct clk_ops meson_clk_ops = { - .disable= meson_clk_disable, - .enable = meson_clk_enable, - .get_rate = meson_clk_get_rate, - .set_rate = meson_clk_set_rate, - .set_parent = meson_clk_set_parent, -}; - static int meson_clk_probe(struct udevice *dev) { struct meson_clk *priv = dev_get_priv(dev); @@ -644,15 +636,6 @@ static const struct udevice_id meson_clk_ids[] = { { } }; -U_BOOT_DRIVER(meson_clk) = { - .name = "meson-clk-a1", - .id = UCLASS_CLK, - .of_match = meson_clk_ids, - .priv_auto = sizeof(struct meson_clk), - .ops= &meson_clk_ops, - .probe = meson_clk_probe, -}; - static const char *meson_clk_get_name(struct clk *clk, int id) { const struct meson_clk_info *info; @@ -733,3 +716,20 @@ int soc_clk_dump(void) return 0; } + +static struct clk_ops meson_clk_ops = { + .disable= meson_clk_disable, + .enable = meson_clk_enable, + .get_rate = meson_clk_get_rate, + .set_rate = meson_clk_set_rate, + .set_parent = meson_clk_set_parent, +}; + +U_BOOT_DRIVER(meson_clk) = { + .name = "meson-clk-a1", + .id = UCLASS_CLK, + .of_match = meson_clk_ids, + .priv_auto = sizeof(struct meson_clk), + .ops= &meson_clk_ops, + .probe = meson_clk_probe, +}; -- 2.34.1
[PATCH v7 3/8] clk: k210: Move soc_clk_dump function
Move clock dump function to avoid forward declaration after switching to dump in clk_ops. Reviewed-by: Sean Anderson Signed-off-by: Igor Prusov --- drivers/clk/clk_k210.c | 92 +- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/clk/clk_k210.c b/drivers/clk/clk_k210.c index c534cc07e0..2f17152021 100644 --- a/drivers/clk/clk_k210.c +++ b/drivers/clk/clk_k210.c @@ -1238,52 +1238,6 @@ static int k210_clk_request(struct clk *clk) return 0; } -static const struct clk_ops k210_clk_ops = { - .request = k210_clk_request, - .set_rate = k210_clk_set_rate, - .get_rate = k210_clk_get_rate, - .set_parent = k210_clk_set_parent, - .enable = k210_clk_enable, - .disable = k210_clk_disable, -}; - -static int k210_clk_probe(struct udevice *dev) -{ - int ret; - struct k210_clk_priv *priv = dev_get_priv(dev); - - priv->base = dev_read_addr_ptr(dev_get_parent(dev)); - if (!priv->base) - return -EINVAL; - - ret = clk_get_by_index(dev, 0, &priv->in0); - if (ret) - return ret; - - /* -* Force setting defaults, even before relocation. This is so we can -* set the clock rate for PLL1 before we relocate into aisram. -*/ - if (!(gd->flags & GD_FLG_RELOC)) - clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE); - - return 0; -} - -static const struct udevice_id k210_clk_ids[] = { - { .compatible = "canaan,k210-clk" }, - { }, -}; - -U_BOOT_DRIVER(k210_clk) = { - .name = "k210_clk", - .id = UCLASS_CLK, - .of_match = k210_clk_ids, - .ops = &k210_clk_ops, - .probe = k210_clk_probe, - .priv_auto = sizeof(struct k210_clk_priv), -}; - #if IS_ENABLED(CONFIG_CMD_CLK) static char show_enabled(struct k210_clk_priv *priv, int id) { @@ -1342,3 +1296,49 @@ int soc_clk_dump(void) return 0; } #endif + +static const struct clk_ops k210_clk_ops = { + .request = k210_clk_request, + .set_rate = k210_clk_set_rate, + .get_rate = k210_clk_get_rate, + .set_parent = k210_clk_set_parent, + .enable = k210_clk_enable, + .disable = k210_clk_disable, +}; + +static int k210_clk_probe(struct udevice *dev) +{ + int ret; + struct k210_clk_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev_get_parent(dev)); + if (!priv->base) + return -EINVAL; + + ret = clk_get_by_index(dev, 0, &priv->in0); + if (ret) + return ret; + + /* +* Force setting defaults, even before relocation. This is so we can +* set the clock rate for PLL1 before we relocate into aisram. +*/ + if (!(gd->flags & GD_FLG_RELOC)) + clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE); + + return 0; +} + +static const struct udevice_id k210_clk_ids[] = { + { .compatible = "canaan,k210-clk" }, + { }, +}; + +U_BOOT_DRIVER(k210_clk) = { + .name = "k210_clk", + .id = UCLASS_CLK, + .of_match = k210_clk_ids, + .ops = &k210_clk_ops, + .probe = k210_clk_probe, + .priv_auto = sizeof(struct k210_clk_priv), +}; -- 2.34.1
[PATCH v7 2/8] clk: ast2600: Move soc_clk_dump function
Move clock dump function to avoid forward declaration after switching to dump in clk_ops. Signed-off-by: Igor Prusov --- drivers/clk/aspeed/clk_ast2600.c | 70 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index e5ada5b6d4..b3cc8392fa 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -1104,41 +1104,6 @@ static int ast2600_clk_enable(struct clk *clk) return 0; } -struct clk_ops ast2600_clk_ops = { - .get_rate = ast2600_clk_get_rate, - .set_rate = ast2600_clk_set_rate, - .enable = ast2600_clk_enable, -}; - -static int ast2600_clk_probe(struct udevice *dev) -{ - struct ast2600_clk_priv *priv = dev_get_priv(dev); - - priv->scu = devfdt_get_addr_ptr(dev); - if (IS_ERR(priv->scu)) - return PTR_ERR(priv->scu); - - ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); - ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); - ast2600_configure_mac12_clk(priv->scu); - ast2600_configure_mac34_clk(priv->scu); - ast2600_configure_rsa_ecc_clk(priv->scu); - - return 0; -} - -static int ast2600_clk_bind(struct udevice *dev) -{ - int ret; - - /* The reset driver does not have a device node, so bind it here */ - ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); - if (ret) - debug("Warning: No reset driver: ret=%d\n", ret); - - return 0; -} - struct aspeed_clks { ulong id; const char *name; @@ -1203,6 +1168,41 @@ int soc_clk_dump(void) return 0; } +struct clk_ops ast2600_clk_ops = { + .get_rate = ast2600_clk_get_rate, + .set_rate = ast2600_clk_set_rate, + .enable = ast2600_clk_enable, +}; + +static int ast2600_clk_probe(struct udevice *dev) +{ + struct ast2600_clk_priv *priv = dev_get_priv(dev); + + priv->scu = devfdt_get_addr_ptr(dev); + if (IS_ERR(priv->scu)) + return PTR_ERR(priv->scu); + + ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); + ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); + ast2600_configure_mac12_clk(priv->scu); + ast2600_configure_mac34_clk(priv->scu); + ast2600_configure_rsa_ecc_clk(priv->scu); + + return 0; +} + +static int ast2600_clk_bind(struct udevice *dev) +{ + int ret; + + /* The reset driver does not have a device node, so bind it here */ + ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); + if (ret) + debug("Warning: No reset driver: ret=%d\n", ret); + + return 0; +} + static const struct udevice_id ast2600_clk_ids[] = { { .compatible = "aspeed,ast2600-scu", }, { }, -- 2.34.1
[PATCH v7 1/8] clk: zynq: Move soc_clk_dump to Zynq clock driver
Move clock dump function in preparation for switching to dump function in clk_ops. Acked-by: Michal Simek Signed-off-by: Igor Prusov --- arch/arm/mach-zynq/clk.c | 57 --- drivers/clk/clk_zynq.c | 58 2 files changed, 58 insertions(+), 57 deletions(-) diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c index 1945f60e08..e6a67326dd 100644 --- a/arch/arm/mach-zynq/clk.c +++ b/arch/arm/mach-zynq/clk.c @@ -13,20 +13,6 @@ DECLARE_GLOBAL_DATA_PTR; -static const char * const clk_names[clk_max] = { - "armpll", "ddrpll", "iopll", - "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", - "ddr2x", "ddr3x", "dci", - "lqspi", "smc", "pcap", "gem0", "gem1", - "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", - "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", - "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", - "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", - "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", - "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", - "smc_aper", "swdt", "dbg_trc", "dbg_apb" -}; - /** * set_cpu_clk_info() - Setup clock information * @@ -65,46 +51,3 @@ int set_cpu_clk_info(void) return 0; } - -/** - * soc_clk_dump() - Print clock frequencies - * Returns zero on success - * - * Implementation for the clk dump command. - */ -int soc_clk_dump(void) -{ - struct udevice *dev; - int i, ret; - - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(zynq_clk), &dev); - if (ret) - return ret; - - printf("clk\t\tfrequency\n"); - for (i = 0; i < clk_max; i++) { - const char *name = clk_names[i]; - if (name) { - struct clk clk; - unsigned long rate; - - clk.id = i; - ret = clk_request(dev, &clk); - if (ret < 0) - return ret; - - rate = clk_get_rate(&clk); - - clk_free(&clk); - - if ((rate == (unsigned long)-ENOSYS) || - (rate == (unsigned long)-ENXIO)) - printf("%10s%20s\n", name, "unknown"); - else - printf("%10s%20lu\n", name, rate); - } - } - - return 0; -} diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c index e80500e382..be5226175f 100644 --- a/drivers/clk/clk_zynq.c +++ b/drivers/clk/clk_zynq.c @@ -454,6 +454,64 @@ static int dummy_enable(struct clk *clk) return 0; } +static const char * const clk_names[clk_max] = { + "armpll", "ddrpll", "iopll", + "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", + "ddr2x", "ddr3x", "dci", + "lqspi", "smc", "pcap", "gem0", "gem1", + "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", + "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", + "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", + "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", + "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", + "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", + "smc_aper", "swdt", "dbg_trc", "dbg_apb" +}; + +/** + * soc_clk_dump() - Print clock frequencies + * Returns zero on success + * + * Implementation for the clk dump command. + */ +int soc_clk_dump(void) +{ + struct udevice *dev; + int i, ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(zynq_clk), &dev); + if (ret) + return ret; + + printf("clk\t\tfrequency\n"); + for (i = 0; i < clk_max; i++) { + const char *name = clk_names[i]; + + if (name) { + struct clk clk; + unsigned long rate; + + clk.id = i; + ret = clk_request(dev, &clk); + if (ret < 0) + return ret; + + rate = clk_get_rate(&clk); + + clk_free(&clk); + + if ((rate == (unsigned long)-ENOSYS) || + (rate == (unsigned long)-ENXIO)) + printf("%10s%20s\n", name, "unknown"); + else + printf("%10s%20lu\n", name, rate); + } + } + + return 0; +} + static struct clk_ops zynq_clk_ops = { .get_rate = zynq_clk_get_rate, #ifndef CONFIG_SPL_BUILD -- 2.34.1
[PATCH v7 0/8] clk: Switch from soc_clk_dump to clk_ops function
Currently clock providers may override default implementation of soc_clk_dump function to replace clk dump command output. This causes confusing behaviour when u-boot is built with one of such drivers enabled but still has clocks defined using CCF. For example, enabling CMD_CLK and using clk dump on sandbox target will not show CCF clocks because k210 driver overrides common soc_clk_dump. Changelog: v1 -> v2: - Add missing static to dump functions v2 -> v3: - Make soc_clk_dump in cmd/clk.c static instead of removing __weak v3 -> v4: - Rebase and refactor dump for new Amlogic A1 clock controller driver v4 -> v5: - Add docs for dump() function in clk_ops - Print driver and device names before calling corresponding dump() v5 -> v6: - dump() return type changed to void - meson_clk_dump() and helper functions moved under CONFIG_CMD_CLK to fix unused-function diagnostic v6 -> v7: - fix return type of k210_clk_dump() - fix clk_ops dump() docs since it returns void now Igor Prusov (8): clk: zynq: Move soc_clk_dump to Zynq clock driver clk: ast2600: Move soc_clk_dump function clk: k210: Move soc_clk_dump function clk: amlogic: Move driver and ops structs clk: Add dump operation to clk_ops cmd: clk: Use dump function from clk_ops clk: treewide: switch to clock dump from clk_ops cmd: clk: Make soc_clk_dump static arch/arm/mach-zynq/clk.c | 57 -- arch/mips/mach-pic32/cpu.c | 23 -- cmd/clk.c | 13 +++- drivers/clk/aspeed/clk_ast2600.c | 83 ++-- drivers/clk/clk_k210.c | 104 - drivers/clk/clk_pic32.c| 37 + drivers/clk/clk_versal.c | 9 ++- drivers/clk/clk_zynq.c | 52 + drivers/clk/clk_zynqmp.c | 22 +++--- drivers/clk/imx/clk-imx8.c | 13 +--- drivers/clk/meson/a1.c | 58 ++ drivers/clk/mvebu/armada-37xx-periph.c | 20 +++-- drivers/clk/stm32/clk-stm32mp1.c | 31 ++-- include/clk-uclass.h | 13 include/clk.h | 2 - 15 files changed, 269 insertions(+), 268 deletions(-) -- 2.34.1
Re: [PATCH v6 7/8] clk: treewide: switch to clock dump from clk_ops
On Wed, Nov 08, 2023 at 12:02:44PM -0500, Sean Anderson wrote: > On 11/5/23 03:38, Igor Prusov wrote: > > Switch to using new dump operation in clock provider drivers instead of > > overriding soc_clk_dump. > > > > Signed-off-by: Igor Prusov > > Tested-by: Patrice Chotard > > Reviewed-by: Sean Anderson > > --- > > arch/mips/mach-pic32/cpu.c | 23 > > drivers/clk/aspeed/clk_ast2600.c | 13 + > > drivers/clk/clk_k210.c | 12 +++-- > > drivers/clk/clk_pic32.c| 37 ++ > > drivers/clk/clk_versal.c | 9 --- > > drivers/clk/clk_zynq.c | 28 --- > > drivers/clk/clk_zynqmp.c | 22 +++ > > drivers/clk/imx/clk-imx8.c | 13 +++-- > > drivers/clk/meson/a1.c | 28 ++- > > drivers/clk/mvebu/armada-37xx-periph.c | 20 +- > > drivers/clk/stm32/clk-stm32mp1.c | 31 ++--- > > 11 files changed, 108 insertions(+), 128 deletions(-) > > > > diff --git a/arch/mips/mach-pic32/cpu.c b/arch/mips/mach-pic32/cpu.c > > index dbf8c9cd22..3181a946a2 100644 > > --- a/arch/mips/mach-pic32/cpu.c > > +++ b/arch/mips/mach-pic32/cpu.c > > @@ -143,26 +143,3 @@ const char *get_core_name(void) > > return str; > > } > > #endif > > -#ifdef CONFIG_CMD_CLK > > - > > -int soc_clk_dump(void) > > -{ > > - int i; > > - > > - printf("PLL Speed: %lu MHz\n", > > - CLK_MHZ(rate(PLLCLK))); > > - > > - printf("CPU Speed: %lu MHz\n", CLK_MHZ(rate(PB7CLK))); > > - > > - printf("MPLL Speed: %lu MHz\n", CLK_MHZ(rate(MPLL))); > > - > > - for (i = PB1CLK; i <= PB7CLK; i++) > > - printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1, > > - CLK_MHZ(rate(i))); > > - > > - for (i = REF1CLK; i <= REF5CLK; i++) > > - printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1, > > - CLK_MHZ(rate(i))); > > - return 0; > > -} > > -#endif > > diff --git a/drivers/clk/aspeed/clk_ast2600.c > > b/drivers/clk/aspeed/clk_ast2600.c > > index b3cc8392fa..eecfacd7fc 100644 > > --- a/drivers/clk/aspeed/clk_ast2600.c > > +++ b/drivers/clk/aspeed/clk_ast2600.c > > @@ -1109,6 +1109,7 @@ struct aspeed_clks { > > const char *name; > > }; > > +#if IS_ENABLED(CONFIG_CMD_CLK) > > static struct aspeed_clks aspeed_clk_names[] = { > > { ASPEED_CLK_HPLL, "hpll" }, > > { ASPEED_CLK_MPLL, "mpll" }, > > @@ -1123,18 +1124,12 @@ static struct aspeed_clks aspeed_clk_names[] = { > > { ASPEED_CLK_HUARTX, "huxclk" }, > > }; > > -int soc_clk_dump(void) > > +static void ast2600_clk_dump(struct udevice *dev) > > { > > - struct udevice *dev; > > struct clk clk; > > unsigned long rate; > > int i, ret; > > - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(aspeed_scu), > > - &dev); > > - if (ret) > > - return ret; > > - > > printf("Clk\t\tHz\n"); > > for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) { > > @@ -1167,11 +1162,15 @@ int soc_clk_dump(void) > > return 0; > > } > > +#endif > > struct clk_ops ast2600_clk_ops = { > > .get_rate = ast2600_clk_get_rate, > > .set_rate = ast2600_clk_set_rate, > > .enable = ast2600_clk_enable, > > +#if IS_ENABLED(CONFIG_CMD_CLK) > > + .dump = ast2600_clk_dump, > > +#endif > > }; > > static int ast2600_clk_probe(struct udevice *dev) > > diff --git a/drivers/clk/clk_k210.c b/drivers/clk/clk_k210.c > > index 2f17152021..b8d666e805 100644 > > --- a/drivers/clk/clk_k210.c > > +++ b/drivers/clk/clk_k210.c > > @@ -1276,16 +1276,10 @@ static void show_clks(struct k210_clk_priv *priv, > > int id, int depth) > > } > > } > > -int soc_clk_dump(void) > > +static int k210_clk_dump(struct udevice *dev) > > void? Yep, will fix in next version along with dump() docs. Thanks for review! > > > { > > - int ret; > > - struct udevice *dev; > > struct k210_clk_priv *priv; > > - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(k210_clk), > > - &dev); > > - if (ret) > > -
[PATCH v6 8/8] cmd: clk: Make soc_clk_dump static
After introducing dump to clk_ops there is no need to override or expose this symbol anymore. Signed-off-by: Igor Prusov Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard Reviewed-by: Sean Anderson --- cmd/clk.c | 4 ++-- include/clk.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cmd/clk.c b/cmd/clk.c index 4b9709d3ff..7bbcbfeda3 100644 --- a/cmd/clk.c +++ b/cmd/clk.c @@ -59,7 +59,7 @@ static void show_clks(struct udevice *dev, int depth, int last_flag) } } -int __weak soc_clk_dump(void) +static int soc_clk_dump(void) { struct udevice *dev; const struct clk_ops *ops; @@ -81,7 +81,7 @@ int __weak soc_clk_dump(void) return 0; } #else -int __weak soc_clk_dump(void) +static int soc_clk_dump(void) { puts("Not implemented\n"); return 1; diff --git a/include/clk.h b/include/clk.h index 249c0e0ab4..3d6394477b 100644 --- a/include/clk.h +++ b/include/clk.h @@ -676,8 +676,6 @@ static inline bool clk_valid(struct clk *clk) return clk && !!clk->dev; } -int soc_clk_dump(void); - #endif #define clk_prepare_enable(clk) clk_enable(clk) -- 2.34.1
[PATCH v6 7/8] clk: treewide: switch to clock dump from clk_ops
Switch to using new dump operation in clock provider drivers instead of overriding soc_clk_dump. Signed-off-by: Igor Prusov Tested-by: Patrice Chotard Reviewed-by: Sean Anderson --- arch/mips/mach-pic32/cpu.c | 23 drivers/clk/aspeed/clk_ast2600.c | 13 + drivers/clk/clk_k210.c | 12 +++-- drivers/clk/clk_pic32.c| 37 ++ drivers/clk/clk_versal.c | 9 --- drivers/clk/clk_zynq.c | 28 --- drivers/clk/clk_zynqmp.c | 22 +++ drivers/clk/imx/clk-imx8.c | 13 +++-- drivers/clk/meson/a1.c | 28 ++- drivers/clk/mvebu/armada-37xx-periph.c | 20 +- drivers/clk/stm32/clk-stm32mp1.c | 31 ++--- 11 files changed, 108 insertions(+), 128 deletions(-) diff --git a/arch/mips/mach-pic32/cpu.c b/arch/mips/mach-pic32/cpu.c index dbf8c9cd22..3181a946a2 100644 --- a/arch/mips/mach-pic32/cpu.c +++ b/arch/mips/mach-pic32/cpu.c @@ -143,26 +143,3 @@ const char *get_core_name(void) return str; } #endif -#ifdef CONFIG_CMD_CLK - -int soc_clk_dump(void) -{ - int i; - - printf("PLL Speed: %lu MHz\n", - CLK_MHZ(rate(PLLCLK))); - - printf("CPU Speed: %lu MHz\n", CLK_MHZ(rate(PB7CLK))); - - printf("MPLL Speed: %lu MHz\n", CLK_MHZ(rate(MPLL))); - - for (i = PB1CLK; i <= PB7CLK; i++) - printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1, - CLK_MHZ(rate(i))); - - for (i = REF1CLK; i <= REF5CLK; i++) - printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1, - CLK_MHZ(rate(i))); - return 0; -} -#endif diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index b3cc8392fa..eecfacd7fc 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -1109,6 +1109,7 @@ struct aspeed_clks { const char *name; }; +#if IS_ENABLED(CONFIG_CMD_CLK) static struct aspeed_clks aspeed_clk_names[] = { { ASPEED_CLK_HPLL, "hpll" }, { ASPEED_CLK_MPLL, "mpll" }, @@ -1123,18 +1124,12 @@ static struct aspeed_clks aspeed_clk_names[] = { { ASPEED_CLK_HUARTX, "huxclk" }, }; -int soc_clk_dump(void) +static void ast2600_clk_dump(struct udevice *dev) { - struct udevice *dev; struct clk clk; unsigned long rate; int i, ret; - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(aspeed_scu), - &dev); - if (ret) - return ret; - printf("Clk\t\tHz\n"); for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) { @@ -1167,11 +1162,15 @@ int soc_clk_dump(void) return 0; } +#endif struct clk_ops ast2600_clk_ops = { .get_rate = ast2600_clk_get_rate, .set_rate = ast2600_clk_set_rate, .enable = ast2600_clk_enable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = ast2600_clk_dump, +#endif }; static int ast2600_clk_probe(struct udevice *dev) diff --git a/drivers/clk/clk_k210.c b/drivers/clk/clk_k210.c index 2f17152021..b8d666e805 100644 --- a/drivers/clk/clk_k210.c +++ b/drivers/clk/clk_k210.c @@ -1276,16 +1276,10 @@ static void show_clks(struct k210_clk_priv *priv, int id, int depth) } } -int soc_clk_dump(void) +static int k210_clk_dump(struct udevice *dev) { - int ret; - struct udevice *dev; struct k210_clk_priv *priv; - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(k210_clk), - &dev); - if (ret) - return ret; priv = dev_get_priv(dev); puts(" Rate Enabled Name\n"); @@ -1293,7 +1287,6 @@ int soc_clk_dump(void) printf(" %-9lu %-7c %*s%s\n", clk_get_rate(&priv->in0), 'y', 0, "", priv->in0.dev->name); show_clks(priv, K210_CLK_IN0, 1); - return 0; } #endif @@ -1304,6 +1297,9 @@ static const struct clk_ops k210_clk_ops = { .set_parent = k210_clk_set_parent, .enable = k210_clk_enable, .disable = k210_clk_disable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = k210_clk_dump, +#endif }; static int k210_clk_probe(struct udevice *dev) diff --git a/drivers/clk/clk_pic32.c b/drivers/clk/clk_pic32.c index ef06a7fb9f..a77d0e7419 100644 --- a/drivers/clk/clk_pic32.c +++ b/drivers/clk/clk_pic32.c @@ -20,6 +20,8 @@ DECLARE_GLOBAL_DATA_PTR; +#define CLK_MHZ(x) ((x) / 100) + /* Primary oscillator */ #define SYS_POSC_CLK_HZ2400 @@ -385,9 +387,44 @@ static ulong pic32_set_rate(struct clk *clk, ulong rate) return rate; } +#if IS_ENABLED(CONFIG_CMD_CLK) +static void
[PATCH v6 1/8] clk: zynq: Move soc_clk_dump to Zynq clock driver
Move clock dump function in preparation for switching to dump function in clk_ops. Signed-off-by: Igor Prusov Acked-by: Michal Simek --- arch/arm/mach-zynq/clk.c | 57 --- drivers/clk/clk_zynq.c | 58 2 files changed, 58 insertions(+), 57 deletions(-) diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c index 1945f60e08..e6a67326dd 100644 --- a/arch/arm/mach-zynq/clk.c +++ b/arch/arm/mach-zynq/clk.c @@ -13,20 +13,6 @@ DECLARE_GLOBAL_DATA_PTR; -static const char * const clk_names[clk_max] = { - "armpll", "ddrpll", "iopll", - "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", - "ddr2x", "ddr3x", "dci", - "lqspi", "smc", "pcap", "gem0", "gem1", - "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", - "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", - "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", - "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", - "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", - "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", - "smc_aper", "swdt", "dbg_trc", "dbg_apb" -}; - /** * set_cpu_clk_info() - Setup clock information * @@ -65,46 +51,3 @@ int set_cpu_clk_info(void) return 0; } - -/** - * soc_clk_dump() - Print clock frequencies - * Returns zero on success - * - * Implementation for the clk dump command. - */ -int soc_clk_dump(void) -{ - struct udevice *dev; - int i, ret; - - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(zynq_clk), &dev); - if (ret) - return ret; - - printf("clk\t\tfrequency\n"); - for (i = 0; i < clk_max; i++) { - const char *name = clk_names[i]; - if (name) { - struct clk clk; - unsigned long rate; - - clk.id = i; - ret = clk_request(dev, &clk); - if (ret < 0) - return ret; - - rate = clk_get_rate(&clk); - - clk_free(&clk); - - if ((rate == (unsigned long)-ENOSYS) || - (rate == (unsigned long)-ENXIO)) - printf("%10s%20s\n", name, "unknown"); - else - printf("%10s%20lu\n", name, rate); - } - } - - return 0; -} diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c index e80500e382..be5226175f 100644 --- a/drivers/clk/clk_zynq.c +++ b/drivers/clk/clk_zynq.c @@ -454,6 +454,64 @@ static int dummy_enable(struct clk *clk) return 0; } +static const char * const clk_names[clk_max] = { + "armpll", "ddrpll", "iopll", + "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", + "ddr2x", "ddr3x", "dci", + "lqspi", "smc", "pcap", "gem0", "gem1", + "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", + "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", + "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", + "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", + "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", + "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", + "smc_aper", "swdt", "dbg_trc", "dbg_apb" +}; + +/** + * soc_clk_dump() - Print clock frequencies + * Returns zero on success + * + * Implementation for the clk dump command. + */ +int soc_clk_dump(void) +{ + struct udevice *dev; + int i, ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(zynq_clk), &dev); + if (ret) + return ret; + + printf("clk\t\tfrequency\n"); + for (i = 0; i < clk_max; i++) { + const char *name = clk_names[i]; + + if (name) { + struct clk clk; + unsigned long rate; + + clk.id = i; + ret = clk_request(dev, &clk); + if (ret < 0) + return ret; + + rate = clk_get_rate(&clk); + + clk_free(&clk); + + if ((rate == (unsigned long)-ENOSYS) || + (rate == (unsigned long)-ENXIO)) + printf("%10s%20s\n", name, "unknown"); + else + printf("%10s%20lu\n", name, rate); + } + } + + return 0; +} + static struct clk_ops zynq_clk_ops = { .get_rate = zynq_clk_get_rate, #ifndef CONFIG_SPL_BUILD -- 2.34.1
[PATCH v6 3/8] clk: k210: Move soc_clk_dump function
Move clock dump function to avoid forward declaration after switching to dump in clk_ops. Signed-off-by: Igor Prusov Reviewed-by: Sean Anderson --- drivers/clk/clk_k210.c | 92 +- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/clk/clk_k210.c b/drivers/clk/clk_k210.c index c534cc07e0..2f17152021 100644 --- a/drivers/clk/clk_k210.c +++ b/drivers/clk/clk_k210.c @@ -1238,52 +1238,6 @@ static int k210_clk_request(struct clk *clk) return 0; } -static const struct clk_ops k210_clk_ops = { - .request = k210_clk_request, - .set_rate = k210_clk_set_rate, - .get_rate = k210_clk_get_rate, - .set_parent = k210_clk_set_parent, - .enable = k210_clk_enable, - .disable = k210_clk_disable, -}; - -static int k210_clk_probe(struct udevice *dev) -{ - int ret; - struct k210_clk_priv *priv = dev_get_priv(dev); - - priv->base = dev_read_addr_ptr(dev_get_parent(dev)); - if (!priv->base) - return -EINVAL; - - ret = clk_get_by_index(dev, 0, &priv->in0); - if (ret) - return ret; - - /* -* Force setting defaults, even before relocation. This is so we can -* set the clock rate for PLL1 before we relocate into aisram. -*/ - if (!(gd->flags & GD_FLG_RELOC)) - clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE); - - return 0; -} - -static const struct udevice_id k210_clk_ids[] = { - { .compatible = "canaan,k210-clk" }, - { }, -}; - -U_BOOT_DRIVER(k210_clk) = { - .name = "k210_clk", - .id = UCLASS_CLK, - .of_match = k210_clk_ids, - .ops = &k210_clk_ops, - .probe = k210_clk_probe, - .priv_auto = sizeof(struct k210_clk_priv), -}; - #if IS_ENABLED(CONFIG_CMD_CLK) static char show_enabled(struct k210_clk_priv *priv, int id) { @@ -1342,3 +1296,49 @@ int soc_clk_dump(void) return 0; } #endif + +static const struct clk_ops k210_clk_ops = { + .request = k210_clk_request, + .set_rate = k210_clk_set_rate, + .get_rate = k210_clk_get_rate, + .set_parent = k210_clk_set_parent, + .enable = k210_clk_enable, + .disable = k210_clk_disable, +}; + +static int k210_clk_probe(struct udevice *dev) +{ + int ret; + struct k210_clk_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev_get_parent(dev)); + if (!priv->base) + return -EINVAL; + + ret = clk_get_by_index(dev, 0, &priv->in0); + if (ret) + return ret; + + /* +* Force setting defaults, even before relocation. This is so we can +* set the clock rate for PLL1 before we relocate into aisram. +*/ + if (!(gd->flags & GD_FLG_RELOC)) + clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE); + + return 0; +} + +static const struct udevice_id k210_clk_ids[] = { + { .compatible = "canaan,k210-clk" }, + { }, +}; + +U_BOOT_DRIVER(k210_clk) = { + .name = "k210_clk", + .id = UCLASS_CLK, + .of_match = k210_clk_ids, + .ops = &k210_clk_ops, + .probe = k210_clk_probe, + .priv_auto = sizeof(struct k210_clk_priv), +}; -- 2.34.1
[PATCH v6 2/8] clk: ast2600: Move soc_clk_dump function
Move clock dump function to avoid forward declaration after switching to dump in clk_ops. Signed-off-by: Igor Prusov --- drivers/clk/aspeed/clk_ast2600.c | 70 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index e5ada5b6d4..b3cc8392fa 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -1104,41 +1104,6 @@ static int ast2600_clk_enable(struct clk *clk) return 0; } -struct clk_ops ast2600_clk_ops = { - .get_rate = ast2600_clk_get_rate, - .set_rate = ast2600_clk_set_rate, - .enable = ast2600_clk_enable, -}; - -static int ast2600_clk_probe(struct udevice *dev) -{ - struct ast2600_clk_priv *priv = dev_get_priv(dev); - - priv->scu = devfdt_get_addr_ptr(dev); - if (IS_ERR(priv->scu)) - return PTR_ERR(priv->scu); - - ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); - ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); - ast2600_configure_mac12_clk(priv->scu); - ast2600_configure_mac34_clk(priv->scu); - ast2600_configure_rsa_ecc_clk(priv->scu); - - return 0; -} - -static int ast2600_clk_bind(struct udevice *dev) -{ - int ret; - - /* The reset driver does not have a device node, so bind it here */ - ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); - if (ret) - debug("Warning: No reset driver: ret=%d\n", ret); - - return 0; -} - struct aspeed_clks { ulong id; const char *name; @@ -1203,6 +1168,41 @@ int soc_clk_dump(void) return 0; } +struct clk_ops ast2600_clk_ops = { + .get_rate = ast2600_clk_get_rate, + .set_rate = ast2600_clk_set_rate, + .enable = ast2600_clk_enable, +}; + +static int ast2600_clk_probe(struct udevice *dev) +{ + struct ast2600_clk_priv *priv = dev_get_priv(dev); + + priv->scu = devfdt_get_addr_ptr(dev); + if (IS_ERR(priv->scu)) + return PTR_ERR(priv->scu); + + ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); + ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); + ast2600_configure_mac12_clk(priv->scu); + ast2600_configure_mac34_clk(priv->scu); + ast2600_configure_rsa_ecc_clk(priv->scu); + + return 0; +} + +static int ast2600_clk_bind(struct udevice *dev) +{ + int ret; + + /* The reset driver does not have a device node, so bind it here */ + ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); + if (ret) + debug("Warning: No reset driver: ret=%d\n", ret); + + return 0; +} + static const struct udevice_id ast2600_clk_ids[] = { { .compatible = "aspeed,ast2600-scu", }, { }, -- 2.34.1
[PATCH v6 4/8] clk: amlogic: Move driver and ops structs
Move driver and ops structs to avoid forward declaration after switching to dump in clk_ops. Signed-off-by: Igor Prusov Reviewed-by: Neil Armstrong --- drivers/clk/meson/a1.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/clk/meson/a1.c b/drivers/clk/meson/a1.c index 1075ba7333..e3fa9db7d0 100644 --- a/drivers/clk/meson/a1.c +++ b/drivers/clk/meson/a1.c @@ -601,14 +601,6 @@ static int meson_clk_set_parent(struct clk *clk, struct clk *parent_clk) return meson_mux_set_parent_by_id(clk, parent_clk->id); } -static struct clk_ops meson_clk_ops = { - .disable= meson_clk_disable, - .enable = meson_clk_enable, - .get_rate = meson_clk_get_rate, - .set_rate = meson_clk_set_rate, - .set_parent = meson_clk_set_parent, -}; - static int meson_clk_probe(struct udevice *dev) { struct meson_clk *priv = dev_get_priv(dev); @@ -638,15 +630,6 @@ static const struct udevice_id meson_clk_ids[] = { { } }; -U_BOOT_DRIVER(meson_clk) = { - .name = "meson-clk-a1", - .id = UCLASS_CLK, - .of_match = meson_clk_ids, - .priv_auto = sizeof(struct meson_clk), - .ops= &meson_clk_ops, - .probe = meson_clk_probe, -}; - static const char *meson_clk_get_name(struct clk *clk, int id) { const struct meson_clk_info *info; @@ -727,3 +710,20 @@ int soc_clk_dump(void) return 0; } + +static struct clk_ops meson_clk_ops = { + .disable= meson_clk_disable, + .enable = meson_clk_enable, + .get_rate = meson_clk_get_rate, + .set_rate = meson_clk_set_rate, + .set_parent = meson_clk_set_parent, +}; + +U_BOOT_DRIVER(meson_clk) = { + .name = "meson-clk-a1", + .id = UCLASS_CLK, + .of_match = meson_clk_ids, + .priv_auto = sizeof(struct meson_clk), + .ops= &meson_clk_ops, + .probe = meson_clk_probe, +}; -- 2.34.1
[PATCH v6 5/8] clk: Add dump operation to clk_ops
This adds dump function to struct clk_ops which should replace soc_clk_dump. It allows clock drivers to provide custom dump implementation without overriding generic CCF dump function. Signed-off-by: Igor Prusov Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard --- include/clk-uclass.h | 15 +++ 1 file changed, 15 insertions(+) diff --git a/include/clk-uclass.h b/include/clk-uclass.h index a22f1a5d84..3419daab34 100644 --- a/include/clk-uclass.h +++ b/include/clk-uclass.h @@ -25,6 +25,7 @@ struct ofnode_phandle_args; * @set_parent: Set current clock parent * @enable: Enable a clock. * @disable: Disable a clock. + * @dump: Print clock information. * * The individual methods are described more fully below. */ @@ -39,6 +40,9 @@ struct clk_ops { int (*set_parent)(struct clk *clk, struct clk *parent); int (*enable)(struct clk *clk); int (*disable)(struct clk *clk); +#if IS_ENABLED(CONFIG_CMD_CLK) + void (*dump)(struct udevice *dev); +#endif }; #if 0 /* For documentation only */ @@ -135,6 +139,17 @@ int enable(struct clk *clk); * Return: zero on success, or -ve error code. */ int disable(struct clk *clk); + +/** + * dump() - Print clock information. + * @clk: The clock device to dump. + * + * If present, this function is called by "clk dump" command for each + * bound device. + * + * Return: zero on success, or -ve error code. + */ +void dump(struct udevice *dev); #endif #endif -- 2.34.1
[PATCH v6 6/8] cmd: clk: Use dump function from clk_ops
Add another loop to dump additional info from clock providers that implement dump operation. Signed-off-by: Igor Prusov Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard --- cmd/clk.c | 9 + 1 file changed, 9 insertions(+) diff --git a/cmd/clk.c b/cmd/clk.c index c7c379d7a6..4b9709d3ff 100644 --- a/cmd/clk.c +++ b/cmd/clk.c @@ -62,6 +62,7 @@ static void show_clks(struct udevice *dev, int depth, int last_flag) int __weak soc_clk_dump(void) { struct udevice *dev; + const struct clk_ops *ops; printf(" Rate Usecnt Name\n"); printf("--\n"); @@ -69,6 +70,14 @@ int __weak soc_clk_dump(void) uclass_foreach_dev_probe(UCLASS_CLK, dev) show_clks(dev, -1, 0); + uclass_foreach_dev_probe(UCLASS_CLK, dev) { + ops = dev_get_driver_ops(dev); + if (ops && ops->dump) { + printf("\n%s %s:\n", dev->driver->name, dev->name); + ops->dump(dev); + } + } + return 0; } #else -- 2.34.1
[PATCH v6 0/8] clk: Switch from soc_clk_dump to clk_ops function
Currently clock providers may override default implementation of soc_clk_dump function to replace clk dump command output. This causes confusing behaviour when u-boot is built with one of such drivers enabled but still has clocks defined using CCF. For example, enabling CMD_CLK and using clk dump on sandbox target will not show CCF clocks because k210 driver overrides common soc_clk_dump. Changelog: v1 -> v2: - Add missing static to dump functions v2 -> v3: - Make soc_clk_dump in cmd/clk.c static instead of removing __weak v3 -> v4: - Rebase and refactor dump for new Amlogic A1 clock controller driver v4 -> v5: - Add docs for dump() function in clk_ops - Print driver and device names before calling corresponding dump() v5 -> v6: - dump() return type changed to void - meson_clk_dump() and helper functions moved under CONFIG_CMD_CLK to fix unused-function diagnostic Igor Prusov (8): clk: zynq: Move soc_clk_dump to Zynq clock driver clk: ast2600: Move soc_clk_dump function clk: k210: Move soc_clk_dump function clk: amlogic: Move driver and ops structs clk: Add dump operation to clk_ops cmd: clk: Use dump function from clk_ops clk: treewide: switch to clock dump from clk_ops cmd: clk: Make soc_clk_dump static arch/arm/mach-zynq/clk.c | 57 -- arch/mips/mach-pic32/cpu.c | 23 -- cmd/clk.c | 13 +++- drivers/clk/aspeed/clk_ast2600.c | 83 ++-- drivers/clk/clk_k210.c | 104 - drivers/clk/clk_pic32.c| 37 + drivers/clk/clk_versal.c | 9 ++- drivers/clk/clk_zynq.c | 52 + drivers/clk/clk_zynqmp.c | 22 +++--- drivers/clk/imx/clk-imx8.c | 13 +--- drivers/clk/meson/a1.c | 58 ++ drivers/clk/mvebu/armada-37xx-periph.c | 20 +++-- drivers/clk/stm32/clk-stm32mp1.c | 31 ++-- include/clk-uclass.h | 15 include/clk.h | 2 - 15 files changed, 271 insertions(+), 268 deletions(-) -- 2.34.1
Re: [PATCH v5 5/8] clk: Add dump operation to clk_ops
On Sat, Nov 04, 2023 at 02:40:34PM -0400, Sean Anderson wrote: > On 11/4/23 14:09, Igor Prusov wrote: > > On Sat, Nov 04, 2023 at 11:24:32AM -0400, Sean Anderson wrote: > > > On 11/2/23 08:20, Igor Prusov wrote: > > > > This adds dump function to struct clk_ops which should replace > > > > soc_clk_dump. It allows clock drivers to provide custom dump > > > > implementation without overriding generic CCF dump function. > > > > > > > > Signed-off-by: Igor Prusov > > > > Reviewed-by: Patrice Chotard > > > > Tested-by: Patrice Chotard > > > > --- > > > >include/clk-uclass.h | 15 +++ > > > >1 file changed, 15 insertions(+) > > > > > > > > diff --git a/include/clk-uclass.h b/include/clk-uclass.h > > > > index a22f1a5d84..793bf14160 100644 > > > > --- a/include/clk-uclass.h > > > > +++ b/include/clk-uclass.h > > > > @@ -25,6 +25,7 @@ struct ofnode_phandle_args; > > > > * @set_parent: Set current clock parent > > > > * @enable: Enable a clock. > > > > * @disable: Disable a clock. > > > > + * @dump: Print clock information. > > > > * > > > > * The individual methods are described more fully below. > > > > */ > > > > @@ -39,6 +40,9 @@ struct clk_ops { > > > > int (*set_parent)(struct clk *clk, struct clk *parent); > > > > int (*enable)(struct clk *clk); > > > > int (*disable)(struct clk *clk); > > > > +#if IS_ENABLED(CONFIG_CMD_CLK) > > > > + int (*dump)(struct udevice *dev); > > > > +#endif > > > >}; > > > >#if 0 /* For documentation only */ > > > > @@ -135,6 +139,17 @@ int enable(struct clk *clk); > > > > * Return: zero on success, or -ve error code. > > > > */ > > > >int disable(struct clk *clk); > > > > + > > > > +/** > > > > + * dump() - Print clock information. > > > > + * @clk: The clock device to dump. > > > > + * > > > > + * If present, this function is called by "clk dump" command for each > > > > + * bound device. > > > > + * > > > > + * Return: zero on success, or -ve error code. > > > > + */ > > > > +int dump(struct udevice *dev); > > > > > > Actually, this should return void, since we don't do anything with the > > > return code. > > Good catch! Though there is, for example, zynqmp_clk_dump() that may > > return an error code. Wouldn't it be better to print an error message > > with the code in soc_clk_dump()? It might be convinient to have common > > code handling unexpected errors during dump. > > Since this function is for printing, if the driver gets an error > it should just print the error itself. It can probably provide a better > error message than we can. And this command is mainly informational anyway, > so we don't really need to set the return code (e.g. $?). Got it, will fix in v6.
Re: [PATCH v5 5/8] clk: Add dump operation to clk_ops
On Sat, Nov 04, 2023 at 11:24:32AM -0400, Sean Anderson wrote: > On 11/2/23 08:20, Igor Prusov wrote: > > This adds dump function to struct clk_ops which should replace > > soc_clk_dump. It allows clock drivers to provide custom dump > > implementation without overriding generic CCF dump function. > > > > Signed-off-by: Igor Prusov > > Reviewed-by: Patrice Chotard > > Tested-by: Patrice Chotard > > --- > > include/clk-uclass.h | 15 +++ > > 1 file changed, 15 insertions(+) > > > > diff --git a/include/clk-uclass.h b/include/clk-uclass.h > > index a22f1a5d84..793bf14160 100644 > > --- a/include/clk-uclass.h > > +++ b/include/clk-uclass.h > > @@ -25,6 +25,7 @@ struct ofnode_phandle_args; > >* @set_parent: Set current clock parent > >* @enable: Enable a clock. > >* @disable: Disable a clock. > > + * @dump: Print clock information. > >* > >* The individual methods are described more fully below. > >*/ > > @@ -39,6 +40,9 @@ struct clk_ops { > > int (*set_parent)(struct clk *clk, struct clk *parent); > > int (*enable)(struct clk *clk); > > int (*disable)(struct clk *clk); > > +#if IS_ENABLED(CONFIG_CMD_CLK) > > + int (*dump)(struct udevice *dev); > > +#endif > > }; > > #if 0 /* For documentation only */ > > @@ -135,6 +139,17 @@ int enable(struct clk *clk); > >* Return: zero on success, or -ve error code. > >*/ > > int disable(struct clk *clk); > > + > > +/** > > + * dump() - Print clock information. > > + * @clk: The clock device to dump. > > + * > > + * If present, this function is called by "clk dump" command for each > > + * bound device. > > + * > > + * Return: zero on success, or -ve error code. > > + */ > > +int dump(struct udevice *dev); > > Actually, this should return void, since we don't do anything with the return > code. Good catch! Though there is, for example, zynqmp_clk_dump() that may return an error code. Wouldn't it be better to print an error message with the code in soc_clk_dump()? It might be convinient to have common code handling unexpected errors during dump. > > --Sean > > > #endif > > #endif > -- Best Regards, Igor Prusov
[PATCH v5 7/8] clk: treewide: switch to clock dump from clk_ops
Switch to using new dump operation in clock provider drivers instead of overriding soc_clk_dump. Signed-off-by: Igor Prusov Tested-by: Patrice Chotard Reviewed-by: Sean Anderson --- arch/mips/mach-pic32/cpu.c | 23 --- drivers/clk/aspeed/clk_ast2600.c | 13 - drivers/clk/clk_k210.c | 11 +++- drivers/clk/clk_pic32.c| 39 ++ drivers/clk/clk_versal.c | 7 - drivers/clk/clk_zynq.c | 19 - drivers/clk/clk_zynqmp.c | 13 - drivers/clk/imx/clk-imx8.c | 11 +++- drivers/clk/meson/a1.c | 24 drivers/clk/mvebu/armada-37xx-periph.c | 5 +++- drivers/clk/stm32/clk-stm32mp1.c | 29 ++- 11 files changed, 89 insertions(+), 105 deletions(-) diff --git a/arch/mips/mach-pic32/cpu.c b/arch/mips/mach-pic32/cpu.c index dbf8c9cd22..3181a946a2 100644 --- a/arch/mips/mach-pic32/cpu.c +++ b/arch/mips/mach-pic32/cpu.c @@ -143,26 +143,3 @@ const char *get_core_name(void) return str; } #endif -#ifdef CONFIG_CMD_CLK - -int soc_clk_dump(void) -{ - int i; - - printf("PLL Speed: %lu MHz\n", - CLK_MHZ(rate(PLLCLK))); - - printf("CPU Speed: %lu MHz\n", CLK_MHZ(rate(PB7CLK))); - - printf("MPLL Speed: %lu MHz\n", CLK_MHZ(rate(MPLL))); - - for (i = PB1CLK; i <= PB7CLK; i++) - printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1, - CLK_MHZ(rate(i))); - - for (i = REF1CLK; i <= REF5CLK; i++) - printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1, - CLK_MHZ(rate(i))); - return 0; -} -#endif diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index b3cc8392fa..e1365d3f81 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -1109,6 +1109,7 @@ struct aspeed_clks { const char *name; }; +#if IS_ENABLED(CONFIG_CMD_CLK) static struct aspeed_clks aspeed_clk_names[] = { { ASPEED_CLK_HPLL, "hpll" }, { ASPEED_CLK_MPLL, "mpll" }, @@ -1123,18 +1124,12 @@ static struct aspeed_clks aspeed_clk_names[] = { { ASPEED_CLK_HUARTX, "huxclk" }, }; -int soc_clk_dump(void) +static int ast2600_clk_dump(struct udevice *dev) { - struct udevice *dev; struct clk clk; unsigned long rate; int i, ret; - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(aspeed_scu), - &dev); - if (ret) - return ret; - printf("Clk\t\tHz\n"); for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) { @@ -1167,11 +1162,15 @@ int soc_clk_dump(void) return 0; } +#endif struct clk_ops ast2600_clk_ops = { .get_rate = ast2600_clk_get_rate, .set_rate = ast2600_clk_set_rate, .enable = ast2600_clk_enable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = ast2600_clk_dump, +#endif }; static int ast2600_clk_probe(struct udevice *dev) diff --git a/drivers/clk/clk_k210.c b/drivers/clk/clk_k210.c index 2f17152021..058940b828 100644 --- a/drivers/clk/clk_k210.c +++ b/drivers/clk/clk_k210.c @@ -1276,16 +1276,10 @@ static void show_clks(struct k210_clk_priv *priv, int id, int depth) } } -int soc_clk_dump(void) +static int k210_clk_dump(struct udevice *dev) { - int ret; - struct udevice *dev; struct k210_clk_priv *priv; - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(k210_clk), - &dev); - if (ret) - return ret; priv = dev_get_priv(dev); puts(" Rate Enabled Name\n"); @@ -1304,6 +1298,9 @@ static const struct clk_ops k210_clk_ops = { .set_parent = k210_clk_set_parent, .enable = k210_clk_enable, .disable = k210_clk_disable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = k210_clk_dump, +#endif }; static int k210_clk_probe(struct udevice *dev) diff --git a/drivers/clk/clk_pic32.c b/drivers/clk/clk_pic32.c index ef06a7fb9f..f756fc88f0 100644 --- a/drivers/clk/clk_pic32.c +++ b/drivers/clk/clk_pic32.c @@ -20,6 +20,8 @@ DECLARE_GLOBAL_DATA_PTR; +#define CLK_MHZ(x) ((x) / 100) + /* Primary oscillator */ #define SYS_POSC_CLK_HZ2400 @@ -385,9 +387,46 @@ static ulong pic32_set_rate(struct clk *clk, ulong rate) return rate; } +#if IS_ENABLED(CONFIG_CMD_CLK) +static int pic32_dump(struct udevice *dev) +{ + int i; + struct clk clk; + + clk.dev = dev; + + clk.id = PLLCLK; + printf("PLL Speed: %lu MHz\n", + CLK_MHZ(pic32_get_rate(&clk))); + + clk.id = PB7CLK; + printf("CPU Speed: %lu MHz\n", CLK_
[PATCH v5 8/8] cmd: clk: Make soc_clk_dump static
After introducing dump to clk_ops there is no need to override or expose this symbol anymore. Signed-off-by: Igor Prusov Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard Reviewed-by: Sean Anderson --- cmd/clk.c | 4 ++-- include/clk.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cmd/clk.c b/cmd/clk.c index 4b9709d3ff..7bbcbfeda3 100644 --- a/cmd/clk.c +++ b/cmd/clk.c @@ -59,7 +59,7 @@ static void show_clks(struct udevice *dev, int depth, int last_flag) } } -int __weak soc_clk_dump(void) +static int soc_clk_dump(void) { struct udevice *dev; const struct clk_ops *ops; @@ -81,7 +81,7 @@ int __weak soc_clk_dump(void) return 0; } #else -int __weak soc_clk_dump(void) +static int soc_clk_dump(void) { puts("Not implemented\n"); return 1; diff --git a/include/clk.h b/include/clk.h index d91285235f..bf0d9c9d7f 100644 --- a/include/clk.h +++ b/include/clk.h @@ -674,8 +674,6 @@ static inline bool clk_valid(struct clk *clk) return clk && !!clk->dev; } -int soc_clk_dump(void); - #endif #define clk_prepare_enable(clk) clk_enable(clk) -- 2.34.1
[PATCH v5 6/8] cmd: clk: Use dump function from clk_ops
Add another loop to dump additional info from clock providers that implement dump operation. Signed-off-by: Igor Prusov Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard --- cmd/clk.c | 9 + 1 file changed, 9 insertions(+) diff --git a/cmd/clk.c b/cmd/clk.c index c7c379d7a6..4b9709d3ff 100644 --- a/cmd/clk.c +++ b/cmd/clk.c @@ -62,6 +62,7 @@ static void show_clks(struct udevice *dev, int depth, int last_flag) int __weak soc_clk_dump(void) { struct udevice *dev; + const struct clk_ops *ops; printf(" Rate Usecnt Name\n"); printf("--\n"); @@ -69,6 +70,14 @@ int __weak soc_clk_dump(void) uclass_foreach_dev_probe(UCLASS_CLK, dev) show_clks(dev, -1, 0); + uclass_foreach_dev_probe(UCLASS_CLK, dev) { + ops = dev_get_driver_ops(dev); + if (ops && ops->dump) { + printf("\n%s %s:\n", dev->driver->name, dev->name); + ops->dump(dev); + } + } + return 0; } #else -- 2.34.1
[PATCH v5 5/8] clk: Add dump operation to clk_ops
This adds dump function to struct clk_ops which should replace soc_clk_dump. It allows clock drivers to provide custom dump implementation without overriding generic CCF dump function. Signed-off-by: Igor Prusov Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard --- include/clk-uclass.h | 15 +++ 1 file changed, 15 insertions(+) diff --git a/include/clk-uclass.h b/include/clk-uclass.h index a22f1a5d84..793bf14160 100644 --- a/include/clk-uclass.h +++ b/include/clk-uclass.h @@ -25,6 +25,7 @@ struct ofnode_phandle_args; * @set_parent: Set current clock parent * @enable: Enable a clock. * @disable: Disable a clock. + * @dump: Print clock information. * * The individual methods are described more fully below. */ @@ -39,6 +40,9 @@ struct clk_ops { int (*set_parent)(struct clk *clk, struct clk *parent); int (*enable)(struct clk *clk); int (*disable)(struct clk *clk); +#if IS_ENABLED(CONFIG_CMD_CLK) + int (*dump)(struct udevice *dev); +#endif }; #if 0 /* For documentation only */ @@ -135,6 +139,17 @@ int enable(struct clk *clk); * Return: zero on success, or -ve error code. */ int disable(struct clk *clk); + +/** + * dump() - Print clock information. + * @clk: The clock device to dump. + * + * If present, this function is called by "clk dump" command for each + * bound device. + * + * Return: zero on success, or -ve error code. + */ +int dump(struct udevice *dev); #endif #endif -- 2.34.1
[PATCH v5 1/8] clk: zynq: Move soc_clk_dump to Zynq clock driver
Move clock dump function in preparation for switching to dump function in clk_ops. Signed-off-by: Igor Prusov Acked-by: Michal Simek --- arch/arm/mach-zynq/clk.c | 57 --- drivers/clk/clk_zynq.c | 58 2 files changed, 58 insertions(+), 57 deletions(-) diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c index 1945f60e08..e6a67326dd 100644 --- a/arch/arm/mach-zynq/clk.c +++ b/arch/arm/mach-zynq/clk.c @@ -13,20 +13,6 @@ DECLARE_GLOBAL_DATA_PTR; -static const char * const clk_names[clk_max] = { - "armpll", "ddrpll", "iopll", - "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", - "ddr2x", "ddr3x", "dci", - "lqspi", "smc", "pcap", "gem0", "gem1", - "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", - "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", - "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", - "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", - "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", - "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", - "smc_aper", "swdt", "dbg_trc", "dbg_apb" -}; - /** * set_cpu_clk_info() - Setup clock information * @@ -65,46 +51,3 @@ int set_cpu_clk_info(void) return 0; } - -/** - * soc_clk_dump() - Print clock frequencies - * Returns zero on success - * - * Implementation for the clk dump command. - */ -int soc_clk_dump(void) -{ - struct udevice *dev; - int i, ret; - - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(zynq_clk), &dev); - if (ret) - return ret; - - printf("clk\t\tfrequency\n"); - for (i = 0; i < clk_max; i++) { - const char *name = clk_names[i]; - if (name) { - struct clk clk; - unsigned long rate; - - clk.id = i; - ret = clk_request(dev, &clk); - if (ret < 0) - return ret; - - rate = clk_get_rate(&clk); - - clk_free(&clk); - - if ((rate == (unsigned long)-ENOSYS) || - (rate == (unsigned long)-ENXIO)) - printf("%10s%20s\n", name, "unknown"); - else - printf("%10s%20lu\n", name, rate); - } - } - - return 0; -} diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c index e80500e382..be5226175f 100644 --- a/drivers/clk/clk_zynq.c +++ b/drivers/clk/clk_zynq.c @@ -454,6 +454,64 @@ static int dummy_enable(struct clk *clk) return 0; } +static const char * const clk_names[clk_max] = { + "armpll", "ddrpll", "iopll", + "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", + "ddr2x", "ddr3x", "dci", + "lqspi", "smc", "pcap", "gem0", "gem1", + "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", + "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", + "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", + "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", + "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", + "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", + "smc_aper", "swdt", "dbg_trc", "dbg_apb" +}; + +/** + * soc_clk_dump() - Print clock frequencies + * Returns zero on success + * + * Implementation for the clk dump command. + */ +int soc_clk_dump(void) +{ + struct udevice *dev; + int i, ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(zynq_clk), &dev); + if (ret) + return ret; + + printf("clk\t\tfrequency\n"); + for (i = 0; i < clk_max; i++) { + const char *name = clk_names[i]; + + if (name) { + struct clk clk; + unsigned long rate; + + clk.id = i; + ret = clk_request(dev, &clk); + if (ret < 0) + return ret; + + rate = clk_get_rate(&clk); + + clk_free(&clk); + + if ((rate == (unsigned long)-ENOSYS) || + (rate == (unsigned long)-ENXIO)) + printf("%10s%20s\n", name, "unknown"); + else + printf("%10s%20lu\n", name, rate); + } + } + + return 0; +} + static struct clk_ops zynq_clk_ops = { .get_rate = zynq_clk_get_rate, #ifndef CONFIG_SPL_BUILD -- 2.34.1
[PATCH v5 4/8] clk: amlogic: Move driver and ops structs
Move driver and ops structs to avoid forward declaration after switching to dump in clk_ops. Signed-off-by: Igor Prusov Reviewed-by: Neil Armstrong --- drivers/clk/meson/a1.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/clk/meson/a1.c b/drivers/clk/meson/a1.c index 1075ba7333..e3fa9db7d0 100644 --- a/drivers/clk/meson/a1.c +++ b/drivers/clk/meson/a1.c @@ -601,14 +601,6 @@ static int meson_clk_set_parent(struct clk *clk, struct clk *parent_clk) return meson_mux_set_parent_by_id(clk, parent_clk->id); } -static struct clk_ops meson_clk_ops = { - .disable= meson_clk_disable, - .enable = meson_clk_enable, - .get_rate = meson_clk_get_rate, - .set_rate = meson_clk_set_rate, - .set_parent = meson_clk_set_parent, -}; - static int meson_clk_probe(struct udevice *dev) { struct meson_clk *priv = dev_get_priv(dev); @@ -638,15 +630,6 @@ static const struct udevice_id meson_clk_ids[] = { { } }; -U_BOOT_DRIVER(meson_clk) = { - .name = "meson-clk-a1", - .id = UCLASS_CLK, - .of_match = meson_clk_ids, - .priv_auto = sizeof(struct meson_clk), - .ops= &meson_clk_ops, - .probe = meson_clk_probe, -}; - static const char *meson_clk_get_name(struct clk *clk, int id) { const struct meson_clk_info *info; @@ -727,3 +710,20 @@ int soc_clk_dump(void) return 0; } + +static struct clk_ops meson_clk_ops = { + .disable= meson_clk_disable, + .enable = meson_clk_enable, + .get_rate = meson_clk_get_rate, + .set_rate = meson_clk_set_rate, + .set_parent = meson_clk_set_parent, +}; + +U_BOOT_DRIVER(meson_clk) = { + .name = "meson-clk-a1", + .id = UCLASS_CLK, + .of_match = meson_clk_ids, + .priv_auto = sizeof(struct meson_clk), + .ops= &meson_clk_ops, + .probe = meson_clk_probe, +}; -- 2.34.1
[PATCH v5 3/8] clk: k210: Move soc_clk_dump function
Move clock dump function to avoid forward declaration after switching to dump in clk_ops. Signed-off-by: Igor Prusov Reviewed-by: Sean Anderson --- drivers/clk/clk_k210.c | 92 +- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/clk/clk_k210.c b/drivers/clk/clk_k210.c index c534cc07e0..2f17152021 100644 --- a/drivers/clk/clk_k210.c +++ b/drivers/clk/clk_k210.c @@ -1238,52 +1238,6 @@ static int k210_clk_request(struct clk *clk) return 0; } -static const struct clk_ops k210_clk_ops = { - .request = k210_clk_request, - .set_rate = k210_clk_set_rate, - .get_rate = k210_clk_get_rate, - .set_parent = k210_clk_set_parent, - .enable = k210_clk_enable, - .disable = k210_clk_disable, -}; - -static int k210_clk_probe(struct udevice *dev) -{ - int ret; - struct k210_clk_priv *priv = dev_get_priv(dev); - - priv->base = dev_read_addr_ptr(dev_get_parent(dev)); - if (!priv->base) - return -EINVAL; - - ret = clk_get_by_index(dev, 0, &priv->in0); - if (ret) - return ret; - - /* -* Force setting defaults, even before relocation. This is so we can -* set the clock rate for PLL1 before we relocate into aisram. -*/ - if (!(gd->flags & GD_FLG_RELOC)) - clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE); - - return 0; -} - -static const struct udevice_id k210_clk_ids[] = { - { .compatible = "canaan,k210-clk" }, - { }, -}; - -U_BOOT_DRIVER(k210_clk) = { - .name = "k210_clk", - .id = UCLASS_CLK, - .of_match = k210_clk_ids, - .ops = &k210_clk_ops, - .probe = k210_clk_probe, - .priv_auto = sizeof(struct k210_clk_priv), -}; - #if IS_ENABLED(CONFIG_CMD_CLK) static char show_enabled(struct k210_clk_priv *priv, int id) { @@ -1342,3 +1296,49 @@ int soc_clk_dump(void) return 0; } #endif + +static const struct clk_ops k210_clk_ops = { + .request = k210_clk_request, + .set_rate = k210_clk_set_rate, + .get_rate = k210_clk_get_rate, + .set_parent = k210_clk_set_parent, + .enable = k210_clk_enable, + .disable = k210_clk_disable, +}; + +static int k210_clk_probe(struct udevice *dev) +{ + int ret; + struct k210_clk_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev_get_parent(dev)); + if (!priv->base) + return -EINVAL; + + ret = clk_get_by_index(dev, 0, &priv->in0); + if (ret) + return ret; + + /* +* Force setting defaults, even before relocation. This is so we can +* set the clock rate for PLL1 before we relocate into aisram. +*/ + if (!(gd->flags & GD_FLG_RELOC)) + clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE); + + return 0; +} + +static const struct udevice_id k210_clk_ids[] = { + { .compatible = "canaan,k210-clk" }, + { }, +}; + +U_BOOT_DRIVER(k210_clk) = { + .name = "k210_clk", + .id = UCLASS_CLK, + .of_match = k210_clk_ids, + .ops = &k210_clk_ops, + .probe = k210_clk_probe, + .priv_auto = sizeof(struct k210_clk_priv), +}; -- 2.34.1
[PATCH v5 2/8] clk: ast2600: Move soc_clk_dump function
Move clock dump function to avoid forward declaration after switching to dump in clk_ops. Signed-off-by: Igor Prusov --- drivers/clk/aspeed/clk_ast2600.c | 70 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index e5ada5b6d4..b3cc8392fa 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -1104,41 +1104,6 @@ static int ast2600_clk_enable(struct clk *clk) return 0; } -struct clk_ops ast2600_clk_ops = { - .get_rate = ast2600_clk_get_rate, - .set_rate = ast2600_clk_set_rate, - .enable = ast2600_clk_enable, -}; - -static int ast2600_clk_probe(struct udevice *dev) -{ - struct ast2600_clk_priv *priv = dev_get_priv(dev); - - priv->scu = devfdt_get_addr_ptr(dev); - if (IS_ERR(priv->scu)) - return PTR_ERR(priv->scu); - - ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); - ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); - ast2600_configure_mac12_clk(priv->scu); - ast2600_configure_mac34_clk(priv->scu); - ast2600_configure_rsa_ecc_clk(priv->scu); - - return 0; -} - -static int ast2600_clk_bind(struct udevice *dev) -{ - int ret; - - /* The reset driver does not have a device node, so bind it here */ - ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); - if (ret) - debug("Warning: No reset driver: ret=%d\n", ret); - - return 0; -} - struct aspeed_clks { ulong id; const char *name; @@ -1203,6 +1168,41 @@ int soc_clk_dump(void) return 0; } +struct clk_ops ast2600_clk_ops = { + .get_rate = ast2600_clk_get_rate, + .set_rate = ast2600_clk_set_rate, + .enable = ast2600_clk_enable, +}; + +static int ast2600_clk_probe(struct udevice *dev) +{ + struct ast2600_clk_priv *priv = dev_get_priv(dev); + + priv->scu = devfdt_get_addr_ptr(dev); + if (IS_ERR(priv->scu)) + return PTR_ERR(priv->scu); + + ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); + ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); + ast2600_configure_mac12_clk(priv->scu); + ast2600_configure_mac34_clk(priv->scu); + ast2600_configure_rsa_ecc_clk(priv->scu); + + return 0; +} + +static int ast2600_clk_bind(struct udevice *dev) +{ + int ret; + + /* The reset driver does not have a device node, so bind it here */ + ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); + if (ret) + debug("Warning: No reset driver: ret=%d\n", ret); + + return 0; +} + static const struct udevice_id ast2600_clk_ids[] = { { .compatible = "aspeed,ast2600-scu", }, { }, -- 2.34.1
[PATCH v5 0/8] clk: Switch from soc_clk_dump to clk_ops function
Currently clock providers may override default implementation of soc_clk_dump function to replace clk dump command output. This causes confusing behaviour when u-boot is built with one of such drivers enabled but still has clocks defined using CCF. For example, enabling CMD_CLK and using clk dump on sandbox target will not show CCF clocks because k210 driver overrides common soc_clk_dump. Changelog: v1 -> v2: - Add missing static to dump functions v2 -> v3: - Make soc_clk_dump in cmd/clk.c static instead of removing __weak v3 -> v4: - Rebase and refactor dump for new Amlogic A1 clock controller driver v4 -> v5: - Add docs for dump() function in clk_ops - Print driver and device names before calling corresponding dump() Igor Prusov (8): clk: zynq: Move soc_clk_dump to Zynq clock driver clk: ast2600: Move soc_clk_dump function clk: k210: Move soc_clk_dump function clk: amlogic: Move driver and ops structs clk: Add dump operation to clk_ops cmd: clk: Use dump function from clk_ops clk: treewide: switch to clock dump from clk_ops cmd: clk: Make soc_clk_dump static arch/arm/mach-zynq/clk.c | 57 -- arch/mips/mach-pic32/cpu.c | 23 -- cmd/clk.c | 13 +++- drivers/clk/aspeed/clk_ast2600.c | 83 ++-- drivers/clk/clk_k210.c | 103 - drivers/clk/clk_pic32.c| 39 ++ drivers/clk/clk_versal.c | 7 +- drivers/clk/clk_zynq.c | 51 drivers/clk/clk_zynqmp.c | 13 ++-- drivers/clk/imx/clk-imx8.c | 11 +-- drivers/clk/meson/a1.c | 54 + drivers/clk/mvebu/armada-37xx-periph.c | 5 +- drivers/clk/stm32/clk-stm32mp1.c | 29 ++- include/clk-uclass.h | 15 include/clk.h | 2 - 15 files changed, 256 insertions(+), 249 deletions(-) -- 2.34.1
[PATCH v2 2/2] ARM: amlogic: ad401: enable SPIFC
Enable Amlogic A1 SPI FLash Controller support. Signed-off-by: Igor Prusov Reviewed-by: Neil Armstrong --- configs/ad401_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/ad401_defconfig b/configs/ad401_defconfig index b9aca3ab0d..b44b9c63e8 100644 --- a/configs/ad401_defconfig +++ b/configs/ad401_defconfig @@ -51,6 +51,7 @@ CONFIG_DEBUG_UART_SKIP_INIT=y CONFIG_MESON_SERIAL=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_MESON_SPIFC_A1=y CONFIG_USB=y CONFIG_DM_USB_GADGET=y CONFIG_USB_GADGET=y -- 2.34.1
[PATCH v2 1/2] spi: add support for Amlogic A1 SPI Flash Controller
From: Igor Prusov Add A1 SPIFC driver from Linux. Slightly modified to use u-boot driver framework and accommodate to lack of ioread32_rep/iowrite32_rep. Based on Linux version 6.6-rc4 Signed-off-by: Igor Prusov Signed-off-by: Martin Kurbanov Reviewed-by: Simon Glass --- drivers/spi/Kconfig | 9 + drivers/spi/Makefile | 1 + drivers/spi/meson_spifc_a1.c | 384 +++ 3 files changed, 394 insertions(+) create mode 100644 drivers/spi/meson_spifc_a1.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 854b8b88da..66cf727113 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -251,6 +251,15 @@ config MICROCHIP_COREQSPI Enable the QSPI driver for Microchip FPGA QSPI controllers. This driver can be used on Polarfire SoC. +config MESON_SPIFC_A1 + bool "Amlogic Meson A1 SPI Flash Controller driver" + depends on ARCH_MESON + help + Enable the Amlogic A1 SPI Flash Controller (SPIFC) driver. + This driver can be used to access the SPI NOR/NAND flash chips + with STR mode frequency up to 98MHz. Dual and quad modes are + supported by controller. + config MPC8XX_SPI bool "MPC8XX SPI Driver" depends on MPC8xx diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index c27b3327c3..14bdb97f18 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_ICH_SPI) += ich.o obj-$(CONFIG_IPROC_QSPI) += iproc_qspi.o obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o +obj-$(CONFIG_MESON_SPIFC_A1) += meson_spifc_a1.o obj-$(CONFIG_MICROCHIP_COREQSPI) += microchip_coreqspi.o obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o diff --git a/drivers/spi/meson_spifc_a1.c b/drivers/spi/meson_spifc_a1.c new file mode 100644 index 00..7cefb03197 --- /dev/null +++ b/drivers/spi/meson_spifc_a1.c @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for Amlogic A1 SPI flash controller (SPIFC) + * + * Copyright (c) 2023, SberDevices. All Rights Reserved. + * + * Author: Martin Kurbanov + * + * Ported to u-boot: + * Author: Igor Prusov + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPIFC_A1_AHB_CTRL_REG 0x0 +#define SPIFC_A1_AHB_BUS_ENBIT(31) + +#define SPIFC_A1_USER_CTRL0_REG0x200 +#define SPIFC_A1_USER_REQUEST_ENABLE BIT(31) +#define SPIFC_A1_USER_REQUEST_FINISH BIT(30) +#define SPIFC_A1_USER_DATA_UPDATED BIT(0) + +#define SPIFC_A1_USER_CTRL1_REG0x204 +#define SPIFC_A1_USER_CMD_ENABLE BIT(30) +#define SPIFC_A1_USER_CMD_MODE GENMASK(29, 28) +#define SPIFC_A1_USER_CMD_CODE GENMASK(27, 20) +#define SPIFC_A1_USER_ADDR_ENABLE BIT(19) +#define SPIFC_A1_USER_ADDR_MODEGENMASK(18, 17) +#define SPIFC_A1_USER_ADDR_BYTES GENMASK(16, 15) +#define SPIFC_A1_USER_DOUT_ENABLE BIT(14) +#define SPIFC_A1_USER_DOUT_MODEGENMASK(11, 10) +#define SPIFC_A1_USER_DOUT_BYTES GENMASK(9, 0) + +#define SPIFC_A1_USER_CTRL2_REG0x208 +#define SPIFC_A1_USER_DUMMY_ENABLE BIT(31) +#define SPIFC_A1_USER_DUMMY_MODE GENMASK(30, 29) +#define SPIFC_A1_USER_DUMMY_CLK_SYCLES GENMASK(28, 23) + +#define SPIFC_A1_USER_CTRL3_REG0x20c +#define SPIFC_A1_USER_DIN_ENABLE BIT(31) +#define SPIFC_A1_USER_DIN_MODE GENMASK(28, 27) +#define SPIFC_A1_USER_DIN_BYTESGENMASK(25, 16) + +#define SPIFC_A1_USER_ADDR_REG 0x210 + +#define SPIFC_A1_AHB_REQ_CTRL_REG 0x214 +#define SPIFC_A1_AHB_REQ_ENABLEBIT(31) + +#define SPIFC_A1_ACTIMING0_REG (0x0088 << 2) +#define SPIFC_A1_TSLCH GENMASK(31, 30) +#define SPIFC_A1_TCLSH GENMASK(29, 28) +#define SPIFC_A1_TSHWL GENMASK(20, 16) +#define SPIFC_A1_TSHSL2GENMASK(15, 12) +#define SPIFC_A1_TSHSL1GENMASK(11, 8) +#define SPIFC_A1_TWHSL GENMASK(7, 0) + +#define SPIFC_A1_DBUF_CTRL_REG 0x240 +#define SPIFC_A1_DBUF_DIR BIT(31) +#define SPIFC_A1_DBUF_AUTO_UPDATE_ADDR BIT(30) +#define SPIFC_A1_DBUF_ADDR GENMASK(7, 0) + +#define SPIFC_A1_DBUF_DATA_REG 0x244 + +#define SPIFC_A1_USER_DBUF_ADDR_REG0x248 + +#define SPIFC_A1_BUFFER_SIZE 512U + +#define SPIFC_A1_MAX_HZ2 +#define SPIFC_A1_MIN_HZ100 + +#define SPIFC_A1_USER_CMD(op) ( \ + SPIFC_A1_USER_CMD_ENABLE | \ + FIELD_PREP(SPIFC_A1_USER_CMD_CODE, (op)->cmd.opcode) | \ + FIELD_PREP(SPIFC_A1_USER_CMD_MODE, ilog2((op)->cmd.buswidth))) + +#define SPIFC_A1_USER_ADDR(op) ( \ + SPIFC_A1_USER_ADDR_ENABLE | \ + FIELD_PREP(SPIFC_A1_USER_ADDR
[PATCH v2 0/2] ARM: amlogic: Add A1 SPIFC support
A1 family boards have new version of SPIFC controller, that is incompatible with meson_spifc driver. This series ports A1 SPIFC driver from Linux and enables it for ad401 board. Changes in V2: - more details in Kconfig help message - removed unused field of struct amlogic_spifc_a1 - add missed check for NULL during probe Igor Prusov (2): spi: add support for Amlogic A1 SPI Flash Controller ARM: amlogic: ad401: enable SPIFC configs/ad401_defconfig | 1 + drivers/spi/Kconfig | 9 + drivers/spi/Makefile | 1 + drivers/spi/meson_spifc_a1.c | 384 +++ 4 files changed, 395 insertions(+) create mode 100644 drivers/spi/meson_spifc_a1.c -- 2.34.1
Re: [RESEND PATCH v1 1/2] spi: add support for Amlogic A1 SPI Flash Controller
On Tue, Oct 17, 2023 at 09:33:02PM -0600, Simon Glass wrote: > Hi Igor, > > On Tue, 17 Oct 2023 at 11:18, Igor Prusov wrote: > > > > From: Igor Prusov > > > > Add A1 SPIFC driver from Linux. Slightly modified to use u-boot driver > > framework and accommodate to lack of ioread32_rep/iowrite32_rep. > > Well, you could bring them in! > I was thinking about it, but I'd prefer to make a separate series with it, if you don't mind. Need some time to figure out best way to integrate them into u-boot and I'd like to take a look at other drivers that could use those while I'm at it. [...] -- Best Regards, Igor Prusov
Re: [RESEND PATCH v1 1/2] spi: add support for Amlogic A1 SPI Flash Controller
On Tue, Oct 17, 2023 at 09:33:02PM -0600, Simon Glass wrote: > Hi Igor, > > On Tue, 17 Oct 2023 at 11:18, Igor Prusov wrote: > > > > From: Igor Prusov > > > > Add A1 SPIFC driver from Linux. Slightly modified to use u-boot driver > > framework and accommodate to lack of ioread32_rep/iowrite32_rep. > > Well, you could bring them in! > > > > > Based on Linux version 6.6-rc4 > > > > Signed-off-by: Igor Prusov > > Signed-off-by: Martin Kurbanov > > --- > > drivers/spi/Kconfig | 8 + > > drivers/spi/Makefile | 1 + > > drivers/spi/meson_spifc_a1.c | 384 +++ > > 3 files changed, 393 insertions(+) > > create mode 100644 drivers/spi/meson_spifc_a1.c > > Reviewed-by: Simon Glass > > nits below > > > > > diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig > > index 854b8b88da..dedb366370 100644 > > --- a/drivers/spi/Kconfig > > +++ b/drivers/spi/Kconfig > > @@ -251,6 +251,14 @@ config MICROCHIP_COREQSPI > > Enable the QSPI driver for Microchip FPGA QSPI controllers. > > This driver can be used on Polarfire SoC. > > > > +config MESON_SPIFC_A1 > > + bool "Amlogic Meson A1 SPI Flash Controller driver" > > + depends on ARCH_MESON > > + help > > + Enable the Amlogic A1 SPI Flash Controller (SPIFC) driver. > > + This driver can be used to access the SPI NOR/NAND flash chips on > > + Amlogic A1 SoC. > > What speeds does and modes it support? Can you add a little more detail? > Sure, will add in v2. > > + > > config MPC8XX_SPI > > bool "MPC8XX SPI Driver" > > depends on MPC8xx > > diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile > > index c27b3327c3..14bdb97f18 100644 > > --- a/drivers/spi/Makefile > > +++ b/drivers/spi/Makefile > > @@ -41,6 +41,7 @@ obj-$(CONFIG_ICH_SPI) += ich.o > > obj-$(CONFIG_IPROC_QSPI) += iproc_qspi.o > > obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o > > obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o > > +obj-$(CONFIG_MESON_SPIFC_A1) += meson_spifc_a1.o > > obj-$(CONFIG_MICROCHIP_COREQSPI) += microchip_coreqspi.o > > obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o > > obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o > > diff --git a/drivers/spi/meson_spifc_a1.c b/drivers/spi/meson_spifc_a1.c > > new file mode 100644 > > index 000000..4b840c4634 > > --- /dev/null > > +++ b/drivers/spi/meson_spifc_a1.c > > @@ -0,0 +1,384 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Driver for Amlogic A1 SPI flash controller (SPIFC) > > + * > > + * Copyright (c) 2023, SberDevices. All Rights Reserved. > > + * > > + * Author: Martin Kurbanov > > + * > > + * Ported to u-boot: > > + * Author: Igor Prusov > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#define SPIFC_A1_AHB_CTRL_REG 0x0 > > +#define SPIFC_A1_AHB_BUS_ENBIT(31) > > + > > +#define SPIFC_A1_USER_CTRL0_REG0x200 > > +#define SPIFC_A1_USER_REQUEST_ENABLE BIT(31) > > +#define SPIFC_A1_USER_REQUEST_FINISH BIT(30) > > +#define SPIFC_A1_USER_DATA_UPDATED BIT(0) > > + > > +#define SPIFC_A1_USER_CTRL1_REG0x204 > > +#define SPIFC_A1_USER_CMD_ENABLE BIT(30) > > +#define SPIFC_A1_USER_CMD_MODE GENMASK(29, 28) > > +#define SPIFC_A1_USER_CMD_CODE GENMASK(27, 20) > > +#define SPIFC_A1_USER_ADDR_ENABLE BIT(19) > > +#define SPIFC_A1_USER_ADDR_MODEGENMASK(18, 17) > > +#define SPIFC_A1_USER_ADDR_BYTES GENMASK(16, 15) > > +#define SPIFC_A1_USER_DOUT_ENABLE BIT(14) > > +#define SPIFC_A1_USER_DOUT_MODEGENMASK(11, 10) > > +#define SPIFC_A1_USER_DOUT_BYTES GENMASK(9, 0) > > + > > +#define SPIFC_A1_USER_CTRL2_REG0x208 > > +#define SPIFC_A1_USER_DUMMY_ENABLE BIT(31) > > +#define SPIFC_A1_USER_DUMMY_MODE GENMASK(30, 29) > > +#define SPIFC_A1_USER_DUMMY_CLK_SYCLES GENMASK(28, 23) > > + > > +#define SPIFC_A1_USER_CTRL3_REG0x20c > > +#define SPIFC_A1_USER_DIN_ENABLE BIT(31) > > +#define SPIFC_A1_USER_DIN_MODE GENMASK(28, 27) > > +#define SPIFC_A1_USER_DIN_BYTESGENMASK(25, 16) > > + > > +#define SPIFC_A1_USE
[PATCH v1 2/2] arm: meson-a1: dts: Sync DT with Linux
Import device tree changes from Linux v6.6-rc6 for Amlogic A1 board. Signed-off-by: Igor Prusov --- arch/arm/dts/meson-a1.dtsi | 356 - 1 file changed, 351 insertions(+), 5 deletions(-) diff --git a/arch/arm/dts/meson-a1.dtsi b/arch/arm/dts/meson-a1.dtsi index e3a42c5b24..648e7f4942 100644 --- a/arch/arm/dts/meson-a1.dtsi +++ b/arch/arm/dts/meson-a1.dtsi @@ -3,9 +3,13 @@ * Copyright (c) 2019 Amlogic, Inc. All rights reserved. */ -#include -#include +#include +#include #include +#include +#include +#include +#include / { compatible = "amlogic,a1"; @@ -37,9 +41,19 @@ l2: l2-cache0 { compatible = "cache"; cache-level = <2>; + cache-unified; }; }; + efuse: efuse { + compatible = "amlogic,meson-gxbb-efuse"; + clocks = <&clkc_periphs CLKID_OTP>; + #address-cells = <1>; + #size-cells = <1>; + secure-monitor = <&sm>; + power-domains = <&pwrc PWRC_OTP_ID>; + }; + psci { compatible = "arm,psci-1.0"; method = "smc"; @@ -65,7 +79,6 @@ pwrc: power-controller { compatible = "amlogic,meson-a1-pwrc"; #power-domain-cells = <1>; - status = "okay"; }; }; @@ -75,6 +88,16 @@ #size-cells = <2>; ranges; + spifc: spi@fd000400 { + compatible = "amlogic,a1-spifc"; + reg = <0x0 0xfd000400 0x0 0x290>; + clocks = <&clkc_periphs CLKID_SPIFC>; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&pwrc PWRC_SPIFC_ID>; + status = "disabled"; + }; + apb: bus@fe00 { compatible = "simple-bus"; reg = <0x0 0xfe00 0x0 0x100>; @@ -103,10 +126,200 @@ gpio-ranges = <&periphs_pinctrl 0 0 62>; }; + i2c0_f11_pins: i2c0-f11 { + mux { + groups = "i2c0_sck_f11", +"i2c0_sda_f12"; + function = "i2c0"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + i2c0_f9_pins: i2c0-f9 { + mux { + groups = "i2c0_sck_f9", +"i2c0_sda_f10"; + function = "i2c0"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + i2c1_x_pins: i2c1-x { + mux { + groups = "i2c1_sck_x", +"i2c1_sda_x"; + function = "i2c1"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + i2c1_a_pins: i2c1-a { + mux { + groups = "i2c1_sck_a", +"i2c1_sda_a"; + function = "i2c1"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + i2c2_x0_pins: i2c2-x0 { + m
[PATCH v1 1/2] serial: amlogic: Add UART compatible for A1 board
Add additional compatible to allow using serial driver with A1 board. After compatible change in DTS [1], serial_meson driver should still be able to work with console device. [1] https://lore.kernel.org/all/20230705181833.16137-8-ddroko...@sberdevices.ru/ Signed-off-by: Igor Prusov --- drivers/serial/serial_meson.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/serial/serial_meson.c b/drivers/serial/serial_meson.c index 934de2ab23..be5f380f85 100644 --- a/drivers/serial/serial_meson.c +++ b/drivers/serial/serial_meson.c @@ -232,6 +232,7 @@ static const struct dm_serial_ops meson_serial_ops = { static const struct udevice_id meson_serial_ids[] = { { .compatible = "amlogic,meson-uart" }, { .compatible = "amlogic,meson-gx-uart" }, + { .compatible = "amlogic,meson-a1-uart" }, { } }; -- 2.34.1
[PATCH v1 0/2] arm: dts: meson-a1 Sync DT with Linux
This series syncs Device Tree for Amlogic A1 with Linux. Currently DTS in Linix has different compatible string for serial devices, which is not recognized by serial_meson driver, so new compatible is added to driver as well. Additional driver changes are not required because new compatible only differentiates between ttyAML and ttyS names for serial console devices. Igor Prusov (2): serial: amlogic: Add UART compatible for A1 board arm: meson-a1: dts: Sync DT with Linux arch/arm/dts/meson-a1.dtsi| 356 +- drivers/serial/serial_meson.c | 1 + 2 files changed, 352 insertions(+), 5 deletions(-) -- 2.34.1
[PATCH v2 1/1] mtd: spinand: add support for ESMT F50x1G41LB
Adaptation of Linux commit d74c36480a67 This patch adds support for ESMT F50L1G41LB and F50D1G41LB. It seems that ESMT likes to use random JEDEC ID from other vendors. Their 1G chips uses 0xc8 from GigaDevice and 2G/4G chips uses 0x2c from Micron. For this reason, the ESMT entry is named esmt_c8 with explicit JEDEC ID in variable name. Datasheets: https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50L1G41LB(2M).pdf https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50D1G41LB(2M).pdf Signed-off-by: Igor Prusov Signed-off-by: Chuanhong Guo Signed-off-by: Martin Kurbanov Signed-off-by: Dmitry Rokosov Tested-by: Martin Kurbanov --- drivers/mtd/nand/spi/Makefile | 3 +- drivers/mtd/nand/spi/core.c | 1 + drivers/mtd/nand/spi/esmt.c | 137 ++ include/linux/mtd/spinand.h | 1 + 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 drivers/mtd/nand/spi/esmt.c diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile index 3051de4f7e..f172f4787f 100644 --- a/drivers/mtd/nand/spi/Makefile +++ b/drivers/mtd/nand/spi/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o +spinand-objs := core.o esmt.o gigadevice.o macronix.o micron.o paragon.o +spinand-objs += toshiba.o winbond.o obj-$(CONFIG_MTD_SPI_NAND) += spinand.o diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 597b088ca7..8ca33459f9 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -828,6 +828,7 @@ static const struct spinand_manufacturer *spinand_manufacturers[] = { ¶gon_spinand_manufacturer, &toshiba_spinand_manufacturer, &winbond_spinand_manufacturer, + &esmt_c8_spinand_manufacturer, }; static int spinand_manufacturer_match(struct spinand_device *spinand, diff --git a/drivers/mtd/nand/spi/esmt.c b/drivers/mtd/nand/spi/esmt.c new file mode 100644 index 00..7e07b26827 --- /dev/null +++ b/drivers/mtd/nand/spi/esmt.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Author: + * Chuanhong Guo - the main driver logic + * Martin Kurbanov - OOB layout + */ + +#ifndef __UBOOT__ +#include +#include +#endif +#include + +/* ESMT uses GigaDevice 0xc8 JECDEC ID on some SPI NANDs */ +#define SPINAND_MFR_ESMT_C80xc8 + +static SPINAND_OP_VARIANTS(read_cache_variants, + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); + +static SPINAND_OP_VARIANTS(write_cache_variants, + SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), + SPINAND_PROG_LOAD(true, 0, NULL, 0)); + +static SPINAND_OP_VARIANTS(update_cache_variants, + SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), + SPINAND_PROG_LOAD(false, 0, NULL, 0)); + +/* + * OOB spare area map (64 bytes) + * + * Bad Block Markers + * filled by HW and kernel Reserved + * | +---+---+ + * | | | | + * | |OOB free data Area |non ECC protected | + * | +-|-+-|-+-|-+ + * | | | | | | | | + * +-|---|--+--|-|--+--|-|--+--|-|--+ + * | | | section0 | | |section1 | | |section2 | | | section3 | + * +-v-+-v-+---++--v--+--v--+-+-+--v--+--v--+-+-+--v--+--v--+-+-+ + * | | | || | | | | | | | | | | | | + * |0:1|2:3|4:7|8:15|16:17|18:19|20:23|24:31|32:33|34:35|36:39|40:47|48:49|50:51|52:55|56:63| + * | | | || | | | | | | | | | | | | + * +---+---+-^-+--^-+-+-+--^--+--^--+-+-+--^--+--^--+-+-+--^--+--^--+ + * ||| | | | | | + * | +|-+-|-+-|-+ + * | ECC Area|(Main + Spare) - filled|by ESMT NAND HW | + * | | | | + * +-+---+---+ + * OOB ECC protected Area - not used due to + * partial programming from some filesystems + * (like JFFS2 with cleanmarkers) + *
[PATCH v2 0/1] mtd: spinand: add support for ESMT F50x1G41LB
This series ports ESMT NAND support from Linux. Changes in v2: - Dropped detect procedure rework patch, since similar one was already applied to u-boot in commit b20913e3cb. - Updated NAND_MEMORG values, so that they are correct after mbb parameter was added in 8acaec923b. Igor Prusov (1): mtd: spinand: add support for ESMT F50x1G41LB drivers/mtd/nand/spi/Makefile | 3 +- drivers/mtd/nand/spi/core.c | 1 + drivers/mtd/nand/spi/esmt.c | 137 ++ include/linux/mtd/spinand.h | 1 + 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 drivers/mtd/nand/spi/esmt.c -- 2.34.1
Re: [PATCH v1 1/2] mtd: spinand: rework detect procedure for different READ_ID operation
Hi Frieder, On Mon, Oct 09, 2023 at 10:23:53AM +0200, Frieder Schrempf wrote: > On 04.10.23 17:07, Igor Prusov wrote: > > Adaptation of Linux commit f1541773af49. > > > > Currently there are 3 different variants of read_id implementation: > > 1. opcode only. Found in GD5FxGQ4xF. > > 2. opcode + 1 addr byte. Found in GD5GxGQ4xA/E > > 3. opcode + 1 dummy byte. Found in other currently supported chips. > > > > Original implementation was for variant 1 and let detect function > > of chips with variant 2 and 3 to ignore the first byte. This isn't > > robust: > > > > 1. For chips of variant 2, if SPI master doesn't keep MOSI low > > during read, chip will get a random id offset, and the entire id > > buffer will shift by that offset, causing detect failure. > > > > 2. For chips of variant 1, if it happens to get a devid that equals > > to manufacture id of variant 2 or 3 chips, it'll get incorrectly > > detected. > > > > This patch reworks detect procedure to address problems above. New > > logic do detection for all variants separatedly, in 1-2-3 order. > > Since all current detect methods do exactly the same id matching > > procedure, unify them into core.c and remove detect method from > > manufacture_ops. > > > > Signed-off-by: Chuanhong Guo > > Signed-off-by: Igor Prusov > > An adaptation of this patch was already sent long ago [1] and Dario also > picked it up in nand-next [2]. Though it looks like this was never > merged upstream as there wasn't any pull request sent to Tom, right? Thanks for pointing this out, looks like this rework made it to upstream, so I'll drop it in v2. > Dario, as you already seem to have rebased nand-next recently, can you > please sent the changes to Tom for picking them up? As the merge window > is open at the moment it would be good to get it done soon. Thanks! > > [1] > https://patchwork.ozlabs.org/project/uboot/patch/20230110115843.391630-1-frie...@fris.de/ > [2] > https://source.denx.de/u-boot/custodians/u-boot-nand-flash/-/commits/nand-next/ -- Best Regards, Igor Prusov
[RESEND PATCH v1 1/2] spi: add support for Amlogic A1 SPI Flash Controller
From: Igor Prusov Add A1 SPIFC driver from Linux. Slightly modified to use u-boot driver framework and accommodate to lack of ioread32_rep/iowrite32_rep. Based on Linux version 6.6-rc4 Signed-off-by: Igor Prusov Signed-off-by: Martin Kurbanov --- drivers/spi/Kconfig | 8 + drivers/spi/Makefile | 1 + drivers/spi/meson_spifc_a1.c | 384 +++ 3 files changed, 393 insertions(+) create mode 100644 drivers/spi/meson_spifc_a1.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 854b8b88da..dedb366370 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -251,6 +251,14 @@ config MICROCHIP_COREQSPI Enable the QSPI driver for Microchip FPGA QSPI controllers. This driver can be used on Polarfire SoC. +config MESON_SPIFC_A1 + bool "Amlogic Meson A1 SPI Flash Controller driver" + depends on ARCH_MESON + help + Enable the Amlogic A1 SPI Flash Controller (SPIFC) driver. + This driver can be used to access the SPI NOR/NAND flash chips on + Amlogic A1 SoC. + config MPC8XX_SPI bool "MPC8XX SPI Driver" depends on MPC8xx diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index c27b3327c3..14bdb97f18 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_ICH_SPI) += ich.o obj-$(CONFIG_IPROC_QSPI) += iproc_qspi.o obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o +obj-$(CONFIG_MESON_SPIFC_A1) += meson_spifc_a1.o obj-$(CONFIG_MICROCHIP_COREQSPI) += microchip_coreqspi.o obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o diff --git a/drivers/spi/meson_spifc_a1.c b/drivers/spi/meson_spifc_a1.c new file mode 100644 index 00..4b840c4634 --- /dev/null +++ b/drivers/spi/meson_spifc_a1.c @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for Amlogic A1 SPI flash controller (SPIFC) + * + * Copyright (c) 2023, SberDevices. All Rights Reserved. + * + * Author: Martin Kurbanov + * + * Ported to u-boot: + * Author: Igor Prusov + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPIFC_A1_AHB_CTRL_REG 0x0 +#define SPIFC_A1_AHB_BUS_ENBIT(31) + +#define SPIFC_A1_USER_CTRL0_REG0x200 +#define SPIFC_A1_USER_REQUEST_ENABLE BIT(31) +#define SPIFC_A1_USER_REQUEST_FINISH BIT(30) +#define SPIFC_A1_USER_DATA_UPDATED BIT(0) + +#define SPIFC_A1_USER_CTRL1_REG0x204 +#define SPIFC_A1_USER_CMD_ENABLE BIT(30) +#define SPIFC_A1_USER_CMD_MODE GENMASK(29, 28) +#define SPIFC_A1_USER_CMD_CODE GENMASK(27, 20) +#define SPIFC_A1_USER_ADDR_ENABLE BIT(19) +#define SPIFC_A1_USER_ADDR_MODEGENMASK(18, 17) +#define SPIFC_A1_USER_ADDR_BYTES GENMASK(16, 15) +#define SPIFC_A1_USER_DOUT_ENABLE BIT(14) +#define SPIFC_A1_USER_DOUT_MODEGENMASK(11, 10) +#define SPIFC_A1_USER_DOUT_BYTES GENMASK(9, 0) + +#define SPIFC_A1_USER_CTRL2_REG0x208 +#define SPIFC_A1_USER_DUMMY_ENABLE BIT(31) +#define SPIFC_A1_USER_DUMMY_MODE GENMASK(30, 29) +#define SPIFC_A1_USER_DUMMY_CLK_SYCLES GENMASK(28, 23) + +#define SPIFC_A1_USER_CTRL3_REG0x20c +#define SPIFC_A1_USER_DIN_ENABLE BIT(31) +#define SPIFC_A1_USER_DIN_MODE GENMASK(28, 27) +#define SPIFC_A1_USER_DIN_BYTESGENMASK(25, 16) + +#define SPIFC_A1_USER_ADDR_REG 0x210 + +#define SPIFC_A1_AHB_REQ_CTRL_REG 0x214 +#define SPIFC_A1_AHB_REQ_ENABLEBIT(31) + +#define SPIFC_A1_ACTIMING0_REG (0x0088 << 2) +#define SPIFC_A1_TSLCH GENMASK(31, 30) +#define SPIFC_A1_TCLSH GENMASK(29, 28) +#define SPIFC_A1_TSHWL GENMASK(20, 16) +#define SPIFC_A1_TSHSL2GENMASK(15, 12) +#define SPIFC_A1_TSHSL1GENMASK(11, 8) +#define SPIFC_A1_TWHSL GENMASK(7, 0) + +#define SPIFC_A1_DBUF_CTRL_REG 0x240 +#define SPIFC_A1_DBUF_DIR BIT(31) +#define SPIFC_A1_DBUF_AUTO_UPDATE_ADDR BIT(30) +#define SPIFC_A1_DBUF_ADDR GENMASK(7, 0) + +#define SPIFC_A1_DBUF_DATA_REG 0x244 + +#define SPIFC_A1_USER_DBUF_ADDR_REG0x248 + +#define SPIFC_A1_BUFFER_SIZE 512U + +#define SPIFC_A1_MAX_HZ2 +#define SPIFC_A1_MIN_HZ100 + +#define SPIFC_A1_USER_CMD(op) ( \ + SPIFC_A1_USER_CMD_ENABLE | \ + FIELD_PREP(SPIFC_A1_USER_CMD_CODE, (op)->cmd.opcode) | \ + FIELD_PREP(SPIFC_A1_USER_CMD_MODE, ilog2((op)->cmd.buswidth))) + +#define SPIFC_A1_USER_ADDR(op) ( \ + SPIFC_A1_USER_ADDR_ENABLE | \ + FIELD_PREP(SPIFC_A1_USER_ADDR_MODE, ilog2((op)->addr.buswidth)) | \ + FIELD_PREP(SPIFC_A1_USER_ADDR_BYTES, (op)->addr.nbyte
[RESEND PATCH v1 2/2] ARM: amlogic: ad401: enable SPIFC
From: Igor Prusov Enable Amlogic A1 SPI FLash Controller support. Signed-off-by: Igor Prusov Reviewed-by: Neil Armstrong --- configs/ad401_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/ad401_defconfig b/configs/ad401_defconfig index b9aca3ab0d..b44b9c63e8 100644 --- a/configs/ad401_defconfig +++ b/configs/ad401_defconfig @@ -51,6 +51,7 @@ CONFIG_DEBUG_UART_SKIP_INIT=y CONFIG_MESON_SERIAL=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_MESON_SPIFC_A1=y CONFIG_USB=y CONFIG_DM_USB_GADGET=y CONFIG_USB_GADGET=y -- 2.34.1
[RESEND PATCH v1 0/2] ARM: amlogic: Add A1 SPIFC support
A1 family boards have new version of SPIFC controller, that is incompatible with meson_spifc driver. This series ports A1 SPIFC driver from Linux and enables it for ad401 board. Igor Prusov (2): spi: add support for Amlogic A1 SPI Flash Controller ARM: amlogic: ad401: enable SPIFC configs/ad401_defconfig | 1 + drivers/spi/Kconfig | 8 + drivers/spi/Makefile | 1 + drivers/spi/meson_spifc_a1.c | 384 +++ 4 files changed, 394 insertions(+) create mode 100644 drivers/spi/meson_spifc_a1.c -- 2.34.1
[PATCH v4 7/8] clk: treewide: switch to clock dump from clk_ops
Switch to using new dump operation in clock provider drivers instead of overriding soc_clk_dump. Signed-off-by: Igor Prusov Tested-by: Patrice Chotard --- arch/mips/mach-pic32/cpu.c | 23 --- drivers/clk/aspeed/clk_ast2600.c | 13 - drivers/clk/clk_k210.c | 11 +++- drivers/clk/clk_pic32.c| 39 ++ drivers/clk/clk_versal.c | 7 - drivers/clk/clk_zynq.c | 19 - drivers/clk/clk_zynqmp.c | 13 - drivers/clk/imx/clk-imx8.c | 11 +++- drivers/clk/meson/a1.c | 24 drivers/clk/mvebu/armada-37xx-periph.c | 5 +++- drivers/clk/stm32/clk-stm32mp1.c | 29 ++- 11 files changed, 89 insertions(+), 105 deletions(-) diff --git a/arch/mips/mach-pic32/cpu.c b/arch/mips/mach-pic32/cpu.c index 7ed306e045..68099dd02f 100644 --- a/arch/mips/mach-pic32/cpu.c +++ b/arch/mips/mach-pic32/cpu.c @@ -144,26 +144,3 @@ const char *get_core_name(void) return str; } #endif -#ifdef CONFIG_CMD_CLK - -int soc_clk_dump(void) -{ - int i; - - printf("PLL Speed: %lu MHz\n", - CLK_MHZ(rate(PLLCLK))); - - printf("CPU Speed: %lu MHz\n", CLK_MHZ(rate(PB7CLK))); - - printf("MPLL Speed: %lu MHz\n", CLK_MHZ(rate(MPLL))); - - for (i = PB1CLK; i <= PB7CLK; i++) - printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1, - CLK_MHZ(rate(i))); - - for (i = REF1CLK; i <= REF5CLK; i++) - printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1, - CLK_MHZ(rate(i))); - return 0; -} -#endif diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index b3cc8392fa..e1365d3f81 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -1109,6 +1109,7 @@ struct aspeed_clks { const char *name; }; +#if IS_ENABLED(CONFIG_CMD_CLK) static struct aspeed_clks aspeed_clk_names[] = { { ASPEED_CLK_HPLL, "hpll" }, { ASPEED_CLK_MPLL, "mpll" }, @@ -1123,18 +1124,12 @@ static struct aspeed_clks aspeed_clk_names[] = { { ASPEED_CLK_HUARTX, "huxclk" }, }; -int soc_clk_dump(void) +static int ast2600_clk_dump(struct udevice *dev) { - struct udevice *dev; struct clk clk; unsigned long rate; int i, ret; - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(aspeed_scu), - &dev); - if (ret) - return ret; - printf("Clk\t\tHz\n"); for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) { @@ -1167,11 +1162,15 @@ int soc_clk_dump(void) return 0; } +#endif struct clk_ops ast2600_clk_ops = { .get_rate = ast2600_clk_get_rate, .set_rate = ast2600_clk_set_rate, .enable = ast2600_clk_enable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = ast2600_clk_dump, +#endif }; static int ast2600_clk_probe(struct udevice *dev) diff --git a/drivers/clk/clk_k210.c b/drivers/clk/clk_k210.c index 2f17152021..058940b828 100644 --- a/drivers/clk/clk_k210.c +++ b/drivers/clk/clk_k210.c @@ -1276,16 +1276,10 @@ static void show_clks(struct k210_clk_priv *priv, int id, int depth) } } -int soc_clk_dump(void) +static int k210_clk_dump(struct udevice *dev) { - int ret; - struct udevice *dev; struct k210_clk_priv *priv; - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(k210_clk), - &dev); - if (ret) - return ret; priv = dev_get_priv(dev); puts(" Rate Enabled Name\n"); @@ -1304,6 +1298,9 @@ static const struct clk_ops k210_clk_ops = { .set_parent = k210_clk_set_parent, .enable = k210_clk_enable, .disable = k210_clk_disable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = k210_clk_dump, +#endif }; static int k210_clk_probe(struct udevice *dev) diff --git a/drivers/clk/clk_pic32.c b/drivers/clk/clk_pic32.c index ef06a7fb9f..f756fc88f0 100644 --- a/drivers/clk/clk_pic32.c +++ b/drivers/clk/clk_pic32.c @@ -20,6 +20,8 @@ DECLARE_GLOBAL_DATA_PTR; +#define CLK_MHZ(x) ((x) / 100) + /* Primary oscillator */ #define SYS_POSC_CLK_HZ2400 @@ -385,9 +387,46 @@ static ulong pic32_set_rate(struct clk *clk, ulong rate) return rate; } +#if IS_ENABLED(CONFIG_CMD_CLK) +static int pic32_dump(struct udevice *dev) +{ + int i; + struct clk clk; + + clk.dev = dev; + + clk.id = PLLCLK; + printf("PLL Speed: %lu MHz\n", + CLK_MHZ(pic32_get_rate(&clk))); + + clk.id = PB7CLK; + printf("CPU Speed: %lu MHz\n", CLK_MHZ(pic32_get_rate(&c
[PATCH v4 8/8] cmd: clk: Make soc_clk_dump static
After introducing dump to clk_ops there is no need to override or expose this symbol anymore. Signed-off-by: Igor Prusov Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard --- cmd/clk.c | 4 ++-- include/clk.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cmd/clk.c b/cmd/clk.c index 90cc6fa906..f55911db7a 100644 --- a/cmd/clk.c +++ b/cmd/clk.c @@ -59,7 +59,7 @@ static void show_clks(struct udevice *dev, int depth, int last_flag) } } -int __weak soc_clk_dump(void) +static int soc_clk_dump(void) { struct udevice *dev; const struct clk_ops *ops; @@ -81,7 +81,7 @@ int __weak soc_clk_dump(void) return 0; } #else -int __weak soc_clk_dump(void) +static int soc_clk_dump(void) { puts("Not implemented\n"); return 1; diff --git a/include/clk.h b/include/clk.h index d91285235f..bf0d9c9d7f 100644 --- a/include/clk.h +++ b/include/clk.h @@ -674,8 +674,6 @@ static inline bool clk_valid(struct clk *clk) return clk && !!clk->dev; } -int soc_clk_dump(void); - #endif #define clk_prepare_enable(clk) clk_enable(clk) -- 2.34.1
[PATCH v4 6/8] cmd: clk: Use dump function from clk_ops
Add another loop to dump additional info from clock providers that implement dump operation. Signed-off-by: Igor Prusov Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard --- cmd/clk.c | 9 + 1 file changed, 9 insertions(+) diff --git a/cmd/clk.c b/cmd/clk.c index c7c379d7a6..90cc6fa906 100644 --- a/cmd/clk.c +++ b/cmd/clk.c @@ -62,6 +62,7 @@ static void show_clks(struct udevice *dev, int depth, int last_flag) int __weak soc_clk_dump(void) { struct udevice *dev; + const struct clk_ops *ops; printf(" Rate Usecnt Name\n"); printf("--\n"); @@ -69,6 +70,14 @@ int __weak soc_clk_dump(void) uclass_foreach_dev_probe(UCLASS_CLK, dev) show_clks(dev, -1, 0); + uclass_foreach_dev_probe(UCLASS_CLK, dev) { + ops = dev_get_driver_ops(dev); + if (ops && ops->dump) { + printf("--\n"); + ops->dump(dev); + } + } + return 0; } #else -- 2.34.1
[PATCH v4 5/8] clk: Add dump operation to clk_ops
This adds dump function to struct clk_ops which should replace soc_clk_dump. It allows clock drivers to provide custom dump implementation without overriding generic CCF dump function. Signed-off-by: Igor Prusov Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard --- include/clk-uclass.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/clk-uclass.h b/include/clk-uclass.h index a22f1a5d84..30621e4823 100644 --- a/include/clk-uclass.h +++ b/include/clk-uclass.h @@ -39,6 +39,9 @@ struct clk_ops { int (*set_parent)(struct clk *clk, struct clk *parent); int (*enable)(struct clk *clk); int (*disable)(struct clk *clk); +#if IS_ENABLED(CONFIG_CMD_CLK) + int (*dump)(struct udevice *dev); +#endif }; #if 0 /* For documentation only */ -- 2.34.1
[PATCH v4 3/8] clk: k210: Move soc_clk_dump function
Move clock dump function to avoid forward declaration after switching to dump in clk_ops. Signed-off-by: Igor Prusov --- drivers/clk/clk_k210.c | 92 +- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/clk/clk_k210.c b/drivers/clk/clk_k210.c index c534cc07e0..2f17152021 100644 --- a/drivers/clk/clk_k210.c +++ b/drivers/clk/clk_k210.c @@ -1238,52 +1238,6 @@ static int k210_clk_request(struct clk *clk) return 0; } -static const struct clk_ops k210_clk_ops = { - .request = k210_clk_request, - .set_rate = k210_clk_set_rate, - .get_rate = k210_clk_get_rate, - .set_parent = k210_clk_set_parent, - .enable = k210_clk_enable, - .disable = k210_clk_disable, -}; - -static int k210_clk_probe(struct udevice *dev) -{ - int ret; - struct k210_clk_priv *priv = dev_get_priv(dev); - - priv->base = dev_read_addr_ptr(dev_get_parent(dev)); - if (!priv->base) - return -EINVAL; - - ret = clk_get_by_index(dev, 0, &priv->in0); - if (ret) - return ret; - - /* -* Force setting defaults, even before relocation. This is so we can -* set the clock rate for PLL1 before we relocate into aisram. -*/ - if (!(gd->flags & GD_FLG_RELOC)) - clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE); - - return 0; -} - -static const struct udevice_id k210_clk_ids[] = { - { .compatible = "canaan,k210-clk" }, - { }, -}; - -U_BOOT_DRIVER(k210_clk) = { - .name = "k210_clk", - .id = UCLASS_CLK, - .of_match = k210_clk_ids, - .ops = &k210_clk_ops, - .probe = k210_clk_probe, - .priv_auto = sizeof(struct k210_clk_priv), -}; - #if IS_ENABLED(CONFIG_CMD_CLK) static char show_enabled(struct k210_clk_priv *priv, int id) { @@ -1342,3 +1296,49 @@ int soc_clk_dump(void) return 0; } #endif + +static const struct clk_ops k210_clk_ops = { + .request = k210_clk_request, + .set_rate = k210_clk_set_rate, + .get_rate = k210_clk_get_rate, + .set_parent = k210_clk_set_parent, + .enable = k210_clk_enable, + .disable = k210_clk_disable, +}; + +static int k210_clk_probe(struct udevice *dev) +{ + int ret; + struct k210_clk_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev_get_parent(dev)); + if (!priv->base) + return -EINVAL; + + ret = clk_get_by_index(dev, 0, &priv->in0); + if (ret) + return ret; + + /* +* Force setting defaults, even before relocation. This is so we can +* set the clock rate for PLL1 before we relocate into aisram. +*/ + if (!(gd->flags & GD_FLG_RELOC)) + clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE); + + return 0; +} + +static const struct udevice_id k210_clk_ids[] = { + { .compatible = "canaan,k210-clk" }, + { }, +}; + +U_BOOT_DRIVER(k210_clk) = { + .name = "k210_clk", + .id = UCLASS_CLK, + .of_match = k210_clk_ids, + .ops = &k210_clk_ops, + .probe = k210_clk_probe, + .priv_auto = sizeof(struct k210_clk_priv), +}; -- 2.34.1
[PATCH v4 4/8] clk: amlogic: Move driver and ops structs
Move driver and ops structs to avoid forward declaration after switching to dump in clk_ops. Signed-off-by: Igor Prusov --- drivers/clk/meson/a1.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/clk/meson/a1.c b/drivers/clk/meson/a1.c index 1075ba7333..e3fa9db7d0 100644 --- a/drivers/clk/meson/a1.c +++ b/drivers/clk/meson/a1.c @@ -601,14 +601,6 @@ static int meson_clk_set_parent(struct clk *clk, struct clk *parent_clk) return meson_mux_set_parent_by_id(clk, parent_clk->id); } -static struct clk_ops meson_clk_ops = { - .disable= meson_clk_disable, - .enable = meson_clk_enable, - .get_rate = meson_clk_get_rate, - .set_rate = meson_clk_set_rate, - .set_parent = meson_clk_set_parent, -}; - static int meson_clk_probe(struct udevice *dev) { struct meson_clk *priv = dev_get_priv(dev); @@ -638,15 +630,6 @@ static const struct udevice_id meson_clk_ids[] = { { } }; -U_BOOT_DRIVER(meson_clk) = { - .name = "meson-clk-a1", - .id = UCLASS_CLK, - .of_match = meson_clk_ids, - .priv_auto = sizeof(struct meson_clk), - .ops= &meson_clk_ops, - .probe = meson_clk_probe, -}; - static const char *meson_clk_get_name(struct clk *clk, int id) { const struct meson_clk_info *info; @@ -727,3 +710,20 @@ int soc_clk_dump(void) return 0; } + +static struct clk_ops meson_clk_ops = { + .disable= meson_clk_disable, + .enable = meson_clk_enable, + .get_rate = meson_clk_get_rate, + .set_rate = meson_clk_set_rate, + .set_parent = meson_clk_set_parent, +}; + +U_BOOT_DRIVER(meson_clk) = { + .name = "meson-clk-a1", + .id = UCLASS_CLK, + .of_match = meson_clk_ids, + .priv_auto = sizeof(struct meson_clk), + .ops= &meson_clk_ops, + .probe = meson_clk_probe, +}; -- 2.34.1
[PATCH v4 0/8] clk: Switch from soc_clk_dump to clk_ops function
Currently clock providers may override default implementation of soc_clk_dump function to replace clk dump command output. This causes confusing behaviour when u-boot is built with one of such drivers enabled but still has clocks defined using CCF. For example, enabling CMD_CLK and using clk dump on sandbox target will not show CCF clocks because k210 driver overrides common soc_clk_dump. Changelog: v1 -> v2: - Add missing static to dump functions v2 -> v3: - Make soc_clk_dump in cmd/clk.c static instead of removing __weak v3 -> v4: - Rebase and refactor dump for new Amlogic A1 clock controller driver Igor Prusov (8): clk: zynq: Move soc_clk_dump to Zynq clock driver clk: ast2600: Move soc_clk_dump function clk: k210: Move soc_clk_dump function clk: amlogic: Move driver and ops structs clk: Add dump operation to clk_ops cmd: clk: Use dump function from clk_ops clk: treewide: switch to clock dump from clk_ops cmd: clk: Make soc_clk_dump static arch/arm/mach-zynq/clk.c | 57 -- arch/mips/mach-pic32/cpu.c | 23 -- cmd/clk.c | 13 +++- drivers/clk/aspeed/clk_ast2600.c | 83 ++-- drivers/clk/clk_k210.c | 103 - drivers/clk/clk_pic32.c| 39 ++ drivers/clk/clk_versal.c | 7 +- drivers/clk/clk_zynq.c | 51 drivers/clk/clk_zynqmp.c | 13 ++-- drivers/clk/imx/clk-imx8.c | 11 +-- drivers/clk/meson/a1.c | 54 + drivers/clk/mvebu/armada-37xx-periph.c | 5 +- drivers/clk/stm32/clk-stm32mp1.c | 29 ++- include/clk-uclass.h | 3 + include/clk.h | 2 - 15 files changed, 244 insertions(+), 249 deletions(-) -- 2.34.1
[PATCH v4 2/8] clk: ast2600: Move soc_clk_dump function
Move clock dump function to avoid forward declaration after switching to dump in clk_ops. Signed-off-by: Igor Prusov --- drivers/clk/aspeed/clk_ast2600.c | 70 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index e5ada5b6d4..b3cc8392fa 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -1104,41 +1104,6 @@ static int ast2600_clk_enable(struct clk *clk) return 0; } -struct clk_ops ast2600_clk_ops = { - .get_rate = ast2600_clk_get_rate, - .set_rate = ast2600_clk_set_rate, - .enable = ast2600_clk_enable, -}; - -static int ast2600_clk_probe(struct udevice *dev) -{ - struct ast2600_clk_priv *priv = dev_get_priv(dev); - - priv->scu = devfdt_get_addr_ptr(dev); - if (IS_ERR(priv->scu)) - return PTR_ERR(priv->scu); - - ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); - ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); - ast2600_configure_mac12_clk(priv->scu); - ast2600_configure_mac34_clk(priv->scu); - ast2600_configure_rsa_ecc_clk(priv->scu); - - return 0; -} - -static int ast2600_clk_bind(struct udevice *dev) -{ - int ret; - - /* The reset driver does not have a device node, so bind it here */ - ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); - if (ret) - debug("Warning: No reset driver: ret=%d\n", ret); - - return 0; -} - struct aspeed_clks { ulong id; const char *name; @@ -1203,6 +1168,41 @@ int soc_clk_dump(void) return 0; } +struct clk_ops ast2600_clk_ops = { + .get_rate = ast2600_clk_get_rate, + .set_rate = ast2600_clk_set_rate, + .enable = ast2600_clk_enable, +}; + +static int ast2600_clk_probe(struct udevice *dev) +{ + struct ast2600_clk_priv *priv = dev_get_priv(dev); + + priv->scu = devfdt_get_addr_ptr(dev); + if (IS_ERR(priv->scu)) + return PTR_ERR(priv->scu); + + ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); + ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); + ast2600_configure_mac12_clk(priv->scu); + ast2600_configure_mac34_clk(priv->scu); + ast2600_configure_rsa_ecc_clk(priv->scu); + + return 0; +} + +static int ast2600_clk_bind(struct udevice *dev) +{ + int ret; + + /* The reset driver does not have a device node, so bind it here */ + ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); + if (ret) + debug("Warning: No reset driver: ret=%d\n", ret); + + return 0; +} + static const struct udevice_id ast2600_clk_ids[] = { { .compatible = "aspeed,ast2600-scu", }, { }, -- 2.34.1
[PATCH v4 1/8] clk: zynq: Move soc_clk_dump to Zynq clock driver
Move clock dump function in preparation for switching to dump function in clk_ops. Signed-off-by: Igor Prusov Acked-by: Michal Simek --- arch/arm/mach-zynq/clk.c | 57 --- drivers/clk/clk_zynq.c | 58 2 files changed, 58 insertions(+), 57 deletions(-) diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c index 1945f60e08..e6a67326dd 100644 --- a/arch/arm/mach-zynq/clk.c +++ b/arch/arm/mach-zynq/clk.c @@ -13,20 +13,6 @@ DECLARE_GLOBAL_DATA_PTR; -static const char * const clk_names[clk_max] = { - "armpll", "ddrpll", "iopll", - "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", - "ddr2x", "ddr3x", "dci", - "lqspi", "smc", "pcap", "gem0", "gem1", - "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", - "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", - "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", - "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", - "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", - "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", - "smc_aper", "swdt", "dbg_trc", "dbg_apb" -}; - /** * set_cpu_clk_info() - Setup clock information * @@ -65,46 +51,3 @@ int set_cpu_clk_info(void) return 0; } - -/** - * soc_clk_dump() - Print clock frequencies - * Returns zero on success - * - * Implementation for the clk dump command. - */ -int soc_clk_dump(void) -{ - struct udevice *dev; - int i, ret; - - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(zynq_clk), &dev); - if (ret) - return ret; - - printf("clk\t\tfrequency\n"); - for (i = 0; i < clk_max; i++) { - const char *name = clk_names[i]; - if (name) { - struct clk clk; - unsigned long rate; - - clk.id = i; - ret = clk_request(dev, &clk); - if (ret < 0) - return ret; - - rate = clk_get_rate(&clk); - - clk_free(&clk); - - if ((rate == (unsigned long)-ENOSYS) || - (rate == (unsigned long)-ENXIO)) - printf("%10s%20s\n", name, "unknown"); - else - printf("%10s%20lu\n", name, rate); - } - } - - return 0; -} diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c index e80500e382..be5226175f 100644 --- a/drivers/clk/clk_zynq.c +++ b/drivers/clk/clk_zynq.c @@ -454,6 +454,64 @@ static int dummy_enable(struct clk *clk) return 0; } +static const char * const clk_names[clk_max] = { + "armpll", "ddrpll", "iopll", + "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", + "ddr2x", "ddr3x", "dci", + "lqspi", "smc", "pcap", "gem0", "gem1", + "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", + "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", + "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", + "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", + "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", + "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", + "smc_aper", "swdt", "dbg_trc", "dbg_apb" +}; + +/** + * soc_clk_dump() - Print clock frequencies + * Returns zero on success + * + * Implementation for the clk dump command. + */ +int soc_clk_dump(void) +{ + struct udevice *dev; + int i, ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(zynq_clk), &dev); + if (ret) + return ret; + + printf("clk\t\tfrequency\n"); + for (i = 0; i < clk_max; i++) { + const char *name = clk_names[i]; + + if (name) { + struct clk clk; + unsigned long rate; + + clk.id = i; + ret = clk_request(dev, &clk); + if (ret < 0) + return ret; + + rate = clk_get_rate(&clk); + + clk_free(&clk); + + if ((rate == (unsigned long)-ENOSYS) || + (rate == (unsigned long)-ENXIO)) + printf("%10s%20s\n", name, "unknown"); + else + printf("%10s%20lu\n", name, rate); + } + } + + return 0; +} + static struct clk_ops zynq_clk_ops = { .get_rate = zynq_clk_get_rate, #ifndef CONFIG_SPL_BUILD -- 2.34.1
[PATCH v1 2/2] mtd: spinand: add support for ESMT F50x1G41LB
Adaptation of Linux commit d74c36480a67 This patch adds support for ESMT F50L1G41LB and F50D1G41LB. It seems that ESMT likes to use random JEDEC ID from other vendors. Their 1G chips uses 0xc8 from GigaDevice and 2G/4G chips uses 0x2c from Micron. For this reason, the ESMT entry is named esmt_c8 with explicit JEDEC ID in variable name. Datasheets: https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50L1G41LB(2M).pdf https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50D1G41LB(2M).pdf Signed-off-by: Igor Prusov Signed-off-by: Chuanhong Guo Signed-off-by: Martin Kurbanov Signed-off-by: Dmitry Rokosov Tested-by: Martin Kurbanov --- drivers/mtd/nand/spi/Makefile | 2 +- drivers/mtd/nand/spi/core.c | 1 + drivers/mtd/nand/spi/esmt.c | 137 ++ include/linux/mtd/spinand.h | 1 + 4 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 drivers/mtd/nand/spi/esmt.c diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile index 6c65b187e8..0585fe8e67 100644 --- a/drivers/mtd/nand/spi/Makefile +++ b/drivers/mtd/nand/spi/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -spinand-objs := core.o gigadevice.o macronix.o micron.o toshiba.o winbond.o +spinand-objs := core.o gigadevice.o macronix.o micron.o toshiba.o winbond.o esmt.o obj-$(CONFIG_MTD_SPI_NAND) += spinand.o diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 3ea746fd13..b84df30bff 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -837,6 +837,7 @@ static const struct spinand_manufacturer *spinand_manufacturers[] = { µn_spinand_manufacturer, &toshiba_spinand_manufacturer, &winbond_spinand_manufacturer, + &esmt_c8_spinand_manufacturer, }; static int spinand_manufacturer_match(struct spinand_device *spinand, diff --git a/drivers/mtd/nand/spi/esmt.c b/drivers/mtd/nand/spi/esmt.c new file mode 100644 index 00..6dacb8d981 --- /dev/null +++ b/drivers/mtd/nand/spi/esmt.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Author: + * Chuanhong Guo - the main driver logic + * Martin Kurbanov - OOB layout + */ + +#ifndef __UBOOT__ +#include +#include +#endif +#include + +/* ESMT uses GigaDevice 0xc8 JECDEC ID on some SPI NANDs */ +#define SPINAND_MFR_ESMT_C80xc8 + +static SPINAND_OP_VARIANTS(read_cache_variants, + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); + +static SPINAND_OP_VARIANTS(write_cache_variants, + SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), + SPINAND_PROG_LOAD(true, 0, NULL, 0)); + +static SPINAND_OP_VARIANTS(update_cache_variants, + SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), + SPINAND_PROG_LOAD(false, 0, NULL, 0)); + +/* + * OOB spare area map (64 bytes) + * + * Bad Block Markers + * filled by HW and kernel Reserved + * | +---+---+ + * | | | | + * | |OOB free data Area |non ECC protected | + * | +-|-+-|-+-|-+ + * | | | | | | | | + * +-|---|--+--|-|--+--|-|--+--|-|--+ + * | | | section0 | | |section1 | | |section2 | | | section3 | + * +-v-+-v-+---++--v--+--v--+-+-+--v--+--v--+-+-+--v--+--v--+-+-+ + * | | | || | | | | | | | | | | | | + * |0:1|2:3|4:7|8:15|16:17|18:19|20:23|24:31|32:33|34:35|36:39|40:47|48:49|50:51|52:55|56:63| + * | | | || | | | | | | | | | | | | + * +---+---+-^-+--^-+-+-+--^--+--^--+-+-+--^--+--^--+-+-+--^--+--^--+ + * ||| | | | | | + * | +|-+-|-+-|-+ + * | ECC Area|(Main + Spare) - filled|by ESMT NAND HW | + * | | | | + * +-+---+---+ + * OOB ECC protected Area - not used due to + * partial programming from some filesystems + * (like JFFS2 with cleanmarkers) + */ + +#define ESMT_OOB_SECTION_COUNT
[PATCH v1 1/2] mtd: spinand: rework detect procedure for different READ_ID operation
Adaptation of Linux commit f1541773af49. Currently there are 3 different variants of read_id implementation: 1. opcode only. Found in GD5FxGQ4xF. 2. opcode + 1 addr byte. Found in GD5GxGQ4xA/E 3. opcode + 1 dummy byte. Found in other currently supported chips. Original implementation was for variant 1 and let detect function of chips with variant 2 and 3 to ignore the first byte. This isn't robust: 1. For chips of variant 2, if SPI master doesn't keep MOSI low during read, chip will get a random id offset, and the entire id buffer will shift by that offset, causing detect failure. 2. For chips of variant 1, if it happens to get a devid that equals to manufacture id of variant 2 or 3 chips, it'll get incorrectly detected. This patch reworks detect procedure to address problems above. New logic do detection for all variants separatedly, in 1-2-3 order. Since all current detect methods do exactly the same id matching procedure, unify them into core.c and remove detect method from manufacture_ops. Signed-off-by: Chuanhong Guo Signed-off-by: Igor Prusov --- drivers/mtd/nand/spi/core.c | 85 +++ drivers/mtd/nand/spi/gigadevice.c | 30 +++ drivers/mtd/nand/spi/macronix.c | 45 ++-- drivers/mtd/nand/spi/micron.c | 50 -- drivers/mtd/nand/spi/toshiba.c| 66 +++- drivers/mtd/nand/spi/winbond.c| 34 +++-- include/linux/mtd/spinand.h | 66 7 files changed, 185 insertions(+), 191 deletions(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 4ee11e812d..3ea746fd13 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #else @@ -452,10 +453,11 @@ out: return status & STATUS_BUSY ? -ETIMEDOUT : 0; } -static int spinand_read_id_op(struct spinand_device *spinand, u8 *buf) +static int spinand_read_id_op(struct spinand_device *spinand, u8 naddr, + u8 ndummy, u8 *buf) { - struct spi_mem_op op = SPINAND_READID_OP(0, spinand->scratchbuf, -SPINAND_MAX_ID_LEN); + struct spi_mem_op op = SPINAND_READID_OP( + naddr, ndummy, spinand->scratchbuf, SPINAND_MAX_ID_LEN); int ret; ret = spi_mem_exec_op(spinand->slave, &op); @@ -837,24 +839,63 @@ static const struct spinand_manufacturer *spinand_manufacturers[] = { &winbond_spinand_manufacturer, }; -static int spinand_manufacturer_detect(struct spinand_device *spinand) +static int spinand_manufacturer_match(struct spinand_device *spinand, + enum spinand_readid_method rdid_method) { + u8 *id = spinand->id.data; unsigned int i; int ret; for (i = 0; i < ARRAY_SIZE(spinand_manufacturers); i++) { - ret = spinand_manufacturers[i]->ops->detect(spinand); - if (ret > 0) { - spinand->manufacturer = spinand_manufacturers[i]; - return 0; - } else if (ret < 0) { - return ret; - } + const struct spinand_manufacturer *manufacturer = + spinand_manufacturers[i]; + + if (id[0] != manufacturer->id) + continue; + + ret = spinand_match_and_init(spinand, +manufacturer->chips, +manufacturer->nchips, +rdid_method); + if (ret < 0) + continue; + + spinand->manufacturer = manufacturer; + return 0; } return -ENOTSUPP; } +static int spinand_id_detect(struct spinand_device *spinand) +{ + u8 *id = spinand->id.data; + int ret; + + ret = spinand_read_id_op(spinand, 0, 0, id); + if (ret) + return ret; + ret = spinand_manufacturer_match(spinand, SPINAND_READID_METHOD_OPCODE); + if (!ret) + return 0; + + ret = spinand_read_id_op(spinand, 1, 0, id); + if (ret) + return ret; + ret = spinand_manufacturer_match(spinand, +SPINAND_READID_METHOD_OPCODE_ADDR); + if (!ret) + return 0; + + ret = spinand_read_id_op(spinand, 0, 1, id); + if (ret) + return ret; + ret = spinand_manufacturer_match(spinand, +SPINAND_READID_METHOD_OPCODE_DUMMY); + + return ret; +} + static int spinand_manufacturer_init(struct spinand_device *spinand) { if (spinand->manufacturer->ops->init) @@ -910,9 +951,9 @@ spinand_select_op_v
[PATCH v1 0/2] mtd: spinand: add support for ESMT F50x1G41LB
This series ports ESMT NAND support from Linux. Since both ESMT and Gigadevice use the same manufacturer ID, core part of SPI NAND framework should be updated as well to allow for such chips detection. Currently all detect() ops return an error code when chip's manufacturer ID matches, but device ID does not. This forces spinand_manufacturer_detect function to stop and report an error. Porting a rework from Linux allows us to fix this issue and keep u-boot and kernel in sync. Igor Prusov (2): mtd: spinand: rework detect procedure for different READ_ID operation mtd: spinand: add support for ESMT F50x1G41LB drivers/mtd/nand/spi/Makefile | 2 +- drivers/mtd/nand/spi/core.c | 86 ++- drivers/mtd/nand/spi/esmt.c | 137 ++ drivers/mtd/nand/spi/gigadevice.c | 30 ++- drivers/mtd/nand/spi/macronix.c | 45 -- drivers/mtd/nand/spi/micron.c | 50 +-- drivers/mtd/nand/spi/toshiba.c| 66 +++--- drivers/mtd/nand/spi/winbond.c| 34 ++-- include/linux/mtd/spinand.h | 67 ++- 9 files changed, 325 insertions(+), 192 deletions(-) create mode 100644 drivers/mtd/nand/spi/esmt.c -- 2.34.1
[PATCH v1 2/2] ARM: amlogic: ad401: enable SPIFC
From: Igor Prusov Enable Amlogic A1 SPI FLash Controller support. Signed-off-by: Igor Prusov --- configs/ad401_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/ad401_defconfig b/configs/ad401_defconfig index 31752cc7f5..9a88e20a6a 100644 --- a/configs/ad401_defconfig +++ b/configs/ad401_defconfig @@ -51,4 +51,5 @@ CONFIG_DEBUG_UART_SKIP_INIT=y CONFIG_MESON_SERIAL=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_MESON_SPIFC_A1=y CONFIG_WDT=y -- 2.34.1
[PATCH v1 1/2] spi: add support for Amlogic A1 SPI Flash Controller
From: Igor Prusov Add A1 SPIFC driver from Linux. Slightly modified to use u-boot driver framework and accommodate to lack of ioread32_rep/iowrite32_rep. Based on Linux version 6.6-rc4 Signed-off-by: Igor Prusov Signed-off-by: Martin Kurbanov --- drivers/spi/Kconfig | 8 + drivers/spi/Makefile | 1 + drivers/spi/meson_spifc_a1.c | 384 +++ 3 files changed, 393 insertions(+) create mode 100644 drivers/spi/meson_spifc_a1.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 854b8b88da..dedb366370 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -251,6 +251,14 @@ config MICROCHIP_COREQSPI Enable the QSPI driver for Microchip FPGA QSPI controllers. This driver can be used on Polarfire SoC. +config MESON_SPIFC_A1 + bool "Amlogic Meson A1 SPI Flash Controller driver" + depends on ARCH_MESON + help + Enable the Amlogic A1 SPI Flash Controller (SPIFC) driver. + This driver can be used to access the SPI NOR/NAND flash chips on + Amlogic A1 SoC. + config MPC8XX_SPI bool "MPC8XX SPI Driver" depends on MPC8xx diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index c27b3327c3..14bdb97f18 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_ICH_SPI) += ich.o obj-$(CONFIG_IPROC_QSPI) += iproc_qspi.o obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o +obj-$(CONFIG_MESON_SPIFC_A1) += meson_spifc_a1.o obj-$(CONFIG_MICROCHIP_COREQSPI) += microchip_coreqspi.o obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o diff --git a/drivers/spi/meson_spifc_a1.c b/drivers/spi/meson_spifc_a1.c new file mode 100644 index 00..4b840c4634 --- /dev/null +++ b/drivers/spi/meson_spifc_a1.c @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for Amlogic A1 SPI flash controller (SPIFC) + * + * Copyright (c) 2023, SberDevices. All Rights Reserved. + * + * Author: Martin Kurbanov + * + * Ported to u-boot: + * Author: Igor Prusov + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPIFC_A1_AHB_CTRL_REG 0x0 +#define SPIFC_A1_AHB_BUS_ENBIT(31) + +#define SPIFC_A1_USER_CTRL0_REG0x200 +#define SPIFC_A1_USER_REQUEST_ENABLE BIT(31) +#define SPIFC_A1_USER_REQUEST_FINISH BIT(30) +#define SPIFC_A1_USER_DATA_UPDATED BIT(0) + +#define SPIFC_A1_USER_CTRL1_REG0x204 +#define SPIFC_A1_USER_CMD_ENABLE BIT(30) +#define SPIFC_A1_USER_CMD_MODE GENMASK(29, 28) +#define SPIFC_A1_USER_CMD_CODE GENMASK(27, 20) +#define SPIFC_A1_USER_ADDR_ENABLE BIT(19) +#define SPIFC_A1_USER_ADDR_MODEGENMASK(18, 17) +#define SPIFC_A1_USER_ADDR_BYTES GENMASK(16, 15) +#define SPIFC_A1_USER_DOUT_ENABLE BIT(14) +#define SPIFC_A1_USER_DOUT_MODEGENMASK(11, 10) +#define SPIFC_A1_USER_DOUT_BYTES GENMASK(9, 0) + +#define SPIFC_A1_USER_CTRL2_REG0x208 +#define SPIFC_A1_USER_DUMMY_ENABLE BIT(31) +#define SPIFC_A1_USER_DUMMY_MODE GENMASK(30, 29) +#define SPIFC_A1_USER_DUMMY_CLK_SYCLES GENMASK(28, 23) + +#define SPIFC_A1_USER_CTRL3_REG0x20c +#define SPIFC_A1_USER_DIN_ENABLE BIT(31) +#define SPIFC_A1_USER_DIN_MODE GENMASK(28, 27) +#define SPIFC_A1_USER_DIN_BYTESGENMASK(25, 16) + +#define SPIFC_A1_USER_ADDR_REG 0x210 + +#define SPIFC_A1_AHB_REQ_CTRL_REG 0x214 +#define SPIFC_A1_AHB_REQ_ENABLEBIT(31) + +#define SPIFC_A1_ACTIMING0_REG (0x0088 << 2) +#define SPIFC_A1_TSLCH GENMASK(31, 30) +#define SPIFC_A1_TCLSH GENMASK(29, 28) +#define SPIFC_A1_TSHWL GENMASK(20, 16) +#define SPIFC_A1_TSHSL2GENMASK(15, 12) +#define SPIFC_A1_TSHSL1GENMASK(11, 8) +#define SPIFC_A1_TWHSL GENMASK(7, 0) + +#define SPIFC_A1_DBUF_CTRL_REG 0x240 +#define SPIFC_A1_DBUF_DIR BIT(31) +#define SPIFC_A1_DBUF_AUTO_UPDATE_ADDR BIT(30) +#define SPIFC_A1_DBUF_ADDR GENMASK(7, 0) + +#define SPIFC_A1_DBUF_DATA_REG 0x244 + +#define SPIFC_A1_USER_DBUF_ADDR_REG0x248 + +#define SPIFC_A1_BUFFER_SIZE 512U + +#define SPIFC_A1_MAX_HZ2 +#define SPIFC_A1_MIN_HZ100 + +#define SPIFC_A1_USER_CMD(op) ( \ + SPIFC_A1_USER_CMD_ENABLE | \ + FIELD_PREP(SPIFC_A1_USER_CMD_CODE, (op)->cmd.opcode) | \ + FIELD_PREP(SPIFC_A1_USER_CMD_MODE, ilog2((op)->cmd.buswidth))) + +#define SPIFC_A1_USER_ADDR(op) ( \ + SPIFC_A1_USER_ADDR_ENABLE | \ + FIELD_PREP(SPIFC_A1_USER_ADDR_MODE, ilog2((op)->addr.buswidth)) | \ + FIELD_PREP(SPIFC_A1_USER_ADDR_BYTES, (op)->addr.nbyte
[PATCH v1 0/2] ARM: amlogic: Add A1 SPIFC support
A1 family boards have new version of SPIFC controller, that is incompatible with meson_spifc driver. This series ports A1 SPIFC driver from Linux and enables it for ad401 board. Igor Prusov (2): spi: add support for Amlogic A1 SPI Flash Controller ARM: amlogic: ad401: enable SPIFC configs/ad401_defconfig | 1 + drivers/spi/Kconfig | 8 + drivers/spi/Makefile | 1 + drivers/spi/meson_spifc_a1.c | 384 +++ 4 files changed, 394 insertions(+) create mode 100644 drivers/spi/meson_spifc_a1.c -- 2.34.1
[PATCH v2 2/2] clk: Add clock driver for Amlogic A1
This patch adds basic clock driver for Amlogic A1 Family which supports enabling/disabling some gates, getting frequencies and setting rate with limited reparenting. Signed-off-by: Igor Prusov Reviewed-by: Simon Glass --- arch/arm/include/asm/arch-meson/clock-a1.h | 23 + drivers/clk/meson/Kconfig | 8 + drivers/clk/meson/Makefile | 1 + drivers/clk/meson/a1.c | 723 + 4 files changed, 755 insertions(+) create mode 100644 arch/arm/include/asm/arch-meson/clock-a1.h create mode 100644 drivers/clk/meson/a1.c diff --git a/arch/arm/include/asm/arch-meson/clock-a1.h b/arch/arm/include/asm/arch-meson/clock-a1.h new file mode 100644 index 00..f6795f5e0c --- /dev/null +++ b/arch/arm/include/asm/arch-meson/clock-a1.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2018 - AmLogic, Inc. + * Copyright 2023 (C) SberDevices, Inc. + */ + +#ifndef _ARCH_MESON_CLOCK_A1_H_ +#define _ARCH_MESON_CLOCK_A1_H_ + +/* + * Clock controller register offsets + */ +#define A1_SYS_OSCIN_CTRL 0x0 +#define A1_SYS_CLK_CTRL0 0x10 +#define A1_SYS_CLK_EN0 0x1c +#define A1_SAR_ADC_CLK_CTR 0xc0 +#define A1_SPIFC_CLK_CTRL 0xd8 +#define A1_USB_BUSCLK_CTRL 0xdc +#define A1_SD_EMMC_CLK_CTRL0xe0 + +#define A1_ANACTRL_FIXPLL_CTRL00x0 + +#endif /* _ARCH_MESON_CLOCK_A1_H_ */ diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 994b44ad7a..cdc9d6f76c 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -21,3 +21,11 @@ config CLK_MESON_G12A help Enable clock support for the Amlogic G12A SoC family, such as the S905X/D2 + +config CLK_MESON_A1 + bool "Enable clock support for Amlogic A1" + depends on CLK && ARCH_MESON + default MESON_A1 + help + Enable clock support for the Amlogic A1 SoC family, such as + the A113L diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index a486b13e9c..d975f07aab 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_MESON_AXG) += axg.o obj-$(CONFIG_CLK_MESON_AXG) += axg-ao.o obj-$(CONFIG_CLK_MESON_G12A) += g12a.o obj-$(CONFIG_CLK_MESON_G12A) += g12a-ao.o +obj-$(CONFIG_CLK_MESON_A1) += a1.o diff --git a/drivers/clk/meson/a1.c b/drivers/clk/meson/a1.c new file mode 100644 index 00..3aec42f33b --- /dev/null +++ b/drivers/clk/meson/a1.c @@ -0,0 +1,723 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2023 SberDevices, Inc. + * Author: Igor Prusov + */ + +#include +#include +#include +#include +#include +#include +#include +#include "clk_meson.h" + +/* + * This driver supports both PLL and peripherals clock sources. + * Following operations are supported: + * - calculating clock frequency on a limited tree + * - reading muxes and dividers + * - enabling/disabling gates without propagation + * - reparenting without rate propagation, only on muxes + * - setting rates with limited reparenting, only on dividers with mux parent + */ + +#define NR_CLKS154 +#define NR_PLL_CLKS11 + +/* External clock IDs. Those should not overlap with regular IDs */ +#define EXTERNAL_XTAL (NR_CLKS + 0) +#define EXTERNAL_FCLK_DIV2 (NR_CLKS + 1) +#define EXTERNAL_FCLK_DIV3 (NR_CLKS + 2) +#define EXTERNAL_FCLK_DIV5 (NR_CLKS + 3) +#define EXTERNAL_FCLK_DIV7 (NR_CLKS + 4) + +#define EXTERNAL_FIXPLL_IN (NR_PLL_CLKS + 1) + +#define SET_PARM_VALUE(_priv, _parm, _val) \ + regmap_update_bits((_priv)->map, (_parm)->reg_off, \ + SETPMASK((_parm)->width, (_parm)->shift),\ + (_val) << (_parm)->shift) + +#define GET_PARM_VALUE(_priv, _parm) \ +({ \ + uint _reg; \ + regmap_read((_priv)->map, (_parm)->reg_off, &_reg); \ + PARM_GET((_parm)->width, (_parm)->shift, _reg); \ +}) + +struct meson_clk { + struct regmap *map; +}; + +/** + * enum meson_clk_type - The type of clock + * @MESON_CLK_ANY: Special value that matches any clock type + * @MESON_CLK_GATE: This clock is a gate + * @MESON_CLK_MUX: This clock is a multiplexer + * @MESON_CLK_DIV: This clock is a configurable divider + * @MESON_CLK_FIXED_DIV: This clock is a configurable divider + * @MESON_CLK_EXTERNAL: This is an external clock from different clock provider + * @MESON_CLK_PLL: This is a PLL + */ +enum meson_clk_type { + MESON_CLK_ANY = 0, + MESON_CLK_GATE, +
[PATCH v2 1/2] dt-bindings: clock: Add Amlogic A1 clock bindings
Add clock bindings for Amlogic A1 from linux-next next-20230821. Signed-off-by: Igor Prusov Reviewed-by: Simon Glass --- .../clock/amlogic,a1-peripherals-clkc.h | 168 ++ .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 25 +++ 2 files changed, 193 insertions(+) create mode 100644 include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h diff --git a/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h new file mode 100644 index 00..06f198ee76 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h @@ -0,0 +1,168 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + * Author: Jian Hu + * + * Copyright (c) 2023, SberDevices. All Rights Reserved. + * Author: Dmitry Rokosov + */ + +#ifndef __A1_PERIPHERALS_CLKC_H +#define __A1_PERIPHERALS_CLKC_H + +#define CLKID_XTAL_IN 0 +#define CLKID_FIXPLL_IN1 +#define CLKID_USB_PHY_IN 2 +#define CLKID_USB_CTRL_IN 3 +#define CLKID_HIFIPLL_IN 4 +#define CLKID_SYSPLL_IN5 +#define CLKID_DDS_IN 6 +#define CLKID_SYS 7 +#define CLKID_CLKTREE 8 +#define CLKID_RESET_CTRL 9 +#define CLKID_ANALOG_CTRL 10 +#define CLKID_PWR_CTRL 11 +#define CLKID_PAD_CTRL 12 +#define CLKID_SYS_CTRL 13 +#define CLKID_TEMP_SENSOR 14 +#define CLKID_AM2AXI_DIV 15 +#define CLKID_SPICC_B 16 +#define CLKID_SPICC_A 17 +#define CLKID_MSR 18 +#define CLKID_AUDIO19 +#define CLKID_JTAG_CTRL20 +#define CLKID_SARADC_EN21 +#define CLKID_PWM_EF 22 +#define CLKID_PWM_CD 23 +#define CLKID_PWM_AB 24 +#define CLKID_CEC 25 +#define CLKID_I2C_S26 +#define CLKID_IR_CTRL 27 +#define CLKID_I2C_M_D 28 +#define CLKID_I2C_M_C 29 +#define CLKID_I2C_M_B 30 +#define CLKID_I2C_M_A 31 +#define CLKID_ACODEC 32 +#define CLKID_OTP 33 +#define CLKID_SD_EMMC_A34 +#define CLKID_USB_PHY 35 +#define CLKID_USB_CTRL 36 +#define CLKID_SYS_DSPB 37 +#define CLKID_SYS_DSPA 38 +#define CLKID_DMA 39 +#define CLKID_IRQ_CTRL 40 +#define CLKID_NIC 41 +#define CLKID_GIC 42 +#define CLKID_UART_C 43 +#define CLKID_UART_B 44 +#define CLKID_UART_A 45 +#define CLKID_SYS_PSRAM46 +#define CLKID_RSA 47 +#define CLKID_CORESIGHT48 +#define CLKID_AM2AXI_VAD 49 +#define CLKID_AUDIO_VAD50 +#define CLKID_AXI_DMC 51 +#define CLKID_AXI_PSRAM52 +#define CLKID_RAMB 53 +#define CLKID_RAMA 54 +#define CLKID_AXI_SPIFC55 +#define CLKID_AXI_NIC 56 +#define CLKID_AXI_DMA 57 +#define CLKID_CPU_CTRL 58 +#define CLKID_ROM 59 +#define CLKID_PROC_I2C 60 +#define CLKID_DSPA_SEL 61 +#define CLKID_DSPB_SEL 62 +#define CLKID_DSPA_EN 63 +#define CLKID_DSPA_EN_NIC 64 +#define CLKID_DSPB_EN 65 +#define CLKID_DSPB_EN_NIC 66 +#define CLKID_RTC 67 +#define CLKID_CECA_32K 68 +#define CLKID_CECB_32K 69 +#define CLKID_24M 70 +#define CLKID_12M 71 +#define CLKID_FCLK_DIV2_DIVN 72 +#define CLKID_GEN 73 +#define CLKID_SARADC_SEL 74 +#define CLKID_SARADC 75 +#define CLKID_PWM_A76 +#define CLKID_PWM_B77 +#define CLKID_PWM_C78 +#define CLKID_PWM_D79 +#define CLKID_PWM_E80 +#define CLKID_PWM_F81 +#define CLKID_SPICC82 +#define CLKID_TS 83 +#define CLKID_SPIFC84 +#define CLKID_USB_BUS 85 +#define CLKID_SD_EMMC 86 +#define CLKID_PSRAM87 +#define CLKID_DMC 88 +#define CLKID_SYS_A_SEL89 +#define CLKID_SYS_A_DIV90 +#define CLKID_SYS_A91 +#define CLKID_SYS_B_SEL92 +#define CLKID_SYS_B_DIV93 +#define CLKID_SYS_B94 +#define CLKID_DSPA_A_SEL 95 +#define CLKID_DSPA_A_DIV 96 +#define CLKID_DSPA_A 97 +#define CLKID_DSPA_B_SEL 98 +#define CLKID_DSPA_B_DIV 99 +#define CLKID_DSPA_B 100 +#define CLKID_DSPB_A_SEL 101 +#define CLKID_DSPB_A_DIV 102 +#define CLKID_DSPB_A 103 +#define CLKID_DSPB_B_SEL 104 +#define CLKID_DSPB_B_DIV 105 +#define CLKID_DSPB_B 106 +#define CLKID_RTC_32K_IN 107 +#define CLKID_RTC_32K_DIV 108 +#define CLKID_RTC_32K_XTAL 109 +#define
[PATCH v2 0/2] clk: amlogic: a1: Add Amlogic A1 clock driver
This series adds dt-bindings and driver implementation for Amlogic A1 PLL and Peripherals clock controllers. V1: https://lore.kernel.org/all/20230917101308.1250-1-ivpru...@salutedevices.com/ V1 -> V2: - Add more verbose comments for driver Igor Prusov (2): dt-bindings: clock: Add Amlogic A1 clock bindings clk: Add clock driver for Amlogic A1 arch/arm/include/asm/arch-meson/clock-a1.h| 23 + drivers/clk/meson/Kconfig | 8 + drivers/clk/meson/Makefile| 1 + drivers/clk/meson/a1.c| 723 ++ .../clock/amlogic,a1-peripherals-clkc.h | 168 .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 25 + 6 files changed, 948 insertions(+) create mode 100644 arch/arm/include/asm/arch-meson/clock-a1.h create mode 100644 drivers/clk/meson/a1.c create mode 100644 include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h -- 2.34.1
Re: [RESEND PATCH v1 2/2] clk: Add clock driver for Amlogic A1
Hi Simon, On Mon, Sep 18, 2023 at 07:04:47PM -0600, Simon Glass wrote: > On Sun, 17 Sept 2023 at 04:14, Igor Prusov wrote: > > > > This patch adds basic clock driver for Amlogic A1 Family which supports > > enabling/disabling some gates, getting frequencies and setting rate > > with limited reparenting. > > > > Signed-off-by: Igor Prusov > > --- > > arch/arm/include/asm/arch-meson/clock-a1.h | 23 + > > drivers/clk/meson/Kconfig | 8 + > > drivers/clk/meson/Makefile | 1 + > > drivers/clk/meson/a1.c | 681 + > > 4 files changed, 713 insertions(+) > > create mode 100644 arch/arm/include/asm/arch-meson/clock-a1.h > > create mode 100644 drivers/clk/meson/a1.c > > Reviewed-by: Simon Glass > > This could use a few more comments, IMO. Sure, I can add some more comments in V2. > Did it come from Linux? No, I wrote this specifically for u-boot. I initally was looking at other drivers in clk/meson/ for reference, but decided to go for something like clk_k210 driver to separate clocks topology and ops implementation. These clocks were added to Linux in [1], but AFAIU we can't simply re-use Linux clock drivers and get working rate propogation, reparenting e.t.c. [1]: https://lore.kernel.org/all/20230523135351.19133-1-ddroko...@sberdevices.ru/ -- Best Regards, Igor Prusov
[RESEND PATCH v1 2/2] clk: Add clock driver for Amlogic A1
This patch adds basic clock driver for Amlogic A1 Family which supports enabling/disabling some gates, getting frequencies and setting rate with limited reparenting. Signed-off-by: Igor Prusov --- arch/arm/include/asm/arch-meson/clock-a1.h | 23 + drivers/clk/meson/Kconfig | 8 + drivers/clk/meson/Makefile | 1 + drivers/clk/meson/a1.c | 681 + 4 files changed, 713 insertions(+) create mode 100644 arch/arm/include/asm/arch-meson/clock-a1.h create mode 100644 drivers/clk/meson/a1.c diff --git a/arch/arm/include/asm/arch-meson/clock-a1.h b/arch/arm/include/asm/arch-meson/clock-a1.h new file mode 100644 index 00..f6795f5e0c --- /dev/null +++ b/arch/arm/include/asm/arch-meson/clock-a1.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2018 - AmLogic, Inc. + * Copyright 2023 (C) SberDevices, Inc. + */ + +#ifndef _ARCH_MESON_CLOCK_A1_H_ +#define _ARCH_MESON_CLOCK_A1_H_ + +/* + * Clock controller register offsets + */ +#define A1_SYS_OSCIN_CTRL 0x0 +#define A1_SYS_CLK_CTRL0 0x10 +#define A1_SYS_CLK_EN0 0x1c +#define A1_SAR_ADC_CLK_CTR 0xc0 +#define A1_SPIFC_CLK_CTRL 0xd8 +#define A1_USB_BUSCLK_CTRL 0xdc +#define A1_SD_EMMC_CLK_CTRL0xe0 + +#define A1_ANACTRL_FIXPLL_CTRL00x0 + +#endif /* _ARCH_MESON_CLOCK_A1_H_ */ diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 994b44ad7a..cdc9d6f76c 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -21,3 +21,11 @@ config CLK_MESON_G12A help Enable clock support for the Amlogic G12A SoC family, such as the S905X/D2 + +config CLK_MESON_A1 + bool "Enable clock support for Amlogic A1" + depends on CLK && ARCH_MESON + default MESON_A1 + help + Enable clock support for the Amlogic A1 SoC family, such as + the A113L diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index a486b13e9c..d975f07aab 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_MESON_AXG) += axg.o obj-$(CONFIG_CLK_MESON_AXG) += axg-ao.o obj-$(CONFIG_CLK_MESON_G12A) += g12a.o obj-$(CONFIG_CLK_MESON_G12A) += g12a-ao.o +obj-$(CONFIG_CLK_MESON_A1) += a1.o diff --git a/drivers/clk/meson/a1.c b/drivers/clk/meson/a1.c new file mode 100644 index 00..6b2b9e6925 --- /dev/null +++ b/drivers/clk/meson/a1.c @@ -0,0 +1,681 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2023 SberDevices, Inc. + * Author: Igor Prusov + */ + +#include +#include +#include +#include +#include +#include +#include +#include "clk_meson.h" + +/* + * This driver supports both PLL and peripherals clock sources. + * Following operations are supported: + * - calculating clock frequency on a limited tree + * - reading muxes and dividers + * - enabling/disabling gates without propagation + * - reparenting without rate propagation, only on muxes + * - setting rates with limited reparenting, only on dividers with mux parent + */ + +#define NR_CLKS154 +#define NR_PLL_CLKS11 + +#define EXTERNAL_XTAL (NR_CLKS + 0) +#define EXTERNAL_FCLK_DIV2 (NR_CLKS + 1) +#define EXTERNAL_FCLK_DIV3 (NR_CLKS + 2) +#define EXTERNAL_FCLK_DIV5 (NR_CLKS + 3) +#define EXTERNAL_FCLK_DIV7 (NR_CLKS + 4) + +#define EXTERNAL_FIXPLL_IN (NR_PLL_CLKS + 1) + +#define SET_PARM_VALUE(_priv, _parm, _val) \ + regmap_update_bits((_priv)->map, (_parm)->reg_off, \ + SETPMASK((_parm)->width, (_parm)->shift),\ + (_val) << (_parm)->shift) + +#define GET_PARM_VALUE(_priv, _parm) \ +({ \ + uint _reg; \ + regmap_read((_priv)->map, (_parm)->reg_off, &_reg); \ + PARM_GET((_parm)->width, (_parm)->shift, _reg); \ +}) + +struct meson_clk { + struct regmap *map; +}; + +enum meson_clk_type { + MESON_CLK_ANY = 0, + MESON_CLK_GATE, + MESON_CLK_MUX, + MESON_CLK_DIV, + MESON_CLK_FIXED_DIV, + MESON_CLK_EXTERNAL, + MESON_CLK_PLL, +}; + +struct meson_clk_info { + const char *name; + union { + const struct parm *parm; + u8 div; + }; + const unsigned int *parents; + const enum meson_clk_type type; +}; + +struct meson_clk_data { + const u8 num_clocks; + const struct meson_clk_info **clocks; +}; + +#define CLK_MUX(_name, _reg, _shift, _wi
[RESEND PATCH v1 1/2] dt-bindings: clock: Add Amlogic A1 clock bindings
Add clock bindings for Amlogic A1 from linux-next next-20230821. Signed-off-by: Igor Prusov --- .../clock/amlogic,a1-peripherals-clkc.h | 168 ++ .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 25 +++ 2 files changed, 193 insertions(+) create mode 100644 include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h diff --git a/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h new file mode 100644 index 00..06f198ee76 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h @@ -0,0 +1,168 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + * Author: Jian Hu + * + * Copyright (c) 2023, SberDevices. All Rights Reserved. + * Author: Dmitry Rokosov + */ + +#ifndef __A1_PERIPHERALS_CLKC_H +#define __A1_PERIPHERALS_CLKC_H + +#define CLKID_XTAL_IN 0 +#define CLKID_FIXPLL_IN1 +#define CLKID_USB_PHY_IN 2 +#define CLKID_USB_CTRL_IN 3 +#define CLKID_HIFIPLL_IN 4 +#define CLKID_SYSPLL_IN5 +#define CLKID_DDS_IN 6 +#define CLKID_SYS 7 +#define CLKID_CLKTREE 8 +#define CLKID_RESET_CTRL 9 +#define CLKID_ANALOG_CTRL 10 +#define CLKID_PWR_CTRL 11 +#define CLKID_PAD_CTRL 12 +#define CLKID_SYS_CTRL 13 +#define CLKID_TEMP_SENSOR 14 +#define CLKID_AM2AXI_DIV 15 +#define CLKID_SPICC_B 16 +#define CLKID_SPICC_A 17 +#define CLKID_MSR 18 +#define CLKID_AUDIO19 +#define CLKID_JTAG_CTRL20 +#define CLKID_SARADC_EN21 +#define CLKID_PWM_EF 22 +#define CLKID_PWM_CD 23 +#define CLKID_PWM_AB 24 +#define CLKID_CEC 25 +#define CLKID_I2C_S26 +#define CLKID_IR_CTRL 27 +#define CLKID_I2C_M_D 28 +#define CLKID_I2C_M_C 29 +#define CLKID_I2C_M_B 30 +#define CLKID_I2C_M_A 31 +#define CLKID_ACODEC 32 +#define CLKID_OTP 33 +#define CLKID_SD_EMMC_A34 +#define CLKID_USB_PHY 35 +#define CLKID_USB_CTRL 36 +#define CLKID_SYS_DSPB 37 +#define CLKID_SYS_DSPA 38 +#define CLKID_DMA 39 +#define CLKID_IRQ_CTRL 40 +#define CLKID_NIC 41 +#define CLKID_GIC 42 +#define CLKID_UART_C 43 +#define CLKID_UART_B 44 +#define CLKID_UART_A 45 +#define CLKID_SYS_PSRAM46 +#define CLKID_RSA 47 +#define CLKID_CORESIGHT48 +#define CLKID_AM2AXI_VAD 49 +#define CLKID_AUDIO_VAD50 +#define CLKID_AXI_DMC 51 +#define CLKID_AXI_PSRAM52 +#define CLKID_RAMB 53 +#define CLKID_RAMA 54 +#define CLKID_AXI_SPIFC55 +#define CLKID_AXI_NIC 56 +#define CLKID_AXI_DMA 57 +#define CLKID_CPU_CTRL 58 +#define CLKID_ROM 59 +#define CLKID_PROC_I2C 60 +#define CLKID_DSPA_SEL 61 +#define CLKID_DSPB_SEL 62 +#define CLKID_DSPA_EN 63 +#define CLKID_DSPA_EN_NIC 64 +#define CLKID_DSPB_EN 65 +#define CLKID_DSPB_EN_NIC 66 +#define CLKID_RTC 67 +#define CLKID_CECA_32K 68 +#define CLKID_CECB_32K 69 +#define CLKID_24M 70 +#define CLKID_12M 71 +#define CLKID_FCLK_DIV2_DIVN 72 +#define CLKID_GEN 73 +#define CLKID_SARADC_SEL 74 +#define CLKID_SARADC 75 +#define CLKID_PWM_A76 +#define CLKID_PWM_B77 +#define CLKID_PWM_C78 +#define CLKID_PWM_D79 +#define CLKID_PWM_E80 +#define CLKID_PWM_F81 +#define CLKID_SPICC82 +#define CLKID_TS 83 +#define CLKID_SPIFC84 +#define CLKID_USB_BUS 85 +#define CLKID_SD_EMMC 86 +#define CLKID_PSRAM87 +#define CLKID_DMC 88 +#define CLKID_SYS_A_SEL89 +#define CLKID_SYS_A_DIV90 +#define CLKID_SYS_A91 +#define CLKID_SYS_B_SEL92 +#define CLKID_SYS_B_DIV93 +#define CLKID_SYS_B94 +#define CLKID_DSPA_A_SEL 95 +#define CLKID_DSPA_A_DIV 96 +#define CLKID_DSPA_A 97 +#define CLKID_DSPA_B_SEL 98 +#define CLKID_DSPA_B_DIV 99 +#define CLKID_DSPA_B 100 +#define CLKID_DSPB_A_SEL 101 +#define CLKID_DSPB_A_DIV 102 +#define CLKID_DSPB_A 103 +#define CLKID_DSPB_B_SEL 104 +#define CLKID_DSPB_B_DIV 105 +#define CLKID_DSPB_B 106 +#define CLKID_RTC_32K_IN 107 +#define CLKID_RTC_32K_DIV 108 +#define CLKID_RTC_32K_XTAL 109 +#define CLKID_RTC_32K_SEL 110 +#define
[RESEND PATCH v1 0/2] clk: amlogic: a1: Add Amlogic A1 clock driver
This series adds dt-bindings and driver implementation for Amlogic A1 PLL and Peripherals clock controllers. Igor Prusov (2): dt-bindings: clock: Add Amlogic A1 clock bindings clk: Add clock driver for Amlogic A1 arch/arm/include/asm/arch-meson/clock-a1.h| 23 + drivers/clk/meson/Kconfig | 8 + drivers/clk/meson/Makefile| 1 + drivers/clk/meson/a1.c| 681 ++ .../clock/amlogic,a1-peripherals-clkc.h | 168 + .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 25 + 6 files changed, 906 insertions(+) create mode 100644 arch/arm/include/asm/arch-meson/clock-a1.h create mode 100644 drivers/clk/meson/a1.c create mode 100644 include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h -- 2.34.1
[PATCH v1 2/2] clk: Add clock driver for Amlogic A1
This patch adds basic clock driver for Amlogic A1 Family which supports enabling/disabling some gates, getting frequencies and setting rate with limited reparenting. Signed-off-by: Igor Prusov --- arch/arm/include/asm/arch-meson/clock-a1.h | 23 + drivers/clk/meson/Kconfig | 8 + drivers/clk/meson/Makefile | 1 + drivers/clk/meson/a1.c | 681 + 4 files changed, 713 insertions(+) create mode 100644 arch/arm/include/asm/arch-meson/clock-a1.h create mode 100644 drivers/clk/meson/a1.c diff --git a/arch/arm/include/asm/arch-meson/clock-a1.h b/arch/arm/include/asm/arch-meson/clock-a1.h new file mode 100644 index 00..f6795f5e0c --- /dev/null +++ b/arch/arm/include/asm/arch-meson/clock-a1.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2018 - AmLogic, Inc. + * Copyright 2023 (C) SberDevices, Inc. + */ + +#ifndef _ARCH_MESON_CLOCK_A1_H_ +#define _ARCH_MESON_CLOCK_A1_H_ + +/* + * Clock controller register offsets + */ +#define A1_SYS_OSCIN_CTRL 0x0 +#define A1_SYS_CLK_CTRL0 0x10 +#define A1_SYS_CLK_EN0 0x1c +#define A1_SAR_ADC_CLK_CTR 0xc0 +#define A1_SPIFC_CLK_CTRL 0xd8 +#define A1_USB_BUSCLK_CTRL 0xdc +#define A1_SD_EMMC_CLK_CTRL0xe0 + +#define A1_ANACTRL_FIXPLL_CTRL00x0 + +#endif /* _ARCH_MESON_CLOCK_A1_H_ */ diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 994b44ad7a..cdc9d6f76c 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -21,3 +21,11 @@ config CLK_MESON_G12A help Enable clock support for the Amlogic G12A SoC family, such as the S905X/D2 + +config CLK_MESON_A1 + bool "Enable clock support for Amlogic A1" + depends on CLK && ARCH_MESON + default MESON_A1 + help + Enable clock support for the Amlogic A1 SoC family, such as + the A113L diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index a486b13e9c..d975f07aab 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_MESON_AXG) += axg.o obj-$(CONFIG_CLK_MESON_AXG) += axg-ao.o obj-$(CONFIG_CLK_MESON_G12A) += g12a.o obj-$(CONFIG_CLK_MESON_G12A) += g12a-ao.o +obj-$(CONFIG_CLK_MESON_A1) += a1.o diff --git a/drivers/clk/meson/a1.c b/drivers/clk/meson/a1.c new file mode 100644 index 00..6b2b9e6925 --- /dev/null +++ b/drivers/clk/meson/a1.c @@ -0,0 +1,681 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2023 SberDevices, Inc. + * Author: Igor Prusov + */ + +#include +#include +#include +#include +#include +#include +#include +#include "clk_meson.h" + +/* + * This driver supports both PLL and peripherals clock sources. + * Following operations are supported: + * - calculating clock frequency on a limited tree + * - reading muxes and dividers + * - enabling/disabling gates without propagation + * - reparenting without rate propagation, only on muxes + * - setting rates with limited reparenting, only on dividers with mux parent + */ + +#define NR_CLKS154 +#define NR_PLL_CLKS11 + +#define EXTERNAL_XTAL (NR_CLKS + 0) +#define EXTERNAL_FCLK_DIV2 (NR_CLKS + 1) +#define EXTERNAL_FCLK_DIV3 (NR_CLKS + 2) +#define EXTERNAL_FCLK_DIV5 (NR_CLKS + 3) +#define EXTERNAL_FCLK_DIV7 (NR_CLKS + 4) + +#define EXTERNAL_FIXPLL_IN (NR_PLL_CLKS + 1) + +#define SET_PARM_VALUE(_priv, _parm, _val) \ + regmap_update_bits((_priv)->map, (_parm)->reg_off, \ + SETPMASK((_parm)->width, (_parm)->shift),\ + (_val) << (_parm)->shift) + +#define GET_PARM_VALUE(_priv, _parm) \ +({ \ + uint _reg; \ + regmap_read((_priv)->map, (_parm)->reg_off, &_reg); \ + PARM_GET((_parm)->width, (_parm)->shift, _reg); \ +}) + +struct meson_clk { + struct regmap *map; +}; + +enum meson_clk_type { + MESON_CLK_ANY = 0, + MESON_CLK_GATE, + MESON_CLK_MUX, + MESON_CLK_DIV, + MESON_CLK_FIXED_DIV, + MESON_CLK_EXTERNAL, + MESON_CLK_PLL, +}; + +struct meson_clk_info { + const char *name; + union { + const struct parm *parm; + u8 div; + }; + const unsigned int *parents; + const enum meson_clk_type type; +}; + +struct meson_clk_data { + const u8 num_clocks; + const struct meson_clk_info **clocks; +}; + +#define CLK_MUX(_name, _reg, _shift, _wi
[PATCH v1 1/2] dt-bindings: clock: Add Amlogic A1 clock bindings
Add clock bindings for Amlogic A1 from linux-next next-20230821. Signed-off-by: Igor Prusov --- .../clock/amlogic,a1-peripherals-clkc.h | 168 ++ .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 25 +++ 2 files changed, 193 insertions(+) create mode 100644 include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h diff --git a/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h new file mode 100644 index 00..06f198ee76 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h @@ -0,0 +1,168 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + * Author: Jian Hu + * + * Copyright (c) 2023, SberDevices. All Rights Reserved. + * Author: Dmitry Rokosov + */ + +#ifndef __A1_PERIPHERALS_CLKC_H +#define __A1_PERIPHERALS_CLKC_H + +#define CLKID_XTAL_IN 0 +#define CLKID_FIXPLL_IN1 +#define CLKID_USB_PHY_IN 2 +#define CLKID_USB_CTRL_IN 3 +#define CLKID_HIFIPLL_IN 4 +#define CLKID_SYSPLL_IN5 +#define CLKID_DDS_IN 6 +#define CLKID_SYS 7 +#define CLKID_CLKTREE 8 +#define CLKID_RESET_CTRL 9 +#define CLKID_ANALOG_CTRL 10 +#define CLKID_PWR_CTRL 11 +#define CLKID_PAD_CTRL 12 +#define CLKID_SYS_CTRL 13 +#define CLKID_TEMP_SENSOR 14 +#define CLKID_AM2AXI_DIV 15 +#define CLKID_SPICC_B 16 +#define CLKID_SPICC_A 17 +#define CLKID_MSR 18 +#define CLKID_AUDIO19 +#define CLKID_JTAG_CTRL20 +#define CLKID_SARADC_EN21 +#define CLKID_PWM_EF 22 +#define CLKID_PWM_CD 23 +#define CLKID_PWM_AB 24 +#define CLKID_CEC 25 +#define CLKID_I2C_S26 +#define CLKID_IR_CTRL 27 +#define CLKID_I2C_M_D 28 +#define CLKID_I2C_M_C 29 +#define CLKID_I2C_M_B 30 +#define CLKID_I2C_M_A 31 +#define CLKID_ACODEC 32 +#define CLKID_OTP 33 +#define CLKID_SD_EMMC_A34 +#define CLKID_USB_PHY 35 +#define CLKID_USB_CTRL 36 +#define CLKID_SYS_DSPB 37 +#define CLKID_SYS_DSPA 38 +#define CLKID_DMA 39 +#define CLKID_IRQ_CTRL 40 +#define CLKID_NIC 41 +#define CLKID_GIC 42 +#define CLKID_UART_C 43 +#define CLKID_UART_B 44 +#define CLKID_UART_A 45 +#define CLKID_SYS_PSRAM46 +#define CLKID_RSA 47 +#define CLKID_CORESIGHT48 +#define CLKID_AM2AXI_VAD 49 +#define CLKID_AUDIO_VAD50 +#define CLKID_AXI_DMC 51 +#define CLKID_AXI_PSRAM52 +#define CLKID_RAMB 53 +#define CLKID_RAMA 54 +#define CLKID_AXI_SPIFC55 +#define CLKID_AXI_NIC 56 +#define CLKID_AXI_DMA 57 +#define CLKID_CPU_CTRL 58 +#define CLKID_ROM 59 +#define CLKID_PROC_I2C 60 +#define CLKID_DSPA_SEL 61 +#define CLKID_DSPB_SEL 62 +#define CLKID_DSPA_EN 63 +#define CLKID_DSPA_EN_NIC 64 +#define CLKID_DSPB_EN 65 +#define CLKID_DSPB_EN_NIC 66 +#define CLKID_RTC 67 +#define CLKID_CECA_32K 68 +#define CLKID_CECB_32K 69 +#define CLKID_24M 70 +#define CLKID_12M 71 +#define CLKID_FCLK_DIV2_DIVN 72 +#define CLKID_GEN 73 +#define CLKID_SARADC_SEL 74 +#define CLKID_SARADC 75 +#define CLKID_PWM_A76 +#define CLKID_PWM_B77 +#define CLKID_PWM_C78 +#define CLKID_PWM_D79 +#define CLKID_PWM_E80 +#define CLKID_PWM_F81 +#define CLKID_SPICC82 +#define CLKID_TS 83 +#define CLKID_SPIFC84 +#define CLKID_USB_BUS 85 +#define CLKID_SD_EMMC 86 +#define CLKID_PSRAM87 +#define CLKID_DMC 88 +#define CLKID_SYS_A_SEL89 +#define CLKID_SYS_A_DIV90 +#define CLKID_SYS_A91 +#define CLKID_SYS_B_SEL92 +#define CLKID_SYS_B_DIV93 +#define CLKID_SYS_B94 +#define CLKID_DSPA_A_SEL 95 +#define CLKID_DSPA_A_DIV 96 +#define CLKID_DSPA_A 97 +#define CLKID_DSPA_B_SEL 98 +#define CLKID_DSPA_B_DIV 99 +#define CLKID_DSPA_B 100 +#define CLKID_DSPB_A_SEL 101 +#define CLKID_DSPB_A_DIV 102 +#define CLKID_DSPB_A 103 +#define CLKID_DSPB_B_SEL 104 +#define CLKID_DSPB_B_DIV 105 +#define CLKID_DSPB_B 106 +#define CLKID_RTC_32K_IN 107 +#define CLKID_RTC_32K_DIV 108 +#define CLKID_RTC_32K_XTAL 109 +#define CLKID_RTC_32K_SEL 110 +#define
[PATCH v1 0/2] clk: amlogic: a1: Add Amlogic A1 clock driver
This series adds dt-bindings and driver implementation for Amlogic A1 PLL and Peripherals clock controllers. Igor Prusov (2): dt-bindings: clock: Add Amlogic A1 clock bindings clk: Add clock driver for Amlogic A1 arch/arm/include/asm/arch-meson/clock-a1.h| 23 + drivers/clk/meson/Kconfig | 8 + drivers/clk/meson/Makefile| 1 + drivers/clk/meson/a1.c| 681 ++ .../clock/amlogic,a1-peripherals-clkc.h | 168 + .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 25 + 6 files changed, 906 insertions(+) create mode 100644 arch/arm/include/asm/arch-meson/clock-a1.h create mode 100644 drivers/clk/meson/a1.c create mode 100644 include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h -- 2.34.1
Re: [PATCH v3 0/7] clk: Switch from soc_clk_dump to clk_ops function
+Simon Glass Hi Simon, Apologies for the ping, but could you please take a look at this series? There was not much feedback after a while, so I'd like to understand whether proposed fix is viable or not. On Fri, Jul 14, 2023 at 06:24:37PM +0300, Igor Prusov wrote: > Currently clock providers may override default implementation of > soc_clk_dump function to replace clk dump command output. This causes > confusing behaviour when u-boot is built with one of such drivers > enabled but still has clocks defined using CCF. For example, enabling > CMD_CLK and using clk dump on sandbox target will not show CCF clocks > because k210 driver overrides common soc_clk_dump. > > Changelog: > v1 -> v2: > - Add missing static to dump functions > v2 -> v3: > - Make soc_clk_dump in cmd/clk.c static instead of removing __weak > > Igor Prusov (7): > clk: zynq: Move soc_clk_dump to Zynq clock driver > clk: ast2600: Move soc_clk_dump function > clk: k210: Move soc_clk_dump function > clk: Add dump operation to clk_ops > cmd: clk: Use dump function from clk_ops > clk: treewide: switch to clock dump from clk_ops > cmd: clk: Make soc_clk_dump static > > arch/arm/mach-zynq/clk.c | 57 -- > arch/mips/mach-pic32/cpu.c | 23 -- > cmd/clk.c | 13 +++- > drivers/clk/aspeed/clk_ast2600.c | 83 ++-- > drivers/clk/clk_k210.c | 103 - > drivers/clk/clk_pic32.c| 39 ++ > drivers/clk/clk_versal.c | 7 +- > drivers/clk/clk_zynq.c | 51 > drivers/clk/clk_zynqmp.c | 13 ++-- > drivers/clk/imx/clk-imx8.c | 11 +-- > drivers/clk/mvebu/armada-37xx-periph.c | 5 +- > drivers/clk/stm32/clk-stm32mp1.c | 29 ++- > include/clk-uclass.h | 3 + > include/clk.h | 2 - > 14 files changed, 223 insertions(+), 216 deletions(-) > > -- > 2.34.1 > -- Best Regards, Igor Prusov
[PATCH v3 6/7] clk: treewide: switch to clock dump from clk_ops
Switch to using new dump operation in clock provider drivers instead of overriding soc_clk_dump. Signed-off-by: Igor Prusov --- arch/mips/mach-pic32/cpu.c | 23 --- drivers/clk/aspeed/clk_ast2600.c | 13 - drivers/clk/clk_k210.c | 11 +++- drivers/clk/clk_pic32.c| 39 ++ drivers/clk/clk_versal.c | 7 - drivers/clk/clk_zynq.c | 19 - drivers/clk/clk_zynqmp.c | 13 - drivers/clk/imx/clk-imx8.c | 11 +++- drivers/clk/mvebu/armada-37xx-periph.c | 5 +++- drivers/clk/stm32/clk-stm32mp1.c | 29 ++- 10 files changed, 83 insertions(+), 87 deletions(-) diff --git a/arch/mips/mach-pic32/cpu.c b/arch/mips/mach-pic32/cpu.c index ec3c250531..99401745da 100644 --- a/arch/mips/mach-pic32/cpu.c +++ b/arch/mips/mach-pic32/cpu.c @@ -148,26 +148,3 @@ const char *get_core_name(void) return str; } #endif -#ifdef CONFIG_CMD_CLK - -int soc_clk_dump(void) -{ - int i; - - printf("PLL Speed: %lu MHz\n", - CLK_MHZ(rate(PLLCLK))); - - printf("CPU Speed: %lu MHz\n", CLK_MHZ(rate(PB7CLK))); - - printf("MPLL Speed: %lu MHz\n", CLK_MHZ(rate(MPLL))); - - for (i = PB1CLK; i <= PB7CLK; i++) - printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1, - CLK_MHZ(rate(i))); - - for (i = REF1CLK; i <= REF5CLK; i++) - printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1, - CLK_MHZ(rate(i))); - return 0; -} -#endif diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index b3cc8392fa..e1365d3f81 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -1109,6 +1109,7 @@ struct aspeed_clks { const char *name; }; +#if IS_ENABLED(CONFIG_CMD_CLK) static struct aspeed_clks aspeed_clk_names[] = { { ASPEED_CLK_HPLL, "hpll" }, { ASPEED_CLK_MPLL, "mpll" }, @@ -1123,18 +1124,12 @@ static struct aspeed_clks aspeed_clk_names[] = { { ASPEED_CLK_HUARTX, "huxclk" }, }; -int soc_clk_dump(void) +static int ast2600_clk_dump(struct udevice *dev) { - struct udevice *dev; struct clk clk; unsigned long rate; int i, ret; - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(aspeed_scu), - &dev); - if (ret) - return ret; - printf("Clk\t\tHz\n"); for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) { @@ -1167,11 +1162,15 @@ int soc_clk_dump(void) return 0; } +#endif struct clk_ops ast2600_clk_ops = { .get_rate = ast2600_clk_get_rate, .set_rate = ast2600_clk_set_rate, .enable = ast2600_clk_enable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = ast2600_clk_dump, +#endif }; static int ast2600_clk_probe(struct udevice *dev) diff --git a/drivers/clk/clk_k210.c b/drivers/clk/clk_k210.c index 2f17152021..058940b828 100644 --- a/drivers/clk/clk_k210.c +++ b/drivers/clk/clk_k210.c @@ -1276,16 +1276,10 @@ static void show_clks(struct k210_clk_priv *priv, int id, int depth) } } -int soc_clk_dump(void) +static int k210_clk_dump(struct udevice *dev) { - int ret; - struct udevice *dev; struct k210_clk_priv *priv; - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(k210_clk), - &dev); - if (ret) - return ret; priv = dev_get_priv(dev); puts(" Rate Enabled Name\n"); @@ -1304,6 +1298,9 @@ static const struct clk_ops k210_clk_ops = { .set_parent = k210_clk_set_parent, .enable = k210_clk_enable, .disable = k210_clk_disable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = k210_clk_dump, +#endif }; static int k210_clk_probe(struct udevice *dev) diff --git a/drivers/clk/clk_pic32.c b/drivers/clk/clk_pic32.c index ef06a7fb9f..f756fc88f0 100644 --- a/drivers/clk/clk_pic32.c +++ b/drivers/clk/clk_pic32.c @@ -20,6 +20,8 @@ DECLARE_GLOBAL_DATA_PTR; +#define CLK_MHZ(x) ((x) / 100) + /* Primary oscillator */ #define SYS_POSC_CLK_HZ2400 @@ -385,9 +387,46 @@ static ulong pic32_set_rate(struct clk *clk, ulong rate) return rate; } +#if IS_ENABLED(CONFIG_CMD_CLK) +static int pic32_dump(struct udevice *dev) +{ + int i; + struct clk clk; + + clk.dev = dev; + + clk.id = PLLCLK; + printf("PLL Speed: %lu MHz\n", + CLK_MHZ(pic32_get_rate(&clk))); + + clk.id = PB7CLK; + printf("CPU Speed: %lu MHz\n", CLK_MHZ(pic32_get_rate(&clk))); + + clk.id = MPLL; + printf("MPLL Speed: %lu MHz\n", CLK_MHZ(pic32_ge
[PATCH v3 7/7] cmd: clk: Make soc_clk_dump static
After introducing dump to clk_ops there is no need to override or expose this symbol anymore. Signed-off-by: Igor Prusov --- cmd/clk.c | 4 ++-- include/clk.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cmd/clk.c b/cmd/clk.c index 55fb96e631..59155d7902 100644 --- a/cmd/clk.c +++ b/cmd/clk.c @@ -59,7 +59,7 @@ static void show_clks(struct udevice *dev, int depth, int last_flag) } } -int __weak soc_clk_dump(void) +static int soc_clk_dump(void) { struct udevice *dev; const struct clk_ops *ops; @@ -81,7 +81,7 @@ int __weak soc_clk_dump(void) return 0; } #else -int __weak soc_clk_dump(void) +static int soc_clk_dump(void) { puts("Not implemented\n"); return 1; diff --git a/include/clk.h b/include/clk.h index d91285235f..bf0d9c9d7f 100644 --- a/include/clk.h +++ b/include/clk.h @@ -674,8 +674,6 @@ static inline bool clk_valid(struct clk *clk) return clk && !!clk->dev; } -int soc_clk_dump(void); - #endif #define clk_prepare_enable(clk) clk_enable(clk) -- 2.34.1
[PATCH v3 5/7] cmd: clk: Use dump function from clk_ops
Add another loop to dump additional info from clock providers that implement dump operation. Signed-off-by: Igor Prusov --- cmd/clk.c | 9 + 1 file changed, 9 insertions(+) diff --git a/cmd/clk.c b/cmd/clk.c index ff7c7649a1..55fb96e631 100644 --- a/cmd/clk.c +++ b/cmd/clk.c @@ -62,6 +62,7 @@ static void show_clks(struct udevice *dev, int depth, int last_flag) int __weak soc_clk_dump(void) { struct udevice *dev; + const struct clk_ops *ops; printf(" Rate Usecnt Name\n"); printf("--\n"); @@ -69,6 +70,14 @@ int __weak soc_clk_dump(void) uclass_foreach_dev_probe(UCLASS_CLK, dev) show_clks(dev, -1, 0); + uclass_foreach_dev_probe(UCLASS_CLK, dev) { + ops = dev_get_driver_ops(dev); + if (ops && ops->dump) { + printf("--\n"); + ops->dump(dev); + } + } + return 0; } #else -- 2.34.1
[PATCH v3 4/7] clk: Add dump operation to clk_ops
This adds dump function to struct clk_ops which should replace soc_clk_dump. It allows clock drivers to provide custom dump implementation without overriding generic CCF dump function. Signed-off-by: Igor Prusov --- include/clk-uclass.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/clk-uclass.h b/include/clk-uclass.h index 65ebff9ed2..f29f4c0d01 100644 --- a/include/clk-uclass.h +++ b/include/clk-uclass.h @@ -39,6 +39,9 @@ struct clk_ops { int (*set_parent)(struct clk *clk, struct clk *parent); int (*enable)(struct clk *clk); int (*disable)(struct clk *clk); +#if IS_ENABLED(CONFIG_CMD_CLK) + int (*dump)(struct udevice *dev); +#endif }; #if 0 /* For documentation only */ -- 2.34.1
[PATCH v3 3/7] clk: k210: Move soc_clk_dump function
Move clock dump function to avoid forward declaration after switching to dump in clk_ops. Signed-off-by: Igor Prusov --- drivers/clk/clk_k210.c | 92 +- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/clk/clk_k210.c b/drivers/clk/clk_k210.c index c534cc07e0..2f17152021 100644 --- a/drivers/clk/clk_k210.c +++ b/drivers/clk/clk_k210.c @@ -1238,52 +1238,6 @@ static int k210_clk_request(struct clk *clk) return 0; } -static const struct clk_ops k210_clk_ops = { - .request = k210_clk_request, - .set_rate = k210_clk_set_rate, - .get_rate = k210_clk_get_rate, - .set_parent = k210_clk_set_parent, - .enable = k210_clk_enable, - .disable = k210_clk_disable, -}; - -static int k210_clk_probe(struct udevice *dev) -{ - int ret; - struct k210_clk_priv *priv = dev_get_priv(dev); - - priv->base = dev_read_addr_ptr(dev_get_parent(dev)); - if (!priv->base) - return -EINVAL; - - ret = clk_get_by_index(dev, 0, &priv->in0); - if (ret) - return ret; - - /* -* Force setting defaults, even before relocation. This is so we can -* set the clock rate for PLL1 before we relocate into aisram. -*/ - if (!(gd->flags & GD_FLG_RELOC)) - clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE); - - return 0; -} - -static const struct udevice_id k210_clk_ids[] = { - { .compatible = "canaan,k210-clk" }, - { }, -}; - -U_BOOT_DRIVER(k210_clk) = { - .name = "k210_clk", - .id = UCLASS_CLK, - .of_match = k210_clk_ids, - .ops = &k210_clk_ops, - .probe = k210_clk_probe, - .priv_auto = sizeof(struct k210_clk_priv), -}; - #if IS_ENABLED(CONFIG_CMD_CLK) static char show_enabled(struct k210_clk_priv *priv, int id) { @@ -1342,3 +1296,49 @@ int soc_clk_dump(void) return 0; } #endif + +static const struct clk_ops k210_clk_ops = { + .request = k210_clk_request, + .set_rate = k210_clk_set_rate, + .get_rate = k210_clk_get_rate, + .set_parent = k210_clk_set_parent, + .enable = k210_clk_enable, + .disable = k210_clk_disable, +}; + +static int k210_clk_probe(struct udevice *dev) +{ + int ret; + struct k210_clk_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev_get_parent(dev)); + if (!priv->base) + return -EINVAL; + + ret = clk_get_by_index(dev, 0, &priv->in0); + if (ret) + return ret; + + /* +* Force setting defaults, even before relocation. This is so we can +* set the clock rate for PLL1 before we relocate into aisram. +*/ + if (!(gd->flags & GD_FLG_RELOC)) + clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE); + + return 0; +} + +static const struct udevice_id k210_clk_ids[] = { + { .compatible = "canaan,k210-clk" }, + { }, +}; + +U_BOOT_DRIVER(k210_clk) = { + .name = "k210_clk", + .id = UCLASS_CLK, + .of_match = k210_clk_ids, + .ops = &k210_clk_ops, + .probe = k210_clk_probe, + .priv_auto = sizeof(struct k210_clk_priv), +}; -- 2.34.1
[PATCH v3 0/7] clk: Switch from soc_clk_dump to clk_ops function
Currently clock providers may override default implementation of soc_clk_dump function to replace clk dump command output. This causes confusing behaviour when u-boot is built with one of such drivers enabled but still has clocks defined using CCF. For example, enabling CMD_CLK and using clk dump on sandbox target will not show CCF clocks because k210 driver overrides common soc_clk_dump. Changelog: v1 -> v2: - Add missing static to dump functions v2 -> v3: - Make soc_clk_dump in cmd/clk.c static instead of removing __weak Igor Prusov (7): clk: zynq: Move soc_clk_dump to Zynq clock driver clk: ast2600: Move soc_clk_dump function clk: k210: Move soc_clk_dump function clk: Add dump operation to clk_ops cmd: clk: Use dump function from clk_ops clk: treewide: switch to clock dump from clk_ops cmd: clk: Make soc_clk_dump static arch/arm/mach-zynq/clk.c | 57 -- arch/mips/mach-pic32/cpu.c | 23 -- cmd/clk.c | 13 +++- drivers/clk/aspeed/clk_ast2600.c | 83 ++-- drivers/clk/clk_k210.c | 103 - drivers/clk/clk_pic32.c| 39 ++ drivers/clk/clk_versal.c | 7 +- drivers/clk/clk_zynq.c | 51 drivers/clk/clk_zynqmp.c | 13 ++-- drivers/clk/imx/clk-imx8.c | 11 +-- drivers/clk/mvebu/armada-37xx-periph.c | 5 +- drivers/clk/stm32/clk-stm32mp1.c | 29 ++- include/clk-uclass.h | 3 + include/clk.h | 2 - 14 files changed, 223 insertions(+), 216 deletions(-) -- 2.34.1
[PATCH v3 1/7] clk: zynq: Move soc_clk_dump to Zynq clock driver
Move clock dump function in preparation for switching to dump function in clk_ops. Signed-off-by: Igor Prusov Acked-by: Michal Simek --- arch/arm/mach-zynq/clk.c | 57 --- drivers/clk/clk_zynq.c | 58 2 files changed, 58 insertions(+), 57 deletions(-) diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c index 1945f60e08..e6a67326dd 100644 --- a/arch/arm/mach-zynq/clk.c +++ b/arch/arm/mach-zynq/clk.c @@ -13,20 +13,6 @@ DECLARE_GLOBAL_DATA_PTR; -static const char * const clk_names[clk_max] = { - "armpll", "ddrpll", "iopll", - "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", - "ddr2x", "ddr3x", "dci", - "lqspi", "smc", "pcap", "gem0", "gem1", - "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", - "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", - "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", - "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", - "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", - "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", - "smc_aper", "swdt", "dbg_trc", "dbg_apb" -}; - /** * set_cpu_clk_info() - Setup clock information * @@ -65,46 +51,3 @@ int set_cpu_clk_info(void) return 0; } - -/** - * soc_clk_dump() - Print clock frequencies - * Returns zero on success - * - * Implementation for the clk dump command. - */ -int soc_clk_dump(void) -{ - struct udevice *dev; - int i, ret; - - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(zynq_clk), &dev); - if (ret) - return ret; - - printf("clk\t\tfrequency\n"); - for (i = 0; i < clk_max; i++) { - const char *name = clk_names[i]; - if (name) { - struct clk clk; - unsigned long rate; - - clk.id = i; - ret = clk_request(dev, &clk); - if (ret < 0) - return ret; - - rate = clk_get_rate(&clk); - - clk_free(&clk); - - if ((rate == (unsigned long)-ENOSYS) || - (rate == (unsigned long)-ENXIO)) - printf("%10s%20s\n", name, "unknown"); - else - printf("%10s%20lu\n", name, rate); - } - } - - return 0; -} diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c index e80500e382..be5226175f 100644 --- a/drivers/clk/clk_zynq.c +++ b/drivers/clk/clk_zynq.c @@ -454,6 +454,64 @@ static int dummy_enable(struct clk *clk) return 0; } +static const char * const clk_names[clk_max] = { + "armpll", "ddrpll", "iopll", + "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", + "ddr2x", "ddr3x", "dci", + "lqspi", "smc", "pcap", "gem0", "gem1", + "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", + "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", + "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", + "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", + "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", + "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", + "smc_aper", "swdt", "dbg_trc", "dbg_apb" +}; + +/** + * soc_clk_dump() - Print clock frequencies + * Returns zero on success + * + * Implementation for the clk dump command. + */ +int soc_clk_dump(void) +{ + struct udevice *dev; + int i, ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(zynq_clk), &dev); + if (ret) + return ret; + + printf("clk\t\tfrequency\n"); + for (i = 0; i < clk_max; i++) { + const char *name = clk_names[i]; + + if (name) { + struct clk clk; + unsigned long rate; + + clk.id = i; + ret = clk_request(dev, &clk); + if (ret < 0) + return ret; + + rate = clk_get_rate(&clk); + + clk_free(&clk); + + if ((rate == (unsigned long)-ENOSYS) || + (rate == (unsigned long)-ENXIO)) + printf("%10s%20s\n", name, "unknown"); + else + printf("%10s%20lu\n", name, rate); + } + } + + return 0; +} + static struct clk_ops zynq_clk_ops = { .get_rate = zynq_clk_get_rate, #ifndef CONFIG_SPL_BUILD -- 2.34.1
[PATCH v3 2/7] clk: ast2600: Move soc_clk_dump function
Move clock dump function to avoid forward declaration after switching to dump in clk_ops. Signed-off-by: Igor Prusov --- drivers/clk/aspeed/clk_ast2600.c | 70 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index e5ada5b6d4..b3cc8392fa 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -1104,41 +1104,6 @@ static int ast2600_clk_enable(struct clk *clk) return 0; } -struct clk_ops ast2600_clk_ops = { - .get_rate = ast2600_clk_get_rate, - .set_rate = ast2600_clk_set_rate, - .enable = ast2600_clk_enable, -}; - -static int ast2600_clk_probe(struct udevice *dev) -{ - struct ast2600_clk_priv *priv = dev_get_priv(dev); - - priv->scu = devfdt_get_addr_ptr(dev); - if (IS_ERR(priv->scu)) - return PTR_ERR(priv->scu); - - ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); - ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); - ast2600_configure_mac12_clk(priv->scu); - ast2600_configure_mac34_clk(priv->scu); - ast2600_configure_rsa_ecc_clk(priv->scu); - - return 0; -} - -static int ast2600_clk_bind(struct udevice *dev) -{ - int ret; - - /* The reset driver does not have a device node, so bind it here */ - ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); - if (ret) - debug("Warning: No reset driver: ret=%d\n", ret); - - return 0; -} - struct aspeed_clks { ulong id; const char *name; @@ -1203,6 +1168,41 @@ int soc_clk_dump(void) return 0; } +struct clk_ops ast2600_clk_ops = { + .get_rate = ast2600_clk_get_rate, + .set_rate = ast2600_clk_set_rate, + .enable = ast2600_clk_enable, +}; + +static int ast2600_clk_probe(struct udevice *dev) +{ + struct ast2600_clk_priv *priv = dev_get_priv(dev); + + priv->scu = devfdt_get_addr_ptr(dev); + if (IS_ERR(priv->scu)) + return PTR_ERR(priv->scu); + + ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); + ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); + ast2600_configure_mac12_clk(priv->scu); + ast2600_configure_mac34_clk(priv->scu); + ast2600_configure_rsa_ecc_clk(priv->scu); + + return 0; +} + +static int ast2600_clk_bind(struct udevice *dev) +{ + int ret; + + /* The reset driver does not have a device node, so bind it here */ + ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); + if (ret) + debug("Warning: No reset driver: ret=%d\n", ret); + + return 0; +} + static const struct udevice_id ast2600_clk_ids[] = { { .compatible = "aspeed,ast2600-scu", }, { }, -- 2.34.1