diff options
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/Kconfig | 28 | ||||
-rw-r--r-- | drivers/serial/Makefile | 7 | ||||
-rw-r--r-- | drivers/serial/ns16550.c | 49 | ||||
-rw-r--r-- | drivers/serial/serial-uclass.c | 20 | ||||
-rw-r--r-- | drivers/serial/serial.c | 2 | ||||
-rw-r--r-- | drivers/serial/serial_dw.c | 39 | ||||
-rw-r--r-- | drivers/serial/serial_keystone.c | 48 | ||||
-rw-r--r-- | drivers/serial/serial_omap.c | 54 | ||||
-rw-r--r-- | drivers/serial/serial_ppc.c | 40 | ||||
-rw-r--r-- | drivers/serial/serial_rockchip.c | 43 | ||||
-rw-r--r-- | drivers/serial/serial_stm32.c | 203 | ||||
-rw-r--r-- | drivers/serial/serial_tegra.c | 54 | ||||
-rw-r--r-- | drivers/serial/serial_x86.c | 44 | ||||
-rw-r--r-- | drivers/serial/serial_zynq.c | 5 |
14 files changed, 163 insertions, 473 deletions
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index eba96f4..1fc287e 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -53,6 +53,7 @@ config DEBUG_UART choice prompt "Select which UART will provide the debug UART" depends on DEBUG_UART + default DEBUG_UART_NS16550 config DEBUG_UART_ALTERA_JTAGUART bool "Altera JTAG UART" @@ -94,7 +95,7 @@ config DEBUG_UART_S5P config DEBUG_UART_ZYNQ bool "Xilinx Zynq" help - Select this to enable a debug UART using the serial_s5p driver. You + Select this to enable a debug UART using the serial_zynq driver. You will need to provide parameters to make this work. The driver will be available until the real driver-model serial is running. @@ -185,14 +186,15 @@ config ALTERA_UART Select this to enable an UART for Altera devices. Please find details on the "Embedded Peripherals IP User Guide" of Altera. -config ROCKCHIP_SERIAL - bool "Rockchip on-chip UART support" - depends on ARCH_ROCKCHIP && DM_SERIAL +config SYS_NS16550 + bool "NS16550 UART or compatible" help - Select this to enable a debug UART for Rockchip devices. This uses - the ns16550 driver. You will need to #define CONFIG_SYS_NS16550 in - your board config header. The clock input is automatically set to - use the oscillator (24MHz). + Support NS16550 UART or compatible. This can be enabled in the + device tree with the correct input clock frequency. If the input + clock frequency is not defined in the device tree, the macro + CONFIG_SYS_NS16550_CLK defined in a legacy board header file will + be used. It can be a constant or a function to get clock, eg, + get_serial_clock(). config SANDBOX_SERIAL bool "Sandbox UART support" @@ -221,14 +223,4 @@ config UNIPHIER_SERIAL If you have a UniPhier based board and want to use the on-chip serial ports, say Y to this option. If unsure, say N. -config X86_SERIAL - bool "Support for 16550 serial port on x86 machines" - depends on X86 - default y - help - Most x86 machines have a ns16550 UART or compatible. This can be - enabled in the device tree with the correct input clock frequency - provided (default 1843200). Enable this to obtain serial console - output. - endmenu diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 1818c7c..dd87147 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -8,7 +8,6 @@ ifdef CONFIG_DM_SERIAL obj-y += serial-uclass.o obj-$(CONFIG_PL01X_SERIAL) += serial_pl01x.o -obj-$(CONFIG_PPC) += serial_ppc.o else obj-y += serial.o obj-$(CONFIG_PL010_SERIAL) += serial_pl01x.o @@ -20,12 +19,10 @@ obj-$(CONFIG_ALTERA_UART) += altera_uart.o obj-$(CONFIG_ALTERA_JTAG_UART) += altera_jtag_uart.o obj-$(CONFIG_ARM_DCC) += arm_dcc.o obj-$(CONFIG_ATMEL_USART) += atmel_usart.o -obj-$(CONFIG_DW_SERIAL) += serial_dw.o obj-$(CONFIG_EFI_APP) += serial_efi.o obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o obj-$(CONFIG_MCFUART) += mcfuart.o obj-$(CONFIG_OPENCORES_YANU) += opencores_yanu.o -obj-$(CONFIG_KEYSTONE_SERIAL) += serial_keystone.o obj-$(CONFIG_SYS_NS16550) += ns16550.o obj-$(CONFIG_S5P) += serial_s5p.o obj-$(CONFIG_IMX_SERIAL) += serial_imx.o @@ -41,12 +38,8 @@ obj-$(CONFIG_ZYNQ_SERIAL) += serial_zynq.o obj-$(CONFIG_BFIN_SERIAL) += serial_bfin.o obj-$(CONFIG_FSL_LPUART) += serial_lpuart.o obj-$(CONFIG_MXS_AUART) += mxs_auart.o -obj-$(CONFIG_ROCKCHIP_SERIAL) += serial_rockchip.o obj-$(CONFIG_ARC_SERIAL) += serial_arc.o -obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o -obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o -obj-$(CONFIG_X86_SERIAL) += serial_x86.o obj-$(CONFIG_STM32_SERIAL) += serial_stm32.o ifndef CONFIG_SPL_BUILD diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 6433844..3fab3f1 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -8,7 +8,6 @@ #include <dm.h> #include <errno.h> #include <fdtdec.h> -#include <mapmem.h> #include <ns16550.h> #include <serial.h> #include <watchdog.h> @@ -57,6 +56,10 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_DM_SERIAL +#ifndef CONFIG_SYS_NS16550_CLK +#define CONFIG_SYS_NS16550_CLK 0 +#endif + static inline void serial_out_shift(void *addr, int shift, int value) { #ifdef CONFIG_SYS_NS16550_PORT_MAPPED @@ -97,7 +100,7 @@ static void ns16550_writeb(NS16550_t port, int offset, int value) unsigned char *addr; offset *= 1 << plat->reg_shift; - addr = map_sysmem(plat->base, 0) + offset; + addr = map_physmem(plat->base, 0, MAP_NOCACHE) + offset; /* * As far as we know it doesn't make sense to support selection of * these options at run-time, so use the existing CONFIG options. @@ -111,7 +114,7 @@ static int ns16550_readb(NS16550_t port, int offset) unsigned char *addr; offset *= 1 << plat->reg_shift; - addr = map_sysmem(plat->base, 0) + offset; + addr = map_physmem(plat->base, 0, MAP_NOCACHE) + offset; return serial_in_shift(addr, plat->reg_shift); } @@ -400,7 +403,14 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev) plat->base = addr; plat->reg_shift = fdtdec_get_int(gd->fdt_blob, dev->of_offset, - "reg-shift", 1); + "reg-shift", 0); + plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "clock-frequency", + CONFIG_SYS_NS16550_CLK); + if (!plat->clock) { + debug("ns16550 clock not defined\n"); + return -EINVAL; + } return 0; } @@ -412,4 +422,35 @@ const struct dm_serial_ops ns16550_serial_ops = { .getc = ns16550_serial_getc, .setbrg = ns16550_serial_setbrg, }; + +#if CONFIG_IS_ENABLED(OF_CONTROL) +static const struct udevice_id ns16550_serial_ids[] = { + { .compatible = "ns16550" }, + { .compatible = "ns16550a" }, + { .compatible = "nvidia,tegra20-uart" }, + { .compatible = "rockchip,rk3036-uart" }, + { .compatible = "snps,dw-apb-uart" }, + { .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 + +U_BOOT_DRIVER(ns16550_serial) = { + .name = "ns16550_serial", + .id = UCLASS_SERIAL, +#if CONFIG_IS_ENABLED(OF_CONTROL) + .of_match = ns16550_serial_ids, + .ofdata_to_platdata = ns16550_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 /* CONFIG_DM_SERIAL */ diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 842f78b..4bf9a5c 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -64,9 +64,9 @@ static void serial_find_console_or_panic(void) } /* - * If the console is not marked to be bound before relocation, - * bind it anyway. - */ + * If the console is not marked to be bound before relocation, + * bind it anyway. + */ if (node > 0 && !lists_bind_fdt(gd->dm_root, blob, node, &dev)) { if (!device_probe(dev)) { @@ -77,13 +77,13 @@ static void serial_find_console_or_panic(void) } if (!SPL_BUILD || !CONFIG_IS_ENABLED(OF_CONTROL) || !blob) { /* - * Try to use CONFIG_CONS_INDEX if available (it is numbered - * from 1!). - * - * Failing that, get the device with sequence number 0, or in - * extremis just the first serial device we can find. But we - * insist on having a console (even if it is silent). - */ + * Try to use CONFIG_CONS_INDEX if available (it is numbered + * from 1!). + * + * Failing that, get the device with sequence number 0, or in + * extremis just the first serial device we can find. But we + * insist on having a console (even if it is silent). + */ #ifdef CONFIG_CONS_INDEX #define INDEX (CONFIG_CONS_INDEX - 1) #else diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index 422d3ae..f1bd15b 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -527,7 +527,7 @@ static const int bauds[] = CONFIG_SYS_BAUDRATE_TABLE; * * Do a loopback test of the currently selected serial port. This * function is only useful in the context of the POST testing framwork. - * The serial port is firstly configured into loopback mode and then + * The serial port is first configured into loopback mode and then * characters are sent through it. * * Returns 0 on success, value otherwise. diff --git a/drivers/serial/serial_dw.c b/drivers/serial/serial_dw.c deleted file mode 100644 index a348f29..0000000 --- a/drivers/serial/serial_dw.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2014 Google, Inc - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <dm.h> -#include <ns16550.h> -#include <serial.h> - -static const struct udevice_id dw_serial_ids[] = { - { .compatible = "snps,dw-apb-uart" }, - { } -}; - -static int dw_serial_ofdata_to_platdata(struct udevice *dev) -{ - struct ns16550_platdata *plat = dev_get_platdata(dev); - int ret; - - ret = ns16550_serial_ofdata_to_platdata(dev); - if (ret) - return ret; - plat->clock = CONFIG_SYS_NS16550_CLK; - - return 0; -} - -U_BOOT_DRIVER(serial_ns16550) = { - .name = "serial_dw", - .id = UCLASS_SERIAL, - .of_match = dw_serial_ids, - .ofdata_to_platdata = dw_serial_ofdata_to_platdata, - .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), - .priv_auto_alloc_size = sizeof(struct NS16550), - .probe = ns16550_serial_probe, - .ops = &ns16550_serial_ops, -}; diff --git a/drivers/serial/serial_keystone.c b/drivers/serial/serial_keystone.c deleted file mode 100644 index 7b5ab6c..0000000 --- a/drivers/serial/serial_keystone.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2015 Texas Instruments, <www.ti.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <dm.h> -#include <fdtdec.h> -#include <ns16550.h> -#include <serial.h> -#include <asm/arch/clock.h> - -DECLARE_GLOBAL_DATA_PTR; - -#if CONFIG_IS_ENABLED(OF_CONTROL) -static const struct udevice_id keystone_serial_ids[] = { - { .compatible = "ti,keystone-uart" }, - { .compatible = "ns16550a" }, - { } -}; - -static int keystone_serial_ofdata_to_platdata(struct udevice *dev) -{ - struct ns16550_platdata *plat = dev_get_platdata(dev); - int ret; - - ret = ns16550_serial_ofdata_to_platdata(dev); - if (ret) - return ret; - plat->clock = CONFIG_SYS_NS16550_CLK; - return 0; -} -#endif - -U_BOOT_DRIVER(serial_keystone_ns16550) = { - .name = "serial_keystone", - .id = UCLASS_SERIAL, -#if CONFIG_IS_ENABLED(OF_CONTROL) - .of_match = of_match_ptr(keystone_serial_ids), - .ofdata_to_platdata = of_match_ptr(keystone_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, -}; diff --git a/drivers/serial/serial_omap.c b/drivers/serial/serial_omap.c deleted file mode 100644 index 891cd7b..0000000 --- a/drivers/serial/serial_omap.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2014 Google, Inc - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <dm.h> -#include <fdtdec.h> -#include <ns16550.h> -#include <serial.h> - -DECLARE_GLOBAL_DATA_PTR; - -#define DEFAULT_CLK_SPEED 48000000 /* 48Mhz */ - -#if CONFIG_IS_ENABLED(OF_CONTROL) -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" }, - { } -}; - -static int omap_serial_ofdata_to_platdata(struct udevice *dev) -{ - struct ns16550_platdata *plat = dev_get_platdata(dev); - int ret; - - ret = ns16550_serial_ofdata_to_platdata(dev); - if (ret) - return ret; - plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset, - "clock-frequency", DEFAULT_CLK_SPEED); - plat->reg_shift = 2; - - return 0; -} -#endif - -U_BOOT_DRIVER(serial_omap_ns16550) = { - .name = "serial_omap", - .id = UCLASS_SERIAL, - .of_match = of_match_ptr(omap_serial_ids), - .ofdata_to_platdata = of_match_ptr(omap_serial_ofdata_to_platdata), - .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), - .priv_auto_alloc_size = sizeof(struct NS16550), - .probe = ns16550_serial_probe, - .ops = &ns16550_serial_ops, - .flags = DM_FLAG_PRE_RELOC, -}; diff --git a/drivers/serial/serial_ppc.c b/drivers/serial/serial_ppc.c deleted file mode 100644 index 47141c6..0000000 --- a/drivers/serial/serial_ppc.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2014 Google, Inc - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <dm.h> -#include <ns16550.h> -#include <serial.h> - -static const struct udevice_id ppc_serial_ids[] = { - { .compatible = "ns16550" }, - { } -}; - -static int ppc_serial_ofdata_to_platdata(struct udevice *dev) -{ - struct ns16550_platdata *plat = dev_get_platdata(dev); - int ret; - - ret = ns16550_serial_ofdata_to_platdata(dev); - if (ret) - return ret; - plat->clock = get_serial_clock(); - - return 0; -} - -U_BOOT_DRIVER(serial_ns16550) = { - .name = "serial_ppc", - .id = UCLASS_SERIAL, - .of_match = ppc_serial_ids, - .ofdata_to_platdata = ppc_serial_ofdata_to_platdata, - .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), - .priv_auto_alloc_size = sizeof(struct NS16550), - .probe = ns16550_serial_probe, - .ops = &ns16550_serial_ops, - .flags = DM_FLAG_PRE_RELOC, -}; diff --git a/drivers/serial/serial_rockchip.c b/drivers/serial/serial_rockchip.c deleted file mode 100644 index 0e7bbfc..0000000 --- a/drivers/serial/serial_rockchip.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2015 Google, Inc - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <dm.h> -#include <ns16550.h> -#include <serial.h> -#include <asm/arch/clock.h> - -static const struct udevice_id rockchip_serial_ids[] = { - { .compatible = "rockchip,rk3288-uart" }, - { } -}; - -static int rockchip_serial_ofdata_to_platdata(struct udevice *dev) -{ - struct ns16550_platdata *plat = dev_get_platdata(dev); - int ret; - - ret = ns16550_serial_ofdata_to_platdata(dev); - if (ret) - return ret; - - /* Do all Rockchip parts use 24MHz? */ - plat->clock = 24 * 1000000; - - return 0; -} - -U_BOOT_DRIVER(serial_ns16550) = { - .name = "serial_rockchip", - .id = UCLASS_SERIAL, - .of_match = rockchip_serial_ids, - .ofdata_to_platdata = rockchip_serial_ofdata_to_platdata, - .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), - .priv_auto_alloc_size = sizeof(struct NS16550), - .probe = ns16550_serial_probe, - .ops = &ns16550_serial_ops, - .flags = DM_FLAG_PRE_RELOC, -}; diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c index 8b2830b..91a5dde 100644 --- a/drivers/serial/serial_stm32.c +++ b/drivers/serial/serial_stm32.c @@ -1,45 +1,18 @@ /* * (C) Copyright 2015 - * Kamil Lulko, <rev13@wp.pl> + * Kamil Lulko, <kamil.lulko@gmail.com> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <dm.h> #include <asm/io.h> #include <serial.h> #include <asm/arch/stm32.h> +#include <dm/platform_data/serial_stm32.h> -/* - * Set up the usart port - */ -#if (CONFIG_STM32_USART >= 1) && (CONFIG_STM32_USART <= 6) -#define USART_PORT (CONFIG_STM32_USART - 1) -#else -#define USART_PORT 0 -#endif -/* - * Set up the usart base address - * - * --STM32_USARTD_BASE means default setting - */ -#define STM32_USART1_BASE (STM32_APB2PERIPH_BASE + 0x1000) -#define STM32_USART2_BASE (STM32_APB1PERIPH_BASE + 0x4400) -#define STM32_USART3_BASE (STM32_APB1PERIPH_BASE + 0x4800) -#define STM32_USART6_BASE (STM32_APB2PERIPH_BASE + 0x1400) -#define STM32_USARTD_BASE STM32_USART1_BASE -/* - * RCC USART specific definitions - * - * --RCC_ENR_USARTDEN means default setting - */ -#define RCC_ENR_USART1EN (1 << 4) -#define RCC_ENR_USART2EN (1 << 17) -#define RCC_ENR_USART3EN (1 << 18) -#define RCC_ENR_USART6EN (1 << 5) -#define RCC_ENR_USARTDEN RCC_ENR_USART1EN - -struct stm32_serial { +struct stm32_usart { u32 sr; u32 dr; u32 brr; @@ -49,120 +22,136 @@ struct stm32_serial { u32 gtpr; }; -#define USART_CR1_RE (1 << 2) -#define USART_CR1_TE (1 << 3) -#define USART_CR1_UE (1 << 13) +#define USART_CR1_RE (1 << 2) +#define USART_CR1_TE (1 << 3) +#define USART_CR1_UE (1 << 13) #define USART_SR_FLAG_RXNE (1 << 5) -#define USART_SR_FLAG_TXE (1 << 7) +#define USART_SR_FLAG_TXE (1 << 7) -#define USART_BRR_F_MASK 0xF +#define USART_BRR_F_MASK 0xF #define USART_BRR_M_SHIFT 4 #define USART_BRR_M_MASK 0xFFF0 DECLARE_GLOBAL_DATA_PTR; -static const unsigned long usart_base[] = { - STM32_USART1_BASE, - STM32_USART2_BASE, - STM32_USART3_BASE, - STM32_USARTD_BASE, - STM32_USARTD_BASE, - STM32_USART6_BASE -}; +#define MAX_SERIAL_PORTS 4 -static const unsigned long rcc_enr_en[] = { - RCC_ENR_USART1EN, - RCC_ENR_USART2EN, - RCC_ENR_USART3EN, - RCC_ENR_USARTDEN, - RCC_ENR_USARTDEN, - RCC_ENR_USART6EN +/* + * RCC USART specific definitions + */ +#define RCC_ENR_USART1EN (1 << 4) +#define RCC_ENR_USART2EN (1 << 17) +#define RCC_ENR_USART3EN (1 << 18) +#define RCC_ENR_USART6EN (1 << 5) + +/* Array used to figure out which RCC bit needs to be set */ +static const unsigned long usart_port_rcc_pairs[MAX_SERIAL_PORTS][2] = { + { STM32_USART1_BASE, RCC_ENR_USART1EN }, + { STM32_USART2_BASE, RCC_ENR_USART2EN }, + { STM32_USART3_BASE, RCC_ENR_USART3EN }, + { STM32_USART6_BASE, RCC_ENR_USART6EN } }; -static void stm32_serial_setbrg(void) +static int stm32_serial_setbrg(struct udevice *dev, int baudrate) { - serial_init(); -} + struct stm32_serial_platdata *plat = dev->platdata; + struct stm32_usart *const usart = plat->base; + u32 clock, int_div, frac_div, tmp; -static int stm32_serial_init(void) -{ - struct stm32_serial *usart = - (struct stm32_serial *)usart_base[USART_PORT]; - u32 clock, int_div, frac_div, tmp; - - if ((usart_base[USART_PORT] & STM32_BUS_MASK) == - STM32_APB1PERIPH_BASE) { - setbits_le32(&STM32_RCC->apb1enr, rcc_enr_en[USART_PORT]); + if (((u32)usart & STM32_BUS_MASK) == STM32_APB1PERIPH_BASE) clock = clock_get(CLOCK_APB1); - } else if ((usart_base[USART_PORT] & STM32_BUS_MASK) == - STM32_APB2PERIPH_BASE) { - setbits_le32(&STM32_RCC->apb2enr, rcc_enr_en[USART_PORT]); + else if (((u32)usart & STM32_BUS_MASK) == STM32_APB2PERIPH_BASE) clock = clock_get(CLOCK_APB2); - } else { - return -1; - } + else + return -EINVAL; - int_div = (25 * clock) / (4 * gd->baudrate); + int_div = (25 * clock) / (4 * baudrate); tmp = ((int_div / 100) << USART_BRR_M_SHIFT) & USART_BRR_M_MASK; frac_div = int_div - (100 * (tmp >> USART_BRR_M_SHIFT)); tmp |= (((frac_div * 16) + 50) / 100) & USART_BRR_F_MASK; - writel(tmp, &usart->brr); - setbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE); return 0; } -static int stm32_serial_getc(void) +static int stm32_serial_getc(struct udevice *dev) { - struct stm32_serial *usart = - (struct stm32_serial *)usart_base[USART_PORT]; - while ((readl(&usart->sr) & USART_SR_FLAG_RXNE) == 0) - ; + struct stm32_serial_platdata *plat = dev->platdata; + struct stm32_usart *const usart = plat->base; + + if ((readl(&usart->sr) & USART_SR_FLAG_RXNE) == 0) + return -EAGAIN; + return readl(&usart->dr); } -static void stm32_serial_putc(const char c) +static int stm32_serial_putc(struct udevice *dev, const char c) { - struct stm32_serial *usart = - (struct stm32_serial *)usart_base[USART_PORT]; + struct stm32_serial_platdata *plat = dev->platdata; + struct stm32_usart *const usart = plat->base; - if (c == '\n') - stm32_serial_putc('\r'); + if ((readl(&usart->sr) & USART_SR_FLAG_TXE) == 0) + return -EAGAIN; - while ((readl(&usart->sr) & USART_SR_FLAG_TXE) == 0) - ; writel(c, &usart->dr); + + return 0; } -static int stm32_serial_tstc(void) +static int stm32_serial_pending(struct udevice *dev, bool input) { - struct stm32_serial *usart = - (struct stm32_serial *)usart_base[USART_PORT]; - u8 ret; + struct stm32_serial_platdata *plat = dev->platdata; + struct stm32_usart *const usart = plat->base; - ret = readl(&usart->sr) & USART_SR_FLAG_RXNE; - return ret; + if (input) + return readl(&usart->sr) & USART_SR_FLAG_RXNE ? 1 : 0; + else + return readl(&usart->sr) & USART_SR_FLAG_TXE ? 0 : 1; } -static struct serial_device stm32_serial_drv = { - .name = "stm32_serial", - .start = stm32_serial_init, - .stop = NULL, - .setbrg = stm32_serial_setbrg, - .putc = stm32_serial_putc, - .puts = default_serial_puts, - .getc = stm32_serial_getc, - .tstc = stm32_serial_tstc, -}; - -void stm32_serial_initialize(void) +static int stm32_serial_probe(struct udevice *dev) { - serial_register(&stm32_serial_drv); -} + struct stm32_serial_platdata *plat = dev->platdata; + struct stm32_usart *const usart = plat->base; + int usart_port = -1; + int i; + + for (i = 0; i < MAX_SERIAL_PORTS; i++) { + if ((u32)usart == usart_port_rcc_pairs[i][0]) { + usart_port = i; + break; + } + } -__weak struct serial_device *default_serial_console(void) -{ - return &stm32_serial_drv; + if (usart_port == -1) + return -EINVAL; + + if (((u32)usart & STM32_BUS_MASK) == STM32_APB1PERIPH_BASE) + setbits_le32(&STM32_RCC->apb1enr, + usart_port_rcc_pairs[usart_port][1]); + else if (((u32)usart & STM32_BUS_MASK) == STM32_APB2PERIPH_BASE) + setbits_le32(&STM32_RCC->apb2enr, + usart_port_rcc_pairs[usart_port][1]); + else + return -EINVAL; + + setbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE); + + return 0; } + +static const struct dm_serial_ops stm32_serial_ops = { + .putc = stm32_serial_putc, + .pending = stm32_serial_pending, + .getc = stm32_serial_getc, + .setbrg = stm32_serial_setbrg, +}; + +U_BOOT_DRIVER(serial_stm32) = { + .name = "serial_stm32", + .id = UCLASS_SERIAL, + .ops = &stm32_serial_ops, + .probe = stm32_serial_probe, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/serial/serial_tegra.c b/drivers/serial/serial_tegra.c deleted file mode 100644 index 0c84f0b..0000000 --- a/drivers/serial/serial_tegra.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2014 Google, Inc - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <dm.h> -#include <ns16550.h> -#include <serial.h> - -#if CONFIG_IS_ENABLED(OF_CONTROL) -static const struct udevice_id tegra_serial_ids[] = { - { .compatible = "nvidia,tegra20-uart" }, - { } -}; - -static int tegra_serial_ofdata_to_platdata(struct udevice *dev) -{ - struct ns16550_platdata *plat = dev_get_platdata(dev); - int ret; - - ret = ns16550_serial_ofdata_to_platdata(dev); - if (ret) - return ret; - plat->clock = V_NS16550_CLK; - - return 0; -} -#else -struct ns16550_platdata tegra_serial = { - .base = CONFIG_SYS_NS16550_COM1, - .reg_shift = 2, - .clock = V_NS16550_CLK, -}; - -U_BOOT_DEVICE(ns16550_serial) = { - "serial_tegra20", &tegra_serial -}; -#endif - -U_BOOT_DRIVER(serial_ns16550) = { - .name = "serial_tegra20", - .id = UCLASS_SERIAL, -#if CONFIG_IS_ENABLED(OF_CONTROL) - .of_match = tegra_serial_ids, - .ofdata_to_platdata = tegra_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, -}; diff --git a/drivers/serial/serial_x86.c b/drivers/serial/serial_x86.c deleted file mode 100644 index 4bf6062..0000000 --- a/drivers/serial/serial_x86.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2014 Google, Inc - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <dm.h> -#include <fdtdec.h> -#include <ns16550.h> -#include <serial.h> - -DECLARE_GLOBAL_DATA_PTR; - -static const struct udevice_id x86_serial_ids[] = { - { .compatible = "x86-uart" }, - { } -}; - -static int x86_serial_ofdata_to_platdata(struct udevice *dev) -{ - struct ns16550_platdata *plat = dev_get_platdata(dev); - int ret; - - ret = ns16550_serial_ofdata_to_platdata(dev); - if (ret) - return ret; - - plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset, - "clock-frequency", 1843200); - - return 0; -} - -U_BOOT_DRIVER(serial_ns16550) = { - .name = "serial_x86", - .id = UCLASS_SERIAL, - .of_match = x86_serial_ids, - .ofdata_to_platdata = x86_serial_ofdata_to_platdata, - .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), - .priv_auto_alloc_size = sizeof(struct NS16550), - .probe = ns16550_serial_probe, - .ops = &ns16550_serial_ops, -}; diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c index 88bebed..b2b98de 100644 --- a/drivers/serial/serial_zynq.c +++ b/drivers/serial/serial_zynq.c @@ -180,7 +180,7 @@ static const struct udevice_id zynq_serial_ids[] = { { } }; -U_BOOT_DRIVER(serial_s5p) = { +U_BOOT_DRIVER(serial_zynq) = { .name = "serial_zynq", .id = UCLASS_SERIAL, .of_match = zynq_serial_ids, @@ -192,9 +192,6 @@ U_BOOT_DRIVER(serial_s5p) = { }; #ifdef CONFIG_DEBUG_UART_ZYNQ - -#include <debug_uart.h> - void _debug_uart_init(void) { struct uart_zynq *regs = (struct uart_zynq *)CONFIG_DEBUG_UART_BASE; |