[U-Boot] [PATCH v1 05/18] drivers: serial: add driver for Microchip PIC32 UART controller.
Purna Chandra Mandal
purna.mandal at microchip.com
Thu Dec 17 19:30:56 CET 2015
On 12/17/2015 11:22 PM, Marek Vasut wrote:
> On Thursday, December 17, 2015 at 06:29:32 PM, Purna Chandra Mandal wrote:
>
> Hi!
>
> Minor nits below.
>
> btw do we expect MIPS to become maintained in U-Boot? That's nice :)
>
> [...]
>
>> diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
>> index dd87147..57cd38b 100644
>> --- a/drivers/serial/Makefile
>> +++ b/drivers/serial/Makefile
>> @@ -41,6 +41,7 @@ obj-$(CONFIG_MXS_AUART) += mxs_auart.o
>> obj-$(CONFIG_ARC_SERIAL) += serial_arc.o
>> obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o
>> obj-$(CONFIG_STM32_SERIAL) += serial_stm32.o
>> +obj-$(CONFIG_PIC32_SERIAL) += serial_pic32.o
>>
>> ifndef CONFIG_SPL_BUILD
>> obj-$(CONFIG_USB_TTY) += usbtty.o
>> diff --git a/drivers/serial/serial_pic32.c b/drivers/serial/serial_pic32.c
>> new file mode 100644
>> index 0000000..01c62e7
>> --- /dev/null
>> +++ b/drivers/serial/serial_pic32.c
>> @@ -0,0 +1,220 @@
>> +/*
>> + * (c) 2015 Paul Thacker <paul.thacker at microchip.com>
>> + *
>> + * SPDX-License-Identifier: GPL-2.0+
>> + *
>> + */
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <clk.h>
>> +#include <errno.h>
>> +#include <config.h>
>> +#include <serial.h>
>> +#include <linux/bitops.h>
>> +#include <common.h>
>> +#include <asm/io.h>
>> +#include <asm/arch-pic32/pic32.h>
>> +#include <asm/arch-pic32/clock.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +#define UART_ENABLE BIT(15)
>> +#define UART_ENABLE_RX BIT(12)
>> +#define UART_ENABLE_TX BIT(10)
>> +#define UART_RX_DATA_AVAIL BIT(0)
>> +#define UART_RX_OERR BIT(1)
>> +#define UART_TX_FULL BIT(9)
>> +
>> +/* UART Control */
>> +#define U_BASE(x) (x)
>> +#define U_MODE(x) U_BASE(x)
>> +#define U_MODECLR(x) (U_MODE(x) + _CLR_OFFSET)
>> +#define U_MODESET(x) (U_MODE(x) + _SET_OFFSET)
>> +#define U_STA(x) (U_BASE(x) + 0x10)
>> +#define U_STACLR(x) (U_STA(x) + _CLR_OFFSET)
>> +#define U_STASET(x) (U_STA(x) + _SET_OFFSET)
>> +#define U_TXREG(x) (U_BASE(x) + 0x20)
>> +#define U_RXREG(x) (U_BASE(x) + 0x30)
>> +#define U_BRG(x) (U_BASE(x) + 0x40)
> Why don't you just use uart_priv->regs + PIC32_REGISTER_OFFSET in the code?
> The U_BASE is redundant and so is UMODE.
ack. Will update.
>> +struct pic32_uart_priv {
>> + void __iomem *regs;
>> + ulong uartclk;
>> +};
>> +
>> +static void pic32_serial_setbrg(void __iomem *regs, ulong uart_clk, u32
>> baud) +{
>> + writel(0, U_BRG(regs));
>> + writel((uart_clk / baud / 16) - 1, U_BRG(regs));
>> + udelay(100);
>> +}
>> +
>> +/*
>> + * Initialize the serial port with the given baudrate.
>> + * The settings are always 8 data bits, no parity, 1 stop bit, no start
>> bits. + */
>> +static int pic32_serial_init(void __iomem *regs, ulong clk, u32 baudrate)
>> +{
>> + /* disable and clear mode */
>> + writel(0, U_MODE(regs));
>> + writel(0, U_STA(regs));
>> +
>> + /* set baud rate generator */
>> + pic32_serial_setbrg(regs, clk, baudrate);
>> +
>> + /* enable the UART for TX and RX */
>> + writel(UART_ENABLE_TX | UART_ENABLE_RX, U_STASET(regs));
>> +
>> + /* enable the UART */
>> + writel(UART_ENABLE, U_MODESET(regs));
>> + return 0;
>> +}
>> +
>> +/* Output a single byte to the serial port */
>> +static void pic32_serial_putc(void __iomem *regs, const char c)
>> +{
>> + /* if \n, then add a \r */
>> + if (c == '\n')
>> + pic32_serial_putc(regs, '\r');
>> +
>> + /* Wait for Tx FIFO not full */
>> + while (readl(U_STA(regs)) & UART_TX_FULL)
>> + ;
>> +
>> + /* stuff the tx buffer with the character */
>> + writel(c, U_TXREG(regs));
>> +}
>> +
>> +/* Test whether a character is in the RX buffer */
>> +static int pic32_serial_tstc(void __iomem *regs)
>> +{
>> + /* check if rcv buf overrun error has occurred */
>> + if (readl(U_STA(regs)) & UART_RX_OERR) {
>> + readl(U_RXREG(regs));
>> +
>> + /* clear OERR to keep receiving */
>> + writel(UART_RX_OERR, U_STACLR(regs));
>> + }
>> +
>> + if (readl(U_STA(regs)) & UART_RX_DATA_AVAIL)
>> + return 1; /* yes, there is data in rcv buffer */
>> + else
>> + return 0; /* no data in rcv buffer */
> return readl() & UART_RX_DATA_AVAIL; is sufficient here.
ack.
>> +}
>> +
>> +/*
>> + * Read a single byte from the rx buffer.
>> + * Blocking: waits until a character is received, then returns.
>> + * Return the character read directly from the UART's receive register.
>> + *
>> + */
>> +static int pic32_serial_getc(void __iomem *regs)
>> +{
>> + /* wait here until data is available */
>> + while (!pic32_serial_tstc(regs))
>> + ;
>> +
>> + /* read the character from the rcv buffer */
>> + return readl(U_RXREG(regs));
> return readl() & 0xff, since the return value is a signed integer.
ack.
>> +}
> [...]
>
>> +U_BOOT_DRIVER(pic32_serial) = {
>> + .name = "pic32-uart",
>> + .id = UCLASS_SERIAL,
>> + .of_match = pic32_uart_ids,
>> + .probe = pic32_uart_probe,
>> + .ops = &pic32_uart_ops,
>> + .flags = DM_FLAG_PRE_RELOC,
>> + .ofdata_to_platdata = pic32_uart_ofdata_to_platdata,
>> + .platdata_auto_alloc_size = sizeof(struct pic32_uart_priv),
> Is there some problem with tab/space conversion going on in here?
ack. will fix.
>> +};
>> +
> [...]
More information about the U-Boot
mailing list