On Thu, 11 Apr 2024 14:31:02 +1000 John Watts <cont...@jookia.org> wrote:
Hi, > 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> Thanks for that. I considered this patch already for the last cycle, but dropped it last minute, since I had some doubts and couldn't test it. I will have a look again. Cheers, Andre > 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 > >