Hi there, I've been using my own independent implementation of this patch but today I gave this one a test in my tree and found out it works.
The code looks fine in comparison, so here's a Tested-by and a Reviewed-by. John. Tested-by: John Watts <cont...@jookia.org> Reviewed-by: John Watts <cont...@jookia.org> On Sat, Nov 11, 2023 at 04:33:07PM +0300, Maksim Kiselev wrote: > R528/T113 SoCs uses the same SPI IP as the H6, also have the same clocks > and reset bits layout, but the CCU base is different. Another difference > is that the new SoCs do not have a clock divider inside. Instead of this > we should configure sample mode depending on input clock rate. > > The pin assignment is also different: the H6 uses PC0, the R528/T113 PC4 > instead. This makes for a change in spi0_pinmux_setup() routine. > > This patch extends the H6/H616 #ifdef guards to also cover the R528/T113, > using the shared CONFIG_SUNXI_GEN_NCAT2 and CONFIG_MACH_SUN8I_R528 > symbols. Also use CONFIG_SUNXI_GEN_NCAT2 symbol for the Kconfig > dependency. > > Signed-off-by: Maksim Kiselev <biguncle...@gmail.com> > Tested-by: Sam Edwards <cfswo...@gmail.com> > --- > arch/arm/mach-sunxi/Kconfig | 2 +- > arch/arm/mach-sunxi/spl_spi_sunxi.c | 78 +++++++++++++++++++++-------- > 2 files changed, 58 insertions(+), 22 deletions(-) > > diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig > index a10e4c06b6..732f60821a 100644 > --- a/arch/arm/mach-sunxi/Kconfig > +++ b/arch/arm/mach-sunxi/Kconfig > @@ -1044,7 +1044,7 @@ config SPL_STACK_R_ADDR > > config SPL_SPI_SUNXI > bool "Support for SPI Flash on Allwinner SoCs in SPL" > - depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 > || MACH_SUN50I || MACH_SUN8I_R40 || SUN50I_GEN_H6 || MACH_SUNIV > + depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 > || MACH_SUN50I || MACH_SUN8I_R40 || SUN50I_GEN_H6 || MACH_SUNIV || > SUNXI_GEN_NCAT2 > help > Enable support for SPI Flash. This option allows SPL to read from > sunxi SPI Flash. It uses the same method as the boot ROM, so does > diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c > b/arch/arm/mach-sunxi/spl_spi_sunxi.c > index c2410dd7bb..ba3b1579f0 100644 > --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c > +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c > @@ -73,18 +73,27 @@ > #define SUN6I_CTL_ENABLE BIT(0) > #define SUN6I_CTL_MASTER BIT(1) > #define SUN6I_CTL_SRST BIT(31) > +#define SUN6I_TCR_SDM BIT(13) > #define SUN6I_TCR_XCH BIT(31) > > > /*****************************************************************************/ > > -#define CCM_AHB_GATING0 (0x01C20000 + 0x60) > -#define CCM_H6_SPI_BGR_REG (0x03001000 + 0x96c) > -#ifdef CONFIG_SUN50I_GEN_H6 > -#define CCM_SPI0_CLK (0x03001000 + 0x940) > +#if IS_ENABLED(CONFIG_SUN50I_GEN_H6) > +#define CCM_BASE 0x03001000 > +#elif IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2) > +#define CCM_BASE 0x02001000 > #else > -#define CCM_SPI0_CLK (0x01C20000 + 0xA0) > +#define CCM_BASE 0x01C20000 > #endif > -#define SUN6I_BUS_SOFT_RST_REG0 (0x01C20000 + 0x2C0) > + > +#define CCM_AHB_GATING0 (CCM_BASE + 0x60) > +#define CCM_H6_SPI_BGR_REG (CCM_BASE + 0x96c) > +#if IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2) > +#define CCM_SPI0_CLK (CCM_BASE + 0x940) > +#else > +#define CCM_SPI0_CLK (CCM_BASE + 0xA0) > +#endif > +#define SUN6I_BUS_SOFT_RST_REG0 (CCM_BASE + 0x2C0) > > #define AHB_RESET_SPI0_SHIFT 20 > #define AHB_GATE_OFFSET_SPI0 20 > @@ -102,17 +111,22 @@ > */ > static void spi0_pinmux_setup(unsigned int pin_function) > { > - /* All chips use PC0 and PC2. */ > - sunxi_gpio_set_cfgpin(SUNXI_GPC(0), pin_function); > + /* All chips use PC2. And all chips use PC0, except R528/T113 */ > + if (!IS_ENABLED(CONFIG_MACH_SUN8I_R528)) > + sunxi_gpio_set_cfgpin(SUNXI_GPC(0), pin_function); > + > sunxi_gpio_set_cfgpin(SUNXI_GPC(2), pin_function); > > - /* All chips except H6 and H616 use PC1. */ > - if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6)) > + /* All chips except H6/H616/R528/T113 use PC1. */ > + if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) && > + !IS_ENABLED(CONFIG_MACH_SUN8I_R528)) > sunxi_gpio_set_cfgpin(SUNXI_GPC(1), pin_function); > > - if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) > + if (IS_ENABLED(CONFIG_MACH_SUN50I_H6) || > + IS_ENABLED(CONFIG_MACH_SUN8I_R528)) > sunxi_gpio_set_cfgpin(SUNXI_GPC(5), pin_function); > - if (IS_ENABLED(CONFIG_MACH_SUN50I_H616)) > + if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) || > + IS_ENABLED(CONFIG_MACH_SUN8I_R528)) > sunxi_gpio_set_cfgpin(SUNXI_GPC(4), pin_function); > > /* Older generations use PC23 for CS, newer ones use PC3. */ > @@ -126,7 +140,8 @@ static void spi0_pinmux_setup(unsigned int pin_function) > static bool is_sun6i_gen_spi(void) > { > return IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I) || > - IS_ENABLED(CONFIG_SUN50I_GEN_H6); > + IS_ENABLED(CONFIG_SUN50I_GEN_H6) || > + IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2); > } > > static uintptr_t spi0_base_address(void) > @@ -137,6 +152,9 @@ static uintptr_t spi0_base_address(void) > if (IS_ENABLED(CONFIG_SUN50I_GEN_H6)) > return 0x05010000; > > + if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) > + return 0x04025000; > + > if (!is_sun6i_gen_spi() || > IS_ENABLED(CONFIG_MACH_SUNIV)) > return 0x01C05000; > @@ -152,23 +170,30 @@ static void spi0_enable_clock(void) > uintptr_t base = spi0_base_address(); > > /* Deassert SPI0 reset on SUN6I */ > - if (IS_ENABLED(CONFIG_SUN50I_GEN_H6)) > + if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || > + IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) > setbits_le32(CCM_H6_SPI_BGR_REG, (1U << 16) | 0x1); > else if (is_sun6i_gen_spi()) > setbits_le32(SUN6I_BUS_SOFT_RST_REG0, > (1 << AHB_RESET_SPI0_SHIFT)); > > /* Open the SPI0 gate */ > - if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6)) > + if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) && > + !IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) > setbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0)); > > if (IS_ENABLED(CONFIG_MACH_SUNIV)) { > /* Divide by 32, clock source is AHB clock 200MHz */ > writel(SPI0_CLK_DIV_BY_32, base + SUN6I_SPI0_CCTL); > } else { > - /* Divide by 4 */ > - writel(SPI0_CLK_DIV_BY_4, base + (is_sun6i_gen_spi() ? > - SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL)); > + /* New SoCs do not have a clock divider inside */ > + if (!IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) { > + /* Divide by 4 */ > + writel(SPI0_CLK_DIV_BY_4, > + base + (is_sun6i_gen_spi() ? SUN6I_SPI0_CCTL : > + SUN4I_SPI0_CCTL)); > + } > + > /* 24MHz from OSC24M */ > writel((1 << 31), CCM_SPI0_CLK); > } > @@ -180,6 +205,14 @@ static void spi0_enable_clock(void) > /* Wait for completion */ > while (readl(base + SUN6I_SPI0_GCR) & SUN6I_CTL_SRST) > ; > + > + /* > + * For new SoCs we should configure sample mode depending on > + * input clock. As 24MHz from OSC24M is used, we could use > + * normal sample mode by setting SDM bit in the TCR register > + */ > + if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) > + setbits_le32(base + SUN6I_SPI0_TCR, SUN6I_TCR_SDM); > } else { > /* Enable SPI in the master mode and reset FIFO */ > setbits_le32(base + SUN4I_SPI0_CTL, SUN4I_CTL_MASTER | > @@ -206,11 +239,13 @@ static void spi0_disable_clock(void) > writel(0, CCM_SPI0_CLK); > > /* Close the SPI0 gate */ > - if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6)) > + if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) && > + !IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) > clrbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0)); > > /* Assert SPI0 reset on SUN6I */ > - if (IS_ENABLED(CONFIG_SUN50I_GEN_H6)) > + if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || > + IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) > clrbits_le32(CCM_H6_SPI_BGR_REG, (1U << 16) | 0x1); > else if (is_sun6i_gen_spi()) > clrbits_le32(SUN6I_BUS_SOFT_RST_REG0, > @@ -224,7 +259,8 @@ static void spi0_init(void) > if (IS_ENABLED(CONFIG_MACH_SUN50I) || > IS_ENABLED(CONFIG_SUN50I_GEN_H6)) > pin_function = SUN50I_GPC_SPI0; > - else if (IS_ENABLED(CONFIG_MACH_SUNIV)) > + else if (IS_ENABLED(CONFIG_MACH_SUNIV) || > + IS_ENABLED(CONFIG_MACH_SUN8I_R528)) > pin_function = SUNIV_GPC_SPI0; > > spi0_pinmux_setup(pin_function); > -- > 2.40.1 >