From: Patrice Chotard Date: Fri, 12 Jan 2018 08:23:49 +0000 (+0100) Subject: serial: stm32: Rename serial_stm32x7.c to serial_stm32.c X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=ae74de0dfd4543a18cf1aee68eb1daeb9c125fde;p=project%2Fbcm63xx%2Fu-boot.git serial: stm32: Rename serial_stm32x7.c to serial_stm32.c Now this driver is used across stm32f4, stm32f7 and stm32h7 SoCs family, give it a generic name. Signed-off-by: Patrice Chotard Reviewed-by: Vikas Manocha --- diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig index b618b60795..f4c93f1afb 100644 --- a/arch/arm/mach-stm32/Kconfig +++ b/arch/arm/mach-stm32/Kconfig @@ -38,7 +38,7 @@ config STM32H7 select STM32_SDRAM select STM32_RCC select STM32_RESET - select STM32X7_SERIAL + select STM32_SERIAL select SYSCON source "arch/arm/mach-stm32/stm32f4/Kconfig" diff --git a/configs/stm32f429-discovery_defconfig b/configs/stm32f429-discovery_defconfig index 52bd9319b3..6f7a12f037 100644 --- a/configs/stm32f429-discovery_defconfig +++ b/configs/stm32f429-discovery_defconfig @@ -31,4 +31,4 @@ CONFIG_RAM=y CONFIG_STM32_SDRAM=y CONFIG_DM_RESET=y CONFIG_STM32_RESET=y -CONFIG_STM32X7_SERIAL=y +CONFIG_STM32_SERIAL=y diff --git a/configs/stm32f469-discovery_defconfig b/configs/stm32f469-discovery_defconfig index afffddfc11..5b70aa9f12 100644 --- a/configs/stm32f469-discovery_defconfig +++ b/configs/stm32f469-discovery_defconfig @@ -39,4 +39,4 @@ CONFIG_RAM=y CONFIG_STM32_SDRAM=y CONFIG_DM_RESET=y CONFIG_STM32_RESET=y -CONFIG_STM32X7_SERIAL=y +CONFIG_STM32_SERIAL=y diff --git a/configs/stm32f746-disco_defconfig b/configs/stm32f746-disco_defconfig index 321321fbe8..69df866457 100644 --- a/configs/stm32f746-disco_defconfig +++ b/configs/stm32f746-disco_defconfig @@ -60,7 +60,7 @@ CONFIG_RAM=y CONFIG_STM32_SDRAM=y CONFIG_DM_RESET=y CONFIG_STM32_RESET=y -CONFIG_STM32X7_SERIAL=y +CONFIG_STM32_SERIAL=y CONFIG_DM_SPI=y CONFIG_STM32_QSPI=y CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 122b8e786a..7b20b47964 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -529,7 +529,7 @@ config STI_ASC_SERIAL on STiH410 SoC. This is a basic implementation, it supports following baudrate 9600, 19200, 38400, 57600 and 115200. -config STM32X7_SERIAL +config STM32_SERIAL bool "STMicroelectronics STM32 SoCs on-chip UART" depends on DM_SERIAL && (STM32F4 || STM32F7 || STM32H7) help diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 7adcee3e10..5ef603ab15 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -44,7 +44,7 @@ obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o obj-$(CONFIG_STM32_SERIAL) += serial_stm32.o obj-$(CONFIG_STI_ASC_SERIAL) += serial_sti_asc.o obj-$(CONFIG_PIC32_SERIAL) += serial_pic32.o -obj-$(CONFIG_STM32X7_SERIAL) += serial_stm32x7.o +obj-$(CONFIG_STM32_SERIAL) += serial_stm32.o obj-$(CONFIG_BCM283X_MU_SERIAL) += serial_bcm283x_mu.o obj-$(CONFIG_MSM_SERIAL) += serial_msm.o obj-$(CONFIG_MVEBU_A3700_UART) += serial_mvebu_a3700.o diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c new file mode 100644 index 0000000000..286b954fdd --- /dev/null +++ b/drivers/serial/serial_stm32.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2016, STMicroelectronics - All Rights Reserved + * Author(s): Vikas Manocha, for STMicroelectronics. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include "serial_stm32.h" + +DECLARE_GLOBAL_DATA_PTR; + +static int stm32_serial_setbrg(struct udevice *dev, int baudrate) +{ + struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); + bool stm32f4 = plat->uart_info->stm32f4; + fdt_addr_t base = plat->base; + u32 int_div, mantissa, fraction, oversampling; + + int_div = DIV_ROUND_CLOSEST(plat->clock_rate, baudrate); + + if (int_div < 16) { + oversampling = 8; + setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_OVER8); + } else { + oversampling = 16; + clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_OVER8); + } + + mantissa = (int_div / oversampling) << USART_BRR_M_SHIFT; + fraction = int_div % oversampling; + + writel(mantissa | fraction, base + BRR_OFFSET(stm32f4)); + + return 0; +} + +static int stm32_serial_getc(struct udevice *dev) +{ + struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); + bool stm32f4 = plat->uart_info->stm32f4; + fdt_addr_t base = plat->base; + + if ((readl(base + ISR_OFFSET(stm32f4)) & USART_SR_FLAG_RXNE) == 0) + return -EAGAIN; + + return readl(base + RDR_OFFSET(stm32f4)); +} + +static int stm32_serial_putc(struct udevice *dev, const char c) +{ + struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); + bool stm32f4 = plat->uart_info->stm32f4; + fdt_addr_t base = plat->base; + + if ((readl(base + ISR_OFFSET(stm32f4)) & USART_SR_FLAG_TXE) == 0) + return -EAGAIN; + + writel(c, base + TDR_OFFSET(stm32f4)); + + return 0; +} + +static int stm32_serial_pending(struct udevice *dev, bool input) +{ + struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); + bool stm32f4 = plat->uart_info->stm32f4; + fdt_addr_t base = plat->base; + + if (input) + return readl(base + ISR_OFFSET(stm32f4)) & + USART_SR_FLAG_RXNE ? 1 : 0; + else + return readl(base + ISR_OFFSET(stm32f4)) & + USART_SR_FLAG_TXE ? 0 : 1; +} + +static int stm32_serial_probe(struct udevice *dev) +{ + struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); + struct clk clk; + fdt_addr_t base = plat->base; + int ret; + bool stm32f4; + u8 uart_enable_bit; + + plat->uart_info = (struct stm32_uart_info *)dev_get_driver_data(dev); + stm32f4 = plat->uart_info->stm32f4; + uart_enable_bit = plat->uart_info->uart_enable_bit; + + ret = clk_get_by_index(dev, 0, &clk); + if (ret < 0) + return ret; + + ret = clk_enable(&clk); + if (ret) { + dev_err(dev, "failed to enable clock\n"); + return ret; + } + + plat->clock_rate = clk_get_rate(&clk); + if (plat->clock_rate < 0) { + clk_disable(&clk); + return plat->clock_rate; + }; + + /* Disable uart-> disable overrun-> enable uart */ + clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE | + BIT(uart_enable_bit)); + if (plat->uart_info->has_overrun_disable) + setbits_le32(base + CR3_OFFSET(stm32f4), USART_CR3_OVRDIS); + if (plat->uart_info->has_fifo) + setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_FIFOEN); + setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE | + BIT(uart_enable_bit)); + + return 0; +} + +static const struct udevice_id stm32_serial_id[] = { + { .compatible = "st,stm32-uart", .data = (ulong)&stm32f4_info}, + { .compatible = "st,stm32f7-uart", .data = (ulong)&stm32f7_info}, + { .compatible = "st,stm32h7-uart", .data = (ulong)&stm32h7_info}, + {} +}; + +static int stm32_serial_ofdata_to_platdata(struct udevice *dev) +{ + struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); + + plat->base = devfdt_get_addr(dev); + if (plat->base == FDT_ADDR_T_NONE) + return -EINVAL; + + 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, + .of_match = of_match_ptr(stm32_serial_id), + .ofdata_to_platdata = of_match_ptr(stm32_serial_ofdata_to_platdata), + .platdata_auto_alloc_size = sizeof(struct stm32x7_serial_platdata), + .ops = &stm32_serial_ops, + .probe = stm32_serial_probe, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/serial/serial_stm32.h b/drivers/serial/serial_stm32.h new file mode 100644 index 0000000000..d08ba1f55f --- /dev/null +++ b/drivers/serial/serial_stm32.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2016, STMicroelectronics - All Rights Reserved + * Author(s): Vikas Manocha, for STMicroelectronics. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SERIAL_STM32_ +#define _SERIAL_STM32_ + +#define CR1_OFFSET(x) (x ? 0x0c : 0x00) +#define CR3_OFFSET(x) (x ? 0x14 : 0x08) +#define BRR_OFFSET(x) (x ? 0x08 : 0x0c) +#define ISR_OFFSET(x) (x ? 0x00 : 0x1c) +/* + * STM32F4 has one Data Register (DR) for received or transmitted + * data, so map Receive Data Register (RDR) and Transmit Data + * Register (TDR) at the same offset + */ +#define RDR_OFFSET(x) (x ? 0x04 : 0x24) +#define TDR_OFFSET(x) (x ? 0x04 : 0x28) + +struct stm32_uart_info { + u8 uart_enable_bit; /* UART_CR1_UE */ + bool stm32f4; /* true for STM32F4, false otherwise */ + bool has_overrun_disable; + bool has_fifo; +}; + +struct stm32_uart_info stm32f4_info = { + .stm32f4 = true, + .uart_enable_bit = 13, + .has_overrun_disable = false, + .has_fifo = false, +}; + +struct stm32_uart_info stm32f7_info = { + .uart_enable_bit = 0, + .stm32f4 = false, + .has_overrun_disable = true, + .has_fifo = false, +}; + +struct stm32_uart_info stm32h7_info = { + .uart_enable_bit = 0, + .stm32f4 = false, + .has_overrun_disable = true, + .has_fifo = true, +}; + +/* Information about a serial port */ +struct stm32x7_serial_platdata { + fdt_addr_t base; /* address of registers in physical memory */ + struct stm32_uart_info *uart_info; + unsigned long int clock_rate; +}; + +#define USART_CR1_FIFOEN BIT(29) +#define USART_CR1_OVER8 BIT(15) +#define USART_CR1_TE BIT(3) +#define USART_CR1_RE BIT(2) + +#define USART_CR3_OVRDIS BIT(12) + +#define USART_SR_FLAG_RXNE BIT(5) +#define USART_SR_FLAG_TXE BIT(7) + +#define USART_BRR_F_MASK GENMASK(7, 0) +#define USART_BRR_M_SHIFT 4 +#define USART_BRR_M_MASK GENMASK(15, 4) + +#endif diff --git a/drivers/serial/serial_stm32x7.c b/drivers/serial/serial_stm32x7.c deleted file mode 100644 index d1580e3cb5..0000000000 --- a/drivers/serial/serial_stm32x7.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2016, STMicroelectronics - All Rights Reserved - * Author(s): Vikas Manocha, for STMicroelectronics. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include "serial_stm32x7.h" - -DECLARE_GLOBAL_DATA_PTR; - -static int stm32_serial_setbrg(struct udevice *dev, int baudrate) -{ - struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); - bool stm32f4 = plat->uart_info->stm32f4; - fdt_addr_t base = plat->base; - u32 int_div, mantissa, fraction, oversampling; - - int_div = DIV_ROUND_CLOSEST(plat->clock_rate, baudrate); - - if (int_div < 16) { - oversampling = 8; - setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_OVER8); - } else { - oversampling = 16; - clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_OVER8); - } - - mantissa = (int_div / oversampling) << USART_BRR_M_SHIFT; - fraction = int_div % oversampling; - - writel(mantissa | fraction, base + BRR_OFFSET(stm32f4)); - - return 0; -} - -static int stm32_serial_getc(struct udevice *dev) -{ - struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); - bool stm32f4 = plat->uart_info->stm32f4; - fdt_addr_t base = plat->base; - - if ((readl(base + ISR_OFFSET(stm32f4)) & USART_SR_FLAG_RXNE) == 0) - return -EAGAIN; - - return readl(base + RDR_OFFSET(stm32f4)); -} - -static int stm32_serial_putc(struct udevice *dev, const char c) -{ - struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); - bool stm32f4 = plat->uart_info->stm32f4; - fdt_addr_t base = plat->base; - - if ((readl(base + ISR_OFFSET(stm32f4)) & USART_SR_FLAG_TXE) == 0) - return -EAGAIN; - - writel(c, base + TDR_OFFSET(stm32f4)); - - return 0; -} - -static int stm32_serial_pending(struct udevice *dev, bool input) -{ - struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); - bool stm32f4 = plat->uart_info->stm32f4; - fdt_addr_t base = plat->base; - - if (input) - return readl(base + ISR_OFFSET(stm32f4)) & - USART_SR_FLAG_RXNE ? 1 : 0; - else - return readl(base + ISR_OFFSET(stm32f4)) & - USART_SR_FLAG_TXE ? 0 : 1; -} - -static int stm32_serial_probe(struct udevice *dev) -{ - struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); - struct clk clk; - fdt_addr_t base = plat->base; - int ret; - bool stm32f4; - u8 uart_enable_bit; - - plat->uart_info = (struct stm32_uart_info *)dev_get_driver_data(dev); - stm32f4 = plat->uart_info->stm32f4; - uart_enable_bit = plat->uart_info->uart_enable_bit; - - ret = clk_get_by_index(dev, 0, &clk); - if (ret < 0) - return ret; - - ret = clk_enable(&clk); - if (ret) { - dev_err(dev, "failed to enable clock\n"); - return ret; - } - - plat->clock_rate = clk_get_rate(&clk); - if (plat->clock_rate < 0) { - clk_disable(&clk); - return plat->clock_rate; - }; - - /* Disable uart-> disable overrun-> enable uart */ - clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE | - BIT(uart_enable_bit)); - if (plat->uart_info->has_overrun_disable) - setbits_le32(base + CR3_OFFSET(stm32f4), USART_CR3_OVRDIS); - if (plat->uart_info->has_fifo) - setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_FIFOEN); - setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE | - BIT(uart_enable_bit)); - - return 0; -} - -static const struct udevice_id stm32_serial_id[] = { - { .compatible = "st,stm32-uart", .data = (ulong)&stm32f4_info}, - { .compatible = "st,stm32f7-uart", .data = (ulong)&stm32f7_info}, - { .compatible = "st,stm32h7-uart", .data = (ulong)&stm32h7_info}, - {} -}; - -static int stm32_serial_ofdata_to_platdata(struct udevice *dev) -{ - struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); - - plat->base = devfdt_get_addr(dev); - if (plat->base == FDT_ADDR_T_NONE) - return -EINVAL; - - 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_stm32x7", - .id = UCLASS_SERIAL, - .of_match = of_match_ptr(stm32_serial_id), - .ofdata_to_platdata = of_match_ptr(stm32_serial_ofdata_to_platdata), - .platdata_auto_alloc_size = sizeof(struct stm32x7_serial_platdata), - .ops = &stm32_serial_ops, - .probe = stm32_serial_probe, - .flags = DM_FLAG_PRE_RELOC, -}; diff --git a/drivers/serial/serial_stm32x7.h b/drivers/serial/serial_stm32x7.h deleted file mode 100644 index f7dca39103..0000000000 --- a/drivers/serial/serial_stm32x7.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2016, STMicroelectronics - All Rights Reserved - * Author(s): Vikas Manocha, for STMicroelectronics. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _SERIAL_STM32_X7_ -#define _SERIAL_STM32_X7_ - -#define CR1_OFFSET(x) (x ? 0x0c : 0x00) -#define CR3_OFFSET(x) (x ? 0x14 : 0x08) -#define BRR_OFFSET(x) (x ? 0x08 : 0x0c) -#define ISR_OFFSET(x) (x ? 0x00 : 0x1c) -/* - * STM32F4 has one Data Register (DR) for received or transmitted - * data, so map Receive Data Register (RDR) and Transmit Data - * Register (TDR) at the same offset - */ -#define RDR_OFFSET(x) (x ? 0x04 : 0x24) -#define TDR_OFFSET(x) (x ? 0x04 : 0x28) - -struct stm32_uart_info { - u8 uart_enable_bit; /* UART_CR1_UE */ - bool stm32f4; /* true for STM32F4, false otherwise */ - bool has_overrun_disable; - bool has_fifo; -}; - -struct stm32_uart_info stm32f4_info = { - .stm32f4 = true, - .uart_enable_bit = 13, - .has_overrun_disable = false, - .has_fifo = false, -}; - -struct stm32_uart_info stm32f7_info = { - .uart_enable_bit = 0, - .stm32f4 = false, - .has_overrun_disable = true, - .has_fifo = false, -}; - -struct stm32_uart_info stm32h7_info = { - .uart_enable_bit = 0, - .stm32f4 = false, - .has_overrun_disable = true, - .has_fifo = true, -}; - -/* Information about a serial port */ -struct stm32x7_serial_platdata { - fdt_addr_t base; /* address of registers in physical memory */ - struct stm32_uart_info *uart_info; - unsigned long int clock_rate; -}; - -#define USART_CR1_FIFOEN BIT(29) -#define USART_CR1_OVER8 BIT(15) -#define USART_CR1_TE BIT(3) -#define USART_CR1_RE BIT(2) - -#define USART_CR3_OVRDIS BIT(12) - -#define USART_SR_FLAG_RXNE BIT(5) -#define USART_SR_FLAG_TXE BIT(7) - -#define USART_BRR_F_MASK GENMASK(7, 0) -#define USART_BRR_M_SHIFT 4 -#define USART_BRR_M_MASK GENMASK(15, 4) - -#endif