diff mbox series

[RFC,08/17] sunxi: introduce NCAT2 generation model

Message ID 20221206004549.29015-9-andre.przywara@arm.com
State RFC
Delegated to: Andre Przywara
Headers show
Series sunxi: rework pinctrl and add T113s support | expand

Commit Message

Andre Przywara Dec. 6, 2022, 12:45 a.m. UTC
Allwinner seems to typically stick to a common MMIO memory map for
several SoCs, but from time to time does some breaking changes, which
also introduce new generations of some peripherals. The last time this
happened with the H6, which apart from re-organising the base addresses
also changed the clock controller significantly. We added a
CONFIG_SUN50I_GEN_H6 symbol back then to mark SoCs sharing those traits.

Now the Allwinner D1 changes the memory map again, and also extends the
pincontroller, among other peripherals.
To mark this generation of SoCs, add a CONFIG_SUNXI_GEN_NCAT2 symbol,
this name is reportedly used in the Allwinner BSP code, and prevents us
from inventing our own name.

Add this new symbol to some guards that were already checking for the H6
generation, since many features are shared between the two (like the
renovated clock controller).

This paves the way to introduce a first user of this generation.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 arch/arm/include/asm/arch-sunxi/clock.h       |  2 +-
 arch/arm/include/asm/arch-sunxi/cpu.h         |  2 +
 .../include/asm/arch-sunxi/cpu_sunxi_ncat2.h  | 54 +++++++++++++++++++
 arch/arm/include/asm/arch-sunxi/mmc.h         |  2 +-
 arch/arm/include/asm/arch-sunxi/prcm.h        |  2 +-
 arch/arm/include/asm/arch-sunxi/timer.h       |  2 +-
 arch/arm/mach-sunxi/Kconfig                   | 14 ++++-
 arch/arm/mach-sunxi/Makefile                  |  1 +
 arch/arm/mach-sunxi/board.c                   |  4 +-
 common/spl/Kconfig                            |  2 +-
 drivers/mmc/sunxi_mmc.c                       | 10 ++--
 include/sunxi_gpio.h                          |  3 ++
 12 files changed, 86 insertions(+), 12 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h

Comments

Icenowy Zheng Dec. 6, 2022, 5:38 a.m. UTC | #1
在 2022-12-06星期二的 00:45 +0000,Andre Przywara写道:
> Allwinner seems to typically stick to a common MMIO memory map for
> several SoCs, but from time to time does some breaking changes, which
> also introduce new generations of some peripherals. The last time
> this
> happened with the H6, which apart from re-organising the base
> addresses
> also changed the clock controller significantly. We added a
> CONFIG_SUN50I_GEN_H6 symbol back then to mark SoCs sharing those
> traits.
> 
> Now the Allwinner D1 changes the memory map again, and also extends
> the
> pincontroller, among other peripherals.
> To mark this generation of SoCs, add a CONFIG_SUNXI_GEN_NCAT2 symbol,
> this name is reportedly used in the Allwinner BSP code, and prevents
> us
> from inventing our own name.

Should we also rename the misleading GEN_SUN50I_H6 to GEN_NCAT ?

> 
> Add this new symbol to some guards that were already checking for the
> H6
> generation, since many features are shared between the two (like the
> renovated clock controller).
> 
> This paves the way to introduce a first user of this generation.
> 
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
>  arch/arm/include/asm/arch-sunxi/clock.h       |  2 +-
>  arch/arm/include/asm/arch-sunxi/cpu.h         |  2 +
>  .../include/asm/arch-sunxi/cpu_sunxi_ncat2.h  | 54
> +++++++++++++++++++
>  arch/arm/include/asm/arch-sunxi/mmc.h         |  2 +-
>  arch/arm/include/asm/arch-sunxi/prcm.h        |  2 +-
>  arch/arm/include/asm/arch-sunxi/timer.h       |  2 +-
>  arch/arm/mach-sunxi/Kconfig                   | 14 ++++-
>  arch/arm/mach-sunxi/Makefile                  |  1 +
>  arch/arm/mach-sunxi/board.c                   |  4 +-
>  common/spl/Kconfig                            |  2 +-
>  drivers/mmc/sunxi_mmc.c                       | 10 ++--
>  include/sunxi_gpio.h                          |  3 ++
>  12 files changed, 86 insertions(+), 12 deletions(-)
>  create mode 100644 arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/clock.h
> b/arch/arm/include/asm/arch-sunxi/clock.h
> index 2cfd5407423..3d34261b0e5 100644
> --- a/arch/arm/include/asm/arch-sunxi/clock.h
> +++ b/arch/arm/include/asm/arch-sunxi/clock.h
> @@ -16,7 +16,7 @@
>  /* clock control module regs definition */
>  #if defined(CONFIG_MACH_SUN8I_A83T)
>  #include <asm/arch/clock_sun8i_a83t.h>
> -#elif defined(CONFIG_SUN50I_GEN_H6)
> +#elif defined(CONFIG_SUN50I_GEN_H6) ||
> defined(CONFIG_SUNXI_GEN_NCAT2)
>  #include <asm/arch/clock_sun50i_h6.h>
>  #elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
>        defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUNIV)
> diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h
> b/arch/arm/include/asm/arch-sunxi/cpu.h
> index b08f2023748..768c6572d6b 100644
> --- a/arch/arm/include/asm/arch-sunxi/cpu.h
> +++ b/arch/arm/include/asm/arch-sunxi/cpu.h
> @@ -10,6 +10,8 @@
>  #include <asm/arch/cpu_sun9i.h>
>  #elif defined(CONFIG_SUN50I_GEN_H6)
>  #include <asm/arch/cpu_sun50i_h6.h>
> +#elif defined(CONFIG_SUNXI_GEN_NCAT2)
> +#include <asm/arch/cpu_sunxi_ncat2.h>
>  #else
>  #include <asm/arch/cpu_sun4i.h>
>  #endif
> diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
> b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
> new file mode 100644
> index 00000000000..13093085a5e
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
> @@ -0,0 +1,54 @@
> +/*
> + * (C) Copyright 2022 Arm Limited
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#ifndef _SUNXI_CPU_SUNXI_NCAT2_H
> +#define _SUNXI_CPU_SUNXI_NCAT2_H
> +
> +#define SUNXI_SRAM_A1_BASE             CONFIG_SUNXI_SRAM_ADDRESS
> +#define SUNXI_SRAM_C_BASE              0x00028000
> +#define SUNXI_SRAM_A2_BASE             0x00100000
> +
> +#define SUNXI_SRAMC_BASE               0x02800000
> +#define SUNXI_CCM_BASE                 0x02001000
> +/* SID address space starts at 0x03006000, but e-fuse is at offset
> 0x200 */
> +#define SUNXI_SIDC_BASE                        0x03006000
> +#define SUNXI_SID_BASE                 0x03006200
> +#define SUNXI_TIMER_BASE               0x02050000
> +
> +#ifdef CONFIG_MACH_SUN50I_H6
> +#define SUNXI_DRAM_COM_BASE            0x04002000
> +#define SUNXI_DRAM_CTL0_BASE           0x04003000
> +#define SUNXI_DRAM_PHY0_BASE           0x04005000
> +#endif
> +#define SUNXI_MMC0_BASE                        0x04020000
> +#define SUNXI_MMC1_BASE                        0x04021000
> +#define SUNXI_MMC2_BASE                        0x04022000
> +
> +#define SUNXI_UART0_BASE               0x02500000
> +#define SUNXI_UART1_BASE               0x02500400
> +#define SUNXI_UART2_BASE               0x02500800
> +#define SUNXI_UART3_BASE               0x02500C00
> +#define SUNXI_TWI0_BASE                        0x02502000
> +#define SUNXI_TWI1_BASE                        0x02502400
> +#define SUNXI_TWI2_BASE                        0x02502800
> +#define SUNXI_TWI3_BASE                        0x02502C00
> +#define SUNXI_SPI0_BASE                        0x04025000
> +#define SUNXI_SPI1_BASE                        0x04026000
> +
> +#define SUNXI_RTC_BASE                 0x07000000
> +#define SUNXI_R_CPUCFG_BASE            0x07000400
> +#define SUNXI_PRCM_BASE                        0x07010000
> +#define SUNXI_R_WDOG_BASE              0x07020400
> +#define SUNXI_R_UART_BASE              0x07080000
> +#define SUNXI_R_TWI_BASE               0x07081400
> +
> +#ifndef __ASSEMBLY__
> +void sunxi_board_init(void);
> +void sunxi_reset(void);
> +int sunxi_get_sid(unsigned int *sid);
> +#endif
> +
> +#endif /* _SUNXI_CPU_SUNXI_NCAT2_H */
> diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h
> b/arch/arm/include/asm/arch-sunxi/mmc.h
> index 5daacf10eb1..8ed3e0459c9 100644
> --- a/arch/arm/include/asm/arch-sunxi/mmc.h
> +++ b/arch/arm/include/asm/arch-sunxi/mmc.h
> @@ -45,7 +45,7 @@ struct sunxi_mmc {
>         u32 chda;               /* 0x90 */
>         u32 cbda;               /* 0x94 */
>         u32 res2[26];
> -#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
> +#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
> || defined(CONFIG_SUNXI_GEN_NCAT2)
>         u32 res3[17];
>         u32 samp_dl;
>         u32 res4[46];
> diff --git a/arch/arm/include/asm/arch-sunxi/prcm.h
> b/arch/arm/include/asm/arch-sunxi/prcm.h
> index 5106076f5e9..c5418cfd28d 100644
> --- a/arch/arm/include/asm/arch-sunxi/prcm.h
> +++ b/arch/arm/include/asm/arch-sunxi/prcm.h
> @@ -9,7 +9,7 @@
>  #define _SUNXI_PRCM_H
>  
>  /* prcm regs definition */
> -#if defined(CONFIG_SUN50I_GEN_H6)
> +#if defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
>  #include <asm/arch/prcm_sun50i.h>
>  #else
>  #include <asm/arch/prcm_sun6i.h>
> diff --git a/arch/arm/include/asm/arch-sunxi/timer.h
> b/arch/arm/include/asm/arch-sunxi/timer.h
> index bb5626d893b..e17db8588e2 100644
> --- a/arch/arm/include/asm/arch-sunxi/timer.h
> +++ b/arch/arm/include/asm/arch-sunxi/timer.h
> @@ -76,7 +76,7 @@ struct sunxi_timer_reg {
>         struct sunxi_tgp tgp[4];
>         u8 res5[8];
>         u32 cpu_cfg;
> -#elif defined(CONFIG_SUNXI_GEN_SUN6I) ||
> defined(CONFIG_SUN50I_GEN_H6)
> +#elif defined(CONFIG_SUNXI_GEN_SUN6I) ||
> defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
>         u8 res3[16];
>         struct sunxi_wdog wdog[5];      /* We have 5 watchdogs */
>  #endif
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-
> sunxi/Kconfig
> index 5e019948f85..b59db212fa8 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -102,7 +102,7 @@ config AXP_PMIC_BUS
>  config SUNXI_SRAM_ADDRESS
>         hex
>         default 0x10000 if MACH_SUN9I || MACH_SUN50I ||
> MACH_SUN50I_H5
> -       default 0x20000 if SUN50I_GEN_H6
> +       default 0x20000 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
>         default 0x0
>         ---help---
>         Older Allwinner SoCs have their mask boot ROM mapped just
> below 4GB,
> @@ -144,6 +144,16 @@ config SUN50I_GEN_H6
>         Select this for sunxi SoCs which have H6 like peripherals,
> clocks
>         and memory map.
>  
> +config SUNXI_GEN_NCAT2
> +       bool
> +       select FIT
> +       select SPL_LOAD_FIT
> +       select MMC_SUNXI_HAS_NEW_MODE
> +       select SUPPORT_SPL
> +       ---help---
> +       Select this for sunxi SoCs which have D1 like peripherals,
> clocks
> +       and memory map.
> +
>  config SUNXI_DRAM_DW
>         bool
>         ---help---
> @@ -787,6 +797,7 @@ config VIDEO_SUNXI
>         depends on !MACH_SUN9I
>         depends on !MACH_SUN50I
>         depends on !SUN50I_GEN_H6
> +       depends on !SUNXI_GEN_NCAT2
>         select VIDEO
>         select DISPLAY
>         imply VIDEO_DT_SIMPLEFB
> @@ -1000,6 +1011,7 @@ config SPL_STACK_R_ADDR
>         default 0x2fe00000 if MACH_SUN9I
>         default 0x4fe00000 if MACH_SUN50I
>         default 0x4fe00000 if SUN50I_GEN_H6
> +       default 0x4fe00000 if SUNXI_GEN_NCAT2
>  
>  config SPL_SPI_SUNXI
>         bool "Support for SPI Flash on Allwinner SoCs in SPL"
> diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-
> sunxi/Makefile
> index 671211e9322..1d4c70ec352 100644
> --- a/arch/arm/mach-sunxi/Makefile
> +++ b/arch/arm/mach-sunxi/Makefile
> @@ -25,6 +25,7 @@ obj-$(CONFIG_MACH_SUN8I)      += clock_sun6i.o
>  endif
>  obj-$(CONFIG_MACH_SUN9I)       += clock_sun9i.o gtbus_sun9i.o
>  obj-$(CONFIG_SUN50I_GEN_H6)    += clock_sun50i_h6.o
> +obj-$(CONFIG_SUNXI_GEN_NCAT2)  += clock_sun50i_h6.o
>  ifndef CONFIG_ARM64
>  obj-y  += timer.o
>  endif
> diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-
> sunxi/board.c
> index b6ffbff883c..3763ec3d2e4 100644
> --- a/arch/arm/mach-sunxi/board.c
> +++ b/arch/arm/mach-sunxi/board.c
> @@ -177,7 +177,7 @@ static int gpio_init(void)
>  #error Unsupported console port number. Please fix pin mux settings
> in board.c
>  #endif
>  
> -#ifdef CONFIG_SUN50I_GEN_H6
> +#if defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
>         /* Update PIO power bias configuration by copy hardware
> detected value */
>         val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
>         writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
> @@ -475,7 +475,7 @@ void reset_cpu(void)
>                 /* sun5i sometimes gets stuck without this */
>                 writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
>         }
> -#elif defined(CONFIG_SUNXI_GEN_SUN6I) ||
> defined(CONFIG_SUN50I_GEN_H6)
> +#elif defined(CONFIG_SUNXI_GEN_SUN6I) ||
> defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
>  #if defined(CONFIG_MACH_SUN50I_H6)
>         /* WDOG is broken for some H6 rev. use the R_WDOG instead */
>         static const struct sunxi_wdog *wdog =
> diff --git a/common/spl/Kconfig b/common/spl/Kconfig
> index fef01bdd7da..fdd64db498f 100644
> --- a/common/spl/Kconfig
> +++ b/common/spl/Kconfig
> @@ -265,7 +265,7 @@ config SPL_TEXT_BASE
>         default 0x402F0400 if AM33XX
>         default 0x40301350 if OMAP54XX
>         default 0x10060 if MACH_SUN50I || MACH_SUN50I_H5 ||
> MACH_SUN9I
> -       default 0x20060 if SUN50I_GEN_H6
> +       default 0x20060 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
>         default 0x00060 if ARCH_SUNXI
>         default 0xfffc0000 if ARCH_ZYNQMP
>         default 0x0
> diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
> index a9132af3f64..6ce2729473c 100644
> --- a/drivers/mmc/sunxi_mmc.c
> +++ b/drivers/mmc/sunxi_mmc.c
> @@ -114,6 +114,7 @@ static bool sunxi_mmc_can_calibrate(void)
>         return IS_ENABLED(CONFIG_MACH_SUN50I) ||
>                IS_ENABLED(CONFIG_MACH_SUN50I_H5) ||
>                IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
> +              IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2) ||
>                IS_ENABLED(CONFIG_MACH_SUN8I_R40);
>  }
>  
> @@ -248,7 +249,7 @@ static int mmc_config_clock(struct sunxi_mmc_priv
> *priv, struct mmc *mmc)
>         rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK;
>         writel(rval, &priv->reg->clkcr);
>  
> -#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
> +#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
> || defined(CONFIG_SUNXI_GEN_NCAT2)
>         /* A64 supports calibration of delays on MMC controller and
> we
>          * have to set delay of zero before starting calibration.
>          * Allwinner BSP driver sets a delay only in the case of
> @@ -559,7 +560,8 @@ struct mmc *sunxi_mmc_init(int sdc_no)
>         cfg->host_caps = MMC_MODE_4BIT;
>  
>         if ((IS_ENABLED(CONFIG_MACH_SUN50I) ||
> IS_ENABLED(CONFIG_MACH_SUN8I) ||
> -           IS_ENABLED(CONFIG_SUN50I_GEN_H6)) && (sdc_no == 2))
> +           IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
> +           IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) && (sdc_no == 2))
>                 cfg->host_caps = MMC_MODE_8BIT;
>  
>         cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
> @@ -573,7 +575,7 @@ struct mmc *sunxi_mmc_init(int sdc_no)
>  
>         /* config ahb clock */
>         debug("init mmc %d clock and io\n", sdc_no);
> -#if !defined(CONFIG_SUN50I_GEN_H6)
> +#if !defined(CONFIG_SUN50I_GEN_H6) &&
> !defined(CONFIG_SUNXI_GEN_NCAT2)
>         setbits_le32(&ccm->ahb_gate0, 1 <<
> AHB_GATE_OFFSET_MMC(sdc_no));
>  
>  #ifdef CONFIG_SUNXI_GEN_SUN6I
> @@ -647,7 +649,7 @@ static unsigned get_mclk_offset(void)
>         if (IS_ENABLED(CONFIG_MACH_SUN9I_A80))
>                 return 0x410;
>  
> -       if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
> +       if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
> IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
>                 return 0x830;
>  
>         return 0x88;
> diff --git a/include/sunxi_gpio.h b/include/sunxi_gpio.h
> index 2f8b220f750..04d7aa3d632 100644
> --- a/include/sunxi_gpio.h
> +++ b/include/sunxi_gpio.h
> @@ -16,6 +16,9 @@
>  #elif defined(CONFIG_SUN50I_GEN_H6)
>  #define SUNXI_PIO_BASE         0x0300b000
>  #define SUNXI_R_PIO_BASE       0x07022000
> +#elif defined(CONFIG_SUNXI_GEN_NCAT2)
> +#define SUNXI_PIO_BASE         0x02000000
> +#define SUNXI_R_PIO_BASE       0
>  #else
>  #define SUNXI_PIO_BASE         0x01c20800
>  #define SUNXI_R_PIO_BASE       0x01f02c00
Sam Edwards May 16, 2023, 2:32 a.m. UTC | #2
Hi Andre! Thank you for your efforts on this patchset; I've been 
test-driving it a bit myself this week.

On 12/5/22 17:45, Andre Przywara wrote:

> +#define SUNXI_RTC_BASE			0x07000000
> +#define SUNXI_R_CPUCFG_BASE		0x07000400
> +#define SUNXI_PRCM_BASE			0x07010000
> +#define SUNXI_R_WDOG_BASE		0x07020400
> +#define SUNXI_R_UART_BASE		0x07080000
> +#define SUNXI_R_TWI_BASE		0x07081400

How sure are we that this memory map is consistent across the whole 
NCAT2 family? The documentation for my target (T113-S3) puts the RTC 
base at 0x07090000, for example. I find no mention of there being a PRCM 
peripheral in this particular chip either.

> diff --git a/common/spl/Kconfig b/common/spl/Kconfig
> index fef01bdd7da..fdd64db498f 100644
> --- a/common/spl/Kconfig
> +++ b/common/spl/Kconfig
> @@ -265,7 +265,7 @@ config SPL_TEXT_BASE
>   	default 0x402F0400 if AM33XX
>   	default 0x40301350 if OMAP54XX
>   	default 0x10060 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN9I
> -	default 0x20060 if SUN50I_GEN_H6
> +	default 0x20060 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
>   	default 0x00060 if ARCH_SUNXI
>   	default 0xfffc0000 if ARCH_ZYNQMP
>   	default 0x0

Would it also be good to change the default for CONFIG_SPL_STACK? As-is 
it defaults to 0x8000, which would put it in the BROM region. 
Allwinner's boot0 starts its stack at 0x48000, which I've been using.

> diff --git a/include/sunxi_gpio.h b/include/sunxi_gpio.h
> index 2f8b220f750..04d7aa3d632 100644
> --- a/include/sunxi_gpio.h
> +++ b/include/sunxi_gpio.h
> @@ -16,6 +16,9 @@
>   #elif defined(CONFIG_SUN50I_GEN_H6)
>   #define SUNXI_PIO_BASE		0x0300b000
>   #define SUNXI_R_PIO_BASE	0x07022000
> +#elif defined(CONFIG_SUNXI_GEN_NCAT2)
> +#define SUNXI_PIO_BASE		0x02000000
> +#define SUNXI_R_PIO_BASE	0
>   #else
>   #define SUNXI_PIO_BASE		0x01c20800
>   #define SUNXI_R_PIO_BASE	0x01f02c00

Code elsewhere assumes that SUNXI_R_PIO_BASE is nonzero; on my local 
branch in particular I had to update 
arch/arm/mach-sunxi/board.c:gpio_init. Perhaps it would be better to 
leave SUNXI_R_PIO_BASE undefined in the chips where this gadget is missing?

Much gratitude,
Sam
Andre Przywara May 16, 2023, 9:08 p.m. UTC | #3
On Mon, 15 May 2023 20:32:52 -0600
Sam Edwards <cfsworks@gmail.com> wrote:

Hi Sam,

> Hi Andre! Thank you for your efforts on this patchset; I've been 
> test-driving it a bit myself this week.

many thanks for having a look, that's much appreciated!

> On 12/5/22 17:45, Andre Przywara wrote:
> 
> > +#define SUNXI_RTC_BASE			0x07000000
> > +#define SUNXI_R_CPUCFG_BASE		0x07000400
> > +#define SUNXI_PRCM_BASE			0x07010000
> > +#define SUNXI_R_WDOG_BASE		0x07020400
> > +#define SUNXI_R_UART_BASE		0x07080000
> > +#define SUNXI_R_TWI_BASE		0x07081400  
> 
> How sure are we that this memory map is consistent across the whole 
> NCAT2 family? The documentation for my target (T113-S3) puts the RTC 
> base at 0x07090000, for example. I find no mention of there being a PRCM 
> peripheral in this particular chip either.

This whole memory map is somewhat of a legacy. Apart from a few
addresses for the SPL needs we shouldn't have those defines at all.
Some symbols are needed because there are other macros using them,
although these then are eventually unused.
I have some patches to remove most of the symbols, and patch 14/17
demonstrates some idea how to pin this down to what's really needed.

For this particular case: this was copied from the H6 memory map, some
addresses are just plain wrong for the D1 family. I will try to remove
them as much as possible, leaving only the ones needed in.

> > diff --git a/common/spl/Kconfig b/common/spl/Kconfig
> > index fef01bdd7da..fdd64db498f 100644
> > --- a/common/spl/Kconfig
> > +++ b/common/spl/Kconfig
> > @@ -265,7 +265,7 @@ config SPL_TEXT_BASE
> >   	default 0x402F0400 if AM33XX
> >   	default 0x40301350 if OMAP54XX
> >   	default 0x10060 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN9I
> > -	default 0x20060 if SUN50I_GEN_H6
> > +	default 0x20060 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
> >   	default 0x00060 if ARCH_SUNXI
> >   	default 0xfffc0000 if ARCH_ZYNQMP
> >   	default 0x0  
> 
> Would it also be good to change the default for CONFIG_SPL_STACK? As-is 
> it defaults to 0x8000, which would put it in the BROM region. 
> Allwinner's boot0 starts its stack at 0x48000, which I've been using.

Yeah, well spotted, this was a bug in this early RTC post. I never ran
the SPL, because the DRAM code was missing still. I fixed the stack
pointer meanwhile in an updated (and working) version on Github:
https://github.com/apritzel/u-boot/commit/d5fa559abdf2#diff-19adb575625e29e7a996e0ffb1a266e24239d9b004f17154616220a3f17a24ed

> > diff --git a/include/sunxi_gpio.h b/include/sunxi_gpio.h
> > index 2f8b220f750..04d7aa3d632 100644
> > --- a/include/sunxi_gpio.h
> > +++ b/include/sunxi_gpio.h
> > @@ -16,6 +16,9 @@
> >   #elif defined(CONFIG_SUN50I_GEN_H6)
> >   #define SUNXI_PIO_BASE		0x0300b000
> >   #define SUNXI_R_PIO_BASE	0x07022000
> > +#elif defined(CONFIG_SUNXI_GEN_NCAT2)
> > +#define SUNXI_PIO_BASE		0x02000000
> > +#define SUNXI_R_PIO_BASE	0
> >   #else
> >   #define SUNXI_PIO_BASE		0x01c20800
> >   #define SUNXI_R_PIO_BASE	0x01f02c00  
> 
> Code elsewhere assumes that SUNXI_R_PIO_BASE is nonzero; on my local 
> branch in particular I had to update 
> arch/arm/mach-sunxi/board.c:gpio_init. Perhaps it would be better to 
> leave SUNXI_R_PIO_BASE undefined in the chips where this gadget is missing?

I think leaving it undefined causes more problems, doesn't it? Looking
at #define BANK_TO_GPIO(bank) in
arch/arm/include/asm/arch-sunxi/gpio.h, specifically. I am saying that
because that's what I tried first ;-)

So where did you see problems? If you would (wrongly) reference
PortL somewhere in SPL GPIO code, it would use a wrong pointer, but at
least the code would still compile fine, wouldn't it?

Cheers,
Andre

P.S. Could you try the github post? Then compiled and booted fine for
me, and includes the DRAM code as well now:
https://github.com/apritzel/u-boot/commits/t113s-mq-r-WIP
Sam Edwards May 16, 2023, 11:53 p.m. UTC | #4
On 5/16/23 15:08, Andre Przywara wrote:
> This whole memory map is somewhat of a legacy. Apart from a few
> addresses for the SPL needs we shouldn't have those defines at all.
> Some symbols are needed because there are other macros using them,
> although these then are eventually unused.
> I have some patches to remove most of the symbols, and patch 14/17
> demonstrates some idea how to pin this down to what's really needed.
> 
> For this particular case: this was copied from the H6 memory map, some
> addresses are just plain wrong for the D1 family. I will try to remove
> them as much as possible, leaving only the ones needed in.

I see - the only "tangible" concern I had was the access to 
prcm->res_cal_ctrl done in
arch/arm/mach-sunxi/clock_sun50i_h6.c:clock_init_safe

This doesn't appear to upset the silicon but also doesn't seem necessary 
either -- and with how tight of a memory footprint SPL has to fit into, 
I wanted to check whether this was just something undocumented or dead 
code that needed to be removed. It sounds like it's mostly the latter.

> So where did you see problems? If you would (wrongly) reference
> PortL somewhere in SPL GPIO code, it would use a wrong pointer, but at
> least the code would still compile fine, wouldn't it?

The specific patch I had to apply (to arch/arm/mach-sunxi/board.c) was:
         /* Update PIO power bias configuration by copy hardware 
detected value */
         val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
         writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
-       val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
-       writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
+       if (SUNXI_R_PIO_BASE) {
+               val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
+               writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
+       }

With SUNXI_R_PIO_BASE being 0, this was actually attempting to write to 
BROM. This might also be something that doesn't really upset the 
silicon, though: my debug environment is a concolic emulator I quickly 
hacked up to trace MMIO accesses, and it flagged the write to BROM as an 
error. It was easier to patch the SPL than to have the emulator ignore 
the error (and verify that the T113 was cool with it).

Since this kind of extraneous/erroneous init code tends to remain 
undetected when the symbols they need are dummied-out like this, I 
figured I'd give a nudge in the direction of instead *removing* the 
symbols where appropriate and fixing whatever breaks -- especially since 
we really need to be thrifty about SPL size. But that might also be 
something that happens in a later cleanup pass when the patchset is 
being prepared for upstream inclusion. :)

> P.S. Could you try the github post? Then compiled and booted fine for
> me, and includes the DRAM code as well now:
> https://github.com/apritzel/u-boot/commits/t113s-mq-r-WIP

Ooh, more up-to-date code, thanks for the link! I'll switch to using 
this instead going forward. My pulls from that branch might be 
relatively infrequent since I'm also working on some patches for better 
Clang compatibility concurrent with the efforts here. Is this email 
thread a good venue for feedback against that branch or would you prefer 
that I use GitHub issues instead?

Warm regards,
Sam

P.S. My target is the BMC on the Turing Pi 2 board. They have the same 
SoC and (apparently) UART console configuration, but the differences end 
there: in particular, my target supports boot from either/both 
microSD+SPI-NAND. I might have to start pushing for room for SPI drivers 
in the SPL soon. :)
Andre Przywara May 17, 2023, 12:43 a.m. UTC | #5
On Tue, 16 May 2023 17:53:38 -0600
Sam Edwards <cfsworks@gmail.com> wrote:

Hi Sam,

> On 5/16/23 15:08, Andre Przywara wrote:
> > This whole memory map is somewhat of a legacy. Apart from a few
> > addresses for the SPL needs we shouldn't have those defines at all.
> > Some symbols are needed because there are other macros using them,
> > although these then are eventually unused.
> > I have some patches to remove most of the symbols, and patch 14/17
> > demonstrates some idea how to pin this down to what's really needed.
> > 
> > For this particular case: this was copied from the H6 memory map, some
> > addresses are just plain wrong for the D1 family. I will try to remove
> > them as much as possible, leaving only the ones needed in.  
> 
> I see - the only "tangible" concern I had was the access to 
> prcm->res_cal_ctrl done in
> arch/arm/mach-sunxi/clock_sun50i_h6.c:clock_init_safe
> 
> This doesn't appear to upset the silicon but also doesn't seem necessary 
> either -- and with how tight of a memory footprint SPL has to fit into,

What's the particular concern here? Compared to the A64 we are pretty
cool: it's Thumb2 code and we are at around 27KB, at least with my
toolchain. And I haven't tried, but I am pretty sure the BROM
loads more than 32K, as it does on the H6 and H616 already. The U-Boot
build system and the code already supports this - we rely on this for
the H616 - so we can lift the limit anytime, if really needed.

> I wanted to check whether this was just something undocumented or dead 
> code that needed to be removed. It sounds like it's mostly the latter.

I haven't checked if the vendor boot0 does this. I am pretty sure there
is a PRCM block, it's just regularly not mentioned in the manuals.

> > So where did you see problems? If you would (wrongly) reference
> > PortL somewhere in SPL GPIO code, it would use a wrong pointer, but at
> > least the code would still compile fine, wouldn't it?  
> 
> The specific patch I had to apply (to arch/arm/mach-sunxi/board.c) was:
>          /* Update PIO power bias configuration by copy hardware 
> detected value */
>          val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
>          writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
> -       val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
> -       writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
> +       if (SUNXI_R_PIO_BASE) {
> +               val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
> +               writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
> +       }

Ah, I see, I indeed missed that. We seem to define all symbols anyway,
so we can even lose the #ifdef and use proper if's here.
Will incorporate that in the next drop.

> With SUNXI_R_PIO_BASE being 0, this was actually attempting to write to 
> BROM. This might also be something that doesn't really upset the 
> silicon, though: my debug environment is a concolic emulator I quickly 
> hacked up to trace MMIO accesses, and it flagged the write to BROM as an 
> error. It was easier to patch the SPL than to have the emulator ignore 
> the error (and verify that the T113 was cool with it).

Ah yeah, the Allwinner interconnect is pretty relaxed about those
things: accesses to addresses with no device behind them are usually
ignored (RAZ/WI), where other platform might throw an external abort.
Writes to ROM areas are ignored as well.

> Since this kind of extraneous/erroneous init code tends to remain 
> undetected when the symbols they need are dummied-out like this, I 
> figured I'd give a nudge in the direction of instead *removing* the 
> symbols where appropriate and fixing whatever breaks -- especially since 
> we really need to be thrifty about SPL size. But that might also be 
> something that happens in a later cleanup pass when the patchset is 
> being prepared for upstream inclusion. :)
> 
> > P.S. Could you try the github post? Then compiled and booted fine for
> > me, and includes the DRAM code as well now:
> > https://github.com/apritzel/u-boot/commits/t113s-mq-r-WIP  
> 
> Ooh, more up-to-date code, thanks for the link! I'll switch to using 
> this instead going forward. My pulls from that branch might be 
> relatively infrequent

Don't worry, I won't push to this anymore.

> since I'm also working on some patches for better 
> Clang compatibility concurrent with the efforts here. Is this email 
> thread a good venue for feedback against that branch or would you prefer 
> that I use GitHub issues instead?

Please use this thread here, if you find something still wrong in the
branch. I just pushed it to github since someone asked for a fixed
and complete version, and I didn't have time to prepare a proper post
again.

I will hopefully post a proper version for upstreaming in the next days.


> Warm regards,
> Sam
> 
> P.S. My target is the BMC on the Turing Pi 2 board.

Ah, interesting, didn't know that this is now a BMC - for a
SoC from Allwinner's arch nemesis Rockchip ;-)

> They have the same 
> SoC and (apparently) UART console configuration, but the differences end 
> there: in particular, my target supports boot from either/both 
> microSD+SPI-NAND. I might have to start pushing for room for SPI drivers 
> in the SPL soon. :)

We already have SPI(-NOR) booting support, check
arch/arm/mach-sunxi/spl_spi_sunxi.c. This code is very small, and just
needs to be updated to cover the D1/T113 SPI controller, which is
slightly different. See
https://lore.kernel.org/linux-arm-kernel/20230507150345.1971083-1-bigunclemax@gmail.com/
for the Linux SPI bits.
Regarding SPI-*NAND*: there is
https://patchwork.ozlabs.org/user/todo/uboot/?series=322733
which is supposed to allow loading U-Boot proper from SPI-NAND. I
haven't tested it yet, and wasn't overly happy with the refactoring, but
would appreciate any kind of review or test.

Cheers,
Andre
Andre Przywara May 17, 2023, 8:56 a.m. UTC | #6
On Wed, 17 May 2023 01:43:12 +0100
Andre Przywara <andre.przywara@arm.com> wrote:

+Maksim, as he was interested in the U-Boot series as well and had some
plans for SPI-NOR booting, IIUC.

Cheers,
Andre

> On Tue, 16 May 2023 17:53:38 -0600
> Sam Edwards <cfsworks@gmail.com> wrote:
> 
> Hi Sam,
> 
> > On 5/16/23 15:08, Andre Przywara wrote:  
> > > This whole memory map is somewhat of a legacy. Apart from a few
> > > addresses for the SPL needs we shouldn't have those defines at all.
> > > Some symbols are needed because there are other macros using them,
> > > although these then are eventually unused.
> > > I have some patches to remove most of the symbols, and patch 14/17
> > > demonstrates some idea how to pin this down to what's really needed.
> > > 
> > > For this particular case: this was copied from the H6 memory map, some
> > > addresses are just plain wrong for the D1 family. I will try to remove
> > > them as much as possible, leaving only the ones needed in.    
> > 
> > I see - the only "tangible" concern I had was the access to 
> > prcm->res_cal_ctrl done in
> > arch/arm/mach-sunxi/clock_sun50i_h6.c:clock_init_safe
> > 
> > This doesn't appear to upset the silicon but also doesn't seem necessary 
> > either -- and with how tight of a memory footprint SPL has to fit into,  
> 
> What's the particular concern here? Compared to the A64 we are pretty
> cool: it's Thumb2 code and we are at around 27KB, at least with my
> toolchain. And I haven't tried, but I am pretty sure the BROM
> loads more than 32K, as it does on the H6 and H616 already. The U-Boot
> build system and the code already supports this - we rely on this for
> the H616 - so we can lift the limit anytime, if really needed.
> 
> > I wanted to check whether this was just something undocumented or dead 
> > code that needed to be removed. It sounds like it's mostly the latter.  
> 
> I haven't checked if the vendor boot0 does this. I am pretty sure there
> is a PRCM block, it's just regularly not mentioned in the manuals.
> 
> > > So where did you see problems? If you would (wrongly) reference
> > > PortL somewhere in SPL GPIO code, it would use a wrong pointer, but at
> > > least the code would still compile fine, wouldn't it?    
> > 
> > The specific patch I had to apply (to arch/arm/mach-sunxi/board.c) was:
> >          /* Update PIO power bias configuration by copy hardware 
> > detected value */
> >          val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
> >          writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
> > -       val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
> > -       writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
> > +       if (SUNXI_R_PIO_BASE) {
> > +               val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
> > +               writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
> > +       }  
> 
> Ah, I see, I indeed missed that. We seem to define all symbols anyway,
> so we can even lose the #ifdef and use proper if's here.
> Will incorporate that in the next drop.
> 
> > With SUNXI_R_PIO_BASE being 0, this was actually attempting to write to 
> > BROM. This might also be something that doesn't really upset the 
> > silicon, though: my debug environment is a concolic emulator I quickly 
> > hacked up to trace MMIO accesses, and it flagged the write to BROM as an 
> > error. It was easier to patch the SPL than to have the emulator ignore 
> > the error (and verify that the T113 was cool with it).  
> 
> Ah yeah, the Allwinner interconnect is pretty relaxed about those
> things: accesses to addresses with no device behind them are usually
> ignored (RAZ/WI), where other platform might throw an external abort.
> Writes to ROM areas are ignored as well.
> 
> > Since this kind of extraneous/erroneous init code tends to remain 
> > undetected when the symbols they need are dummied-out like this, I 
> > figured I'd give a nudge in the direction of instead *removing* the 
> > symbols where appropriate and fixing whatever breaks -- especially since 
> > we really need to be thrifty about SPL size. But that might also be 
> > something that happens in a later cleanup pass when the patchset is 
> > being prepared for upstream inclusion. :)
> >   
> > > P.S. Could you try the github post? Then compiled and booted fine for
> > > me, and includes the DRAM code as well now:
> > > https://github.com/apritzel/u-boot/commits/t113s-mq-r-WIP    
> > 
> > Ooh, more up-to-date code, thanks for the link! I'll switch to using 
> > this instead going forward. My pulls from that branch might be 
> > relatively infrequent  
> 
> Don't worry, I won't push to this anymore.
> 
> > since I'm also working on some patches for better 
> > Clang compatibility concurrent with the efforts here. Is this email 
> > thread a good venue for feedback against that branch or would you prefer 
> > that I use GitHub issues instead?  
> 
> Please use this thread here, if you find something still wrong in the
> branch. I just pushed it to github since someone asked for a fixed
> and complete version, and I didn't have time to prepare a proper post
> again.
> 
> I will hopefully post a proper version for upstreaming in the next days.
> 
> 
> > Warm regards,
> > Sam
> > 
> > P.S. My target is the BMC on the Turing Pi 2 board.  
> 
> Ah, interesting, didn't know that this is now a BMC - for a
> SoC from Allwinner's arch nemesis Rockchip ;-)
> 
> > They have the same 
> > SoC and (apparently) UART console configuration, but the differences end 
> > there: in particular, my target supports boot from either/both 
> > microSD+SPI-NAND. I might have to start pushing for room for SPI drivers 
> > in the SPL soon. :)  
> 
> We already have SPI(-NOR) booting support, check
> arch/arm/mach-sunxi/spl_spi_sunxi.c. This code is very small, and just
> needs to be updated to cover the D1/T113 SPI controller, which is
> slightly different. See
> https://lore.kernel.org/linux-arm-kernel/20230507150345.1971083-1-bigunclemax@gmail.com/
> for the Linux SPI bits.
> Regarding SPI-*NAND*: there is
> https://patchwork.ozlabs.org/user/todo/uboot/?series=322733
> which is supposed to allow loading U-Boot proper from SPI-NAND. I
> haven't tested it yet, and wasn't overly happy with the refactoring, but
> would appreciate any kind of review or test.
> 
> Cheers,
> Andre
Maxim Kiselev May 17, 2023, 2:04 p.m. UTC | #7
Hi Sam,

> I might have to start pushing for room for SPI drivers
> in the SPL soon. :)

As Andre already pointed out, I have a patch which adds boot support
from SPI-NOR for D1/T113 SoCs.
Maybe I can share it somewhere to avoid double work?
Maxim Kiselev May 25, 2023, 6:25 p.m. UTC | #8
Hi, Andre

Could you please include this fix for i2c in the next version of this 
series.

diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index 93bbc6916e..d088ea75b9 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -124,7 +124,7 @@ enum mvtwsi_ctrl_register_fields {
   * on other platforms, it is a normal r/w bit, which is cleared by 
writing 0.
   */

-#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
+#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || 
defined(CONFIG_SUNXI_GEN_NCAT2)
  #define        MVTWSI_CONTROL_CLEAR_IFLG       0x00000008
  #else
  #define        MVTWSI_CONTROL_CLEAR_IFLG       0x00000000
Andre Przywara May 26, 2023, 11:05 a.m. UTC | #9
On Thu, 25 May 2023 21:25:57 +0300
Maksim Kiselev <bigunclemax@gmail.com> wrote:

Hi Maksim,

> Could you please include this fix for i2c in the next version of this 
> series.
> 
> diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
> index 93bbc6916e..d088ea75b9 100644
> --- a/drivers/i2c/mvtwsi.c
> +++ b/drivers/i2c/mvtwsi.c
> @@ -124,7 +124,7 @@ enum mvtwsi_ctrl_register_fields {
>    * on other platforms, it is a normal r/w bit, which is cleared by 
> writing 0.
>    */
> 
> -#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
> +#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || 
> defined(CONFIG_SUNXI_GEN_NCAT2)

Ah, thanks for pointing this out, I never really tried I2C, I think.
So those code lines are of course hideous to begin with, but it's a
nightmare to fix this properly (by looking at the DT compatible
string), and we might need it for the SPL anyway, so would need
something like this anyway.
So I will just go ahead and add this to this patch.

Thanks for the report!

Cheers,
Andre

>   #define        MVTWSI_CONTROL_CLEAR_IFLG       0x00000008
>   #else
>   #define        MVTWSI_CONTROL_CLEAR_IFLG       0x00000000
>
Sam Edwards June 3, 2023, 6:03 p.m. UTC | #10
Hi again Andre,

On 12/5/22 17:45, Andre Przywara wrote:
> diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
> index b6ffbff883c..3763ec3d2e4 100644
> --- a/arch/arm/mach-sunxi/board.c
> +++ b/arch/arm/mach-sunxi/board.c
> @@ -177,7 +177,7 @@ static int gpio_init(void)
>   #error Unsupported console port number. Please fix pin mux settings in board.c
>   #endif
>   
> -#ifdef CONFIG_SUN50I_GEN_H6
> +#if defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
>   	/* Update PIO power bias configuration by copy hardware detected value */
>   	val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
>   	writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
> @@ -475,7 +475,7 @@ void reset_cpu(void)
>   		/* sun5i sometimes gets stuck without this */
>   		writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
>   	}
> -#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
> +#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
>   #if defined(CONFIG_MACH_SUN50I_H6)
>   	/* WDOG is broken for some H6 rev. use the R_WDOG instead */
>   	static const struct sunxi_wdog *wdog =

It appears that the R528/T113s updated the watchdog slightly from H6 in 
that it now requires a key (0x16AA << 16) OR'd in all writes to 
WDOG_SOFT_RST_REG, WDOG_CFG_REG, and WDOG_MODE_REG, or it will ignore 
those writes. This reset code busywaits indefinitely unless I add that 
key. It looks like sunxi_wdt.c needs to be updated as well, but I don't 
know if that's in-scope for this patchset.

Cheers,
Sam
diff mbox series

Patch

diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h
index 2cfd5407423..3d34261b0e5 100644
--- a/arch/arm/include/asm/arch-sunxi/clock.h
+++ b/arch/arm/include/asm/arch-sunxi/clock.h
@@ -16,7 +16,7 @@ 
 /* clock control module regs definition */
 #if defined(CONFIG_MACH_SUN8I_A83T)
 #include <asm/arch/clock_sun8i_a83t.h>
-#elif defined(CONFIG_SUN50I_GEN_H6)
+#elif defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
 #include <asm/arch/clock_sun50i_h6.h>
 #elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
       defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUNIV)
diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h
index b08f2023748..768c6572d6b 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu.h
@@ -10,6 +10,8 @@ 
 #include <asm/arch/cpu_sun9i.h>
 #elif defined(CONFIG_SUN50I_GEN_H6)
 #include <asm/arch/cpu_sun50i_h6.h>
+#elif defined(CONFIG_SUNXI_GEN_NCAT2)
+#include <asm/arch/cpu_sunxi_ncat2.h>
 #else
 #include <asm/arch/cpu_sun4i.h>
 #endif
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
new file mode 100644
index 00000000000..13093085a5e
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
@@ -0,0 +1,54 @@ 
+/*
+ * (C) Copyright 2022 Arm Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _SUNXI_CPU_SUNXI_NCAT2_H
+#define _SUNXI_CPU_SUNXI_NCAT2_H
+
+#define SUNXI_SRAM_A1_BASE		CONFIG_SUNXI_SRAM_ADDRESS
+#define SUNXI_SRAM_C_BASE		0x00028000
+#define SUNXI_SRAM_A2_BASE		0x00100000
+
+#define SUNXI_SRAMC_BASE		0x02800000
+#define SUNXI_CCM_BASE			0x02001000
+/* SID address space starts at 0x03006000, but e-fuse is at offset 0x200 */
+#define SUNXI_SIDC_BASE			0x03006000
+#define SUNXI_SID_BASE			0x03006200
+#define SUNXI_TIMER_BASE		0x02050000
+
+#ifdef CONFIG_MACH_SUN50I_H6
+#define SUNXI_DRAM_COM_BASE		0x04002000
+#define SUNXI_DRAM_CTL0_BASE		0x04003000
+#define SUNXI_DRAM_PHY0_BASE		0x04005000
+#endif
+#define SUNXI_MMC0_BASE			0x04020000
+#define SUNXI_MMC1_BASE			0x04021000
+#define SUNXI_MMC2_BASE			0x04022000
+
+#define SUNXI_UART0_BASE		0x02500000
+#define SUNXI_UART1_BASE		0x02500400
+#define SUNXI_UART2_BASE		0x02500800
+#define SUNXI_UART3_BASE		0x02500C00
+#define SUNXI_TWI0_BASE			0x02502000
+#define SUNXI_TWI1_BASE			0x02502400
+#define SUNXI_TWI2_BASE			0x02502800
+#define SUNXI_TWI3_BASE			0x02502C00
+#define SUNXI_SPI0_BASE			0x04025000
+#define SUNXI_SPI1_BASE			0x04026000
+
+#define SUNXI_RTC_BASE			0x07000000
+#define SUNXI_R_CPUCFG_BASE		0x07000400
+#define SUNXI_PRCM_BASE			0x07010000
+#define SUNXI_R_WDOG_BASE		0x07020400
+#define SUNXI_R_UART_BASE		0x07080000
+#define SUNXI_R_TWI_BASE		0x07081400
+
+#ifndef __ASSEMBLY__
+void sunxi_board_init(void);
+void sunxi_reset(void);
+int sunxi_get_sid(unsigned int *sid);
+#endif
+
+#endif /* _SUNXI_CPU_SUNXI_NCAT2_H */
diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
index 5daacf10eb1..8ed3e0459c9 100644
--- a/arch/arm/include/asm/arch-sunxi/mmc.h
+++ b/arch/arm/include/asm/arch-sunxi/mmc.h
@@ -45,7 +45,7 @@  struct sunxi_mmc {
 	u32 chda;		/* 0x90 */
 	u32 cbda;		/* 0x94 */
 	u32 res2[26];
-#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
+#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
 	u32 res3[17];
 	u32 samp_dl;
 	u32 res4[46];
diff --git a/arch/arm/include/asm/arch-sunxi/prcm.h b/arch/arm/include/asm/arch-sunxi/prcm.h
index 5106076f5e9..c5418cfd28d 100644
--- a/arch/arm/include/asm/arch-sunxi/prcm.h
+++ b/arch/arm/include/asm/arch-sunxi/prcm.h
@@ -9,7 +9,7 @@ 
 #define _SUNXI_PRCM_H
 
 /* prcm regs definition */
-#if defined(CONFIG_SUN50I_GEN_H6)
+#if defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
 #include <asm/arch/prcm_sun50i.h>
 #else
 #include <asm/arch/prcm_sun6i.h>
diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h
index bb5626d893b..e17db8588e2 100644
--- a/arch/arm/include/asm/arch-sunxi/timer.h
+++ b/arch/arm/include/asm/arch-sunxi/timer.h
@@ -76,7 +76,7 @@  struct sunxi_timer_reg {
 	struct sunxi_tgp tgp[4];
 	u8 res5[8];
 	u32 cpu_cfg;
-#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
+#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
 	u8 res3[16];
 	struct sunxi_wdog wdog[5];	/* We have 5 watchdogs */
 #endif
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 5e019948f85..b59db212fa8 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -102,7 +102,7 @@  config AXP_PMIC_BUS
 config SUNXI_SRAM_ADDRESS
 	hex
 	default 0x10000 if MACH_SUN9I || MACH_SUN50I || MACH_SUN50I_H5
-	default 0x20000 if SUN50I_GEN_H6
+	default 0x20000 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
 	default 0x0
 	---help---
 	Older Allwinner SoCs have their mask boot ROM mapped just below 4GB,
@@ -144,6 +144,16 @@  config SUN50I_GEN_H6
 	Select this for sunxi SoCs which have H6 like peripherals, clocks
 	and memory map.
 
+config SUNXI_GEN_NCAT2
+	bool
+	select FIT
+	select SPL_LOAD_FIT
+	select MMC_SUNXI_HAS_NEW_MODE
+	select SUPPORT_SPL
+	---help---
+	Select this for sunxi SoCs which have D1 like peripherals, clocks
+	and memory map.
+
 config SUNXI_DRAM_DW
 	bool
 	---help---
@@ -787,6 +797,7 @@  config VIDEO_SUNXI
 	depends on !MACH_SUN9I
 	depends on !MACH_SUN50I
 	depends on !SUN50I_GEN_H6
+	depends on !SUNXI_GEN_NCAT2
 	select VIDEO
 	select DISPLAY
 	imply VIDEO_DT_SIMPLEFB
@@ -1000,6 +1011,7 @@  config SPL_STACK_R_ADDR
 	default 0x2fe00000 if MACH_SUN9I
 	default 0x4fe00000 if MACH_SUN50I
 	default 0x4fe00000 if SUN50I_GEN_H6
+	default 0x4fe00000 if SUNXI_GEN_NCAT2
 
 config SPL_SPI_SUNXI
 	bool "Support for SPI Flash on Allwinner SoCs in SPL"
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
index 671211e9322..1d4c70ec352 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -25,6 +25,7 @@  obj-$(CONFIG_MACH_SUN8I)	+= clock_sun6i.o
 endif
 obj-$(CONFIG_MACH_SUN9I)	+= clock_sun9i.o gtbus_sun9i.o
 obj-$(CONFIG_SUN50I_GEN_H6)	+= clock_sun50i_h6.o
+obj-$(CONFIG_SUNXI_GEN_NCAT2)	+= clock_sun50i_h6.o
 ifndef CONFIG_ARM64
 obj-y	+= timer.o
 endif
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index b6ffbff883c..3763ec3d2e4 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -177,7 +177,7 @@  static int gpio_init(void)
 #error Unsupported console port number. Please fix pin mux settings in board.c
 #endif
 
-#ifdef CONFIG_SUN50I_GEN_H6
+#if defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
 	/* Update PIO power bias configuration by copy hardware detected value */
 	val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
 	writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
@@ -475,7 +475,7 @@  void reset_cpu(void)
 		/* sun5i sometimes gets stuck without this */
 		writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
 	}
-#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
+#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
 #if defined(CONFIG_MACH_SUN50I_H6)
 	/* WDOG is broken for some H6 rev. use the R_WDOG instead */
 	static const struct sunxi_wdog *wdog =
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index fef01bdd7da..fdd64db498f 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -265,7 +265,7 @@  config SPL_TEXT_BASE
 	default 0x402F0400 if AM33XX
 	default 0x40301350 if OMAP54XX
 	default 0x10060 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN9I
-	default 0x20060 if SUN50I_GEN_H6
+	default 0x20060 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
 	default 0x00060 if ARCH_SUNXI
 	default 0xfffc0000 if ARCH_ZYNQMP
 	default 0x0
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index a9132af3f64..6ce2729473c 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -114,6 +114,7 @@  static bool sunxi_mmc_can_calibrate(void)
 	return IS_ENABLED(CONFIG_MACH_SUN50I) ||
 	       IS_ENABLED(CONFIG_MACH_SUN50I_H5) ||
 	       IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
+	       IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2) ||
 	       IS_ENABLED(CONFIG_MACH_SUN8I_R40);
 }
 
@@ -248,7 +249,7 @@  static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc)
 	rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK;
 	writel(rval, &priv->reg->clkcr);
 
-#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
+#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
 	/* A64 supports calibration of delays on MMC controller and we
 	 * have to set delay of zero before starting calibration.
 	 * Allwinner BSP driver sets a delay only in the case of
@@ -559,7 +560,8 @@  struct mmc *sunxi_mmc_init(int sdc_no)
 	cfg->host_caps = MMC_MODE_4BIT;
 
 	if ((IS_ENABLED(CONFIG_MACH_SUN50I) || IS_ENABLED(CONFIG_MACH_SUN8I) ||
-	    IS_ENABLED(CONFIG_SUN50I_GEN_H6)) && (sdc_no == 2))
+	    IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
+	    IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) && (sdc_no == 2))
 		cfg->host_caps = MMC_MODE_8BIT;
 
 	cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
@@ -573,7 +575,7 @@  struct mmc *sunxi_mmc_init(int sdc_no)
 
 	/* config ahb clock */
 	debug("init mmc %d clock and io\n", sdc_no);
-#if !defined(CONFIG_SUN50I_GEN_H6)
+#if !defined(CONFIG_SUN50I_GEN_H6) && !defined(CONFIG_SUNXI_GEN_NCAT2)
 	setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
 
 #ifdef CONFIG_SUNXI_GEN_SUN6I
@@ -647,7 +649,7 @@  static unsigned get_mclk_offset(void)
 	if (IS_ENABLED(CONFIG_MACH_SUN9I_A80))
 		return 0x410;
 
-	if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
+	if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
 		return 0x830;
 
 	return 0x88;
diff --git a/include/sunxi_gpio.h b/include/sunxi_gpio.h
index 2f8b220f750..04d7aa3d632 100644
--- a/include/sunxi_gpio.h
+++ b/include/sunxi_gpio.h
@@ -16,6 +16,9 @@ 
 #elif defined(CONFIG_SUN50I_GEN_H6)
 #define SUNXI_PIO_BASE		0x0300b000
 #define SUNXI_R_PIO_BASE	0x07022000
+#elif defined(CONFIG_SUNXI_GEN_NCAT2)
+#define SUNXI_PIO_BASE		0x02000000
+#define SUNXI_R_PIO_BASE	0
 #else
 #define SUNXI_PIO_BASE		0x01c20800
 #define SUNXI_R_PIO_BASE	0x01f02c00