[PATCH 1/2] clk: Check that composite clock's div has set_rate()

2023-12-05 Thread Igor Prusov
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()

2023-12-05 Thread Igor Prusov
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()

2023-12-05 Thread Igor Prusov
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

2023-11-14 Thread Igor Prusov
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

2023-11-14 Thread Igor Prusov
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

2023-11-14 Thread Igor Prusov
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()

2023-11-14 Thread Igor Prusov
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

2023-11-14 Thread Igor Prusov
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

2023-11-14 Thread Igor Prusov
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

2023-11-14 Thread Igor Prusov
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

2023-11-14 Thread Igor Prusov
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

2023-11-14 Thread Igor Prusov
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

2023-11-14 Thread Igor Prusov
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

2023-11-14 Thread Igor Prusov
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

2023-11-14 Thread Igor Prusov
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

2023-11-14 Thread Igor Prusov
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

2023-11-14 Thread Igor Prusov
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

2023-11-13 Thread Igor Prusov
_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

2023-11-09 Thread Igor Prusov
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.

2023-11-09 Thread Igor Prusov
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

2023-11-09 Thread Igor Prusov
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

2023-11-09 Thread Igor Prusov
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

2023-11-09 Thread Igor Prusov
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

2023-11-09 Thread Igor Prusov
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

2023-11-09 Thread Igor Prusov
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

2023-11-09 Thread Igor Prusov
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

2023-11-09 Thread Igor Prusov
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

2023-11-09 Thread Igor Prusov
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

2023-11-09 Thread Igor Prusov
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

2023-11-09 Thread Igor Prusov
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

2023-11-09 Thread Igor Prusov
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

2023-11-09 Thread Igor Prusov
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

2023-11-05 Thread Igor Prusov
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

2023-11-05 Thread Igor Prusov
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

2023-11-05 Thread Igor Prusov
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

2023-11-05 Thread Igor Prusov
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

2023-11-05 Thread Igor Prusov
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

2023-11-05 Thread Igor Prusov
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

2023-11-05 Thread Igor Prusov
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

2023-11-05 Thread Igor Prusov
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

2023-11-05 Thread Igor Prusov
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

2023-11-04 Thread Igor Prusov
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

2023-11-04 Thread Igor Prusov
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

2023-11-02 Thread Igor Prusov
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

2023-11-02 Thread Igor Prusov
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

2023-11-02 Thread Igor Prusov
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

2023-11-02 Thread Igor Prusov
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

2023-11-02 Thread Igor Prusov
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

2023-11-02 Thread Igor Prusov
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

2023-11-02 Thread Igor Prusov
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

2023-11-02 Thread Igor Prusov
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

2023-11-02 Thread Igor Prusov
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

2023-10-24 Thread 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



[PATCH v2 1/2] spi: add support for Amlogic A1 SPI Flash Controller

2023-10-24 Thread Igor Prusov
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

2023-10-24 Thread Igor Prusov
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

2023-10-19 Thread Igor Prusov
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

2023-10-19 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-17 Thread Igor Prusov
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

2023-10-04 Thread Igor Prusov
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

2023-10-04 Thread Igor Prusov
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

2023-10-04 Thread Igor Prusov
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

2023-10-03 Thread Igor Prusov
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

2023-10-03 Thread Igor Prusov
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

2023-10-03 Thread Igor Prusov
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

2023-09-25 Thread Igor Prusov
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

2023-09-25 Thread Igor Prusov
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

2023-09-25 Thread Igor Prusov
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

2023-09-19 Thread Igor Prusov
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

2023-09-17 Thread Igor Prusov
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

2023-09-17 Thread Igor Prusov
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

2023-09-17 Thread Igor Prusov
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

2023-08-28 Thread Igor Prusov
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

2023-08-28 Thread Igor Prusov
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

2023-08-28 Thread Igor Prusov
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

2023-07-31 Thread Igor Prusov
+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

2023-07-14 Thread Igor Prusov
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

2023-07-14 Thread Igor Prusov
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

2023-07-14 Thread Igor Prusov
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

2023-07-14 Thread Igor Prusov
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

2023-07-14 Thread Igor Prusov
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

2023-07-14 Thread Igor Prusov
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

2023-07-14 Thread Igor Prusov
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

2023-07-14 Thread Igor Prusov
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



  1   2   >