[U-Boot] [PATCH v3] serial: Add serial driver for Intel MID
Kever Yang
kever.yang at rock-chips.com
Fri Mar 3 10:31:46 UTC 2017
Hi Andy,
On 02/28/2017 08:04 PM, Andy Shevchenko wrote:
> Add a specific serial driver for Intel MID platforms.
>
> It has special fractional divider which can be programmed via UART_PS,
> UART_MUL, and UART_DIV registers.
>
> The UART clock is calculated as
>
> UART clock = XTAL * UART_MUL / UART_DIV
>
> The baudrate is calculated as
>
> baud rate = UART clock / UART_PS / DLAB
>
> Initialize fractional divider correctly for Intel Edison platform.
>
> For backward compatibility we have to set initial DLAB value to 16
> and speed to 115200 baud, where initial frequency is 29491200Hz, and
> XTAL frequency is 38.4MHz.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> ---
> drivers/serial/Kconfig | 9 +++++
> drivers/serial/Makefile | 1 +
> drivers/serial/serial_intel_mid.c | 69 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 79 insertions(+)
> create mode 100644 drivers/serial/serial_intel_mid.c
>
> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
> index b11f3ff89e..99dcdeb00d 100644
> --- a/drivers/serial/Kconfig
> +++ b/drivers/serial/Kconfig
> @@ -347,6 +347,15 @@ config SYS_NS16550
> be used. It can be a constant or a function to get clock, eg,
> get_serial_clock().
>
> +config INTEL_MID_SERIAL
> + bool "Intel MID platform UART support"
> + depends on DM_SERIAL && OF_CONTROL
> + depends on INTEL_MID
> + select SYS_NS16550
> + help
> + Select this to enable a UART for Intel MID platforms.
> + This uses the ns16550 driver as a library.
> +
> config ROCKCHIP_SERIAL
> bool "Rockchip on-chip UART support"
> depends on DM_SERIAL && SPL_OF_PLATDATA
> diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
> index 8430668bf9..abd9dea4dc 100644
> --- a/drivers/serial/Makefile
> +++ b/drivers/serial/Makefile
> @@ -28,6 +28,7 @@ obj-$(CONFIG_S5P) += serial_s5p.o
> obj-$(CONFIG_MXC_UART) += serial_mxc.o
> obj-$(CONFIG_PXA_SERIAL) += serial_pxa.o
> obj-$(CONFIG_MESON_SERIAL) += serial_meson.o
> +obj-$(CONFIG_INTEL_MID_SERIAL) += serial_intel_mid.o
> ifdef CONFIG_SPL_BUILD
> obj-$(CONFIG_ROCKCHIP_SERIAL) += serial_rockchip.o
> endif
> diff --git a/drivers/serial/serial_intel_mid.c b/drivers/serial/serial_intel_mid.c
> new file mode 100644
> index 0000000000..777c09d6d2
> --- /dev/null
> +++ b/drivers/serial/serial_intel_mid.c
> @@ -0,0 +1,69 @@
> +/*
> + * Copyright (c) 2017 Intel Corporation
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <ns16550.h>
> +#include <serial.h>
> +
> +/*
> + * The UART clock is calculated as
> + *
> + * UART clock = XTAL * UART_MUL / UART_DIV
> + *
> + * The baudrate is calculated as
> + *
> + * baud rate = UART clock / UART_PS / DLAB
> + */
> +#define UART_PS 0x30
> +#define UART_MUL 0x34
> +#define UART_DIV 0x38
> +
> +static void mid_writel(struct ns16550_platdata *plat, int offset, int value)
> +{
> + unsigned char *addr;
> +
> + offset *= 1 << plat->reg_shift;
> + addr = (unsigned char *)plat->base + offset;
> +
> + writel(value, addr + plat->reg_offset);
> +}
> +
> +static int mid_serial_probe(struct udevice *dev)
> +{
> + struct ns16550_platdata *plat = dev_get_platdata(dev);
> +
> + /*
> + * Initialize fractional divider correctly for Intel Edison
> + * platform.
> + *
> + * For backward compatibility we have to set initial DLAB value
> + * to 16 and speed to 115200 baud, where initial frequency is
> + * 29491200Hz, and XTAL frequency is 38.4MHz.
> + */
> + mid_writel(plat, UART_MUL, 96);
> + mid_writel(plat, UART_DIV, 125);
> + mid_writel(plat, UART_PS, 16);
> +
> + return ns16550_serial_probe(dev);
> +}
> +
> +static const struct udevice_id mid_serial_ids[] = {
> + { .compatible = "intel,mid-uart" },
> + {}
> +};
> +
> +U_BOOT_DRIVER(serial_intel_mid) = {
> + .name = "serial_intel_mid",
> + .id = UCLASS_SERIAL,
> + .of_match = mid_serial_ids,
> + .ofdata_to_platdata = ns16550_serial_ofdata_to_platdata,
> + .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
> + .priv_auto_alloc_size = sizeof(struct NS16550),
> + .probe = mid_serial_probe,
> + .ops = &ns16550_serial_ops,
> + .flags = DM_FLAG_PRE_RELOC,
> +};
Reviewed-by: Kever Yang <kever.yang at rock-chips.com>
Thanks,
- Kever
More information about the U-Boot
mailing list