[U-Boot] [PATCH] serial: omap: Introduce DM specific omap serial

Adam Ford aford173 at gmail.com
Fri Aug 10 14:17:03 UTC 2018


On Fri, Aug 10, 2018 at 8:07 AM Lokesh Vutla <lokeshvutla at ti.com> wrote:
>
> Add driver model support for OMAP_SERIAL while reusing
> the functions in ns16550.c
>
> Signed-off-by: Lokesh Vutla <lokeshvutla at ti.com>
> ---
>
> Based on the conclusion on the thread[1], added a separate driver for
> omap uart.
>
> [1] https://patchwork.ozlabs.org/patch/944756/
>
>  drivers/serial/Kconfig       |   9 +++
>  drivers/serial/Makefile      |   1 +
>  drivers/serial/ns16550.c     |  42 ------------
>  drivers/serial/serial_omap.c | 121 +++++++++++++++++++++++++++++++++++
>  4 files changed, 131 insertions(+), 42 deletions(-)
>  create mode 100644 drivers/serial/serial_omap.c
>
> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
> index 766e5ced03..0aa2338135 100644
> --- a/drivers/serial/Kconfig
> +++ b/drivers/serial/Kconfig
> @@ -625,6 +625,15 @@ config MSM_SERIAL
>           for example APQ8016 and MSM8916.
>           Single baudrate is supported in current implementation (115200).
>
> +config OMAP_SERIAL
> +       bool "Support for OMAP specific UART"
> +       depends on DM_SERIAL
> +       default y if (ARCH_OMAP2PLUS || SOC_DA8XX)
> +       select SYS_NS16550
> +       help
> +         If you have an TI based SoC and want to use the on-chip serial
> +         port, say Y to this option. If unsure say N.
> +
>  config OWL_SERIAL
>         bool "Actions Semi OWL UART"
>         depends on DM_SERIAL && ARCH_OWL
> diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
> index 9fa81d855d..03dc29ee2e 100644
> --- a/drivers/serial/Makefile
> +++ b/drivers/serial/Makefile
> @@ -65,6 +65,7 @@ obj-$(CONFIG_MVEBU_A3700_UART) += serial_mvebu_a3700.o
>  obj-$(CONFIG_MPC8XX_CONS) += serial_mpc8xx.o
>  obj-$(CONFIG_NULLDEV_SERIAL) += serial_nulldev.o
>  obj-$(CONFIG_OWL_SERIAL) += serial_owl.o
> +obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o
>
>  ifndef CONFIG_SPL_BUILD
>  obj-$(CONFIG_USB_TTY) += usbtty.o
> diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
> index 9c80090aa7..1858465ec9 100644
> --- a/drivers/serial/ns16550.c
> +++ b/drivers/serial/ns16550.c
> @@ -279,42 +279,6 @@ DEBUG_UART_FUNCS
>
>  #endif
>
> -#ifdef CONFIG_DEBUG_UART_OMAP
> -
> -#include <debug_uart.h>
> -
> -static inline void _debug_uart_init(void)
> -{
> -       struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
> -       int baud_divisor;
> -
> -       baud_divisor = ns16550_calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK,
> -                                           CONFIG_BAUDRATE);
> -       serial_dout(&com_port->ier, CONFIG_SYS_NS16550_IER);
> -       serial_dout(&com_port->mdr1, 0x7);
> -       serial_dout(&com_port->mcr, UART_MCRVAL);
> -       serial_dout(&com_port->fcr, UART_FCR_DEFVAL);
> -
> -       serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL);
> -       serial_dout(&com_port->dll, baud_divisor & 0xff);
> -       serial_dout(&com_port->dlm, (baud_divisor >> 8) & 0xff);
> -       serial_dout(&com_port->lcr, UART_LCRVAL);
> -       serial_dout(&com_port->mdr1, 0x0);
> -}
> -
> -static inline void _debug_uart_putc(int ch)
> -{
> -       struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
> -
> -       while (!(serial_din(&com_port->lsr) & UART_LSR_THRE))
> -               ;
> -       serial_dout(&com_port->thr, ch);
> -}
> -
> -DEBUG_UART_FUNCS
> -
> -#endif
> -
>  #ifdef CONFIG_DM_SERIAL
>  static int ns16550_serial_putc(struct udevice *dev, const char ch)
>  {
> @@ -489,12 +453,6 @@ static const struct udevice_id ns16550_serial_ids[] = {
>         { .compatible = "ingenic,jz4780-uart",  .data = PORT_JZ4780  },
>         { .compatible = "nvidia,tegra20-uart",  .data = PORT_NS16550 },
>         { .compatible = "snps,dw-apb-uart",     .data = PORT_NS16550 },
> -       { .compatible = "ti,omap2-uart",        .data = PORT_NS16550 },
> -       { .compatible = "ti,omap3-uart",        .data = PORT_NS16550 },
> -       { .compatible = "ti,omap4-uart",        .data = PORT_NS16550 },
> -       { .compatible = "ti,am3352-uart",       .data = PORT_NS16550 },
> -       { .compatible = "ti,am4372-uart",       .data = PORT_NS16550 },
> -       { .compatible = "ti,dra742-uart",       .data = PORT_NS16550 },
>         {}
>  };

I am not trying to rock the boat, but I am wondering if it's necessary
to completely migrate the driver for OMAP.  I was thinking about the
possibility of creating a structure which includes the PORT_NS16550 as
well as reg-shift and point .data entry to that new structure.  This
way, .compatible = "ti,omapX-uart" would also bring with it the
'reg-shift' for all board using that driver compatible flag.  For the
other boards that don't need it, it can default to something else.

It limits the number of different drivers that do the same thing, and
it allows the DTS and DTSI files to remain in sync with the kernel.

Just a thought.

adam

>  #endif /* OF_CONTROL && !OF_PLATDATA */
> diff --git a/drivers/serial/serial_omap.c b/drivers/serial/serial_omap.c
> new file mode 100644
> index 0000000000..5d408deda9
> --- /dev/null
> +++ b/drivers/serial/serial_omap.c
> @@ -0,0 +1,121 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Texas Instruments' OMAP serial driver
> + *
> + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
> + *     Lokesh Vutla <lokeshvutla at ti.com>
> + */
> +
> +#include <common.h>
> +#include <debug_uart.h>
> +#include <dm.h>
> +#include <dt-structs.h>
> +#include <ns16550.h>
> +#include <serial.h>
> +#include <clk.h>
> +
> +#ifdef CONFIG_DEBUG_UART_OMAP
> +
> +#include <debug_uart.h>
> +
> +static inline void _debug_uart_init(void)
> +{
> +       struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
> +       int baud_divisor;
> +
> +       baud_divisor = ns16550_calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK,
> +                                           CONFIG_BAUDRATE);
> +       serial_dout(&com_port->ier, CONFIG_SYS_NS16550_IER);
> +       serial_dout(&com_port->mdr1, 0x7);
> +       serial_dout(&com_port->mcr, UART_MCRVAL);
> +       serial_dout(&com_port->fcr, UART_FCR_DEFVAL);
> +
> +       serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL);
> +       serial_dout(&com_port->dll, baud_divisor & 0xff);
> +       serial_dout(&com_port->dlm, (baud_divisor >> 8) & 0xff);
> +       serial_dout(&com_port->lcr, UART_LCRVAL);
> +       serial_dout(&com_port->mdr1, 0x0);
> +}
> +
> +static inline void _debug_uart_putc(int ch)
> +{
> +       struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
> +
> +       while (!(serial_din(&com_port->lsr) & UART_LSR_THRE))
> +               ;
> +       serial_dout(&com_port->thr, ch);
> +}
> +
> +DEBUG_UART_FUNCS
> +
> +#endif
> +
> +#if CONFIG_IS_ENABLED(DM_SERIAL)
> +
> +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
> +static int omap_serial_ofdata_to_platdata(struct udevice *dev)
> +{
> +       struct ns16550_platdata *plat = dev->platdata;
> +       fdt_addr_t addr;
> +       struct clk clk;
> +       int err;
> +
> +       /* try Processor Local Bus device first */
> +       addr = dev_read_addr(dev);
> +       if (addr == FDT_ADDR_T_NONE)
> +               return -EINVAL;
> +
> +       plat->base = (unsigned long)map_physmem(addr, 0, MAP_NOCACHE);
> +
> +       plat->reg_offset = dev_read_u32_default(dev, "reg-offset", 0);
> +       plat->reg_shift = 2;
> +
> +       err = clk_get_by_index(dev, 0, &clk);
> +       if (!err) {
> +               err = clk_get_rate(&clk);
> +               if (!IS_ERR_VALUE(err))
> +                       plat->clock = err;
> +       } else if (err != -ENOENT && err != -ENODEV && err != -ENOSYS) {
> +               debug("omap serial failed to get clock\n");
> +               return err;
> +       }
> +
> +       if (!plat->clock)
> +               plat->clock = dev_read_u32_default(dev, "clock-frequency",
> +                                                  CONFIG_SYS_NS16550_CLK);
> +       if (!plat->clock) {
> +               debug("omap serial clock not defined\n");
> +               return -EINVAL;
> +       }
> +
> +       plat->fcr = UART_FCR_DEFVAL;
> +
> +       return 0;
> +}
> +static const struct udevice_id omap_serial_ids[] = {
> +       { .compatible = "ti,omap2-uart", },
> +       { .compatible = "ti,omap3-uart", },
> +       { .compatible = "ti,omap4-uart", },
> +       { .compatible = "ti,am3352-uart", },
> +       { .compatible = "ti,am4372-uart", },
> +       { .compatible = "ti,dra742-uart", },
> +       {}
> +};
> +#endif /* OF_CONTROL && !OF_PLATDATA */
> +
> +#if CONFIG_IS_ENABLED(SERIAL_PRESENT)
> +U_BOOT_DRIVER(omap_serial) = {
> +       .name   = "omap_serial",
> +       .id     = UCLASS_SERIAL,
> +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
> +       .of_match = omap_serial_ids,
> +       .ofdata_to_platdata = omap_serial_ofdata_to_platdata,
> +       .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
> +#endif
> +       .priv_auto_alloc_size = sizeof(struct NS16550),
> +       .probe = ns16550_serial_probe,
> +       .ops    = &ns16550_serial_ops,
> +       .flags  = DM_FLAG_PRE_RELOC,
> +};
> +#endif
> +#endif /* DM_SERIAL */
> --
> 2.18.0
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot


More information about the U-Boot mailing list