Re: [PATCH 1/3] xen/char: add classic i.MX UART driver

"Orzel, Michal" <[email protected]>
Newsgroups gmane.comp.emulators.xen.devel
Message-ID <[email protected]>

On 14-Aug-26 18:25, Wig Cheng wrote:
> Add a console driver for the classic i.MX UART IP ("fsl,imx6q-uart"
> compatible), as found on the i.MX6/7/8M families.  Baudrate and pin
You often mention i.MX 6 and 7 but guard the driver on Arm64. Please do not
mention them if you only intend to support/test i.MX 8.

> configuration are inherited from the bootloader; the driver only
> enables the transmitter/receiver and wires up the RX/TX interrupts,
> mirroring the existing imx-lpuart driver.
> 
> This is needed for the i.MX8M family, whose UART IP differs from the
> LPUART used on i.MX8QM/8QXP.
> 
> Signed-off-by: Wig Cheng <[email protected]>
> ---
>  xen/arch/arm/include/asm/imx-uart.h |  62 ++++++++
>  xen/drivers/char/Kconfig            |   8 +
>  xen/drivers/char/Makefile           |   1 +
>  xen/drivers/char/imx-uart.c         | 227 ++++++++++++++++++++++++++++
Please add entry to MAINTAINERS for this file under ARM

>  4 files changed, 298 insertions(+)
>  create mode 100644 xen/arch/arm/include/asm/imx-uart.h
>  create mode 100644 xen/drivers/char/imx-uart.c
> 
> diff --git a/xen/arch/arm/include/asm/imx-uart.h b/xen/arch/arm/include/asm/imx-uart.h
> new file mode 100644
> index 0000000000..ad4b0b06ff
> --- /dev/null
> +++ b/xen/arch/arm/include/asm/imx-uart.h
> @@ -0,0 +1,62 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
Can this be GPL-2.0 only?
> +/*
> + * xen/arch/arm/include/asm/imx-uart.h
This can go stale. Please drop.

> + *
> + * Register definitions for the classic i.MX UART IP
> + * ("fsl,imx6q-uart" compatible, used on i.MX6/7/8M families).
> + *
> + * Register layout taken from Linux drivers/tty/serial/imx.c.
> + *
> + * Copyright 2026 Open-EP (E-Paper) Community
> + */
> +
> +#ifndef __ASM_ARM_IMX_UART_H__
Should be ASM_IMX_UART_H

> +#define __ASM_ARM_IMX_UART_H__
> +
> +#define URXD0           0x00   /* Receiver Register */
> +#define URTX0           0x40   /* Transmitter Register */
> +#define UCR1            0x80   /* Control Register 1 */
> +#define UCR2            0x84   /* Control Register 2 */
> +#define UCR3            0x88   /* Control Register 3 */
Given that this is not a verbatim 1:1 copy from Linux (no need for it to be),
please do not define macros that are unused.

> +#define UCR4            0x8c   /* Control Register 4 */
> +#define UFCR            0x90   /* FIFO Control Register */
> +#define USR1            0x94   /* Status Register 1 */
> +#define USR2            0x98   /* Status Register 2 */
> +#define UTS             0xb4   /* Test Register */
> +
> +#define URXD_CHARRDY    (1U << 15)
Please use BIT(n, U)

> +#define URXD_RX_DATA    0xff
> +
> +#define UCR1_UARTEN     (1U << 0)
> +#define UCR1_RRDYEN     (1U << 9)   /* Receiver ready interrupt enable */
> +#define UCR1_TRDYEN     (1U << 13)  /* Transmitter ready interrupt enable */
> +#define UCR1_RXDMAEN    (1U << 8)
> +#define UCR1_TXDMAEN    (1U << 3)
> +#define UCR1_ATDMAEN    (1U << 2)
> +
> +#define UCR2_SRST       (1U << 0)   /* 0 = issue software reset */
> +#define UCR2_RXEN       (1U << 1)
> +#define UCR2_TXEN       (1U << 2)
> +
> +#define USR1_RRDY       (1U << 9)   /* Receiver ready */
> +#define USR1_TRDY       (1U << 13)  /* Transmitter ready */
> +
> +#define USR2_RDR        (1U << 0)   /* Receive data ready */
> +#define USR2_ORE        (1U << 1)   /* Overrun error */
> +#define USR2_TXDC       (1U << 3)   /* Transmission complete */
> +#define USR2_TXFE       (1U << 14)  /* Transmit FIFO empty */
> +
> +#define UTS_TXFULL      (1U << 4)
> +#define UTS_RXEMPTY     (1U << 5)
> +#define UTS_TXEMPTY     (1U << 6)
> +
> +#endif /* __ASM_ARM_IMX_UART_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/drivers/char/Kconfig b/xen/drivers/char/Kconfig
> index 8e49a52c73..f237c0220d 100644
> --- a/xen/drivers/char/Kconfig
> +++ b/xen/drivers/char/Kconfig
> @@ -30,6 +30,14 @@ config HAS_IMX_LPUART
>  	help
>  	  This selects the i.MX LPUART. If you have i.MX8QM based board, say Y.
>  
> +config HAS_IMX_UART
> +	bool "i.MX UART driver"
> +	default y
> +	depends on ARM_64
> +	help
> +	  This selects the classic i.MX UART. If you have an i.MX8M family
> +	  based board, say Y.
> +
>  config HAS_MVEBU
>  	bool "Marvell MVEBU UART driver"
>  	default y
> diff --git a/xen/drivers/char/Makefile b/xen/drivers/char/Makefile
> index 8cbbffdca8..039f566926 100644
> --- a/xen/drivers/char/Makefile
> +++ b/xen/drivers/char/Makefile
> @@ -10,6 +10,7 @@ obj-$(CONFIG_HAS_SCIF) += scif-uart.o
>  obj-$(CONFIG_HAS_EHCI) += ehci-dbgp.o
>  obj-$(CONFIG_XHCI) += xhci-dbc.o
>  obj-$(CONFIG_HAS_IMX_LPUART) += imx-lpuart.o
> +obj-$(CONFIG_HAS_IMX_UART) += imx-uart.o
>  obj-$(CONFIG_HAS_LINFLEX) += linflex-uart.o
>  obj-$(CONFIG_GENERIC_UART_INIT) += uart-init.o
>  obj-y += serial.o
> diff --git a/xen/drivers/char/imx-uart.c b/xen/drivers/char/imx-uart.c
> new file mode 100644
> index 0000000000..5ae8c13c40
> --- /dev/null
> +++ b/xen/drivers/char/imx-uart.c
> @@ -0,0 +1,227 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * xen/drivers/char/imx-uart.c
This can go stale. Please drop.

> + *
> + * Driver for the classic i.MX UART IP ("fsl,imx6q-uart"), as found on
> + * the i.MX6/7/8M families (e.g. i.MX8MP).
> + *
> + * Baudrate and pin configuration are inherited from the bootloader.
> + *
> + * Copyright 2026 Open-EP (E-Paper) Community
> + */
> +
> +#include <xen/errno.h>
> +#include <xen/init.h>
> +#include <xen/irq.h>
> +#include <xen/mm.h>
> +#include <xen/serial.h>
> +#include <asm/device.h>
> +#include <asm/imx-uart.h>
> +#include <asm/io.h>
> +
> +#define imx_uart_read(uart, off)       readl((uart)->regs + (off))
> +#define imx_uart_write(uart, off, val) writel((val), (uart)->regs + (off))
> +
> +static struct imx_uart {
> +    uint32_t irq;
> +    char __iomem *regs;
> +    struct irqaction irqaction;
> +    struct vuart_info vuart;
> +} imx8m_com;
> +
> +static void imx_uart_interrupt(int irq, void *data)
> +{
> +    struct serial_port *port = data;
> +    struct imx_uart *uart = port->uart;
> +
> +    if ( imx_uart_read(uart, USR2) & USR2_RDR )
> +        serial_rx_interrupt(port);
> +
> +    if ( imx_uart_read(uart, USR1) & USR1_TRDY )
> +        serial_tx_interrupt(port);
> +}
> +
> +static void __init imx_uart_init_preirq(struct serial_port *port)
> +{
> +    struct imx_uart *uart = port->uart;
> +    uint32_t ucr1, ucr2;
> +
> +    /*
> +     * Reuse the bootloader baudrate/format settings: only make sure the
> +     * UART and both directions are enabled, DMA and interrupts are off.
> +     */
> +    ucr1 = imx_uart_read(uart, UCR1);
> +    ucr1 &= ~(UCR1_RRDYEN | UCR1_TRDYEN | UCR1_RXDMAEN | UCR1_TXDMAEN |
> +              UCR1_ATDMAEN);
What about TXMPTYEN?

> +    ucr1 |= UCR1_UARTEN;
> +    imx_uart_write(uart, UCR1, ucr1);
Only UCR1's enables are cleared, while other UCRs interrupt enables keep
whatever the bootloader left. Either mention UCR1 only or clear others too.

~Michal
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.