[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