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
> >   

Reply via email to