Re: [PATCH v6 7/8] serial: 8250_dw: discover Allwinner A523 FIFO depths through FCC

From: Andy Shevchenko

Date: Tue Nov 03 2026 - 07:28:28 EST


On Mon, Nov 02, 2026 at 12:55:22PM -0700, James Hilliard wrote:
> The A523 UART integration, also used by A527 and T527, has 64-byte FIFOs
> on UART0 and 128-byte FIFOs on UART1 through UART7. Each controller reports
> its TX/RX FIFO depth in bits 31:8 of the FIFO Clock Control register at
> offset 0xf0. The field holds a byte count, not a logarithmic encoding.
>
> Read this field in the sunxi setup callback when platform data does not
> provide a fixed FIFO size. A fixed size takes precedence, so H616 retains
> its 256-byte configuration without accessing FCC. The probe has already
> enabled the clocks and deasserted reset before invoking the callback.
> Leave the FIFO clock-control bits untouched.
>
> Validate the depth before generating the RX trigger table or setting the
> transmit load. The quarter-full threshold must be positive and the
> FIFO-depth-minus-two threshold must fit in the byte-sized table and RX
> trigger API. Report an invalid depth and fail probe instead of generating
> zero or truncated thresholds. This bound follows the current 8250
> table and callback types, not a hardware FIFO-capacity limit; support
> for larger thresholds would require widening that interface.
>
> Select this setup for the A523 compatible. Derive the transmit load and
> RX threshold table from the discovered depth using the common sunxi
> helpers. This handles the different FIFO sizes with one compatible and
> one receive-trigger mapping.
>
> Like H616, this integration has Allwinner-specific debug-divisor and
> RS485 registers overlapping the generic DesignWare feature probes. Use
> the common sunxi PIO setup, BUSY-safe integer divisor programming and
> software RS485 handling. Keep the APB clock gate enabled during termios
> updates with SKIP_SET_RATE.

...

> struct dw8250_platform_data {
> u8 usr_reg;
> u32 cpr_value;
> + /* Fixed FIFO depth; zero selects discovery during setup */

But make the code clearer in this sense.

> unsigned int fifo_size;
> unsigned int quirks;

I'm wondering if we can encode the FIFO size (as power-of-2) into quirks,
but this might be harder to follow in the code.

> int (*setup)(struct uart_port *p);

> p->fifosize = data->pdata->fifo_size;
> + if (!p->fifosize) {
> + u32 fcc = dw8250_readl_ext(p, SUNXI_UART_FCC);
> +
> + p->fifosize = FIELD_GET(SUNXI_UART_FCC_FIFO_DEPTH, fcc);
> + }

if (data->pdata->fifo_size) {
p->fifosize = data->pdata->fifo_size;
} else {
u32 fcc = dw8250_readl_ext(p, SUNXI_UART_FCC);

p->fifosize = FIELD_GET(SUNXI_UART_FCC_FIFO_DEPTH, fcc);
}

> + /*
> + * The byte-sized 8250 RX trigger interface requires positive,
> + * representable thresholds. Larger thresholds require widening it.
> + */
> + if (p->fifosize < SUNXI_UART_RXTRIG_QUARTER_DIV ||
> + p->fifosize - SUNXI_UART_RXTRIG_FULL_MARGIN > U8_MAX)
> + return dev_err_probe(p->dev, -EINVAL,
> + "invalid FIFO size %u\n", p->fifosize);
> +
> up->capabilities = UART_CAP_FIFO | UART_CAP_NOTEMT | UART_CAP_AFE;

--
With Best Regards,
Andy Shevchenko