diff options
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/serial_pl01x.c | 30 | ||||
-rw-r--r-- | drivers/serial/serial_stm32.c | 72 |
2 files changed, 89 insertions, 13 deletions
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index 2124161734c..ad503afcad5 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -20,6 +20,9 @@ #include <dm/platform_data/serial_pl01x.h> #include <linux/compiler.h> #include "serial_pl01x_internal.h" +#include <fdtdec.h> + +DECLARE_GLOBAL_DATA_PTR; #ifndef CONFIG_DM_SERIAL @@ -28,7 +31,6 @@ static enum pl01x_type pl01x_type __attribute__ ((section(".data"))); static struct pl01x_regs *base_regs __attribute__ ((section(".data"))); #define NUM_PORTS (sizeof(port)/sizeof(port[0])) -DECLARE_GLOBAL_DATA_PTR; #endif static int pl01x_putc(struct pl01x_regs *regs, char c) @@ -351,9 +353,35 @@ static const struct dm_serial_ops pl01x_serial_ops = { .setbrg = pl01x_serial_setbrg, }; +#ifdef CONFIG_OF_CONTROL +static const struct udevice_id pl01x_serial_id[] ={ + {.compatible = "arm,pl011", .data = TYPE_PL011}, + {.compatible = "arm,pl010", .data = TYPE_PL010}, + {} +}; + +static int pl01x_serial_ofdata_to_platdata(struct udevice *dev) +{ + struct pl01x_serial_platdata *plat = dev_get_platdata(dev); + fdt_addr_t addr; + + addr = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg"); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + plat->base = addr; + plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "clock", 1); + plat->type = dev_get_driver_data(dev); + return 0; +} +#endif + U_BOOT_DRIVER(serial_pl01x) = { .name = "serial_pl01x", .id = UCLASS_SERIAL, + .of_match = of_match_ptr(pl01x_serial_id), + .ofdata_to_platdata = of_match_ptr(pl01x_serial_ofdata_to_platdata), + .platdata_auto_alloc_size = sizeof(struct pl01x_serial_platdata), .probe = pl01x_serial_probe, .ops = &pl01x_serial_ops, .flags = DM_FLAG_PRE_RELOC, diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c index 3c800961d1a..1b22c692d2c 100644 --- a/drivers/serial/serial_stm32.c +++ b/drivers/serial/serial_stm32.c @@ -10,11 +10,34 @@ #include <serial.h> #include <asm/arch/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 RCC_APB2ENR_USART1EN (1 << 4) - -#define USART_BASE STM32_USART1_BASE -#define RCC_USART_ENABLE RCC_APB2ENR_USART1EN +#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 { u32 sr; @@ -39,6 +62,24 @@ struct stm32_serial { 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 +}; + +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 +}; + static void stm32_serial_setbrg(void) { serial_init(); @@ -46,14 +87,17 @@ static void stm32_serial_setbrg(void) static int stm32_serial_init(void) { - struct stm32_serial *usart = (struct stm32_serial *)USART_BASE; + struct stm32_serial *usart = + (struct stm32_serial *)usart_base[USART_PORT]; u32 clock, int_div, frac_div, tmp; - if ((USART_BASE & STM32_BUS_MASK) == STM32_APB1PERIPH_BASE) { - setbits_le32(&STM32_RCC->apb1enr, RCC_USART_ENABLE); + if ((usart_base[USART_PORT] & STM32_BUS_MASK) == + STM32_APB1PERIPH_BASE) { + setbits_le32(&STM32_RCC->apb1enr, rcc_enr_en[USART_PORT]); clock = clock_get(CLOCK_APB1); - } else if ((USART_BASE & STM32_BUS_MASK) == STM32_APB2PERIPH_BASE) { - setbits_le32(&STM32_RCC->apb2enr, RCC_USART_ENABLE); + } else if ((usart_base[USART_PORT] & STM32_BUS_MASK) == + STM32_APB2PERIPH_BASE) { + setbits_le32(&STM32_RCC->apb2enr, rcc_enr_en[USART_PORT]); clock = clock_get(CLOCK_APB2); } else { return -1; @@ -72,7 +116,8 @@ static int stm32_serial_init(void) static int stm32_serial_getc(void) { - struct stm32_serial *usart = (struct stm32_serial *)USART_BASE; + struct stm32_serial *usart = + (struct stm32_serial *)usart_base[USART_PORT]; while ((readl(&usart->sr) & USART_SR_FLAG_RXNE) == 0) ; return readl(&usart->dr); @@ -80,7 +125,9 @@ static int stm32_serial_getc(void) static void stm32_serial_putc(const char c) { - struct stm32_serial *usart = (struct stm32_serial *)USART_BASE; + struct stm32_serial *usart = + (struct stm32_serial *)usart_base[USART_PORT]; + while ((readl(&usart->sr) & USART_SR_FLAG_TXE) == 0) ; writel(c, &usart->dr); @@ -88,7 +135,8 @@ static void stm32_serial_putc(const char c) static int stm32_serial_tstc(void) { - struct stm32_serial *usart = (struct stm32_serial *)USART_BASE; + struct stm32_serial *usart = + (struct stm32_serial *)usart_base[USART_PORT]; u8 ret; ret = readl(&usart->sr) & USART_SR_FLAG_RXNE; |