From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Marvin Wewer Date: Thu, 23 Oct 2025 13:30:29 +0000 Subject: spi: sunxi: Add support for Allwinner A523 SPI controllers Signed-off-by: Marvin Wewer --- drivers/spi/spi-sunxi.c | 44 ++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/spi/spi-sunxi.c b/drivers/spi/spi-sunxi.c index 111111111111..222222222222 100644 --- a/drivers/spi/spi-sunxi.c +++ b/drivers/spi/spi-sunxi.c @@ -82,10 +82,12 @@ DECLARE_GLOBAL_DATA_PTR; #endif #define SUN4I_SPI_MIN_RATE 3000 #define SUN4I_SPI_DEFAULT_RATE 1000000 #define SUN4I_SPI_TIMEOUT_MS 1000 +#define SUN55I_BUF_STA_REG 0x400 + #define SPI_REG(priv, reg) ((priv)->base + \ (priv)->variant->regs[reg]) #define SPI_BIT(priv, bit) ((priv)->variant->bits[bit]) #define SPI_CS(priv, cs) (((cs) << SPI_BIT(priv, SPI_TCR_CS_SEL)) & \ SPI_BIT(priv, SPI_TCR_CS_MASK)) @@ -128,10 +130,11 @@ struct sun4i_spi_variant { const u32 *bits; u32 fifo_depth; bool has_soft_reset; bool has_burst_ctl; bool has_clk_ctl; + bool has_bsr; }; struct sun4i_spi_plat { struct sun4i_spi_variant *variant; u32 base; @@ -364,10 +367,25 @@ static int sun4i_spi_xfer(struct udevice *dev, unsigned int bitlen, /* Reset FIFOs */ setbits_le32(SPI_REG(priv, SPI_FCR), SPI_BIT(priv, SPI_FCR_RF_RST) | SPI_BIT(priv, SPI_FCR_TF_RST)); + if (priv->variant->has_bsr) { + u32 reg; + int ret; + + ret = readl_poll_timeout(SPI_REG(priv, SPI_FCR), reg, + !(reg & (SPI_BIT(priv, SPI_FCR_RF_RST) | + SPI_BIT(priv, SPI_FCR_TF_RST))), + SUN4I_SPI_TIMEOUT_MS * 1000); + if (ret) { + printf("ERROR: sun4i_spi: FIFO reset timeout\n"); + sun4i_spi_set_cs(bus, slave_plat->cs[0], false); + return ret; + } + } + while (len) { /* Setup the transfer now... */ nbytes = min(len, (priv->variant->fifo_depth - 1)); /* Setup the counters */ @@ -517,10 +535,23 @@ static const unsigned long sun6i_spi_regs[] = { [SPI_BCTL] = SUN6I_BURST_CTL_REG, [SPI_TXD] = SUN6I_TXDATA_REG, [SPI_RXD] = SUN6I_RXDATA_REG, }; +static const unsigned long sun55i_spi_regs[] = { + [SPI_GCR] = SUN6I_GBL_CTL_REG, + [SPI_TCR] = SUN6I_TFR_CTL_REG, + [SPI_FCR] = SUN6I_FIFO_CTL_REG, + [SPI_FSR] = SUN55I_BUF_STA_REG, + [SPI_CCR] = SUN6I_CLK_CTL_REG, + [SPI_BC] = SUN6I_BURST_CNT_REG, + [SPI_TC] = SUN6I_XMIT_CNT_REG, + [SPI_BCTL] = SUN6I_BURST_CTL_REG, + [SPI_TXD] = SUN6I_TXDATA_REG, + [SPI_RXD] = SUN6I_RXDATA_REG, +}; + static const u32 sun6i_spi_bits[] = { [SPI_GCR_TP] = BIT(7), [SPI_GCR_SRST] = BIT(31), [SPI_TCR_CPHA] = BIT(0), [SPI_TCR_CPOL] = BIT(1), @@ -568,10 +599,19 @@ static const struct sun4i_spi_variant sun50i_r329_spi_variant = { .fifo_depth = 64, .has_soft_reset = true, .has_burst_ctl = true, }; +static const struct sun4i_spi_variant sun55i_a523_spi_variant = { + .regs = sun55i_spi_regs, + .bits = sun6i_spi_bits, + .fifo_depth = 64, + .has_soft_reset = true, + .has_burst_ctl = true, + .has_bsr = true, +}; + static const struct udevice_id sun4i_spi_ids[] = { { .compatible = "allwinner,sun4i-a10-spi", .data = (ulong)&sun4i_a10_spi_variant, }, @@ -585,10 +625,14 @@ static const struct udevice_id sun4i_spi_ids[] = { }, { .compatible = "allwinner,sun50i-r329-spi", .data = (ulong)&sun50i_r329_spi_variant, }, + { + .compatible = "allwinner,sun55i-a523-spi", + .data = (ulong)&sun55i_a523_spi_variant, + }, { /* sentinel */ } }; U_BOOT_DRIVER(sun4i_spi) = { .name = "sun4i_spi", -- Armbian