Re: [PATCH RFC 4/9] serial: serial_meson: add minimal non-DM driver

"Ferass El Hafidi" <[email protected]> Mon, 08 Sep 2025 18:04:41 +0000
Newsgroups io.groups.u-boot-amlogic
Message-ID <[email protected]>
On Mon Sep 8, 2025 at 8:11 AM UTC, Neil Armstrong via groups.io wrote:
> On 07/09/2025 16:36, Ferass El Hafidi wrote:
>> It is very limited and minimal, only implements putc/puts.
>> This minimal driver is intended to be used in SPL, and other
>> size-constrained situations.
>> 
>> Signed-off-by: Ferass El Hafidi <[email protected]>
>> ---
>>   drivers/serial/serial.c       |   2 +
>>   drivers/serial/serial_meson.c | 112 +++++++++++++++++++++++++++++++++++++++++-
>>   2 files changed, 113 insertions(+), 1 deletion(-)
>> 
>> diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
>> index e10ca6eef768502ea32bf39a41ae2e3ccd168c66..c0b1eb3056181b95e1861f1ce08fcd82ff81eb71 100644
>> --- a/drivers/serial/serial.c
>> +++ b/drivers/serial/serial.c
>> @@ -129,6 +129,7 @@ serial_initfunc(pxa_serial_initialize);
>>   serial_initfunc(smh_serial_initialize);
>>   serial_initfunc(sh_serial_initialize);
>>   serial_initfunc(mtk_serial_initialize);
>> +serial_initfunc(meson_serial_initialize);
>>   
>>   /**
>>    * serial_register() - Register serial driver with serial driver core
>> @@ -167,6 +168,7 @@ int serial_initialize(void)
>>   	smh_serial_initialize();
>>   	sh_serial_initialize();
>>   	mtk_serial_initialize();
>> +	meson_serial_initialize();
>>   
>>   	serial_assign(default_serial_console()->name);
>>   
>> diff --git a/drivers/serial/serial_meson.c b/drivers/serial/serial_meson.c
>> index bb79b9729579a661084425d6b3c5357da31dc3c0..981ea5e159062b7d13885325e17b833145281158 100644
>> --- a/drivers/serial/serial_meson.c
>> +++ b/drivers/serial/serial_meson.c
>> @@ -3,9 +3,11 @@
>>    * (C) Copyright 2016 Beniamino Galvani <[email protected]>
>>    */
>>   
>> +#if CONFIG_IS_ENABLED(DM_SERIAL)
>>   #include <dm.h>
>> -#include <errno.h>
>>   #include <fdtdec.h>
>> +#endif
>> +#include <errno.h>
>>   #include <linux/kernel.h>
>>   #include <linux/bitops.h>
>>   #include <linux/compiler.h>
>> @@ -51,6 +53,7 @@ struct meson_serial_plat {
>>   #define AML_UART_REG5_USE_NEW_BAUD	BIT(23) /* default 1 (use new baud rate register) */
>>   #define AML_UART_REG5_BAUD_MASK		0x7fffff
>>   
>> +#if CONFIG_IS_ENABLED(DM_SERIAL)
>>   static u32 meson_calc_baud_divisor(ulong src_rate, u32 baud)
>>   {
>>   	/*
>> @@ -245,6 +248,113 @@ U_BOOT_DRIVER(serial_meson) = {
>>   	.plat_auto	= sizeof(struct meson_serial_plat),
>>   };
>>   
>> +DM_DRIVER_ALIAS(serial_meson, amlogic_meson_gx_uart);
>
> Why is this needed ?
>

Hmm, probably leftover from some other thing I was trying to do.  I'll
remove that for the next revision.

>> +
>> +#else
>> +
>> +static int meson_serial_init(void)
>> +{
>> +	struct meson_uart *const uart = (struct meson_uart *)CONFIG_VAL(DEBUG_UART_BASE);
>> +	u32 val;
>> +
>> +	val = readl(&uart->control);
>> +	val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
>> +	writel(val, &uart->control);
>> +	val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
>> +	writel(val, &uart->control);
>> +	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>> +	writel(val, &uart->control);
>> +
>> +	return 0;
>> +}
>> +
>> +static int meson_serial_stop(void)
>> +{
>> +	return 0;
>> +}
>> +
>> +static void meson_serial_setbrg(void)
>> +{
>> +}
>> +
>> +static void meson_serial_putc(const char ch)
>> +{
>> +	struct meson_uart *uart = (struct meson_uart *)CONFIG_VAL(DEBUG_UART_BASE);
>> +
>> +	/* On '\n' also do '\r' */
>> +	if (ch == '\n')
>> +		meson_serial_putc('\r');
>> +
>> +	while (readl(&uart->status) & AML_UART_TX_FULL)
>> +		;
>> +
>> +	writel(ch, &uart->wfifo);
>> +}
>> +
>> +static void meson_serial_puts(const char *s)
>> +{
>> +	while (*s)
>> +		meson_serial_putc(*s++);
>> +}
>> +
>> +static int meson_serial_getc(void)
>> +{
>> +	struct meson_uart *const uart = (struct meson_uart *)CONFIG_VAL(DEBUG_UART_BASE);
>> +	uint32_t status = readl(&uart->status);
>> +
>> +	if (status & AML_UART_RX_EMPTY)
>> +		return -EAGAIN;
>> +
>> +	if (status & AML_UART_ERR) {
>> +		u32 val = readl(&uart->control);
>> +
>> +		/* Clear error */
>> +		val |= AML_UART_CLR_ERR;
>> +		writel(val, &uart->control);
>> +		val &= ~AML_UART_CLR_ERR;
>> +		writel(val, &uart->control);
>> +
>> +		/* Remove spurious byte from fifo */
>> +		readl(&uart->rfifo);
>> +		return -EIO;
>> +	}
>> +
>> +	return readl(&uart->rfifo) & 0xff;
>> +}
>> +
>> +static int meson_serial_tstc(void)
>> +{
>> +	struct meson_uart *const uart = (struct meson_uart *)CONFIG_VAL(DEBUG_UART_BASE);
>> +	uint32_t status = readl(&uart->status);
>> +
>> +	if (status & AML_UART_RX_EMPTY)
>> +		return 0;
>> +	return 1;
>> +}
>> +
>> +struct serial_device meson_serial_device = {
>> +	.name	= "meson_serial",
>> +	.start	= meson_serial_init,
>> +	.stop	= meson_serial_stop,
>> +	.setbrg	= meson_serial_setbrg,
>> +	.getc	= meson_serial_getc,
>> +	.tstc	= meson_serial_tstc,
>> +	.putc	= meson_serial_putc,
>> +	.puts	= meson_serial_puts,
>> +};
>> +
>> +void meson_serial_initialize(void)
>> +{
>> +	serial_register(&meson_serial_device);
>> +}
>> +
>> +__weak struct serial_device *default_serial_console(void)
>> +{
>> +	return &meson_serial_device;
>> +}
>> +
>> +#endif
>> +
>>   #ifdef CONFIG_DEBUG_UART_MESON
>>   
>>   #include <debug_uart.h>
>> 
>
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Groups.io Links: You receive all messages sent to this group.
> View/Reply Online (#2754): https://groups.io/g/u-boot-amlogic/message/2754
> Mute This Topic: https://groups.io/mt/115113901/8399868
> Group Owner: [email protected]
> Unsubscribe: https://groups.io/g/u-boot-amlogic/unsub [[email protected]]
> -=-=-=-=-=-=-=-=-=-=-=-