[PATCH 0/6] mtd: nand: sunxi: Convert to devicetree and the driver model

This series converts the sunxi NAND driver to get its resources (clocks, resets, pins) from the devicetree, and probe using the driver model.
In addition to the immediate cleanup, this allows backporting more patches (bugfixes, newer SoC support) from the Linux driver.
Samuel Holland (6): clk: sunxi: Add NAND clocks and resets pinctrl: sunxi: Add NAND pinmuxes mtd: nand: sunxi: Remove an unnecessary check mtd: nand: sunxi: Convert from fdtdec to ofnode mtd: nand: sunxi: Convert to the driver model mtd: nand: sunxi: Pass the device to the init function
board/sunxi/board.c | 5 +- drivers/clk/sunxi/clk_a10.c | 2 + drivers/clk/sunxi/clk_a10s.c | 2 + drivers/clk/sunxi/clk_a23.c | 3 + drivers/clk/sunxi/clk_a31.c | 6 + drivers/clk/sunxi/clk_a64.c | 3 + drivers/clk/sunxi/clk_a80.c | 8 ++ drivers/clk/sunxi/clk_a83t.c | 3 + drivers/clk/sunxi/clk_h3.c | 3 + drivers/clk/sunxi/clk_h6.c | 6 + drivers/clk/sunxi/clk_h616.c | 6 + drivers/clk/sunxi/clk_r40.c | 3 + drivers/mtd/nand/raw/sunxi_nand.c | 173 ++++++++++++-------------- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 13 ++ include/fdtdec.h | 1 - lib/fdtdec.c | 1 - 16 files changed, 138 insertions(+), 100 deletions(-)

Currently NAND clock setup is done in board code, both in SPL and in U-Boot proper. Add the NAND clocks/resets here so they can be used by the "full" NAND driver once it is converted to the driver model.
The bit locations are copied from the Linux CCU drivers.
Signed-off-by: Samuel Holland samuel@sholland.org ---
drivers/clk/sunxi/clk_a10.c | 2 ++ drivers/clk/sunxi/clk_a10s.c | 2 ++ drivers/clk/sunxi/clk_a23.c | 3 +++ drivers/clk/sunxi/clk_a31.c | 6 ++++++ drivers/clk/sunxi/clk_a64.c | 3 +++ drivers/clk/sunxi/clk_a80.c | 8 ++++++++ drivers/clk/sunxi/clk_a83t.c | 3 +++ drivers/clk/sunxi/clk_h3.c | 3 +++ drivers/clk/sunxi/clk_h6.c | 6 ++++++ drivers/clk/sunxi/clk_h616.c | 6 ++++++ drivers/clk/sunxi/clk_r40.c | 3 +++ 11 files changed, 45 insertions(+)
diff --git a/drivers/clk/sunxi/clk_a10.c b/drivers/clk/sunxi/clk_a10.c index db92848aafde..69c46da841e9 100644 --- a/drivers/clk/sunxi/clk_a10.c +++ b/drivers/clk/sunxi/clk_a10.c @@ -23,6 +23,7 @@ static struct ccu_clk_gate a10_gates[] = { [CLK_AHB_MMC1] = GATE(0x060, BIT(9)), [CLK_AHB_MMC2] = GATE(0x060, BIT(10)), [CLK_AHB_MMC3] = GATE(0x060, BIT(11)), + [CLK_AHB_NAND] = GATE(0x060, BIT(13)), [CLK_AHB_EMAC] = GATE(0x060, BIT(17)), [CLK_AHB_SPI0] = GATE(0x060, BIT(20)), [CLK_AHB_SPI1] = GATE(0x060, BIT(21)), @@ -47,6 +48,7 @@ static struct ccu_clk_gate a10_gates[] = { [CLK_APB1_UART6] = GATE(0x06c, BIT(22)), [CLK_APB1_UART7] = GATE(0x06c, BIT(23)),
+ [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)), [CLK_SPI2] = GATE(0x0a8, BIT(31)), diff --git a/drivers/clk/sunxi/clk_a10s.c b/drivers/clk/sunxi/clk_a10s.c index 0c6564ef3b62..6abccea3aa9e 100644 --- a/drivers/clk/sunxi/clk_a10s.c +++ b/drivers/clk/sunxi/clk_a10s.c @@ -20,6 +20,7 @@ static struct ccu_clk_gate a10s_gates[] = { [CLK_AHB_MMC0] = GATE(0x060, BIT(8)), [CLK_AHB_MMC1] = GATE(0x060, BIT(9)), [CLK_AHB_MMC2] = GATE(0x060, BIT(10)), + [CLK_AHB_NAND] = GATE(0x060, BIT(13)), [CLK_AHB_EMAC] = GATE(0x060, BIT(17)), [CLK_AHB_SPI0] = GATE(0x060, BIT(20)), [CLK_AHB_SPI1] = GATE(0x060, BIT(21)), @@ -35,6 +36,7 @@ static struct ccu_clk_gate a10s_gates[] = { [CLK_APB1_UART2] = GATE(0x06c, BIT(18)), [CLK_APB1_UART3] = GATE(0x06c, BIT(19)),
+ [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)), [CLK_SPI2] = GATE(0x0a8, BIT(31)), diff --git a/drivers/clk/sunxi/clk_a23.c b/drivers/clk/sunxi/clk_a23.c index 0280fb51e2db..342af83b158d 100644 --- a/drivers/clk/sunxi/clk_a23.c +++ b/drivers/clk/sunxi/clk_a23.c @@ -17,6 +17,7 @@ static struct ccu_clk_gate a23_gates[] = { [CLK_BUS_MMC0] = GATE(0x060, BIT(8)), [CLK_BUS_MMC1] = GATE(0x060, BIT(9)), [CLK_BUS_MMC2] = GATE(0x060, BIT(10)), + [CLK_BUS_NAND] = GATE(0x060, BIT(13)), [CLK_BUS_SPI0] = GATE(0x060, BIT(20)), [CLK_BUS_SPI1] = GATE(0x060, BIT(21)), [CLK_BUS_OTG] = GATE(0x060, BIT(24)), @@ -34,6 +35,7 @@ static struct ccu_clk_gate a23_gates[] = { [CLK_BUS_UART3] = GATE(0x06c, BIT(19)), [CLK_BUS_UART4] = GATE(0x06c, BIT(20)),
+ [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)),
@@ -52,6 +54,7 @@ static struct ccu_reset a23_resets[] = { [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)), [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)), [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)), + [RST_BUS_NAND] = RESET(0x2c0, BIT(13)), [RST_BUS_SPI0] = RESET(0x2c0, BIT(20)), [RST_BUS_SPI1] = RESET(0x2c0, BIT(21)), [RST_BUS_OTG] = RESET(0x2c0, BIT(24)), diff --git a/drivers/clk/sunxi/clk_a31.c b/drivers/clk/sunxi/clk_a31.c index 26d25f324080..703ddc01dad0 100644 --- a/drivers/clk/sunxi/clk_a31.c +++ b/drivers/clk/sunxi/clk_a31.c @@ -18,6 +18,8 @@ static struct ccu_clk_gate a31_gates[] = { [CLK_AHB1_MMC1] = GATE(0x060, BIT(9)), [CLK_AHB1_MMC2] = GATE(0x060, BIT(10)), [CLK_AHB1_MMC3] = GATE(0x060, BIT(11)), + [CLK_AHB1_NAND1] = GATE(0x060, BIT(12)), + [CLK_AHB1_NAND0] = GATE(0x060, BIT(13)), [CLK_AHB1_EMAC] = GATE(0x060, BIT(17)), [CLK_AHB1_SPI0] = GATE(0x060, BIT(20)), [CLK_AHB1_SPI1] = GATE(0x060, BIT(21)), @@ -43,6 +45,8 @@ static struct ccu_clk_gate a31_gates[] = { [CLK_APB2_UART4] = GATE(0x06c, BIT(20)), [CLK_APB2_UART5] = GATE(0x06c, BIT(21)),
+ [CLK_NAND0] = GATE(0x080, BIT(31)), + [CLK_NAND1] = GATE(0x084, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)), [CLK_SPI2] = GATE(0x0a8, BIT(31)), @@ -65,6 +69,8 @@ static struct ccu_reset a31_resets[] = { [RST_AHB1_MMC1] = RESET(0x2c0, BIT(9)), [RST_AHB1_MMC2] = RESET(0x2c0, BIT(10)), [RST_AHB1_MMC3] = RESET(0x2c0, BIT(11)), + [RST_AHB1_NAND1] = RESET(0x2c0, BIT(12)), + [RST_AHB1_NAND0] = RESET(0x2c0, BIT(13)), [RST_AHB1_EMAC] = RESET(0x2c0, BIT(17)), [RST_AHB1_SPI0] = RESET(0x2c0, BIT(20)), [RST_AHB1_SPI1] = RESET(0x2c0, BIT(21)), diff --git a/drivers/clk/sunxi/clk_a64.c b/drivers/clk/sunxi/clk_a64.c index cbb9168edb9c..916ff4c2b5d1 100644 --- a/drivers/clk/sunxi/clk_a64.c +++ b/drivers/clk/sunxi/clk_a64.c @@ -19,6 +19,7 @@ static const struct ccu_clk_gate a64_gates[] = { [CLK_BUS_MMC0] = GATE(0x060, BIT(8)), [CLK_BUS_MMC1] = GATE(0x060, BIT(9)), [CLK_BUS_MMC2] = GATE(0x060, BIT(10)), + [CLK_BUS_NAND] = GATE(0x060, BIT(13)), [CLK_BUS_EMAC] = GATE(0x060, BIT(17)), [CLK_BUS_SPI0] = GATE(0x060, BIT(20)), [CLK_BUS_SPI1] = GATE(0x060, BIT(21)), @@ -39,6 +40,7 @@ static const struct ccu_clk_gate a64_gates[] = { [CLK_BUS_UART3] = GATE(0x06c, BIT(19)), [CLK_BUS_UART4] = GATE(0x06c, BIT(20)),
+ [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)),
@@ -58,6 +60,7 @@ static const struct ccu_reset a64_resets[] = { [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)), [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)), [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)), + [RST_BUS_NAND] = RESET(0x2c0, BIT(13)), [RST_BUS_EMAC] = RESET(0x2c0, BIT(17)), [RST_BUS_SPI0] = RESET(0x2c0, BIT(20)), [RST_BUS_SPI1] = RESET(0x2c0, BIT(21)), diff --git a/drivers/clk/sunxi/clk_a80.c b/drivers/clk/sunxi/clk_a80.c index 1ee1f99a8f49..be732f5d1b50 100644 --- a/drivers/clk/sunxi/clk_a80.c +++ b/drivers/clk/sunxi/clk_a80.c @@ -14,12 +14,18 @@ #include <linux/bitops.h>
static const struct ccu_clk_gate a80_gates[] = { + [CLK_NAND0_0] = GATE(0x400, BIT(31)), + [CLK_NAND0_1] = GATE(0x404, BIT(31)), + [CLK_NAND1_0] = GATE(0x408, BIT(31)), + [CLK_NAND1_1] = GATE(0x40c, BIT(31)), [CLK_SPI0] = GATE(0x430, BIT(31)), [CLK_SPI1] = GATE(0x434, BIT(31)), [CLK_SPI2] = GATE(0x438, BIT(31)), [CLK_SPI3] = GATE(0x43c, BIT(31)),
[CLK_BUS_MMC] = GATE(0x580, BIT(8)), + [CLK_BUS_NAND0] = GATE(0x580, BIT(12)), + [CLK_BUS_NAND1] = GATE(0x580, BIT(13)), [CLK_BUS_SPI0] = GATE(0x580, BIT(20)), [CLK_BUS_SPI1] = GATE(0x580, BIT(21)), [CLK_BUS_SPI2] = GATE(0x580, BIT(22)), @@ -42,6 +48,8 @@ static const struct ccu_clk_gate a80_gates[] = {
static const struct ccu_reset a80_resets[] = { [RST_BUS_MMC] = RESET(0x5a0, BIT(8)), + [RST_BUS_NAND0] = RESET(0x5a0, BIT(12)), + [RST_BUS_NAND1] = RESET(0x5a0, BIT(13)), [RST_BUS_SPI0] = RESET(0x5a0, BIT(20)), [RST_BUS_SPI1] = RESET(0x5a0, BIT(21)), [RST_BUS_SPI2] = RESET(0x5a0, BIT(22)), diff --git a/drivers/clk/sunxi/clk_a83t.c b/drivers/clk/sunxi/clk_a83t.c index 4b57434cfaad..36a9317b0f31 100644 --- a/drivers/clk/sunxi/clk_a83t.c +++ b/drivers/clk/sunxi/clk_a83t.c @@ -17,6 +17,7 @@ static struct ccu_clk_gate a83t_gates[] = { [CLK_BUS_MMC0] = GATE(0x060, BIT(8)), [CLK_BUS_MMC1] = GATE(0x060, BIT(9)), [CLK_BUS_MMC2] = GATE(0x060, BIT(10)), + [CLK_BUS_NAND] = GATE(0x060, BIT(13)), [CLK_BUS_EMAC] = GATE(0x060, BIT(17)), [CLK_BUS_SPI0] = GATE(0x060, BIT(20)), [CLK_BUS_SPI1] = GATE(0x060, BIT(21)), @@ -36,6 +37,7 @@ static struct ccu_clk_gate a83t_gates[] = { [CLK_BUS_UART3] = GATE(0x06c, BIT(19)), [CLK_BUS_UART4] = GATE(0x06c, BIT(20)),
+ [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)),
@@ -54,6 +56,7 @@ static struct ccu_reset a83t_resets[] = { [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)), [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)), [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)), + [RST_BUS_NAND] = RESET(0x2c0, BIT(13)), [RST_BUS_EMAC] = RESET(0x2c0, BIT(17)), [RST_BUS_SPI0] = RESET(0x2c0, BIT(20)), [RST_BUS_SPI1] = RESET(0x2c0, BIT(21)), diff --git a/drivers/clk/sunxi/clk_h3.c b/drivers/clk/sunxi/clk_h3.c index 08a830bd1889..c09ba8191dcb 100644 --- a/drivers/clk/sunxi/clk_h3.c +++ b/drivers/clk/sunxi/clk_h3.c @@ -19,6 +19,7 @@ static struct ccu_clk_gate h3_gates[] = { [CLK_BUS_MMC0] = GATE(0x060, BIT(8)), [CLK_BUS_MMC1] = GATE(0x060, BIT(9)), [CLK_BUS_MMC2] = GATE(0x060, BIT(10)), + [CLK_BUS_NAND] = GATE(0x060, BIT(13)), [CLK_BUS_EMAC] = GATE(0x060, BIT(17)), [CLK_BUS_SPI0] = GATE(0x060, BIT(20)), [CLK_BUS_SPI1] = GATE(0x060, BIT(21)), @@ -44,6 +45,7 @@ static struct ccu_clk_gate h3_gates[] = {
[CLK_BUS_EPHY] = GATE(0x070, BIT(0)),
+ [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)),
@@ -66,6 +68,7 @@ static struct ccu_reset h3_resets[] = { [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)), [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)), [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)), + [RST_BUS_NAND] = RESET(0x2c0, BIT(13)), [RST_BUS_EMAC] = RESET(0x2c0, BIT(17)), [RST_BUS_SPI0] = RESET(0x2c0, BIT(20)), [RST_BUS_SPI1] = RESET(0x2c0, BIT(21)), diff --git a/drivers/clk/sunxi/clk_h6.c b/drivers/clk/sunxi/clk_h6.c index b3202342932b..73ef0a3ab4fb 100644 --- a/drivers/clk/sunxi/clk_h6.c +++ b/drivers/clk/sunxi/clk_h6.c @@ -18,6 +18,10 @@ static struct ccu_clk_gate h6_gates[] = {
[CLK_APB1] = GATE_DUMMY,
+ [CLK_NAND0] = GATE(0x810, BIT(31)), + [CLK_NAND1] = GATE(0x814, BIT(31)), + [CLK_BUS_NAND] = GATE(0x82c, BIT(0)), + [CLK_BUS_MMC0] = GATE(0x84c, BIT(0)), [CLK_BUS_MMC1] = GATE(0x84c, BIT(1)), [CLK_BUS_MMC2] = GATE(0x84c, BIT(2)), @@ -58,6 +62,8 @@ static struct ccu_clk_gate h6_gates[] = { };
static struct ccu_reset h6_resets[] = { + [RST_BUS_NAND] = RESET(0x82c, BIT(16)), + [RST_BUS_MMC0] = RESET(0x84c, BIT(16)), [RST_BUS_MMC1] = RESET(0x84c, BIT(17)), [RST_BUS_MMC2] = RESET(0x84c, BIT(18)), diff --git a/drivers/clk/sunxi/clk_h616.c b/drivers/clk/sunxi/clk_h616.c index 80099727defd..cb8083c8f60a 100644 --- a/drivers/clk/sunxi/clk_h616.c +++ b/drivers/clk/sunxi/clk_h616.c @@ -17,6 +17,10 @@ static struct ccu_clk_gate h616_gates[] = {
[CLK_APB1] = GATE_DUMMY,
+ [CLK_NAND0] = GATE(0x810, BIT(31)), + [CLK_NAND1] = GATE(0x814, BIT(31)), + [CLK_BUS_NAND] = GATE(0x82c, BIT(0)), + [CLK_BUS_MMC0] = GATE(0x84c, BIT(0)), [CLK_BUS_MMC1] = GATE(0x84c, BIT(1)), [CLK_BUS_MMC2] = GATE(0x84c, BIT(2)), @@ -67,6 +71,8 @@ static struct ccu_clk_gate h616_gates[] = { };
static struct ccu_reset h616_resets[] = { + [RST_BUS_NAND] = RESET(0x82c, BIT(16)), + [RST_BUS_MMC0] = RESET(0x84c, BIT(16)), [RST_BUS_MMC1] = RESET(0x84c, BIT(17)), [RST_BUS_MMC2] = RESET(0x84c, BIT(18)), diff --git a/drivers/clk/sunxi/clk_r40.c b/drivers/clk/sunxi/clk_r40.c index 45633a2a5249..cc58da71b6f8 100644 --- a/drivers/clk/sunxi/clk_r40.c +++ b/drivers/clk/sunxi/clk_r40.c @@ -18,6 +18,7 @@ static struct ccu_clk_gate r40_gates[] = { [CLK_BUS_MMC1] = GATE(0x060, BIT(9)), [CLK_BUS_MMC2] = GATE(0x060, BIT(10)), [CLK_BUS_MMC3] = GATE(0x060, BIT(11)), + [CLK_BUS_NAND] = GATE(0x060, BIT(13)), [CLK_BUS_SPI0] = GATE(0x060, BIT(20)), [CLK_BUS_SPI1] = GATE(0x060, BIT(21)), [CLK_BUS_SPI2] = GATE(0x060, BIT(22)), @@ -48,6 +49,7 @@ static struct ccu_clk_gate r40_gates[] = { [CLK_BUS_UART6] = GATE(0x06c, BIT(22)), [CLK_BUS_UART7] = GATE(0x06c, BIT(23)),
+ [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)), [CLK_SPI2] = GATE(0x0a8, BIT(31)), @@ -70,6 +72,7 @@ static struct ccu_reset r40_resets[] = { [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)), [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)), [RST_BUS_MMC3] = RESET(0x2c0, BIT(11)), + [RST_BUS_NAND] = RESET(0x2c0, BIT(13)), [RST_BUS_SPI0] = RESET(0x2c0, BIT(20)), [RST_BUS_SPI1] = RESET(0x2c0, BIT(21)), [RST_BUS_SPI2] = RESET(0x2c0, BIT(22)),

On Thu, Jul 14, 2022 at 8:45 AM Samuel Holland samuel@sholland.org wrote:
Currently NAND clock setup is done in board code, both in SPL and in U-Boot proper. Add the NAND clocks/resets here so they can be used by the "full" NAND driver once it is converted to the driver model.
The bit locations are copied from the Linux CCU drivers.
Signed-off-by: Samuel Holland samuel@sholland.org
Reviewed-by: Jagan Teki jagan@amarulasolutions.com

On Wed, 13 Jul 2022 22:15:21 -0500 Samuel Holland samuel@sholland.org wrote:
Hi,
Currently NAND clock setup is done in board code, both in SPL and in U-Boot proper. Add the NAND clocks/resets here so they can be used by the "full" NAND driver once it is converted to the driver model.
The bit locations are copied from the Linux CCU drivers.
Signed-off-by: Samuel Holland samuel@sholland.org
drivers/clk/sunxi/clk_a10.c | 2 ++ drivers/clk/sunxi/clk_a10s.c | 2 ++ drivers/clk/sunxi/clk_a23.c | 3 +++ drivers/clk/sunxi/clk_a31.c | 6 ++++++ drivers/clk/sunxi/clk_a64.c | 3 +++ drivers/clk/sunxi/clk_a80.c | 8 ++++++++ drivers/clk/sunxi/clk_a83t.c | 3 +++ drivers/clk/sunxi/clk_h3.c | 3 +++ drivers/clk/sunxi/clk_h6.c | 6 ++++++ drivers/clk/sunxi/clk_h616.c | 6 ++++++ drivers/clk/sunxi/clk_r40.c | 3 +++ 11 files changed, 45 insertions(+)
diff --git a/drivers/clk/sunxi/clk_a10.c b/drivers/clk/sunxi/clk_a10.c index db92848aafde..69c46da841e9 100644 --- a/drivers/clk/sunxi/clk_a10.c +++ b/drivers/clk/sunxi/clk_a10.c @@ -23,6 +23,7 @@ static struct ccu_clk_gate a10_gates[] = { [CLK_AHB_MMC1] = GATE(0x060, BIT(9)), [CLK_AHB_MMC2] = GATE(0x060, BIT(10)), [CLK_AHB_MMC3] = GATE(0x060, BIT(11)),
- [CLK_AHB_NAND] = GATE(0x060, BIT(13)), [CLK_AHB_EMAC] = GATE(0x060, BIT(17)), [CLK_AHB_SPI0] = GATE(0x060, BIT(20)), [CLK_AHB_SPI1] = GATE(0x060, BIT(21)),
@@ -47,6 +48,7 @@ static struct ccu_clk_gate a10_gates[] = { [CLK_APB1_UART6] = GATE(0x06c, BIT(22)), [CLK_APB1_UART7] = GATE(0x06c, BIT(23)),
- [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)), [CLK_SPI2] = GATE(0x0a8, BIT(31)),
diff --git a/drivers/clk/sunxi/clk_a10s.c b/drivers/clk/sunxi/clk_a10s.c index 0c6564ef3b62..6abccea3aa9e 100644 --- a/drivers/clk/sunxi/clk_a10s.c +++ b/drivers/clk/sunxi/clk_a10s.c @@ -20,6 +20,7 @@ static struct ccu_clk_gate a10s_gates[] = { [CLK_AHB_MMC0] = GATE(0x060, BIT(8)), [CLK_AHB_MMC1] = GATE(0x060, BIT(9)), [CLK_AHB_MMC2] = GATE(0x060, BIT(10)),
- [CLK_AHB_NAND] = GATE(0x060, BIT(13)), [CLK_AHB_EMAC] = GATE(0x060, BIT(17)), [CLK_AHB_SPI0] = GATE(0x060, BIT(20)), [CLK_AHB_SPI1] = GATE(0x060, BIT(21)),
@@ -35,6 +36,7 @@ static struct ccu_clk_gate a10s_gates[] = { [CLK_APB1_UART2] = GATE(0x06c, BIT(18)), [CLK_APB1_UART3] = GATE(0x06c, BIT(19)),
- [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)), [CLK_SPI2] = GATE(0x0a8, BIT(31)),
diff --git a/drivers/clk/sunxi/clk_a23.c b/drivers/clk/sunxi/clk_a23.c index 0280fb51e2db..342af83b158d 100644 --- a/drivers/clk/sunxi/clk_a23.c +++ b/drivers/clk/sunxi/clk_a23.c @@ -17,6 +17,7 @@ static struct ccu_clk_gate a23_gates[] = { [CLK_BUS_MMC0] = GATE(0x060, BIT(8)), [CLK_BUS_MMC1] = GATE(0x060, BIT(9)), [CLK_BUS_MMC2] = GATE(0x060, BIT(10)),
- [CLK_BUS_NAND] = GATE(0x060, BIT(13)), [CLK_BUS_SPI0] = GATE(0x060, BIT(20)), [CLK_BUS_SPI1] = GATE(0x060, BIT(21)), [CLK_BUS_OTG] = GATE(0x060, BIT(24)),
@@ -34,6 +35,7 @@ static struct ccu_clk_gate a23_gates[] = { [CLK_BUS_UART3] = GATE(0x06c, BIT(19)), [CLK_BUS_UART4] = GATE(0x06c, BIT(20)),
- [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)),
@@ -52,6 +54,7 @@ static struct ccu_reset a23_resets[] = { [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)), [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)), [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)),
- [RST_BUS_NAND] = RESET(0x2c0, BIT(13)), [RST_BUS_SPI0] = RESET(0x2c0, BIT(20)), [RST_BUS_SPI1] = RESET(0x2c0, BIT(21)), [RST_BUS_OTG] = RESET(0x2c0, BIT(24)),
diff --git a/drivers/clk/sunxi/clk_a31.c b/drivers/clk/sunxi/clk_a31.c index 26d25f324080..703ddc01dad0 100644 --- a/drivers/clk/sunxi/clk_a31.c +++ b/drivers/clk/sunxi/clk_a31.c @@ -18,6 +18,8 @@ static struct ccu_clk_gate a31_gates[] = { [CLK_AHB1_MMC1] = GATE(0x060, BIT(9)), [CLK_AHB1_MMC2] = GATE(0x060, BIT(10)), [CLK_AHB1_MMC3] = GATE(0x060, BIT(11)),
- [CLK_AHB1_NAND1] = GATE(0x060, BIT(12)),
- [CLK_AHB1_NAND0] = GATE(0x060, BIT(13)), [CLK_AHB1_EMAC] = GATE(0x060, BIT(17)), [CLK_AHB1_SPI0] = GATE(0x060, BIT(20)), [CLK_AHB1_SPI1] = GATE(0x060, BIT(21)),
@@ -43,6 +45,8 @@ static struct ccu_clk_gate a31_gates[] = { [CLK_APB2_UART4] = GATE(0x06c, BIT(20)), [CLK_APB2_UART5] = GATE(0x06c, BIT(21)),
- [CLK_NAND0] = GATE(0x080, BIT(31)),
- [CLK_NAND1] = GATE(0x084, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)), [CLK_SPI2] = GATE(0x0a8, BIT(31)),
@@ -65,6 +69,8 @@ static struct ccu_reset a31_resets[] = { [RST_AHB1_MMC1] = RESET(0x2c0, BIT(9)), [RST_AHB1_MMC2] = RESET(0x2c0, BIT(10)), [RST_AHB1_MMC3] = RESET(0x2c0, BIT(11)),
- [RST_AHB1_NAND1] = RESET(0x2c0, BIT(12)),
- [RST_AHB1_NAND0] = RESET(0x2c0, BIT(13)), [RST_AHB1_EMAC] = RESET(0x2c0, BIT(17)), [RST_AHB1_SPI0] = RESET(0x2c0, BIT(20)), [RST_AHB1_SPI1] = RESET(0x2c0, BIT(21)),
diff --git a/drivers/clk/sunxi/clk_a64.c b/drivers/clk/sunxi/clk_a64.c index cbb9168edb9c..916ff4c2b5d1 100644 --- a/drivers/clk/sunxi/clk_a64.c +++ b/drivers/clk/sunxi/clk_a64.c @@ -19,6 +19,7 @@ static const struct ccu_clk_gate a64_gates[] = { [CLK_BUS_MMC0] = GATE(0x060, BIT(8)), [CLK_BUS_MMC1] = GATE(0x060, BIT(9)), [CLK_BUS_MMC2] = GATE(0x060, BIT(10)),
- [CLK_BUS_NAND] = GATE(0x060, BIT(13)), [CLK_BUS_EMAC] = GATE(0x060, BIT(17)), [CLK_BUS_SPI0] = GATE(0x060, BIT(20)), [CLK_BUS_SPI1] = GATE(0x060, BIT(21)),
@@ -39,6 +40,7 @@ static const struct ccu_clk_gate a64_gates[] = { [CLK_BUS_UART3] = GATE(0x06c, BIT(19)), [CLK_BUS_UART4] = GATE(0x06c, BIT(20)),
- [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)),
@@ -58,6 +60,7 @@ static const struct ccu_reset a64_resets[] = { [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)), [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)), [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)),
- [RST_BUS_NAND] = RESET(0x2c0, BIT(13)), [RST_BUS_EMAC] = RESET(0x2c0, BIT(17)), [RST_BUS_SPI0] = RESET(0x2c0, BIT(20)), [RST_BUS_SPI1] = RESET(0x2c0, BIT(21)),
diff --git a/drivers/clk/sunxi/clk_a80.c b/drivers/clk/sunxi/clk_a80.c index 1ee1f99a8f49..be732f5d1b50 100644 --- a/drivers/clk/sunxi/clk_a80.c +++ b/drivers/clk/sunxi/clk_a80.c @@ -14,12 +14,18 @@ #include <linux/bitops.h>
static const struct ccu_clk_gate a80_gates[] = {
- [CLK_NAND0_0] = GATE(0x400, BIT(31)),
- [CLK_NAND0_1] = GATE(0x404, BIT(31)),
- [CLK_NAND1_0] = GATE(0x408, BIT(31)),
- [CLK_NAND1_1] = GATE(0x40c, BIT(31)),
So my copy of the manual (v1.1 from the Wiki) doesn't have the second pair, although there are two gates, so I assume it's just a doc issue.
[CLK_SPI0] = GATE(0x430, BIT(31)), [CLK_SPI1] = GATE(0x434, BIT(31)), [CLK_SPI2] = GATE(0x438, BIT(31)), [CLK_SPI3] = GATE(0x43c, BIT(31)),
[CLK_BUS_MMC] = GATE(0x580, BIT(8)),
- [CLK_BUS_NAND0] = GATE(0x580, BIT(12)),
- [CLK_BUS_NAND1] = GATE(0x580, BIT(13)),
Those seem to be swapped, in line with the other dual NAND SoCs.
[CLK_BUS_SPI0] = GATE(0x580, BIT(20)), [CLK_BUS_SPI1] = GATE(0x580, BIT(21)), [CLK_BUS_SPI2] = GATE(0x580, BIT(22)), @@ -42,6 +48,8 @@ static const struct ccu_clk_gate a80_gates[] = {
static const struct ccu_reset a80_resets[] = { [RST_BUS_MMC] = RESET(0x5a0, BIT(8)),
- [RST_BUS_NAND0] = RESET(0x5a0, BIT(12)),
- [RST_BUS_NAND1] = RESET(0x5a0, BIT(13)),
and those two as well.
Compared the rest against the respective manuals, they look fine.
Cheers, Andre
[RST_BUS_SPI0] = RESET(0x5a0, BIT(20)), [RST_BUS_SPI1] = RESET(0x5a0, BIT(21)), [RST_BUS_SPI2] = RESET(0x5a0, BIT(22)), diff --git a/drivers/clk/sunxi/clk_a83t.c b/drivers/clk/sunxi/clk_a83t.c index 4b57434cfaad..36a9317b0f31 100644 --- a/drivers/clk/sunxi/clk_a83t.c +++ b/drivers/clk/sunxi/clk_a83t.c @@ -17,6 +17,7 @@ static struct ccu_clk_gate a83t_gates[] = { [CLK_BUS_MMC0] = GATE(0x060, BIT(8)), [CLK_BUS_MMC1] = GATE(0x060, BIT(9)), [CLK_BUS_MMC2] = GATE(0x060, BIT(10)),
- [CLK_BUS_NAND] = GATE(0x060, BIT(13)), [CLK_BUS_EMAC] = GATE(0x060, BIT(17)), [CLK_BUS_SPI0] = GATE(0x060, BIT(20)), [CLK_BUS_SPI1] = GATE(0x060, BIT(21)),
@@ -36,6 +37,7 @@ static struct ccu_clk_gate a83t_gates[] = { [CLK_BUS_UART3] = GATE(0x06c, BIT(19)), [CLK_BUS_UART4] = GATE(0x06c, BIT(20)),
- [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)),
@@ -54,6 +56,7 @@ static struct ccu_reset a83t_resets[] = { [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)), [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)), [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)),
- [RST_BUS_NAND] = RESET(0x2c0, BIT(13)), [RST_BUS_EMAC] = RESET(0x2c0, BIT(17)), [RST_BUS_SPI0] = RESET(0x2c0, BIT(20)), [RST_BUS_SPI1] = RESET(0x2c0, BIT(21)),
diff --git a/drivers/clk/sunxi/clk_h3.c b/drivers/clk/sunxi/clk_h3.c index 08a830bd1889..c09ba8191dcb 100644 --- a/drivers/clk/sunxi/clk_h3.c +++ b/drivers/clk/sunxi/clk_h3.c @@ -19,6 +19,7 @@ static struct ccu_clk_gate h3_gates[] = { [CLK_BUS_MMC0] = GATE(0x060, BIT(8)), [CLK_BUS_MMC1] = GATE(0x060, BIT(9)), [CLK_BUS_MMC2] = GATE(0x060, BIT(10)),
- [CLK_BUS_NAND] = GATE(0x060, BIT(13)), [CLK_BUS_EMAC] = GATE(0x060, BIT(17)), [CLK_BUS_SPI0] = GATE(0x060, BIT(20)), [CLK_BUS_SPI1] = GATE(0x060, BIT(21)),
@@ -44,6 +45,7 @@ static struct ccu_clk_gate h3_gates[] = {
[CLK_BUS_EPHY] = GATE(0x070, BIT(0)),
- [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)),
@@ -66,6 +68,7 @@ static struct ccu_reset h3_resets[] = { [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)), [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)), [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)),
- [RST_BUS_NAND] = RESET(0x2c0, BIT(13)), [RST_BUS_EMAC] = RESET(0x2c0, BIT(17)), [RST_BUS_SPI0] = RESET(0x2c0, BIT(20)), [RST_BUS_SPI1] = RESET(0x2c0, BIT(21)),
diff --git a/drivers/clk/sunxi/clk_h6.c b/drivers/clk/sunxi/clk_h6.c index b3202342932b..73ef0a3ab4fb 100644 --- a/drivers/clk/sunxi/clk_h6.c +++ b/drivers/clk/sunxi/clk_h6.c @@ -18,6 +18,10 @@ static struct ccu_clk_gate h6_gates[] = {
[CLK_APB1] = GATE_DUMMY,
- [CLK_NAND0] = GATE(0x810, BIT(31)),
- [CLK_NAND1] = GATE(0x814, BIT(31)),
- [CLK_BUS_NAND] = GATE(0x82c, BIT(0)),
- [CLK_BUS_MMC0] = GATE(0x84c, BIT(0)), [CLK_BUS_MMC1] = GATE(0x84c, BIT(1)), [CLK_BUS_MMC2] = GATE(0x84c, BIT(2)),
@@ -58,6 +62,8 @@ static struct ccu_clk_gate h6_gates[] = { };
static struct ccu_reset h6_resets[] = {
- [RST_BUS_NAND] = RESET(0x82c, BIT(16)),
- [RST_BUS_MMC0] = RESET(0x84c, BIT(16)), [RST_BUS_MMC1] = RESET(0x84c, BIT(17)), [RST_BUS_MMC2] = RESET(0x84c, BIT(18)),
diff --git a/drivers/clk/sunxi/clk_h616.c b/drivers/clk/sunxi/clk_h616.c index 80099727defd..cb8083c8f60a 100644 --- a/drivers/clk/sunxi/clk_h616.c +++ b/drivers/clk/sunxi/clk_h616.c @@ -17,6 +17,10 @@ static struct ccu_clk_gate h616_gates[] = {
[CLK_APB1] = GATE_DUMMY,
- [CLK_NAND0] = GATE(0x810, BIT(31)),
- [CLK_NAND1] = GATE(0x814, BIT(31)),
- [CLK_BUS_NAND] = GATE(0x82c, BIT(0)),
- [CLK_BUS_MMC0] = GATE(0x84c, BIT(0)), [CLK_BUS_MMC1] = GATE(0x84c, BIT(1)), [CLK_BUS_MMC2] = GATE(0x84c, BIT(2)),
@@ -67,6 +71,8 @@ static struct ccu_clk_gate h616_gates[] = { };
static struct ccu_reset h616_resets[] = {
- [RST_BUS_NAND] = RESET(0x82c, BIT(16)),
- [RST_BUS_MMC0] = RESET(0x84c, BIT(16)), [RST_BUS_MMC1] = RESET(0x84c, BIT(17)), [RST_BUS_MMC2] = RESET(0x84c, BIT(18)),
diff --git a/drivers/clk/sunxi/clk_r40.c b/drivers/clk/sunxi/clk_r40.c index 45633a2a5249..cc58da71b6f8 100644 --- a/drivers/clk/sunxi/clk_r40.c +++ b/drivers/clk/sunxi/clk_r40.c @@ -18,6 +18,7 @@ static struct ccu_clk_gate r40_gates[] = { [CLK_BUS_MMC1] = GATE(0x060, BIT(9)), [CLK_BUS_MMC2] = GATE(0x060, BIT(10)), [CLK_BUS_MMC3] = GATE(0x060, BIT(11)),
- [CLK_BUS_NAND] = GATE(0x060, BIT(13)), [CLK_BUS_SPI0] = GATE(0x060, BIT(20)), [CLK_BUS_SPI1] = GATE(0x060, BIT(21)), [CLK_BUS_SPI2] = GATE(0x060, BIT(22)),
@@ -48,6 +49,7 @@ static struct ccu_clk_gate r40_gates[] = { [CLK_BUS_UART6] = GATE(0x06c, BIT(22)), [CLK_BUS_UART7] = GATE(0x06c, BIT(23)),
- [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)), [CLK_SPI2] = GATE(0x0a8, BIT(31)),
@@ -70,6 +72,7 @@ static struct ccu_reset r40_resets[] = { [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)), [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)), [RST_BUS_MMC3] = RESET(0x2c0, BIT(11)),
- [RST_BUS_NAND] = RESET(0x2c0, BIT(13)), [RST_BUS_SPI0] = RESET(0x2c0, BIT(20)), [RST_BUS_SPI1] = RESET(0x2c0, BIT(21)), [RST_BUS_SPI2] = RESET(0x2c0, BIT(22)),

On 7/18/22 11:10 AM, Andre Przywara wrote:
On Wed, 13 Jul 2022 22:15:21 -0500 Samuel Holland samuel@sholland.org wrote:
Hi,
Currently NAND clock setup is done in board code, both in SPL and in U-Boot proper. Add the NAND clocks/resets here so they can be used by the "full" NAND driver once it is converted to the driver model.
The bit locations are copied from the Linux CCU drivers.
Signed-off-by: Samuel Holland samuel@sholland.org
drivers/clk/sunxi/clk_a10.c | 2 ++ drivers/clk/sunxi/clk_a10s.c | 2 ++ drivers/clk/sunxi/clk_a23.c | 3 +++ drivers/clk/sunxi/clk_a31.c | 6 ++++++ drivers/clk/sunxi/clk_a64.c | 3 +++ drivers/clk/sunxi/clk_a80.c | 8 ++++++++ drivers/clk/sunxi/clk_a83t.c | 3 +++ drivers/clk/sunxi/clk_h3.c | 3 +++ drivers/clk/sunxi/clk_h6.c | 6 ++++++ drivers/clk/sunxi/clk_h616.c | 6 ++++++ drivers/clk/sunxi/clk_r40.c | 3 +++ 11 files changed, 45 insertions(+)
diff --git a/drivers/clk/sunxi/clk_a10.c b/drivers/clk/sunxi/clk_a10.c index db92848aafde..69c46da841e9 100644 --- a/drivers/clk/sunxi/clk_a10.c +++ b/drivers/clk/sunxi/clk_a10.c @@ -23,6 +23,7 @@ static struct ccu_clk_gate a10_gates[] = { [CLK_AHB_MMC1] = GATE(0x060, BIT(9)), [CLK_AHB_MMC2] = GATE(0x060, BIT(10)), [CLK_AHB_MMC3] = GATE(0x060, BIT(11)),
- [CLK_AHB_NAND] = GATE(0x060, BIT(13)), [CLK_AHB_EMAC] = GATE(0x060, BIT(17)), [CLK_AHB_SPI0] = GATE(0x060, BIT(20)), [CLK_AHB_SPI1] = GATE(0x060, BIT(21)),
@@ -47,6 +48,7 @@ static struct ccu_clk_gate a10_gates[] = { [CLK_APB1_UART6] = GATE(0x06c, BIT(22)), [CLK_APB1_UART7] = GATE(0x06c, BIT(23)),
- [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)), [CLK_SPI2] = GATE(0x0a8, BIT(31)),
diff --git a/drivers/clk/sunxi/clk_a10s.c b/drivers/clk/sunxi/clk_a10s.c index 0c6564ef3b62..6abccea3aa9e 100644 --- a/drivers/clk/sunxi/clk_a10s.c +++ b/drivers/clk/sunxi/clk_a10s.c @@ -20,6 +20,7 @@ static struct ccu_clk_gate a10s_gates[] = { [CLK_AHB_MMC0] = GATE(0x060, BIT(8)), [CLK_AHB_MMC1] = GATE(0x060, BIT(9)), [CLK_AHB_MMC2] = GATE(0x060, BIT(10)),
- [CLK_AHB_NAND] = GATE(0x060, BIT(13)), [CLK_AHB_EMAC] = GATE(0x060, BIT(17)), [CLK_AHB_SPI0] = GATE(0x060, BIT(20)), [CLK_AHB_SPI1] = GATE(0x060, BIT(21)),
@@ -35,6 +36,7 @@ static struct ccu_clk_gate a10s_gates[] = { [CLK_APB1_UART2] = GATE(0x06c, BIT(18)), [CLK_APB1_UART3] = GATE(0x06c, BIT(19)),
- [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)), [CLK_SPI2] = GATE(0x0a8, BIT(31)),
diff --git a/drivers/clk/sunxi/clk_a23.c b/drivers/clk/sunxi/clk_a23.c index 0280fb51e2db..342af83b158d 100644 --- a/drivers/clk/sunxi/clk_a23.c +++ b/drivers/clk/sunxi/clk_a23.c @@ -17,6 +17,7 @@ static struct ccu_clk_gate a23_gates[] = { [CLK_BUS_MMC0] = GATE(0x060, BIT(8)), [CLK_BUS_MMC1] = GATE(0x060, BIT(9)), [CLK_BUS_MMC2] = GATE(0x060, BIT(10)),
- [CLK_BUS_NAND] = GATE(0x060, BIT(13)), [CLK_BUS_SPI0] = GATE(0x060, BIT(20)), [CLK_BUS_SPI1] = GATE(0x060, BIT(21)), [CLK_BUS_OTG] = GATE(0x060, BIT(24)),
@@ -34,6 +35,7 @@ static struct ccu_clk_gate a23_gates[] = { [CLK_BUS_UART3] = GATE(0x06c, BIT(19)), [CLK_BUS_UART4] = GATE(0x06c, BIT(20)),
- [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)),
@@ -52,6 +54,7 @@ static struct ccu_reset a23_resets[] = { [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)), [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)), [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)),
- [RST_BUS_NAND] = RESET(0x2c0, BIT(13)), [RST_BUS_SPI0] = RESET(0x2c0, BIT(20)), [RST_BUS_SPI1] = RESET(0x2c0, BIT(21)), [RST_BUS_OTG] = RESET(0x2c0, BIT(24)),
diff --git a/drivers/clk/sunxi/clk_a31.c b/drivers/clk/sunxi/clk_a31.c index 26d25f324080..703ddc01dad0 100644 --- a/drivers/clk/sunxi/clk_a31.c +++ b/drivers/clk/sunxi/clk_a31.c @@ -18,6 +18,8 @@ static struct ccu_clk_gate a31_gates[] = { [CLK_AHB1_MMC1] = GATE(0x060, BIT(9)), [CLK_AHB1_MMC2] = GATE(0x060, BIT(10)), [CLK_AHB1_MMC3] = GATE(0x060, BIT(11)),
- [CLK_AHB1_NAND1] = GATE(0x060, BIT(12)),
- [CLK_AHB1_NAND0] = GATE(0x060, BIT(13)), [CLK_AHB1_EMAC] = GATE(0x060, BIT(17)), [CLK_AHB1_SPI0] = GATE(0x060, BIT(20)), [CLK_AHB1_SPI1] = GATE(0x060, BIT(21)),
@@ -43,6 +45,8 @@ static struct ccu_clk_gate a31_gates[] = { [CLK_APB2_UART4] = GATE(0x06c, BIT(20)), [CLK_APB2_UART5] = GATE(0x06c, BIT(21)),
- [CLK_NAND0] = GATE(0x080, BIT(31)),
- [CLK_NAND1] = GATE(0x084, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)), [CLK_SPI2] = GATE(0x0a8, BIT(31)),
@@ -65,6 +69,8 @@ static struct ccu_reset a31_resets[] = { [RST_AHB1_MMC1] = RESET(0x2c0, BIT(9)), [RST_AHB1_MMC2] = RESET(0x2c0, BIT(10)), [RST_AHB1_MMC3] = RESET(0x2c0, BIT(11)),
- [RST_AHB1_NAND1] = RESET(0x2c0, BIT(12)),
- [RST_AHB1_NAND0] = RESET(0x2c0, BIT(13)), [RST_AHB1_EMAC] = RESET(0x2c0, BIT(17)), [RST_AHB1_SPI0] = RESET(0x2c0, BIT(20)), [RST_AHB1_SPI1] = RESET(0x2c0, BIT(21)),
diff --git a/drivers/clk/sunxi/clk_a64.c b/drivers/clk/sunxi/clk_a64.c index cbb9168edb9c..916ff4c2b5d1 100644 --- a/drivers/clk/sunxi/clk_a64.c +++ b/drivers/clk/sunxi/clk_a64.c @@ -19,6 +19,7 @@ static const struct ccu_clk_gate a64_gates[] = { [CLK_BUS_MMC0] = GATE(0x060, BIT(8)), [CLK_BUS_MMC1] = GATE(0x060, BIT(9)), [CLK_BUS_MMC2] = GATE(0x060, BIT(10)),
- [CLK_BUS_NAND] = GATE(0x060, BIT(13)), [CLK_BUS_EMAC] = GATE(0x060, BIT(17)), [CLK_BUS_SPI0] = GATE(0x060, BIT(20)), [CLK_BUS_SPI1] = GATE(0x060, BIT(21)),
@@ -39,6 +40,7 @@ static const struct ccu_clk_gate a64_gates[] = { [CLK_BUS_UART3] = GATE(0x06c, BIT(19)), [CLK_BUS_UART4] = GATE(0x06c, BIT(20)),
- [CLK_NAND] = GATE(0x080, BIT(31)), [CLK_SPI0] = GATE(0x0a0, BIT(31)), [CLK_SPI1] = GATE(0x0a4, BIT(31)),
@@ -58,6 +60,7 @@ static const struct ccu_reset a64_resets[] = { [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)), [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)), [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)),
- [RST_BUS_NAND] = RESET(0x2c0, BIT(13)), [RST_BUS_EMAC] = RESET(0x2c0, BIT(17)), [RST_BUS_SPI0] = RESET(0x2c0, BIT(20)), [RST_BUS_SPI1] = RESET(0x2c0, BIT(21)),
diff --git a/drivers/clk/sunxi/clk_a80.c b/drivers/clk/sunxi/clk_a80.c index 1ee1f99a8f49..be732f5d1b50 100644 --- a/drivers/clk/sunxi/clk_a80.c +++ b/drivers/clk/sunxi/clk_a80.c @@ -14,12 +14,18 @@ #include <linux/bitops.h>
static const struct ccu_clk_gate a80_gates[] = {
- [CLK_NAND0_0] = GATE(0x400, BIT(31)),
- [CLK_NAND0_1] = GATE(0x404, BIT(31)),
- [CLK_NAND1_0] = GATE(0x408, BIT(31)),
- [CLK_NAND1_1] = GATE(0x40c, BIT(31)),
So my copy of the manual (v1.1 from the Wiki) doesn't have the second pair, although there are two gates, so I assume it's just a doc issue.
[CLK_SPI0] = GATE(0x430, BIT(31)), [CLK_SPI1] = GATE(0x434, BIT(31)), [CLK_SPI2] = GATE(0x438, BIT(31)), [CLK_SPI3] = GATE(0x43c, BIT(31)),
[CLK_BUS_MMC] = GATE(0x580, BIT(8)),
- [CLK_BUS_NAND0] = GATE(0x580, BIT(12)),
- [CLK_BUS_NAND1] = GATE(0x580, BIT(13)),
Those seem to be swapped, in line with the other dual NAND SoCs.
[CLK_BUS_SPI0] = GATE(0x580, BIT(20)), [CLK_BUS_SPI1] = GATE(0x580, BIT(21)), [CLK_BUS_SPI2] = GATE(0x580, BIT(22)), @@ -42,6 +48,8 @@ static const struct ccu_clk_gate a80_gates[] = {
static const struct ccu_reset a80_resets[] = { [RST_BUS_MMC] = RESET(0x5a0, BIT(8)),
- [RST_BUS_NAND0] = RESET(0x5a0, BIT(12)),
- [RST_BUS_NAND1] = RESET(0x5a0, BIT(13)),
and those two as well.
Compared the rest against the respective manuals, they look fine.
Indeed, the manual has them swapped. Then that means the Linux driver is also wrong. I will send a patch for it.
Regards, Samuel

NAND is always at function 2 on port C.
Pin lists and mux values were taken from the Linux drivers.
Signed-off-by: Samuel Holland samuel@sholland.org ---
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 9ce2bc1b3afb..b10e3e7b0690 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -268,6 +268,7 @@ static const struct sunxi_pinctrl_function sun4i_a10_pinctrl_functions[] = { #endif { "mmc2", 3 }, /* PC6-PC15 */ { "mmc3", 2 }, /* PI4-PI9 */ + { "nand0", 2 }, /* PC0-PC24 */ { "spi0", 3 }, /* PC0-PC2, PC23 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ @@ -292,6 +293,7 @@ static const struct sunxi_pinctrl_function sun5i_a13_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG3-PG8 */ { "mmc2", 3 }, /* PC6-PC15 */ + { "nand0", 2 }, /* PC0-PC19 */ { "spi0", 3 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ @@ -318,6 +320,7 @@ static const struct sunxi_pinctrl_function sun6i_a31_pinctrl_functions[] = { { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC6-PC15, PC24 */ { "mmc3", 4 }, /* PC6-PC15, PC24 */ + { "nand0", 2 }, /* PC0-PC26 */ { "spi0", 3 }, /* PC0-PC2, PC27 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -361,6 +364,7 @@ static const struct sunxi_pinctrl_function sun7i_a20_pinctrl_functions[] = { { "mmc1", 4 }, /* PG0-PG5 */ #endif { "mmc2", 3 }, /* PC5-PC15, PC24 */ + { "nand0", 2 }, /* PC0-PC24 */ { "spi0", 3 }, /* PC0-PC2, PC23 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ @@ -384,6 +388,7 @@ static const struct sunxi_pinctrl_function sun8i_a23_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */ + { "nand0", 2 }, /* PC0-PC16 */ { "spi0", 3 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -421,6 +426,7 @@ static const struct sunxi_pinctrl_function sun8i_a33_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */ + { "nand0", 2 }, /* PC0-PC16 */ { "spi0", 3 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -447,6 +453,7 @@ static const struct sunxi_pinctrl_function sun8i_a83t_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */ + { "nand0", 2 }, /* PC0-PC18 */ { "spi0", 3 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -487,6 +494,7 @@ static const struct sunxi_pinctrl_function sun8i_h3_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */ + { "nand0", 2 }, /* PC0-PC16 */ { "spi0", 3 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -553,6 +561,7 @@ static const struct sunxi_pinctrl_function sun9i_a80_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC6-PC16 */ + { "nand0", 2 }, /* PC0-PC18 */ { "spi0", 3 }, /* PC0-PC2, PC19 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ @@ -592,6 +601,7 @@ static const struct sunxi_pinctrl_function sun50i_a64_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC1-PC16 */ + { "nand0", 2 }, /* PC0-PC16 */ { "pwm", 2 }, /* PD22 */ { "spi0", 4 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) @@ -633,6 +643,7 @@ static const struct sunxi_pinctrl_function sun50i_h5_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC1-PC16 */ + { "nand0", 2 }, /* PC0-PC16 */ { "spi0", 3 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -659,6 +670,7 @@ static const struct sunxi_pinctrl_function sun50i_h6_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC1-PC14 */ + { "nand0", 2 }, /* PC0-PC16 */ { "spi0", 4 }, /* PC0-PC7 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -696,6 +708,7 @@ static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC0-PC16 */ + { "nand0", 2 }, /* PC0-PC16 */ { "spi0", 4 }, /* PC0-PC7, PC15-PC16 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */

On Thu, Jul 14, 2022 at 8:45 AM Samuel Holland samuel@sholland.org wrote:
NAND is always at function 2 on port C.
Pin lists and mux values were taken from the Linux drivers.
Signed-off-by: Samuel Holland samuel@sholland.org
Reviewed-by: Jagan Teki jagan@amarulasolutions.com

On Wed, 13 Jul 2022 22:15:22 -0500 Samuel Holland samuel@sholland.org wrote:
Hi,
NAND is always at function 2 on port C.
Indeed.
Pin lists and mux values were taken from the Linux drivers.
Compared against the manuals. I didn't bother the check the pin ranges (I think some additional CS pins were not covered by the comments), but that shouldn't matter anyways.
Reviewed-by: Andre Przywara andre.przywara@arm.com
Signed-off-by: Samuel Holland samuel@sholland.org
Cheers, Andre
P.S.: I see that the A83T kernel pinctrl driver uses "nand" for *some* pins instead of "nand0", not sure if that should to be fixed, or if it's too late for that (not that NAND is mentioned at all in the A83T DT files ...)
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 9ce2bc1b3afb..b10e3e7b0690 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -268,6 +268,7 @@ static const struct sunxi_pinctrl_function sun4i_a10_pinctrl_functions[] = { #endif { "mmc2", 3 }, /* PC6-PC15 */ { "mmc3", 2 }, /* PI4-PI9 */
- { "nand0", 2 }, /* PC0-PC24 */ { "spi0", 3 }, /* PC0-PC2, PC23 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ @@ -292,6 +293,7 @@ static const struct sunxi_pinctrl_function sun5i_a13_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG3-PG8 */ { "mmc2", 3 }, /* PC6-PC15 */
- { "nand0", 2 }, /* PC0-PC19 */ { "spi0", 3 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ @@ -318,6 +320,7 @@ static const struct sunxi_pinctrl_function sun6i_a31_pinctrl_functions[] = { { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC6-PC15, PC24 */ { "mmc3", 4 }, /* PC6-PC15, PC24 */
- { "nand0", 2 }, /* PC0-PC26 */ { "spi0", 3 }, /* PC0-PC2, PC27 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -361,6 +364,7 @@ static const struct sunxi_pinctrl_function sun7i_a20_pinctrl_functions[] = { { "mmc1", 4 }, /* PG0-PG5 */ #endif { "mmc2", 3 }, /* PC5-PC15, PC24 */
- { "nand0", 2 }, /* PC0-PC24 */ { "spi0", 3 }, /* PC0-PC2, PC23 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ @@ -384,6 +388,7 @@ static const struct sunxi_pinctrl_function sun8i_a23_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */
- { "nand0", 2 }, /* PC0-PC16 */ { "spi0", 3 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -421,6 +426,7 @@ static const struct sunxi_pinctrl_function sun8i_a33_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */
- { "nand0", 2 }, /* PC0-PC16 */ { "spi0", 3 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -447,6 +453,7 @@ static const struct sunxi_pinctrl_function sun8i_a83t_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */
- { "nand0", 2 }, /* PC0-PC18 */ { "spi0", 3 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -487,6 +494,7 @@ static const struct sunxi_pinctrl_function sun8i_h3_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */
- { "nand0", 2 }, /* PC0-PC16 */ { "spi0", 3 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -553,6 +561,7 @@ static const struct sunxi_pinctrl_function sun9i_a80_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC6-PC16 */
- { "nand0", 2 }, /* PC0-PC18 */ { "spi0", 3 }, /* PC0-PC2, PC19 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ @@ -592,6 +601,7 @@ static const struct sunxi_pinctrl_function sun50i_a64_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC1-PC16 */
- { "nand0", 2 }, /* PC0-PC16 */ { "pwm", 2 }, /* PD22 */ { "spi0", 4 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) @@ -633,6 +643,7 @@ static const struct sunxi_pinctrl_function sun50i_h5_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC1-PC16 */
- { "nand0", 2 }, /* PC0-PC16 */ { "spi0", 3 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -659,6 +670,7 @@ static const struct sunxi_pinctrl_function sun50i_h6_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC1-PC14 */
- { "nand0", 2 }, /* PC0-PC16 */ { "spi0", 4 }, /* PC0-PC7 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -696,6 +708,7 @@ static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC0-PC16 */
- { "nand0", 2 }, /* PC0-PC16 */ { "spi0", 4 }, /* PC0-PC7, PC15-PC16 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */

Hi Andre
On Mon, Jul 18, 2022 at 6:20 PM Andre Przywara andre.przywara@arm.com wrote:
On Wed, 13 Jul 2022 22:15:22 -0500 Samuel Holland samuel@sholland.org wrote:
Hi,
NAND is always at function 2 on port C.
Indeed.
Pin lists and mux values were taken from the Linux drivers.
Compared against the manuals. I didn't bother the check the pin ranges (I think some additional CS pins were not covered by the comments), but that shouldn't matter anyways.
Reviewed-by: Andre Przywara andre.przywara@arm.com
Signed-off-by: Samuel Holland samuel@sholland.org
Cheers, Andre
P.S.: I see that the A83T kernel pinctrl driver uses "nand" for *some* pins instead of "nand0", not sure if that should to be fixed, or if it's too late for that (not that NAND is mentioned at all in the A83T DT files ...)
Are you going to queue them all?
Michael
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 9ce2bc1b3afb..b10e3e7b0690 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -268,6 +268,7 @@ static const struct sunxi_pinctrl_function sun4i_a10_pinctrl_functions[] = { #endif { "mmc2", 3 }, /* PC6-PC15 */ { "mmc3", 2 }, /* PI4-PI9 */
{ "nand0", 2 }, /* PC0-PC24 */ { "spi0", 3 }, /* PC0-PC2, PC23 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ @@ -292,6 +293,7 @@ static const struct sunxi_pinctrl_function sun5i_a13_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG3-PG8 */ { "mmc2", 3 }, /* PC6-PC15 */
{ "nand0", 2 }, /* PC0-PC19 */ { "spi0", 3 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ @@ -318,6 +320,7 @@ static const struct sunxi_pinctrl_function sun6i_a31_pinctrl_functions[] = { { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC6-PC15, PC24 */ { "mmc3", 4 }, /* PC6-PC15, PC24 */
{ "nand0", 2 }, /* PC0-PC26 */ { "spi0", 3 }, /* PC0-PC2, PC27 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -361,6 +364,7 @@ static const struct sunxi_pinctrl_function sun7i_a20_pinctrl_functions[] = { { "mmc1", 4 }, /* PG0-PG5 */ #endif { "mmc2", 3 }, /* PC5-PC15, PC24 */
{ "nand0", 2 }, /* PC0-PC24 */ { "spi0", 3 }, /* PC0-PC2, PC23 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ @@ -384,6 +388,7 @@ static const struct sunxi_pinctrl_function sun8i_a23_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */
{ "nand0", 2 }, /* PC0-PC16 */ { "spi0", 3 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -421,6 +426,7 @@ static const struct sunxi_pinctrl_function sun8i_a33_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */
{ "nand0", 2 }, /* PC0-PC16 */ { "spi0", 3 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -447,6 +453,7 @@ static const struct sunxi_pinctrl_function sun8i_a83t_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */
{ "nand0", 2 }, /* PC0-PC18 */ { "spi0", 3 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -487,6 +494,7 @@ static const struct sunxi_pinctrl_function sun8i_h3_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */
{ "nand0", 2 }, /* PC0-PC16 */ { "spi0", 3 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -553,6 +561,7 @@ static const struct sunxi_pinctrl_function sun9i_a80_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC6-PC16 */
{ "nand0", 2 }, /* PC0-PC18 */ { "spi0", 3 }, /* PC0-PC2, PC19 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ @@ -592,6 +601,7 @@ static const struct sunxi_pinctrl_function sun50i_a64_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC1-PC16 */
{ "nand0", 2 }, /* PC0-PC16 */ { "pwm", 2 }, /* PD22 */ { "spi0", 4 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) @@ -633,6 +643,7 @@ static const struct sunxi_pinctrl_function sun50i_h5_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC1-PC16 */
{ "nand0", 2 }, /* PC0-PC16 */ { "spi0", 3 }, /* PC0-PC3 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -659,6 +670,7 @@ static const struct sunxi_pinctrl_function sun50i_h6_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC1-PC14 */
{ "nand0", 2 }, /* PC0-PC16 */ { "spi0", 4 }, /* PC0-PC7 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ @@ -696,6 +708,7 @@ static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC0-PC16 */
{ "nand0", 2 }, /* PC0-PC16 */ { "spi0", 4 }, /* PC0-PC7, PC15-PC16 */
#if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */

Hi Andre,
On 7/18/22 11:20 AM, Andre Przywara wrote:
P.S.: I see that the A83T kernel pinctrl driver uses "nand" for *some* pins instead of "nand0", not sure if that should to be fixed, or if it's too late for that (not that NAND is mentioned at all in the A83T DT files ...)
I already sent a patch fixing this, so yes, it is too late ;-)
https://git.kernel.org/torvalds/c/aaefa29270d9
Regards, Samuel

Each chip is required to have a unique CS number ("reg" property) in the range 0-7, so there is no need to separately count the number of chips.
Signed-off-by: Samuel Holland samuel@sholland.org ---
drivers/mtd/nand/raw/sunxi_nand.c | 10 ---------- 1 file changed, 10 deletions(-)
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index c378f08f6805..0f10edfdb208 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1766,16 +1766,6 @@ static int sunxi_nand_chips_init(int node, struct sunxi_nfc *nfc) int nand_node; int ret, i = 0;
- for (nand_node = fdt_first_subnode(blob, node); nand_node >= 0; - nand_node = fdt_next_subnode(blob, nand_node)) - i++; - - if (i > 8) { - dev_err(nfc->dev, "too many NAND chips: %d (max = 8)\n", i); - return -EINVAL; - } - - i = 0; for (nand_node = fdt_first_subnode(blob, node); nand_node >= 0; nand_node = fdt_next_subnode(blob, nand_node)) { ret = sunxi_nand_chip_init(nand_node, nfc, i++);

Hi
On Thu, Jul 14, 2022 at 5:15 AM Samuel Holland samuel@sholland.org wrote:
Each chip is required to have a unique CS number ("reg" property) in the range 0-7, so there is no need to separately count the number of chips.
Signed-off-by: Samuel Holland samuel@sholland.org
drivers/mtd/nand/raw/sunxi_nand.c | 10 ---------- 1 file changed, 10 deletions(-)
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index c378f08f6805..0f10edfdb208 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1766,16 +1766,6 @@ static int sunxi_nand_chips_init(int node, struct sunxi_nfc *nfc) int nand_node; int ret, i = 0;
for (nand_node = fdt_first_subnode(blob, node); nand_node >= 0;
nand_node = fdt_next_subnode(blob, nand_node))
i++;
if (i > 8) {
dev_err(nfc->dev, "too many NAND chips: %d (max = 8)\n", i);
return -EINVAL;
}
i = 0; for (nand_node = fdt_first_subnode(blob, node); nand_node >= 0; nand_node = fdt_next_subnode(blob, nand_node)) { ret = sunxi_nand_chip_init(nand_node, nfc, i++);
-- 2.35.1
Reviewed-by: Michael Trimarchi michael@amarulasolutions.com
-- Michael Nazzareno Trimarchi Co-Founder & Chief Executive Officer M. +39 347 913 2170 michael@amarulasolutions.com __________________________________
Amarula Solutions BV Joop Geesinkweg 125, 1114 AB, Amsterdam, NL T. +31 (0)85 111 9172 info@amarulasolutions.com www.amarulasolutions.com

As a first step toward converting this driver to the driver model, use the ofnode abstraction to replace direct references to the FDT blob.
Using ofnode_read_u32_index removes an extra pair of loops and makes the allwinner,rb property optional, matching the devicetree binding.
Signed-off-by: Samuel Holland samuel@sholland.org ---
drivers/mtd/nand/raw/sunxi_nand.c | 73 +++++++++++-------------------- include/fdtdec.h | 1 - lib/fdtdec.c | 1 - 3 files changed, 26 insertions(+), 49 deletions(-)
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 0f10edfdb208..7185efbebfdd 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -25,11 +25,10 @@ */
#include <common.h> -#include <fdtdec.h> +#include <dm.h> #include <malloc.h> #include <memalign.h> #include <nand.h> -#include <asm/global_data.h> #include <dm/device_compat.h> #include <dm/devres.h> #include <linux/bitops.h> @@ -45,8 +44,6 @@ #include <asm/gpio.h> #include <asm/arch/clock.h>
-DECLARE_GLOBAL_DATA_PTR; - #define NFC_REG_CTL 0x0000 #define NFC_REG_ST 0x0004 #define NFC_REG_INT 0x0008 @@ -1605,19 +1602,18 @@ static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc) return 0; }
-static int sunxi_nand_chip_init(int node, struct sunxi_nfc *nfc, int devnum) +static int sunxi_nand_chip_init(ofnode np, struct sunxi_nfc *nfc, int devnum) { const struct nand_sdr_timings *timings; - const void *blob = gd->fdt_blob; struct sunxi_nand_chip *chip; struct mtd_info *mtd; struct nand_chip *nand; int nsels; int ret; int i; - u32 cs[8], rb[8]; + u32 tmp;
- if (!fdt_getprop(blob, node, "reg", &nsels)) + if (!ofnode_get_property(np, "reg", &nsels)) return -EINVAL;
nsels /= sizeof(u32); @@ -1638,25 +1634,12 @@ static int sunxi_nand_chip_init(int node, struct sunxi_nfc *nfc, int devnum) chip->selected = -1;
for (i = 0; i < nsels; i++) { - cs[i] = -1; - rb[i] = -1; - } - - ret = fdtdec_get_int_array(gd->fdt_blob, node, "reg", cs, nsels); - if (ret) { - dev_err(nfc->dev, "could not retrieve reg property: %d\n", ret); - return ret; - } - - ret = fdtdec_get_int_array(gd->fdt_blob, node, "allwinner,rb", rb, - nsels); - if (ret) { - dev_err(nfc->dev, "could not retrieve reg property: %d\n", ret); - return ret; - } - - for (i = 0; i < nsels; i++) { - int tmp = cs[i]; + ret = ofnode_read_u32_index(np, "reg", i, &tmp); + if (ret) { + dev_err(nfc->dev, "could not retrieve reg property: %d\n", + ret); + return ret; + }
if (tmp > NFC_MAX_CS) { dev_err(nfc->dev, @@ -1671,15 +1654,14 @@ static int sunxi_nand_chip_init(int node, struct sunxi_nfc *nfc, int devnum)
chip->sels[i].cs = tmp;
- tmp = rb[i]; - if (tmp >= 0 && tmp < 2) { + if (!ofnode_read_u32_index(np, "allwinner,rb", i, &tmp) && + tmp < 2) { chip->sels[i].rb.type = RB_NATIVE; chip->sels[i].rb.info.nativeid = tmp; } else { - ret = gpio_request_by_name_nodev(offset_to_ofnode(node), - "rb-gpios", i, - &chip->sels[i].rb.info.gpio, - GPIOD_IS_IN); + ret = gpio_request_by_name_nodev(np, "rb-gpios", i, + &chip->sels[i].rb.info.gpio, + GPIOD_IS_IN); if (ret) chip->sels[i].rb.type = RB_GPIO; else @@ -1711,7 +1693,7 @@ static int sunxi_nand_chip_init(int node, struct sunxi_nfc *nfc, int devnum) * in the DT. */ nand->ecc.mode = NAND_ECC_HW; - nand->flash_node = offset_to_ofnode(node); + nand->flash_node = np; nand->select_chip = sunxi_nfc_select_chip; nand->cmd_ctrl = sunxi_nfc_cmd_ctrl; nand->read_buf = sunxi_nfc_read_buf; @@ -1760,15 +1742,13 @@ static int sunxi_nand_chip_init(int node, struct sunxi_nfc *nfc, int devnum) return 0; }
-static int sunxi_nand_chips_init(int node, struct sunxi_nfc *nfc) +static int sunxi_nand_chips_init(ofnode node, struct sunxi_nfc *nfc) { - const void *blob = gd->fdt_blob; - int nand_node; + ofnode nand_np; int ret, i = 0;
- for (nand_node = fdt_first_subnode(blob, node); nand_node >= 0; - nand_node = fdt_next_subnode(blob, nand_node)) { - ret = sunxi_nand_chip_init(nand_node, nfc, i++); + ofnode_for_each_subnode(nand_np, node) { + ret = sunxi_nand_chip_init(nand_np, nfc, i++); if (ret) return ret; } @@ -1794,10 +1774,9 @@ static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
void sunxi_nand_init(void) { - const void *blob = gd->fdt_blob; struct sunxi_nfc *nfc; - fdt_addr_t regs; - int node; + phys_addr_t regs; + ofnode node; int ret;
nfc = kzalloc(sizeof(*nfc), GFP_KERNEL); @@ -1808,18 +1787,18 @@ void sunxi_nand_init(void) init_waitqueue_head(&nfc->controller.wq); INIT_LIST_HEAD(&nfc->chips);
- node = fdtdec_next_compatible(blob, 0, COMPAT_SUNXI_NAND); - if (node < 0) { + node = ofnode_by_compatible(ofnode_null(), "allwinner,sun4i-a10-nand"); + if (!ofnode_valid(node)) { pr_err("unable to find nfc node in device tree\n"); goto err; }
- if (!fdtdec_get_is_enabled(blob, node)) { + if (!ofnode_is_enabled(node)) { pr_err("nfc disabled in device tree\n"); goto err; }
- regs = fdtdec_get_addr(blob, node, "reg"); + regs = ofnode_get_addr(node); if (regs == FDT_ADDR_T_NONE) { pr_err("unable to find nfc address in device tree\n"); goto err; diff --git a/include/fdtdec.h b/include/fdtdec.h index 12355afd7fa1..71ec155961a2 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -187,7 +187,6 @@ enum fdt_compat_id { COMPAT_INTEL_BAYTRAIL_FSP, /* Intel Bay Trail FSP */ COMPAT_INTEL_BAYTRAIL_FSP_MDP, /* Intel FSP memory-down params */ COMPAT_INTEL_IVYBRIDGE_FSP, /* Intel Ivy Bridge FSP */ - COMPAT_SUNXI_NAND, /* SUNXI NAND controller */ COMPAT_ALTERA_SOCFPGA_CLK, /* SoCFPGA Clock initialization */ COMPAT_ALTERA_SOCFPGA_PINCTRL_SINGLE, /* SoCFPGA pinctrl-single */ COMPAT_ALTERA_SOCFPGA_H2F_BRG, /* SoCFPGA hps2fpga bridge */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index ffa78f97ca0a..8b54b5377876 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -62,7 +62,6 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(INTEL_BAYTRAIL_FSP, "intel,baytrail-fsp"), COMPAT(INTEL_BAYTRAIL_FSP_MDP, "intel,baytrail-fsp-mdp"), COMPAT(INTEL_IVYBRIDGE_FSP, "intel,ivybridge-fsp"), - COMPAT(COMPAT_SUNXI_NAND, "allwinner,sun4i-a10-nand"), COMPAT(ALTERA_SOCFPGA_CLK, "altr,clk-mgr"), COMPAT(ALTERA_SOCFPGA_PINCTRL_SINGLE, "pinctrl-single"), COMPAT(ALTERA_SOCFPGA_H2F_BRG, "altr,socfpga-hps2fpga-bridge"),

Clocks, resets, and pinmuxes are now handled by the driver model, so the only thing the "board" code needs to do is load the driver. This matches the pattern used by other DM raw NAND drivers (there is no NAND uclass).
The actual board code is now only needed in SPL.
Signed-off-by: Samuel Holland samuel@sholland.org ---
board/sunxi/board.c | 5 +- drivers/mtd/nand/raw/sunxi_nand.c | 81 ++++++++++++++++++------------- 2 files changed, 49 insertions(+), 37 deletions(-)
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 21a2407e062f..ea0f33ed31db 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -315,7 +315,7 @@ int dram_init(void) return 0; }
-#if defined(CONFIG_NAND_SUNXI) +#if defined(CONFIG_NAND_SUNXI) && defined(CONFIG_SPL_BUILD) static void nand_pinmux_setup(void) { unsigned int pin; @@ -351,9 +351,6 @@ void board_nand_init(void) { nand_pinmux_setup(); nand_clock_setup(); -#ifndef CONFIG_SPL_BUILD - sunxi_nand_init(); -#endif } #endif
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 7185efbebfdd..dda51a39b065 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -24,11 +24,13 @@ * GNU General Public License for more details. */
+#include <clk.h> #include <common.h> #include <dm.h> #include <malloc.h> #include <memalign.h> #include <nand.h> +#include <reset.h> #include <dm/device_compat.h> #include <dm/devres.h> #include <linux/bitops.h> @@ -260,7 +262,7 @@ static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand) * NAND Controller structure: stores sunxi NAND controller information * * @controller: base controller structure - * @dev: parent device (used to print error messages) + * @dev: DM device (used to print error messages) * @regs: NAND controller registers * @ahb_clk: NAND Controller AHB clock * @mod_clk: NAND Controller mod clock @@ -273,7 +275,7 @@ static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand) */ struct sunxi_nfc { struct nand_hw_control controller; - struct device *dev; + struct udevice *dev; void __iomem *regs; struct clk *ahb_clk; struct clk *mod_clk; @@ -1772,54 +1774,67 @@ static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc) } #endif /* __UBOOT__ */
-void sunxi_nand_init(void) +static int sunxi_nand_probe(struct udevice *dev) { - struct sunxi_nfc *nfc; - phys_addr_t regs; - ofnode node; + struct sunxi_nfc *nfc = dev_get_priv(dev); + struct reset_ctl_bulk rst_bulk; + struct clk_bulk clk_bulk; int ret;
- nfc = kzalloc(sizeof(*nfc), GFP_KERNEL); - if (!nfc) - return; - + nfc->dev = dev; spin_lock_init(&nfc->controller.lock); init_waitqueue_head(&nfc->controller.wq); INIT_LIST_HEAD(&nfc->chips);
- node = ofnode_by_compatible(ofnode_null(), "allwinner,sun4i-a10-nand"); - if (!ofnode_valid(node)) { - pr_err("unable to find nfc node in device tree\n"); - goto err; - } - - if (!ofnode_is_enabled(node)) { - pr_err("nfc disabled in device tree\n"); - goto err; - } + nfc->regs = dev_read_addr_ptr(dev); + if (!nfc->regs) + return -EINVAL;
- regs = ofnode_get_addr(node); - if (regs == FDT_ADDR_T_NONE) { - pr_err("unable to find nfc address in device tree\n"); - goto err; - } + ret = reset_get_bulk(dev, &rst_bulk); + if (!ret) + reset_deassert_bulk(&rst_bulk);
- nfc->regs = (void *)regs; + ret = clk_get_bulk(dev, &clk_bulk); + if (!ret) + clk_enable_bulk(&clk_bulk);
ret = sunxi_nfc_rst(nfc); if (ret) - goto err; + return ret;
- ret = sunxi_nand_chips_init(node, nfc); + ret = sunxi_nand_chips_init(dev_ofnode(dev), nfc); if (ret) { - dev_err(nfc->dev, "failed to init nand chips\n"); - goto err; + dev_err(dev, "failed to init nand chips\n"); + return ret; }
- return; + return 0; +}
-err: - kfree(nfc); +static const struct udevice_id sunxi_nand_ids[] = { + { + .compatible = "allwinner,sun4i-a10-nand", + }, + { } +}; + +U_BOOT_DRIVER(sunxi_nand) = { + .name = "sunxi_nand", + .id = UCLASS_MTD, + .of_match = sunxi_nand_ids, + .probe = sunxi_nand_probe, + .priv_auto = sizeof(struct sunxi_nfc), +}; + +void board_nand_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_MTD, + DM_DRIVER_GET(sunxi_nand), &dev); + if (ret && ret != -ENODEV) + pr_err("Failed to initialize sunxi NAND controller: %d\n", ret); }
MODULE_LICENSE("GPL v2");

Hi
On Thu, Jul 14, 2022 at 5:15 AM Samuel Holland samuel@sholland.org wrote:
Clocks, resets, and pinmuxes are now handled by the driver model, so the only thing the "board" code needs to do is load the driver. This matches the pattern used by other DM raw NAND drivers (there is no NAND uclass).
The actual board code is now only needed in SPL.
Signed-off-by: Samuel Holland samuel@sholland.org
board/sunxi/board.c | 5 +- drivers/mtd/nand/raw/sunxi_nand.c | 81 ++++++++++++++++++------------- 2 files changed, 49 insertions(+), 37 deletions(-)
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 21a2407e062f..ea0f33ed31db 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -315,7 +315,7 @@ int dram_init(void) return 0; }
-#if defined(CONFIG_NAND_SUNXI) +#if defined(CONFIG_NAND_SUNXI) && defined(CONFIG_SPL_BUILD) static void nand_pinmux_setup(void) { unsigned int pin; @@ -351,9 +351,6 @@ void board_nand_init(void) { nand_pinmux_setup(); nand_clock_setup(); -#ifndef CONFIG_SPL_BUILD
sunxi_nand_init();
-#endif } #endif
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 7185efbebfdd..dda51a39b065 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -24,11 +24,13 @@
- GNU General Public License for more details.
*/
+#include <clk.h> #include <common.h> #include <dm.h> #include <malloc.h> #include <memalign.h> #include <nand.h> +#include <reset.h> #include <dm/device_compat.h> #include <dm/devres.h> #include <linux/bitops.h> @@ -260,7 +262,7 @@ static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand)
- NAND Controller structure: stores sunxi NAND controller information
- @controller: base controller structure
- @dev: parent device (used to print error messages)
- @dev: DM device (used to print error messages)
- @regs: NAND controller registers
- @ahb_clk: NAND Controller AHB clock
- @mod_clk: NAND Controller mod clock
@@ -273,7 +275,7 @@ static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand) */ struct sunxi_nfc { struct nand_hw_control controller;
struct device *dev;
struct udevice *dev; void __iomem *regs; struct clk *ahb_clk; struct clk *mod_clk;
@@ -1772,54 +1774,67 @@ static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc) } #endif /* __UBOOT__ */
-void sunxi_nand_init(void) +static int sunxi_nand_probe(struct udevice *dev) {
struct sunxi_nfc *nfc;
phys_addr_t regs;
ofnode node;
struct sunxi_nfc *nfc = dev_get_priv(dev);
struct reset_ctl_bulk rst_bulk;
struct clk_bulk clk_bulk; int ret;
nfc = kzalloc(sizeof(*nfc), GFP_KERNEL);
if (!nfc)
return;
nfc->dev = dev; spin_lock_init(&nfc->controller.lock); init_waitqueue_head(&nfc->controller.wq); INIT_LIST_HEAD(&nfc->chips);
node = ofnode_by_compatible(ofnode_null(), "allwinner,sun4i-a10-nand");
if (!ofnode_valid(node)) {
pr_err("unable to find nfc node in device tree\n");
goto err;
}
if (!ofnode_is_enabled(node)) {
pr_err("nfc disabled in device tree\n");
goto err;
}
nfc->regs = dev_read_addr_ptr(dev);
if (!nfc->regs)
return -EINVAL;
regs = ofnode_get_addr(node);
if (regs == FDT_ADDR_T_NONE) {
pr_err("unable to find nfc address in device tree\n");
goto err;
}
ret = reset_get_bulk(dev, &rst_bulk);
if (!ret)
reset_deassert_bulk(&rst_bulk);
nfc->regs = (void *)regs;
ret = clk_get_bulk(dev, &clk_bulk);
if (!ret)
clk_enable_bulk(&clk_bulk); ret = sunxi_nfc_rst(nfc); if (ret)
goto err;
return ret;
ret = sunxi_nand_chips_init(node, nfc);
ret = sunxi_nand_chips_init(dev_ofnode(dev), nfc); if (ret) {
dev_err(nfc->dev, "failed to init nand chips\n");
goto err;
dev_err(dev, "failed to init nand chips\n");
return ret; }
return;
return 0;
+}
-err:
kfree(nfc);
+static const struct udevice_id sunxi_nand_ids[] = {
{
.compatible = "allwinner,sun4i-a10-nand",
},
{ }
+};
+U_BOOT_DRIVER(sunxi_nand) = {
.name = "sunxi_nand",
.id = UCLASS_MTD,
.of_match = sunxi_nand_ids,
.probe = sunxi_nand_probe,
.priv_auto = sizeof(struct sunxi_nfc),
+};
+void board_nand_init(void) +{
struct udevice *dev;
int ret;
ret = uclass_get_device_by_driver(UCLASS_MTD,
DM_DRIVER_GET(sunxi_nand), &dev);
if (ret && ret != -ENODEV)
pr_err("Failed to initialize sunxi NAND controller: %d\n", ret);
}
MODULE_LICENSE("GPL v2");
2.35.1
Reviewed-by: Michael Trimarchi michael@amarulasolutions.com
Michael

This more closely matches the U-Boot driver to the Linux version.
Signed-off-by: Samuel Holland samuel@sholland.org ---
drivers/mtd/nand/raw/sunxi_nand.c | 39 ++++++++++++++++--------------- 1 file changed, 20 insertions(+), 19 deletions(-)
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index dda51a39b065..c0fa1e310c66 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1604,7 +1604,8 @@ static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc) return 0; }
-static int sunxi_nand_chip_init(ofnode np, struct sunxi_nfc *nfc, int devnum) +static int sunxi_nand_chip_init(struct udevice *dev, struct sunxi_nfc *nfc, + ofnode np, int devnum) { const struct nand_sdr_timings *timings; struct sunxi_nand_chip *chip; @@ -1620,7 +1621,7 @@ static int sunxi_nand_chip_init(ofnode np, struct sunxi_nfc *nfc, int devnum)
nsels /= sizeof(u32); if (!nsels || nsels > 8) { - dev_err(nfc->dev, "invalid reg property size\n"); + dev_err(dev, "invalid reg property size\n"); return -EINVAL; }
@@ -1628,7 +1629,7 @@ static int sunxi_nand_chip_init(ofnode np, struct sunxi_nfc *nfc, int devnum) (nsels * sizeof(struct sunxi_nand_chip_sel)), GFP_KERNEL); if (!chip) { - dev_err(nfc->dev, "could not allocate chip\n"); + dev_err(dev, "could not allocate chip\n"); return -ENOMEM; }
@@ -1638,19 +1639,19 @@ static int sunxi_nand_chip_init(ofnode np, struct sunxi_nfc *nfc, int devnum) for (i = 0; i < nsels; i++) { ret = ofnode_read_u32_index(np, "reg", i, &tmp); if (ret) { - dev_err(nfc->dev, "could not retrieve reg property: %d\n", + dev_err(dev, "could not retrieve reg property: %d\n", ret); return ret; }
if (tmp > NFC_MAX_CS) { - dev_err(nfc->dev, + dev_err(dev, "invalid reg value: %u (max CS = 7)\n", tmp); return -EINVAL; }
if (test_and_set_bit(tmp, &nfc->assigned_cs)) { - dev_err(nfc->dev, "CS %d already assigned\n", tmp); + dev_err(dev, "CS %d already assigned\n", tmp); return -EINVAL; }
@@ -1661,9 +1662,9 @@ static int sunxi_nand_chip_init(ofnode np, struct sunxi_nfc *nfc, int devnum) chip->sels[i].rb.type = RB_NATIVE; chip->sels[i].rb.info.nativeid = tmp; } else { - ret = gpio_request_by_name_nodev(np, "rb-gpios", i, - &chip->sels[i].rb.info.gpio, - GPIOD_IS_IN); + ret = gpio_request_by_name(dev, "rb-gpios", i, + &chip->sels[i].rb.info.gpio, + GPIOD_IS_IN); if (ret) chip->sels[i].rb.type = RB_GPIO; else @@ -1674,7 +1675,7 @@ static int sunxi_nand_chip_init(ofnode np, struct sunxi_nfc *nfc, int devnum) timings = onfi_async_timing_mode_to_sdr_timings(0); if (IS_ERR(timings)) { ret = PTR_ERR(timings); - dev_err(nfc->dev, + dev_err(dev, "could not retrieve timings for ONFI mode 0: %d\n", ret); return ret; @@ -1682,7 +1683,7 @@ static int sunxi_nand_chip_init(ofnode np, struct sunxi_nfc *nfc, int devnum)
ret = sunxi_nand_chip_set_timings(nfc, chip, timings); if (ret) { - dev_err(nfc->dev, "could not configure chip timings: %d\n", ret); + dev_err(dev, "could not configure chip timings: %d\n", ret); return ret; }
@@ -1717,25 +1718,25 @@ static int sunxi_nand_chip_init(ofnode np, struct sunxi_nfc *nfc, int devnum)
ret = sunxi_nand_chip_init_timings(nfc, chip); if (ret) { - dev_err(nfc->dev, "could not configure chip timings: %d\n", ret); + dev_err(dev, "could not configure chip timings: %d\n", ret); return ret; }
ret = sunxi_nand_ecc_init(mtd, &nand->ecc); if (ret) { - dev_err(nfc->dev, "ECC init failed: %d\n", ret); + dev_err(dev, "ECC init failed: %d\n", ret); return ret; }
ret = nand_scan_tail(mtd); if (ret) { - dev_err(nfc->dev, "nand_scan_tail failed: %d\n", ret); + dev_err(dev, "nand_scan_tail failed: %d\n", ret); return ret; }
ret = nand_register(devnum, mtd); if (ret) { - dev_err(nfc->dev, "failed to register mtd device: %d\n", ret); + dev_err(dev, "failed to register mtd device: %d\n", ret); return ret; }
@@ -1744,13 +1745,13 @@ static int sunxi_nand_chip_init(ofnode np, struct sunxi_nfc *nfc, int devnum) return 0; }
-static int sunxi_nand_chips_init(ofnode node, struct sunxi_nfc *nfc) +static int sunxi_nand_chips_init(struct udevice *dev, struct sunxi_nfc *nfc) { ofnode nand_np; int ret, i = 0;
- ofnode_for_each_subnode(nand_np, node) { - ret = sunxi_nand_chip_init(nand_np, nfc, i++); + dev_for_each_subnode(nand_np, dev) { + ret = sunxi_nand_chip_init(dev, nfc, nand_np, i++); if (ret) return ret; } @@ -1802,7 +1803,7 @@ static int sunxi_nand_probe(struct udevice *dev) if (ret) return ret;
- ret = sunxi_nand_chips_init(dev_ofnode(dev), nfc); + ret = sunxi_nand_chips_init(dev, nfc); if (ret) { dev_err(dev, "failed to init nand chips\n"); return ret;

Hi Samuel
On Thu, Jul 14, 2022 at 5:15 AM Samuel Holland samuel@sholland.org wrote:
This series converts the sunxi NAND driver to get its resources (clocks, resets, pins) from the devicetree, and probe using the driver model.
In addition to the immediate cleanup, this allows backporting more patches (bugfixes, newer SoC support) from the Linux driver.
Samuel Holland (6): clk: sunxi: Add NAND clocks and resets pinctrl: sunxi: Add NAND pinmuxes mtd: nand: sunxi: Remove an unnecessary check mtd: nand: sunxi: Convert from fdtdec to ofnode mtd: nand: sunxi: Convert to the driver model mtd: nand: sunxi: Pass the device to the init function
board/sunxi/board.c | 5 +- drivers/clk/sunxi/clk_a10.c | 2 + drivers/clk/sunxi/clk_a10s.c | 2 + drivers/clk/sunxi/clk_a23.c | 3 + drivers/clk/sunxi/clk_a31.c | 6 + drivers/clk/sunxi/clk_a64.c | 3 + drivers/clk/sunxi/clk_a80.c | 8 ++ drivers/clk/sunxi/clk_a83t.c | 3 + drivers/clk/sunxi/clk_h3.c | 3 + drivers/clk/sunxi/clk_h6.c | 6 + drivers/clk/sunxi/clk_h616.c | 6 + drivers/clk/sunxi/clk_r40.c | 3 + drivers/mtd/nand/raw/sunxi_nand.c | 173 ++++++++++++-------------- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 13 ++ include/fdtdec.h | 1 - lib/fdtdec.c | 1 - 16 files changed, 138 insertions(+), 100 deletions(-)
Was in our roadmap and thank you for it. We are looking for sunxi boards that have nand, can you please point where we can find them?
We are still in the process of setting up our account, anyway we will review it quickly.
Michael
-- 2.35.1

在 2022-07-14星期四的 07:38 +0200,Michael Nazzareno Trimarchi写道:
Hi Samuel
On Thu, Jul 14, 2022 at 5:15 AM Samuel Holland samuel@sholland.org wrote:
This series converts the sunxi NAND driver to get its resources (clocks, resets, pins) from the devicetree, and probe using the driver model.
In addition to the immediate cleanup, this allows backporting more patches (bugfixes, newer SoC support) from the Linux driver.
Samuel Holland (6): clk: sunxi: Add NAND clocks and resets pinctrl: sunxi: Add NAND pinmuxes mtd: nand: sunxi: Remove an unnecessary check mtd: nand: sunxi: Convert from fdtdec to ofnode mtd: nand: sunxi: Convert to the driver model mtd: nand: sunxi: Pass the device to the init function
board/sunxi/board.c | 5 +- drivers/clk/sunxi/clk_a10.c | 2 + drivers/clk/sunxi/clk_a10s.c | 2 + drivers/clk/sunxi/clk_a23.c | 3 + drivers/clk/sunxi/clk_a31.c | 6 + drivers/clk/sunxi/clk_a64.c | 3 + drivers/clk/sunxi/clk_a80.c | 8 ++ drivers/clk/sunxi/clk_a83t.c | 3 + drivers/clk/sunxi/clk_h3.c | 3 + drivers/clk/sunxi/clk_h6.c | 6 + drivers/clk/sunxi/clk_h616.c | 6 + drivers/clk/sunxi/clk_r40.c | 3 + drivers/mtd/nand/raw/sunxi_nand.c | 173 ++++++++++++----------
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 13 ++ include/fdtdec.h | 1 - lib/fdtdec.c | 1 - 16 files changed, 138 insertions(+), 100 deletions(-)
Was in our roadmap and thank you for it. We are looking for sunxi boards that have nand, can you please point where we can find them?
NTC C.H.I.P. ? Although NTC does not exist now (well maybe partly because C.H.I.P. uses NAND)
We are still in the process of setting up our account, anyway we will review it quickly.
Michael
-- 2.35.1
participants (5)
-
Andre Przywara
-
Icenowy Zheng
-
Jagan Teki
-
Michael Nazzareno Trimarchi
-
Samuel Holland