[U-Boot] [PATCH 0/7] Add STMicroelectronics STiH410-B2260 board support

From: Patrice Chotard patrice.chotard@st.com
This board is a 96board based on STiH410 SoC. This series adds basic support with serial, mmc and pinctrl support.
v2: _ fix remarks from Jaechon Chung on SDHCI patch _ fix remarks from Antonio Borneo on board patch _ replace some macro by U-boot generic's one _ add missing maintainers in recipients
Patrice Chotard (7): arm: Add support for STMicroelectronics STiH410 soc board: Add STMicroelectronics STiH410-B2260 support STiH410: Add STi serial driver STiH410: Add STi SDHCI driver STiH410: add STi pinctrl driver STiH410-B2260: add device tree STIH410-B2260: Add STiH410-B2260 defconfig
arch/arm/Kconfig | 13 + arch/arm/Makefile | 1 + arch/arm/dts/Makefile | 2 + arch/arm/dts/st-pincfg.h | 71 ++ arch/arm/dts/stih407-clock.dtsi | 326 ++++++ arch/arm/dts/stih407-family.dtsi | 977 +++++++++++++++ arch/arm/dts/stih407-pinctrl.dtsi | 1303 +++++++++++++++++++++ arch/arm/dts/stih410-b2260.dts | 225 ++++ arch/arm/dts/stih410-clock.dtsi | 347 ++++++ arch/arm/dts/stih410-pinctrl.dtsi | 34 + arch/arm/dts/stih410.dtsi | 454 +++++++ arch/arm/include/asm/arch-stih410/gpio.h | 20 + arch/arm/include/asm/arch-stih410/sdhci.h | 69 ++ arch/arm/include/asm/arch-stih410/sti.h | 20 + arch/arm/include/asm/arch-stih410/syscfg.h | 20 + arch/arm/mach-sti/Kconfig | 31 + arch/arm/mach-sti/Makefile | 8 + arch/arm/mach-sti/cpu.c | 16 + arch/arm/mach-sti/timer.c | 47 + board/st/stih410-b2260/Kconfig | 19 + board/st/stih410-b2260/MAINTAINERS | 6 + board/st/stih410-b2260/Makefile | 8 + board/st/stih410-b2260/board.c | 40 + configs/stih410-b2260_defconfig | 22 + drivers/mmc/Kconfig | 7 + drivers/mmc/Makefile | 1 + drivers/mmc/sti_sdhci.c | 140 +++ drivers/pinctrl/Kconfig | 10 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-sti.c | 315 +++++ drivers/serial/Kconfig | 7 + drivers/serial/Makefile | 1 + drivers/serial/serial_sti_asc.c | 219 ++++ include/configs/stih410-b2260.h | 59 + include/dm/platform_data/serial_sti_asc.h | 17 + include/dt-bindings/clock/stih407-clks.h | 90 ++ include/dt-bindings/clock/stih410-clks.h | 25 + include/dt-bindings/interrupt-controller/irq-st.h | 30 + include/dt-bindings/mfd/st-lpc.h | 16 + include/dt-bindings/reset/stih407-resets.h | 65 + 40 files changed, 5082 insertions(+) create mode 100644 arch/arm/dts/st-pincfg.h create mode 100644 arch/arm/dts/stih407-clock.dtsi create mode 100644 arch/arm/dts/stih407-family.dtsi create mode 100644 arch/arm/dts/stih407-pinctrl.dtsi create mode 100644 arch/arm/dts/stih410-b2260.dts create mode 100644 arch/arm/dts/stih410-clock.dtsi create mode 100644 arch/arm/dts/stih410-pinctrl.dtsi create mode 100644 arch/arm/dts/stih410.dtsi create mode 100644 arch/arm/include/asm/arch-stih410/gpio.h create mode 100644 arch/arm/include/asm/arch-stih410/sdhci.h create mode 100644 arch/arm/include/asm/arch-stih410/sti.h create mode 100644 arch/arm/include/asm/arch-stih410/syscfg.h create mode 100644 arch/arm/mach-sti/Kconfig create mode 100644 arch/arm/mach-sti/Makefile create mode 100644 arch/arm/mach-sti/cpu.c create mode 100644 arch/arm/mach-sti/timer.c create mode 100644 board/st/stih410-b2260/Kconfig create mode 100644 board/st/stih410-b2260/MAINTAINERS create mode 100644 board/st/stih410-b2260/Makefile create mode 100644 board/st/stih410-b2260/board.c create mode 100644 configs/stih410-b2260_defconfig create mode 100644 drivers/mmc/sti_sdhci.c create mode 100644 drivers/pinctrl/pinctrl-sti.c create mode 100644 drivers/serial/serial_sti_asc.c create mode 100644 include/configs/stih410-b2260.h create mode 100644 include/dm/platform_data/serial_sti_asc.h create mode 100644 include/dt-bindings/clock/stih407-clks.h create mode 100644 include/dt-bindings/clock/stih410-clks.h create mode 100644 include/dt-bindings/interrupt-controller/irq-st.h create mode 100644 include/dt-bindings/mfd/st-lpc.h create mode 100644 include/dt-bindings/reset/stih407-resets.h

From: Patrice Chotard patrice.chotard@st.com
The STiH410 is an advanced multi-HD AVC processor with 3D graphics acceleration and 1.5-GHz ARM Cortex-A9 SMP CPU part of the stih407 family.
It has wide connectivity including USB 3.0, PCI-e, SATA and gigabit ethernet.
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- arch/arm/Kconfig | 9 ++++++ arch/arm/Makefile | 1 + arch/arm/include/asm/arch-stih410/gpio.h | 20 +++++++++++++ arch/arm/include/asm/arch-stih410/sti.h | 14 +++++++++ arch/arm/include/asm/arch-stih410/syscfg.h | 20 +++++++++++++ arch/arm/mach-sti/Kconfig | 31 ++++++++++++++++++++ arch/arm/mach-sti/Makefile | 8 +++++ arch/arm/mach-sti/cpu.c | 16 ++++++++++ arch/arm/mach-sti/timer.c | 47 ++++++++++++++++++++++++++++++ 9 files changed, 166 insertions(+) create mode 100644 arch/arm/include/asm/arch-stih410/gpio.h create mode 100644 arch/arm/include/asm/arch-stih410/sti.h create mode 100644 arch/arm/include/asm/arch-stih410/syscfg.h create mode 100644 arch/arm/mach-sti/Kconfig create mode 100644 arch/arm/mach-sti/Makefile create mode 100644 arch/arm/mach-sti/cpu.c create mode 100644 arch/arm/mach-sti/timer.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0229800..4aa5eb9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -982,6 +982,13 @@ config STM32 select DM select DM_SERIAL
+config ARCH_STI + bool "Support STMicrolectronics SoCs" + select CPU_V7 + help + Support for STMicroelectronics STiH407/10 SoC family. + This SoC is used on Linaro 96Board STiH410-B2260 + config ARCH_ROCKCHIP bool "Support Rockchip SoCs" select OF_CONTROL @@ -1060,6 +1067,8 @@ source "arch/arm/mach-snapdragon/Kconfig"
source "arch/arm/mach-socfpga/Kconfig"
+source "arch/arm/mach-sti/Kconfig" + source "arch/arm/mach-stm32/Kconfig"
source "arch/arm/mach-tegra/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 0d94700..116f661 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -71,6 +71,7 @@ machine-$(CONFIG_ARCH_SNAPDRAGON) += snapdragon machine-$(CONFIG_ARCH_SOCFPGA) += socfpga machine-$(CONFIG_ARCH_RMOBILE) += rmobile machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip +machine-$(CONFIG_ARCH_STI) += sti machine-$(CONFIG_STM32) += stm32 machine-$(CONFIG_TEGRA) += tegra machine-$(CONFIG_ARCH_UNIPHIER) += uniphier diff --git a/arch/arm/include/asm/arch-stih410/gpio.h b/arch/arm/include/asm/arch-stih410/gpio.h new file mode 100644 index 0000000..977b3f8 --- /dev/null +++ b/arch/arm/include/asm/arch-stih410/gpio.h @@ -0,0 +1,20 @@ +/* + * pins definition for STiH410-B2260 + * + * (C) Copyright 2017 Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _STI_GPIO_H_ +#define _STI_GPIO_H_ + +struct sti_pin_desc { + unsigned char bank; + unsigned char pin; + unsigned char alt; + int dir; +}; + +#endif /* _STI_GPIO_H_ */ + diff --git a/arch/arm/include/asm/arch-stih410/sti.h b/arch/arm/include/asm/arch-stih410/sti.h new file mode 100644 index 0000000..d35c4f0 --- /dev/null +++ b/arch/arm/include/asm/arch-stih410/sti.h @@ -0,0 +1,14 @@ +/* + * (C) Copyright 2017 Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _STI_H_ +#define _STI_H_ + +/* A9_GLOBAL_TIMER_BASE */ +#define STI_A9_CONFIG_BASE 0x08760000 +#define STI_A9_GLOBAL_TIMER_BASE (STI_A9_CONFIG_BASE + 0x0200) + +#endif /* _STI_H_ */ diff --git a/arch/arm/include/asm/arch-stih410/syscfg.h b/arch/arm/include/asm/arch-stih410/syscfg.h new file mode 100644 index 0000000..e027d74 --- /dev/null +++ b/arch/arm/include/asm/arch-stih410/syscfg.h @@ -0,0 +1,20 @@ +/* + * Configuration/Status Registers for STiH410 SoC + * + * (C) Copyright 2017 Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _STI_SYSCFG_H_ +#define _STI_SYSCFG_H_ + +#define STIH410_SYSCONF0_BASE 0x09620000 /* 0-999 */ +#define STIH410_SYSCONF1_BASE 0x09280000 /* 1000-1999 */ +#define STIH410_SYSCONF2_BASE 0x09290000 /* 2000-2999 */ +#define STIH410_SYSCONF3_BASE 0x092a0000 /* 3000-3999 */ +#define STIH410_SYSCONF4_BASE 0x09600000 /* 4000-4999 */ +#define STIH410_SYSCONF5_BASE 0x092b0000 /* 5000-5999 */ +#define STIH410_SYSCONF6_BASE 0x092c0000 /* 6000-6999 */ + +#endif /* _STI_SYSCFG_ */ diff --git a/arch/arm/mach-sti/Kconfig b/arch/arm/mach-sti/Kconfig new file mode 100644 index 0000000..67a3b24 --- /dev/null +++ b/arch/arm/mach-sti/Kconfig @@ -0,0 +1,31 @@ +if ARCH_STI + +config SYS_SOC + default "stih410" + +choice + prompt "STiH410 board select" + +config TARGET_STIH410_B2260 + bool "96Boards STiH410-B2260" + help + Support for 96Board STiH410-B2260 based on STMicrolectronics + STiH410 soc. This board complies with 96Board Open Platform + Specifications. Features: + - 1GB DDR + - On-Board USB combo WiFi/Bluetooth RTL8723BU + with PCB soldered antenna + - Ethernet 1000-BaseT + - Sata + - HDMI + - 2 x USB2 type A + - micro USB2 type AB + - SD card slot + - High speed connector (SD/I2C/USB interfaces) + - Slow speed connector (UART/I2C/GPIO/SPI/PCM interfaces) + +endchoice + +source "board/st/stih410-b2260/Kconfig" + +endif diff --git a/arch/arm/mach-sti/Makefile b/arch/arm/mach-sti/Makefile new file mode 100644 index 0000000..a97101d --- /dev/null +++ b/arch/arm/mach-sti/Makefile @@ -0,0 +1,8 @@ +# +# (C) Copyright 2017 +# Patrice Chotard, patrice.chotard@st.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += cpu.o timer.o diff --git a/arch/arm/mach-sti/cpu.c b/arch/arm/mach-sti/cpu.c new file mode 100644 index 0000000..e8c3fd2 --- /dev/null +++ b/arch/arm/mach-sti/cpu.c @@ -0,0 +1,16 @@ +/* + * (C) Copyright 2017 Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <asm/arch/syscfg.h> +#include <asm/io.h> + +void reset_cpu(ulong addr) +{ + unsigned long *sysconf; + + sysconf = (unsigned long *)STIH410_SYSCONF4_BASE; + generic_clear_bit(0, sysconf); +} diff --git a/arch/arm/mach-sti/timer.c b/arch/arm/mach-sti/timer.c new file mode 100644 index 0000000..cf4511f --- /dev/null +++ b/arch/arm/mach-sti/timer.c @@ -0,0 +1,47 @@ +/* + * (C) Copyright 2017 Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/sti.h> +#include <asm/arch-armv7/globaltimer.h> + +static struct globaltimer * const global_timer = + (struct globaltimer *)STI_A9_GLOBAL_TIMER_BASE; + +static u64 get_cpu_global_timer(void) +{ + u32 low, high; + u64 timer; + + u32 old = readl(&global_timer->cnt_h); + while (1) { + low = readl(&global_timer->cnt_l); + high = readl(&global_timer->cnt_h); + if (old == high) + break; + else + old = high; + } + timer = high; + return (u64)((timer << 32) | low); +} + +int timer_init(void) +{ + writel(0x01, &global_timer->ctl); + return 0; +} + +unsigned long long get_ticks(void) +{ + return get_cpu_global_timer(); +} + +ulong get_tbclk(void) +{ + return (ulong)(CONFIG_SYS_HZ_CLOCK >> 1); +}

H Patrice,
On 2 February 2017 at 09:00, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
The STiH410 is an advanced multi-HD AVC processor with 3D graphics acceleration and 1.5-GHz ARM Cortex-A9 SMP CPU part of the stih407 family.
It has wide connectivity including USB 3.0, PCI-e, SATA and gigabit ethernet.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
arch/arm/Kconfig | 9 ++++++ arch/arm/Makefile | 1 + arch/arm/include/asm/arch-stih410/gpio.h | 20 +++++++++++++ arch/arm/include/asm/arch-stih410/sti.h | 14 +++++++++ arch/arm/include/asm/arch-stih410/syscfg.h | 20 +++++++++++++ arch/arm/mach-sti/Kconfig | 31 ++++++++++++++++++++ arch/arm/mach-sti/Makefile | 8 +++++ arch/arm/mach-sti/cpu.c | 16 ++++++++++ arch/arm/mach-sti/timer.c | 47 ++++++++++++++++++++++++++++++ 9 files changed, 166 insertions(+) create mode 100644 arch/arm/include/asm/arch-stih410/gpio.h create mode 100644 arch/arm/include/asm/arch-stih410/sti.h create mode 100644 arch/arm/include/asm/arch-stih410/syscfg.h create mode 100644 arch/arm/mach-sti/Kconfig create mode 100644 arch/arm/mach-sti/Makefile create mode 100644 arch/arm/mach-sti/cpu.c create mode 100644 arch/arm/mach-sti/timer.c
Are you able to use driver model for the timer (and maybe even CPU)?
Regards, Simon

Hi Simon
On 02/06/2017 04:34 PM, Simon Glass wrote:
H Patrice,
On 2 February 2017 at 09:00, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
The STiH410 is an advanced multi-HD AVC processor with 3D graphics acceleration and 1.5-GHz ARM Cortex-A9 SMP CPU part of the stih407 family.
It has wide connectivity including USB 3.0, PCI-e, SATA and gigabit ethernet.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
arch/arm/Kconfig | 9 ++++++ arch/arm/Makefile | 1 + arch/arm/include/asm/arch-stih410/gpio.h | 20 +++++++++++++ arch/arm/include/asm/arch-stih410/sti.h | 14 +++++++++ arch/arm/include/asm/arch-stih410/syscfg.h | 20 +++++++++++++ arch/arm/mach-sti/Kconfig | 31 ++++++++++++++++++++ arch/arm/mach-sti/Makefile | 8 +++++ arch/arm/mach-sti/cpu.c | 16 ++++++++++ arch/arm/mach-sti/timer.c | 47 ++++++++++++++++++++++++++++++ 9 files changed, 166 insertions(+) create mode 100644 arch/arm/include/asm/arch-stih410/gpio.h create mode 100644 arch/arm/include/asm/arch-stih410/sti.h create mode 100644 arch/arm/include/asm/arch-stih410/syscfg.h create mode 100644 arch/arm/mach-sti/Kconfig create mode 100644 arch/arm/mach-sti/Makefile create mode 100644 arch/arm/mach-sti/cpu.c create mode 100644 arch/arm/mach-sti/timer.c
Are you able to use driver model for the timer (and maybe even CPU)?
I will have a look at this and will try to convert timer and CPU do DM in the next series submission
Thanks
Patrice
Regards, Simon

From: Patrice Chotard patrice.chotard@st.com
This is a 96Board compliant board based on STiH410 SoC: - 1GB DDR - On-Board USB combo WiFi/Bluetooth RTL8723BU with PCB soldered antenna - Ethernet 1000-BaseT - SAtA - HDMI - 2 x USB2.0 type A - 1 x USB2.0 type micro-AB - SD card slot - High speed connector (SD/I2C/USB interfaces) - Low speed connector (UART/I2C/GPIO/SPI/PCM interfaces)
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- board/st/stih410-b2260/Kconfig | 19 +++++++++++++ board/st/stih410-b2260/MAINTAINERS | 6 ++++ board/st/stih410-b2260/Makefile | 8 ++++++ board/st/stih410-b2260/board.c | 28 ++++++++++++++++++ include/configs/stih410-b2260.h | 58 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 119 insertions(+) create mode 100644 board/st/stih410-b2260/Kconfig create mode 100644 board/st/stih410-b2260/MAINTAINERS create mode 100644 board/st/stih410-b2260/Makefile create mode 100644 board/st/stih410-b2260/board.c create mode 100644 include/configs/stih410-b2260.h
diff --git a/board/st/stih410-b2260/Kconfig b/board/st/stih410-b2260/Kconfig new file mode 100644 index 0000000..590add0 --- /dev/null +++ b/board/st/stih410-b2260/Kconfig @@ -0,0 +1,19 @@ +if TARGET_STIH410_B2260 + +config SYS_BOARD + string + default "stih410-b2260" + +config SYS_VENDOR + string + default "st" + +config SYS_SOC + string + default "stih410" + +config SYS_CONFIG_NAME + string + default "stih410-b2260" + +endif diff --git a/board/st/stih410-b2260/MAINTAINERS b/board/st/stih410-b2260/MAINTAINERS new file mode 100644 index 0000000..e78c69a --- /dev/null +++ b/board/st/stih410-b2260/MAINTAINERS @@ -0,0 +1,6 @@ +STIH410-B2260 BOARD +M: Patrice Chotard patrice.chotard@st.com +S: Maintained +F: board/st/stih410-b2260/ +F: include/configs/stih410-b2260.h +F: configs/stih410-b2260_defconfig diff --git a/board/st/stih410-b2260/Makefile b/board/st/stih410-b2260/Makefile new file mode 100644 index 0000000..68a7903 --- /dev/null +++ b/board/st/stih410-b2260/Makefile @@ -0,0 +1,8 @@ +# +# (C) Copyright 2017 +# Patrice Chotard, patrice.chotard@st.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = board.o diff --git a/board/st/stih410-b2260/board.c b/board/st/stih410-b2260/board.c new file mode 100644 index 0000000..0c06bca --- /dev/null +++ b/board/st/stih410-b2260/board.c @@ -0,0 +1,28 @@ +/* + * Board init file for STiH410-B2260 + * + * (C) Copyright 2017 Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + gd->ram_size = PHYS_SDRAM_1_SIZE; + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; +} + +int board_init(void) +{ + return 0; +} diff --git a/include/configs/stih410-b2260.h b/include/configs/stih410-b2260.h new file mode 100644 index 0000000..fade7a1 --- /dev/null +++ b/include/configs/stih410-b2260.h @@ -0,0 +1,58 @@ +/* + * (C) Copyright 2017 + * Patrice Chotard, patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* ram memory-related information */ +#define CONFIG_NR_DRAM_BANKS 1 +#define PHYS_SDRAM_1 0x40000000 +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 +#define PHYS_SDRAM_1_SIZE 0x3FE00000 +#define CONFIG_SYS_TEXT_BASE 0x7D600000 +#define CONFIG_SYS_LOAD_ADDR PHYS_SDRAM_1 /* default load addr */ + +#define CONFIG_BAUDRATE 115200 + +#define CONFIG_SYS_HZ_CLOCK 1000000000 /* 1 GHz */ + +/* Libraries */ +#define CONFIG_MD5 + +#define CONFIG_BOOTARGS \ + "console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel" + +/* Environment */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "board= B2260" \ + "load_addr= #CONFIG_SYS_LOAD_ADDR \0" + +#define CONFIG_ENV_IS_NOWHERE +#define CONFIG_ENV_SIZE 0x4000 +#define CONFIG_SYS_NO_FLASH + +/* Extra Commands */ +#define CONFIG_CMD_ASKENV + +#define CONFIG_SETUP_MEMORY_TAGS + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN 0x1800000 +#define CONFIG_SYS_GBL_DATA_SIZE 1024 /* Global data structures */ +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE - \ + CONFIG_SYS_MALLOC_LEN - \ + CONFIG_SYS_GBL_DATA_SIZE) + +/* Monitor Command Prompt */ +#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */ + +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_SYS_MAX_FLASH_BANKS 1 + +#define CONFIG_SKIP_LOWLEVEL_INIT + +#endif /* __CONFIG_H */

From: Patrice Chotard patrice.chotard@st.com
This patch adds support to ASC (asynchronous serial controller) driver, which is basically a standard serial driver. This IP is common across other STMicroelectronics SoCs
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- arch/arm/Kconfig | 2 + arch/arm/include/asm/arch-stih410/sti.h | 6 + board/st/stih410-b2260/board.c | 12 ++ drivers/serial/Kconfig | 7 + drivers/serial/Makefile | 1 + drivers/serial/serial_sti_asc.c | 219 ++++++++++++++++++++++++++++++ include/configs/stih410-b2260.h | 1 + include/dm/platform_data/serial_sti_asc.h | 17 +++ 8 files changed, 265 insertions(+) create mode 100644 drivers/serial/serial_sti_asc.c create mode 100644 include/dm/platform_data/serial_sti_asc.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4aa5eb9..b91a5b7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -985,6 +985,8 @@ config STM32 config ARCH_STI bool "Support STMicrolectronics SoCs" select CPU_V7 + select DM + select DM_SERIAL help Support for STMicroelectronics STiH407/10 SoC family. This SoC is used on Linaro 96Board STiH410-B2260 diff --git a/arch/arm/include/asm/arch-stih410/sti.h b/arch/arm/include/asm/arch-stih410/sti.h index d35c4f0..f167560 100644 --- a/arch/arm/include/asm/arch-stih410/sti.h +++ b/arch/arm/include/asm/arch-stih410/sti.h @@ -11,4 +11,10 @@ #define STI_A9_CONFIG_BASE 0x08760000 #define STI_A9_GLOBAL_TIMER_BASE (STI_A9_CONFIG_BASE + 0x0200)
+/* STiH410 control registers */ +#define STIH410_COMMS_BASE 0x09800000 + +/* ASC UART located in the main "COMMs" block */ +#define STIH410_ASC1_BASE (STIH410_COMMS_BASE + 0x00031000) + #endif /* _STI_H_ */ diff --git a/board/st/stih410-b2260/board.c b/board/st/stih410-b2260/board.c index 0c06bca..b2cfa7f 100644 --- a/board/st/stih410-b2260/board.c +++ b/board/st/stih410-b2260/board.c @@ -7,6 +7,9 @@ */
#include <common.h> +#include <asm/arch/sti.h> +#include <dm/platdata.h> +#include <dm/platform_data/serial_sti_asc.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -26,3 +29,12 @@ int board_init(void) { return 0; } + +static const struct sti_asc_serial_platdata serial_platdata = { + .base = (struct sti_asc_uart *)STIH410_ASC1_BASE, +}; + +U_BOOT_DEVICE(sti_asc) = { + .name = "serial_sti_asc", + .platdata = &serial_platdata, +}; diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index b11f3ff..7557632 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -413,4 +413,11 @@ config PXA_SERIAL If you have a machine based on a Marvell XScale PXA2xx CPU you can enable its onboard serial ports by enabling this option.
+config STI_ASC_SERIAL + bool "STMicroelectronics on-chip UART" + depends on DM_SERIAL && ARCH_STI + help + Select this to enable Asynchronous Serial Controller available + on STiH410 SoC. + endmenu diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 8430668..84a22ce 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_FSL_LINFLEXUART) += serial_linflexuart.o obj-$(CONFIG_ARC_SERIAL) += serial_arc.o 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_BCM283X_MU_SERIAL) += serial_bcm283x_mu.o diff --git a/drivers/serial/serial_sti_asc.c b/drivers/serial/serial_sti_asc.c new file mode 100644 index 0000000..5279836 --- /dev/null +++ b/drivers/serial/serial_sti_asc.c @@ -0,0 +1,219 @@ +/* + * Support for Serial I/O using STMicroelectronics' on-chip ASC. + * + * Copyright (c) 2017 + * Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <serial.h> +#include <asm/arch/sti.h> +#include <asm/io.h> +#include <dm/platform_data/serial_sti_asc.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define BAUDMODE 0x00001000 +#define RXENABLE 0x00000100 +#define RUN 0x00000080 +#define MODE 0x00000001 +#define MODE_8BIT 0x0001 +#define STOP_1BIT 0x0008 +#define PARITYODD 0x0020 + +#define STA_TF 0x0200 +#define STA_RBF 0x0001 + +struct sti_asc_uart { + u32 baudrate; + u32 txbuf; + u32 rxbuf; + u32 control; + u32 inten; + u32 status; + u32 guardtime; + u32 timeout; + u32 txreset; + u32 rxreset; +}; + +/*---- Values for the BAUDRATE Register -----------------------*/ +#define PCLK (200ul * 1000000ul) +#define BAUDRATE_VAL_M0(bps) (PCLK / (16 * (bps))) +#define BAUDRATE_VAL_M1(bps) ((bps * (1 << 14)) + (1<<13)) / (PCLK/(1 << 6)) + +/* + * MODE 0 + * ICCLK + * ASCBaudRate = ---------------- + * baudrate * 16 + * + * MODE 1 + * baudrate * 16 * 2^16 + * ASCBaudRate = ------------------------ + * ICCLK + * + * NOTE: + * Mode 1 should be used for baudrates of 19200, and above, as it + * has a lower deviation error than Mode 0 for higher frequencies. + * Mode 0 should be used for all baudrates below 19200. + */ + +static int sti_asc_pending(struct udevice *dev, bool input) +{ + struct sti_asc_serial_platdata *plat = dev->platdata; + struct sti_asc_uart *const uart = plat->base; + unsigned long status; + + status = readl(&uart->status); + if (input) + return status & STA_RBF; + else + return status & STA_TF; +} + +/* called to adjust baud-rate */ +static int sti_asc_serial_setbrg(struct udevice *dev, int baudrate) +{ + struct sti_asc_serial_platdata *plat = dev->platdata; + struct sti_asc_uart *const uart = plat->base; + + unsigned long val; + int t, mode = 1; + + switch (baudrate) { + case 9600: + t = BAUDRATE_VAL_M0(9600); + mode = 0; + break; + case 19200: + t = BAUDRATE_VAL_M1(19200); + break; + case 38400: + t = BAUDRATE_VAL_M1(38400); + break; + case 57600: + t = BAUDRATE_VAL_M1(57600); + break; + default: + printf("ASC: unsupported baud rate: %d, using 115200 instead.\n", + baudrate); + case 115200: + t = BAUDRATE_VAL_M1(115200); + break; + } + + /* wait for end of current transmission */ + while (sti_asc_pending(dev, false)) + ; + + /* disable the baudrate generator */ + val = readl(&uart->control); + writel((val & ~RUN), &uart->control); + + /* set baud generator reload value */ + writel(t, &uart->baudrate); + /* reset the RX & TX buffers */ + writel(1, &uart->txreset); + writel(1, &uart->rxreset); + + /* set baud generator mode */ + if (mode) + val |= BAUDMODE; + + /* finally, write value and enable ASC */ + writel(val, &uart->control); + + return 0; +} + +/* initialize the ASC */ +static int sti_asc_serial_probe(struct udevice *dev) +{ + struct sti_asc_serial_platdata *plat = dev->platdata; + struct sti_asc_uart *const uart = plat->base; + unsigned long val; + + sti_asc_serial_setbrg(dev, gd->baudrate); + + /* + * build up the value to be written to CONTROL + * set character length, bit stop number, odd parity + */ + val = RXENABLE | RUN | MODE_8BIT | STOP_1BIT | PARITYODD; + writel(val, &uart->control); + + return 0; +} + +/* blocking function, that returns next char */ +static int sti_asc_serial_getc(struct udevice *dev) +{ + struct sti_asc_serial_platdata *plat = dev->platdata; + struct sti_asc_uart *const uart = plat->base; + + /* polling wait: for a char to be read */ + if (!sti_asc_pending(dev, true)) + return -EAGAIN; + + return readl(&uart->rxbuf); +} + +/* write write out a single char */ +static int sti_asc_serial_putc(struct udevice *dev, const char c) +{ + struct sti_asc_serial_platdata *plat = dev->platdata; + struct sti_asc_uart *const uart = plat->base; + + /* Stream-LF to CR+LF conversion */ + if (c == 10) + sti_asc_serial_putc(dev, '\r'); + + /* wait till safe to write next char */ + while (sti_asc_pending(dev, false)) + ; + + /* finally, write next char */ + writel(c, &uart->txbuf); + + return 0; +} + +static int sti_ofdata_to_platdata(struct udevice *dev) +{ + struct sti_asc_serial_platdata *priv = dev_get_priv(dev); + fdt_addr_t base; + + base = dev_get_addr(dev); + if (base == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->base = (struct sti_asc_uart *)base; + + return 0; +} + +static const struct dm_serial_ops sti_asc_serial_ops = { + .putc = sti_asc_serial_putc, + .pending = sti_asc_pending, + .getc = sti_asc_serial_getc, + .setbrg = sti_asc_serial_setbrg, +}; + +static const struct udevice_id sti_serial_of_match[] = { + { .compatible = "st,asc" }, + { } +}; + +U_BOOT_DRIVER(serial_sti_asc) = { + .name = "serial_sti_asc", + .id = UCLASS_SERIAL, + .of_match = sti_serial_of_match, + .ops = &sti_asc_serial_ops, + .ofdata_to_platdata = sti_ofdata_to_platdata, + .probe = sti_asc_serial_probe, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/include/configs/stih410-b2260.h b/include/configs/stih410-b2260.h index fade7a1..4fea22a 100644 --- a/include/configs/stih410-b2260.h +++ b/include/configs/stih410-b2260.h @@ -17,6 +17,7 @@ #define CONFIG_SYS_LOAD_ADDR PHYS_SDRAM_1 /* default load addr */
#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
#define CONFIG_SYS_HZ_CLOCK 1000000000 /* 1 GHz */
diff --git a/include/dm/platform_data/serial_sti_asc.h b/include/dm/platform_data/serial_sti_asc.h new file mode 100644 index 0000000..c8631f1 --- /dev/null +++ b/include/dm/platform_data/serial_sti_asc.h @@ -0,0 +1,17 @@ +/* + * (C) Copyright 2017 + * Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __SERIAL_STI_ASC_H +#define __SERIAL_STI_ASC_H + +/* Information about a serial port */ +struct sti_asc_serial_platdata { + /* address of registers in physical memory */ + struct sti_asc_uart *base; +}; + +#endif /* __SERIAL_STI_ASC_H */

Hi Patrice,
On 2 February 2017 at 10:00, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
This patch adds support to ASC (asynchronous serial controller) driver, which is basically a standard serial driver. This IP is common across other STMicroelectronics SoCs
Signed-off-by: Patrice Chotard patrice.chotard@st.com
arch/arm/Kconfig | 2 + arch/arm/include/asm/arch-stih410/sti.h | 6 + board/st/stih410-b2260/board.c | 12 ++ drivers/serial/Kconfig | 7 + drivers/serial/Makefile | 1 + drivers/serial/serial_sti_asc.c | 219 ++++++++++++++++++++++++++++++ include/configs/stih410-b2260.h | 1 + include/dm/platform_data/serial_sti_asc.h | 17 +++ 8 files changed, 265 insertions(+) create mode 100644 drivers/serial/serial_sti_asc.c create mode 100644 include/dm/platform_data/serial_sti_asc.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4aa5eb9..b91a5b7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -985,6 +985,8 @@ config STM32 config ARCH_STI bool "Support STMicrolectronics SoCs" select CPU_V7
select DM
select DM_SERIAL help Support for STMicroelectronics STiH407/10 SoC family. This SoC is used on Linaro 96Board STiH410-B2260
diff --git a/arch/arm/include/asm/arch-stih410/sti.h b/arch/arm/include/asm/arch-stih410/sti.h index d35c4f0..f167560 100644 --- a/arch/arm/include/asm/arch-stih410/sti.h +++ b/arch/arm/include/asm/arch-stih410/sti.h @@ -11,4 +11,10 @@ #define STI_A9_CONFIG_BASE 0x08760000 #define STI_A9_GLOBAL_TIMER_BASE (STI_A9_CONFIG_BASE + 0x0200)
+/* STiH410 control registers */ +#define STIH410_COMMS_BASE 0x09800000
+/* ASC UART located in the main "COMMs" block */ +#define STIH410_ASC1_BASE (STIH410_COMMS_BASE + 0x00031000)
Can you get the address of the serial port from the device tree instead, e.g. with dev_get_addr_ptr()?
#endif /* _STI_H_ */ diff --git a/board/st/stih410-b2260/board.c b/board/st/stih410-b2260/board.c index 0c06bca..b2cfa7f 100644 --- a/board/st/stih410-b2260/board.c +++ b/board/st/stih410-b2260/board.c @@ -7,6 +7,9 @@ */
#include <common.h> +#include <asm/arch/sti.h> +#include <dm/platdata.h> +#include <dm/platform_data/serial_sti_asc.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -26,3 +29,12 @@ int board_init(void) { return 0; }
+static const struct sti_asc_serial_platdata serial_platdata = {
.base = (struct sti_asc_uart *)STIH410_ASC1_BASE,
+};
+U_BOOT_DEVICE(sti_asc) = {
.name = "serial_sti_asc",
.platdata = &serial_platdata,
+};
Can you use DT instead of platform data? You have the code for it, so why is this needed?
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index b11f3ff..7557632 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -413,4 +413,11 @@ config PXA_SERIAL If you have a machine based on a Marvell XScale PXA2xx CPU you can enable its onboard serial ports by enabling this option.
+config STI_ASC_SERIAL
bool "STMicroelectronics on-chip UART"
depends on DM_SERIAL && ARCH_STI
help
Select this to enable Asynchronous Serial Controller available
on STiH410 SoC.
Anything more to say? Maximum baud rate, or what hardware features the driver supports? E.g. it only seems to support a subset of baud rates.
endmenu diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 8430668..84a22ce 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_FSL_LINFLEXUART) += serial_linflexuart.o obj-$(CONFIG_ARC_SERIAL) += serial_arc.o 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_BCM283X_MU_SERIAL) += serial_bcm283x_mu.o diff --git a/drivers/serial/serial_sti_asc.c b/drivers/serial/serial_sti_asc.c new file mode 100644 index 0000000..5279836 --- /dev/null +++ b/drivers/serial/serial_sti_asc.c @@ -0,0 +1,219 @@ +/*
- Support for Serial I/O using STMicroelectronics' on-chip ASC.
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0
- */
+#include <common.h> +#include <dm.h> +#include <serial.h> +#include <asm/arch/sti.h> +#include <asm/io.h>
move that up one line
+#include <dm/platform_data/serial_sti_asc.h>
+DECLARE_GLOBAL_DATA_PTR;
+#define BAUDMODE 0x00001000 +#define RXENABLE 0x00000100 +#define RUN 0x00000080 +#define MODE 0x00000001 +#define MODE_8BIT 0x0001 +#define STOP_1BIT 0x0008 +#define PARITYODD 0x0020
+#define STA_TF 0x0200 +#define STA_RBF 0x0001
You could use BIT() if you like
+struct sti_asc_uart {
u32 baudrate;
u32 txbuf;
u32 rxbuf;
u32 control;
u32 inten;
u32 status;
u32 guardtime;
u32 timeout;
u32 txreset;
u32 rxreset;
+};
+/*---- Values for the BAUDRATE Register -----------------------*/
/* Values for the BAUDRATE Register */
+#define PCLK (200ul * 1000000ul) +#define BAUDRATE_VAL_M0(bps) (PCLK / (16 * (bps))) +#define BAUDRATE_VAL_M1(bps) ((bps * (1 << 14)) + (1<<13)) / (PCLK/(1 << 6))
+/*
- MODE 0
ICCLK
- ASCBaudRate = ----------------
baudrate * 16
- MODE 1
baudrate * 16 * 2^16
- ASCBaudRate = ------------------------
ICCLK
- NOTE:
- Mode 1 should be used for baudrates of 19200, and above, as it
- has a lower deviation error than Mode 0 for higher frequencies.
- Mode 0 should be used for all baudrates below 19200.
- */
+static int sti_asc_pending(struct udevice *dev, bool input) +{
struct sti_asc_serial_platdata *plat = dev->platdata;
struct sti_asc_uart *const uart = plat->base;
unsigned long status;
status = readl(&uart->status);
if (input)
return status & STA_RBF;
else
return status & STA_TF;
+}
+/* called to adjust baud-rate */ +static int sti_asc_serial_setbrg(struct udevice *dev, int baudrate) +{
struct sti_asc_serial_platdata *plat = dev->platdata;
struct sti_asc_uart *const uart = plat->base;
drop blank line
unsigned long val;
int t, mode = 1;
switch (baudrate) {
case 9600:
t = BAUDRATE_VAL_M0(9600);
mode = 0;
break;
case 19200:
t = BAUDRATE_VAL_M1(19200);
break;
case 38400:
t = BAUDRATE_VAL_M1(38400);
break;
case 57600:
t = BAUDRATE_VAL_M1(57600);
break;
default:
printf("ASC: unsupported baud rate: %d, using 115200 instead.\n",
baudrate);
debug() ?
case 115200:
t = BAUDRATE_VAL_M1(115200);
break;
}
/* wait for end of current transmission */
while (sti_asc_pending(dev, false))
;
Hmm this should not be here. We should be able to call serial_pending() to check that the device is idle, then avoid the loop here.
Maybe there is something needed in serial_uclass.c?
/* disable the baudrate generator */
val = readl(&uart->control);
writel((val & ~RUN), &uart->control);
Drop extra brackets
/* set baud generator reload value */
writel(t, &uart->baudrate);
/* reset the RX & TX buffers */
writel(1, &uart->txreset);
writel(1, &uart->rxreset);
/* set baud generator mode */
if (mode)
val |= BAUDMODE;
/* finally, write value and enable ASC */
writel(val, &uart->control);
return 0;
+}
+/* initialize the ASC */ +static int sti_asc_serial_probe(struct udevice *dev) +{
struct sti_asc_serial_platdata *plat = dev->platdata;
struct sti_asc_uart *const uart = plat->base;
unsigned long val;
sti_asc_serial_setbrg(dev, gd->baudrate);
/*
* build up the value to be written to CONTROL
* set character length, bit stop number, odd parity
*/
val = RXENABLE | RUN | MODE_8BIT | STOP_1BIT | PARITYODD;
writel(val, &uart->control);
return 0;
+}
+/* blocking function, that returns next char */ +static int sti_asc_serial_getc(struct udevice *dev) +{
struct sti_asc_serial_platdata *plat = dev->platdata;
struct sti_asc_uart *const uart = plat->base;
/* polling wait: for a char to be read */
if (!sti_asc_pending(dev, true))
return -EAGAIN;
return readl(&uart->rxbuf);
+}
+/* write write out a single char */ +static int sti_asc_serial_putc(struct udevice *dev, const char c) +{
struct sti_asc_serial_platdata *plat = dev->platdata;
struct sti_asc_uart *const uart = plat->base;
/* Stream-LF to CR+LF conversion */
if (c == 10)
sti_asc_serial_putc(dev, '\r');
This happens in the uclass, you don't need it here.
/* wait till safe to write next char */
while (sti_asc_pending(dev, false))
;
if (sti_asc_pending(dev, false)) return -EAGAIN
(no loops needed / wanted in drivers)
/* finally, write next char */
writel(c, &uart->txbuf);
return 0;
+}
+static int sti_ofdata_to_platdata(struct udevice *dev) +{
struct sti_asc_serial_platdata *priv = dev_get_priv(dev);
fdt_addr_t base;
base = dev_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
priv->base = (struct sti_asc_uart *)base;
Can I suggest the name 'regs' for the registers? Normally 'base' is the base address. It's the same value, but regs is a pointer and base is a ulong.
return 0;
+}
+static const struct dm_serial_ops sti_asc_serial_ops = {
.putc = sti_asc_serial_putc,
.pending = sti_asc_pending,
.getc = sti_asc_serial_getc,
.setbrg = sti_asc_serial_setbrg,
+};
+static const struct udevice_id sti_serial_of_match[] = {
{ .compatible = "st,asc" },
{ }
+};
+U_BOOT_DRIVER(serial_sti_asc) = {
.name = "serial_sti_asc",
.id = UCLASS_SERIAL,
.of_match = sti_serial_of_match,
.ops = &sti_asc_serial_ops,
.ofdata_to_platdata = sti_ofdata_to_platdata,
.probe = sti_asc_serial_probe,
.flags = DM_FLAG_PRE_RELOC,
+}; diff --git a/include/configs/stih410-b2260.h b/include/configs/stih410-b2260.h index fade7a1..4fea22a 100644 --- a/include/configs/stih410-b2260.h +++ b/include/configs/stih410-b2260.h @@ -17,6 +17,7 @@ #define CONFIG_SYS_LOAD_ADDR PHYS_SDRAM_1 /* default load addr */
#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
#define CONFIG_SYS_HZ_CLOCK 1000000000 /* 1 GHz */
diff --git a/include/dm/platform_data/serial_sti_asc.h b/include/dm/platform_data/serial_sti_asc.h new file mode 100644 index 0000000..c8631f1 --- /dev/null +++ b/include/dm/platform_data/serial_sti_asc.h @@ -0,0 +1,17 @@ +/*
- (C) Copyright 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __SERIAL_STI_ASC_H +#define __SERIAL_STI_ASC_H
+/* Information about a serial port */ +struct sti_asc_serial_platdata {
/* address of registers in physical memory */
struct sti_asc_uart *base;
+};
+#endif /* __SERIAL_STI_ASC_H */
1.9.1
Regards, Simon

Hi Simon
On 02/10/2017 05:22 PM, Simon Glass wrote:
Hi Patrice,
On 2 February 2017 at 10:00, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
This patch adds support to ASC (asynchronous serial controller) driver, which is basically a standard serial driver. This IP is common across other STMicroelectronics SoCs
Signed-off-by: Patrice Chotard patrice.chotard@st.com
arch/arm/Kconfig | 2 + arch/arm/include/asm/arch-stih410/sti.h | 6 + board/st/stih410-b2260/board.c | 12 ++ drivers/serial/Kconfig | 7 + drivers/serial/Makefile | 1 + drivers/serial/serial_sti_asc.c | 219 ++++++++++++++++++++++++++++++ include/configs/stih410-b2260.h | 1 + include/dm/platform_data/serial_sti_asc.h | 17 +++ 8 files changed, 265 insertions(+) create mode 100644 drivers/serial/serial_sti_asc.c create mode 100644 include/dm/platform_data/serial_sti_asc.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4aa5eb9..b91a5b7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -985,6 +985,8 @@ config STM32 config ARCH_STI bool "Support STMicrolectronics SoCs" select CPU_V7
select DM
select DM_SERIAL help Support for STMicroelectronics STiH407/10 SoC family. This SoC is used on Linaro 96Board STiH410-B2260
diff --git a/arch/arm/include/asm/arch-stih410/sti.h b/arch/arm/include/asm/arch-stih410/sti.h index d35c4f0..f167560 100644 --- a/arch/arm/include/asm/arch-stih410/sti.h +++ b/arch/arm/include/asm/arch-stih410/sti.h @@ -11,4 +11,10 @@ #define STI_A9_CONFIG_BASE 0x08760000 #define STI_A9_GLOBAL_TIMER_BASE (STI_A9_CONFIG_BASE + 0x0200)
+/* STiH410 control registers */ +#define STIH410_COMMS_BASE 0x09800000
+/* ASC UART located in the main "COMMs" block */ +#define STIH410_ASC1_BASE (STIH410_COMMS_BASE + 0x00031000)
Can you get the address of the serial port from the device tree instead, e.g. with dev_get_addr_ptr()?
Will be fixed
#endif /* _STI_H_ */ diff --git a/board/st/stih410-b2260/board.c b/board/st/stih410-b2260/board.c index 0c06bca..b2cfa7f 100644 --- a/board/st/stih410-b2260/board.c +++ b/board/st/stih410-b2260/board.c @@ -7,6 +7,9 @@ */
#include <common.h> +#include <asm/arch/sti.h> +#include <dm/platdata.h> +#include <dm/platform_data/serial_sti_asc.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -26,3 +29,12 @@ int board_init(void) { return 0; }
+static const struct sti_asc_serial_platdata serial_platdata = {
.base = (struct sti_asc_uart *)STIH410_ASC1_BASE,
+};
+U_BOOT_DEVICE(sti_asc) = {
.name = "serial_sti_asc",
.platdata = &serial_platdata,
+};
Can you use DT instead of platform data? You have the code for it, so why is this needed?
Yes, i simply forgot to fully convert this driver to DT, i will fix this.
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index b11f3ff..7557632 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -413,4 +413,11 @@ config PXA_SERIAL If you have a machine based on a Marvell XScale PXA2xx CPU you can enable its onboard serial ports by enabling this option.
+config STI_ASC_SERIAL
bool "STMicroelectronics on-chip UART"
depends on DM_SERIAL && ARCH_STI
help
Select this to enable Asynchronous Serial Controller available
on STiH410 SoC.
Anything more to say? Maximum baud rate, or what hardware features the driver supports? E.g. it only seems to support a subset of baud rates.
Will be fixed
endmenu diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 8430668..84a22ce 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_FSL_LINFLEXUART) += serial_linflexuart.o obj-$(CONFIG_ARC_SERIAL) += serial_arc.o 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_BCM283X_MU_SERIAL) += serial_bcm283x_mu.o diff --git a/drivers/serial/serial_sti_asc.c b/drivers/serial/serial_sti_asc.c new file mode 100644 index 0000000..5279836 --- /dev/null +++ b/drivers/serial/serial_sti_asc.c @@ -0,0 +1,219 @@ +/*
- Support for Serial I/O using STMicroelectronics' on-chip ASC.
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0
- */
+#include <common.h> +#include <dm.h> +#include <serial.h> +#include <asm/arch/sti.h> +#include <asm/io.h>
move that up one line
ok
+#include <dm/platform_data/serial_sti_asc.h>
+DECLARE_GLOBAL_DATA_PTR;
+#define BAUDMODE 0x00001000 +#define RXENABLE 0x00000100 +#define RUN 0x00000080 +#define MODE 0x00000001 +#define MODE_8BIT 0x0001 +#define STOP_1BIT 0x0008 +#define PARITYODD 0x0020
+#define STA_TF 0x0200 +#define STA_RBF 0x0001
You could use BIT() if you like
ok
+struct sti_asc_uart {
u32 baudrate;
u32 txbuf;
u32 rxbuf;
u32 control;
u32 inten;
u32 status;
u32 guardtime;
u32 timeout;
u32 txreset;
u32 rxreset;
+};
+/*---- Values for the BAUDRATE Register -----------------------*/
/* Values for the BAUDRATE Register */
ok
+#define PCLK (200ul * 1000000ul) +#define BAUDRATE_VAL_M0(bps) (PCLK / (16 * (bps))) +#define BAUDRATE_VAL_M1(bps) ((bps * (1 << 14)) + (1<<13)) / (PCLK/(1 << 6))
+/*
- MODE 0
ICCLK
- ASCBaudRate = ----------------
baudrate * 16
- MODE 1
baudrate * 16 * 2^16
- ASCBaudRate = ------------------------
ICCLK
- NOTE:
- Mode 1 should be used for baudrates of 19200, and above, as it
- has a lower deviation error than Mode 0 for higher frequencies.
- Mode 0 should be used for all baudrates below 19200.
- */
+static int sti_asc_pending(struct udevice *dev, bool input) +{
struct sti_asc_serial_platdata *plat = dev->platdata;
struct sti_asc_uart *const uart = plat->base;
unsigned long status;
status = readl(&uart->status);
if (input)
return status & STA_RBF;
else
return status & STA_TF;
+}
+/* called to adjust baud-rate */ +static int sti_asc_serial_setbrg(struct udevice *dev, int baudrate) +{
struct sti_asc_serial_platdata *plat = dev->platdata;
struct sti_asc_uart *const uart = plat->base;
drop blank line
ok
unsigned long val;
int t, mode = 1;
switch (baudrate) {
case 9600:
t = BAUDRATE_VAL_M0(9600);
mode = 0;
break;
case 19200:
t = BAUDRATE_VAL_M1(19200);
break;
case 38400:
t = BAUDRATE_VAL_M1(38400);
break;
case 57600:
t = BAUDRATE_VAL_M1(57600);
break;
default:
printf("ASC: unsupported baud rate: %d, using 115200 instead.\n",
baudrate);
debug() ?
ok
case 115200:
t = BAUDRATE_VAL_M1(115200);
break;
}
/* wait for end of current transmission */
while (sti_asc_pending(dev, false))
;
Hmm this should not be here. We should be able to call serial_pending() to check that the device is idle, then avoid the loop here.
Maybe there is something needed in serial_uclass.c?
you are right, it's useless
/* disable the baudrate generator */
val = readl(&uart->control);
writel((val & ~RUN), &uart->control);
Drop extra brackets
ok
/* set baud generator reload value */
writel(t, &uart->baudrate);
/* reset the RX & TX buffers */
writel(1, &uart->txreset);
writel(1, &uart->rxreset);
/* set baud generator mode */
if (mode)
val |= BAUDMODE;
/* finally, write value and enable ASC */
writel(val, &uart->control);
return 0;
+}
+/* initialize the ASC */ +static int sti_asc_serial_probe(struct udevice *dev) +{
struct sti_asc_serial_platdata *plat = dev->platdata;
struct sti_asc_uart *const uart = plat->base;
unsigned long val;
sti_asc_serial_setbrg(dev, gd->baudrate);
/*
* build up the value to be written to CONTROL
* set character length, bit stop number, odd parity
*/
val = RXENABLE | RUN | MODE_8BIT | STOP_1BIT | PARITYODD;
writel(val, &uart->control);
return 0;
+}
+/* blocking function, that returns next char */ +static int sti_asc_serial_getc(struct udevice *dev) +{
struct sti_asc_serial_platdata *plat = dev->platdata;
struct sti_asc_uart *const uart = plat->base;
/* polling wait: for a char to be read */
if (!sti_asc_pending(dev, true))
return -EAGAIN;
return readl(&uart->rxbuf);
+}
+/* write write out a single char */ +static int sti_asc_serial_putc(struct udevice *dev, const char c) +{
struct sti_asc_serial_platdata *plat = dev->platdata;
struct sti_asc_uart *const uart = plat->base;
/* Stream-LF to CR+LF conversion */
if (c == 10)
sti_asc_serial_putc(dev, '\r');
This happens in the uclass, you don't need it here.
ok
/* wait till safe to write next char */
while (sti_asc_pending(dev, false))
;
if (sti_asc_pending(dev, false)) return -EAGAIN
(no loops needed / wanted in drivers)
ok
/* finally, write next char */
writel(c, &uart->txbuf);
return 0;
+}
+static int sti_ofdata_to_platdata(struct udevice *dev) +{
struct sti_asc_serial_platdata *priv = dev_get_priv(dev);
fdt_addr_t base;
base = dev_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
priv->base = (struct sti_asc_uart *)base;
Can I suggest the name 'regs' for the registers? Normally 'base' is the base address. It's the same value, but regs is a pointer and base is a ulong.
ok will fix this
return 0;
+}
+static const struct dm_serial_ops sti_asc_serial_ops = {
.putc = sti_asc_serial_putc,
.pending = sti_asc_pending,
.getc = sti_asc_serial_getc,
.setbrg = sti_asc_serial_setbrg,
+};
+static const struct udevice_id sti_serial_of_match[] = {
{ .compatible = "st,asc" },
{ }
+};
+U_BOOT_DRIVER(serial_sti_asc) = {
.name = "serial_sti_asc",
.id = UCLASS_SERIAL,
.of_match = sti_serial_of_match,
.ops = &sti_asc_serial_ops,
.ofdata_to_platdata = sti_ofdata_to_platdata,
.probe = sti_asc_serial_probe,
.flags = DM_FLAG_PRE_RELOC,
+}; diff --git a/include/configs/stih410-b2260.h b/include/configs/stih410-b2260.h index fade7a1..4fea22a 100644 --- a/include/configs/stih410-b2260.h +++ b/include/configs/stih410-b2260.h @@ -17,6 +17,7 @@ #define CONFIG_SYS_LOAD_ADDR PHYS_SDRAM_1 /* default load addr */
#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
#define CONFIG_SYS_HZ_CLOCK 1000000000 /* 1 GHz */
diff --git a/include/dm/platform_data/serial_sti_asc.h b/include/dm/platform_data/serial_sti_asc.h new file mode 100644 index 0000000..c8631f1 --- /dev/null +++ b/include/dm/platform_data/serial_sti_asc.h @@ -0,0 +1,17 @@ +/*
- (C) Copyright 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __SERIAL_STI_ASC_H +#define __SERIAL_STI_ASC_H
+/* Information about a serial port */ +struct sti_asc_serial_platdata {
/* address of registers in physical memory */
struct sti_asc_uart *base;
+};
+#endif /* __SERIAL_STI_ASC_H */
1.9.1
Regards, Simon

From: Patrice Chotard patrice.chotard@st.com
Add SDHCI host controller found on STMicroelctronics SoCs
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- arch/arm/Kconfig | 2 + arch/arm/include/asm/arch-stih410/sdhci.h | 69 +++++++++++++++ drivers/mmc/Kconfig | 7 ++ drivers/mmc/Makefile | 1 + drivers/mmc/sti_sdhci.c | 140 ++++++++++++++++++++++++++++++ 5 files changed, 219 insertions(+) create mode 100644 arch/arm/include/asm/arch-stih410/sdhci.h create mode 100644 drivers/mmc/sti_sdhci.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b91a5b7..477f36b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -987,6 +987,8 @@ config ARCH_STI select CPU_V7 select DM select DM_SERIAL + select BLK + select DM_MMC help Support for STMicroelectronics STiH407/10 SoC family. This SoC is used on Linaro 96Board STiH410-B2260 diff --git a/arch/arm/include/asm/arch-stih410/sdhci.h b/arch/arm/include/asm/arch-stih410/sdhci.h new file mode 100644 index 0000000..f45b961 --- /dev/null +++ b/arch/arm/include/asm/arch-stih410/sdhci.h @@ -0,0 +1,69 @@ +/* + * (C) Copyright 2017 Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __STI_SDHCI_H__ +#define __STI_SDHCI_H__ + +#define FLASHSS_MMC_CORE_CONFIG_1 0x400 +#define FLASHSS_MMC_CORECFG_TIMEOUT_CLK_UNIT_MHZ BIT(24) +#define FLASHSS_MMC_CORECFG_TIMEOUT_CLK_FREQ_MIN BIT(12) + +#define STI_FLASHSS_MMC_CORE_CONFIG_1 \ + (FLASHSS_MMC_CORECFG_TIMEOUT_CLK_UNIT_MHZ | \ + FLASHSS_MMC_CORECFG_TIMEOUT_CLK_FREQ_MIN) + +#define FLASHSS_MMC_CORE_CONFIG_2 0x404 +#define FLASHSS_MMC_CORECFG_HIGH_SPEED BIT(28) +#define FLASHSS_MMC_CORECFG_8BIT_EMMC BIT(20) +#define MAX_BLK_LENGTH_1024 BIT(16) +#define BASE_CLK_FREQ_200 0xc8 + + +#define STI_FLASHSS_MMC_CORE_CONFIG2 \ + (FLASHSS_MMC_CORECFG_HIGH_SPEED | \ + FLASHSS_MMC_CORECFG_8BIT_EMMC | \ + MAX_BLK_LENGTH_1024 | \ + BASE_CLK_FREQ_200 << 0) + +#define STI_FLASHSS_SDCARD_CORE_CONFIG2 \ + (FLASHSS_MMC_CORECFG_HIGH_SPEED | \ + MAX_BLK_LENGTH_1024 | \ + BASE_CLK_FREQ_200) + +#define FLASHSS_MMC_CORE_CONFIG_3 0x408 +#define FLASHSS_MMC_CORECFG_SLOT_TYPE_EMMC BIT(28) +#define FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT BIT(20) +#define FLASHSS_MMC_CORECFG_3P3_VOLT BIT(8) +#define FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT BIT(4) +#define FLASHSS_MMC_CORECFG_SDMA BIT(0) + +#define STI_FLASHSS_MMC_CORE_CONFIG3 \ + (FLASHSS_MMC_CORECFG_SLOT_TYPE_EMMC | \ + FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT | \ + FLASHSS_MMC_CORECFG_3P3_VOLT | \ + FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT | \ + FLASHSS_MMC_CORECFG_SDMA) + +#define STI_FLASHSS_SDCARD_CORE_CONFIG3 \ + (FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT | \ + FLASHSS_MMC_CORECFG_3P3_VOLT | \ + FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT | \ + FLASHSS_MMC_CORECFG_SDMA) + +#define FLASHSS_MMC_CORE_CONFIG_4 0x40c +#define FLASHSS_MMC_CORECFG_D_DRIVER_SUPPORT BIT(20) +#define FLASHSS_MMC_CORECFG_C_DRIVER_SUPPORT BIT(16) +#define FLASHSS_MMC_CORECFG_A_DRIVER_SUPPORT BIT(12) + +#define STI_FLASHSS_MMC_CORE_CONFIG4 \ + (FLASHSS_MMC_CORECFG_D_DRIVER_SUPPORT | \ + FLASHSS_MMC_CORECFG_C_DRIVER_SUPPORT | \ + FLASHSS_MMC_CORECFG_A_DRIVER_SUPPORT) + +#define ST_MMC_CCONFIG_REG_5 0x210 +#define SYSCONF_MMC1_ENABLE_BIT 3 + +#endif /* _STI_SDHCI_H_ */ diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 0c07781..dfdec27 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -287,6 +287,13 @@ config MMC_SDHCI_SPEAR
If unsure, say N.
+config MMC_SDHCI_STI + bool "SDHCI support for STMicroelectronics SoC" + depends on MMC_SDHCI + help + This selects the Secure Digital Host Controller Interface (SDHCI) + on STMicroelectronics STiH410 SoC. + config MMC_SDHCI_XENON bool "SDHCI support for the Xenon SDHCI controller" depends on MMC_SDHCI && DM_MMC && OF_CONTROL diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index e78bd0d..fc24926 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_MMC_SDHCI_PIC32) += pic32_sdhci.o obj-$(CONFIG_MMC_SDHCI_ROCKCHIP) += rockchip_sdhci.o obj-$(CONFIG_MMC_SDHCI_S5P) += s5p_sdhci.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += spear_sdhci.o +obj-$(CONFIG_MMC_SDHCI_STI) += sti_sdhci.o obj-$(CONFIG_MMC_SDHCI_TEGRA) += tegra_mmc.o obj-$(CONFIG_MMC_SDHCI_XENON) += xenon_sdhci.o obj-$(CONFIG_MMC_SDHCI_ZYNQ) += zynq_sdhci.o diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c new file mode 100644 index 0000000..7a76983 --- /dev/null +++ b/drivers/mmc/sti_sdhci.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2017 + * Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <mmc.h> +#include <sdhci.h> +#include <asm/arch/gpio.h> +#include <asm/arch/sdhci.h> +#include <asm/arch/sti.h> +#include <asm/arch/syscfg.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct sti_sdhci_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + +/** + * sti_mmc_core_config: configure the Arasan HC + * @regbase: base address + * @mmc_instance: mmc instance id + * Description: this function is to configure the Arasan MMC HC. + * This should be called when the system starts in case of, on the SoC, + * it is needed to configure the host controller. + * This happens on some SoCs, i.e. StiH410, where the MMC0 inside the flashSS + * needs to be configured as MMC 4.5 to have full capabilities. + * W/o these settings the SDHCI could configure and use the embedded controller + * with limited features. + */ +static void sti_mmc_core_config(const u32 regbase, int mmc_instance) +{ + unsigned long *sysconf; + + /* only MMC1 has a reset line */ + if (mmc_instance) { + sysconf = (unsigned long *)(STIH410_SYSCONF5_BASE + + ST_MMC_CCONFIG_REG_5); + generic_set_bit(SYSCONF_MMC1_ENABLE_BIT, sysconf); + } + + writel(STI_FLASHSS_MMC_CORE_CONFIG_1, + regbase + FLASHSS_MMC_CORE_CONFIG_1); + + if (mmc_instance) { + writel(STI_FLASHSS_MMC_CORE_CONFIG2, + regbase + FLASHSS_MMC_CORE_CONFIG_2); + writel(STI_FLASHSS_MMC_CORE_CONFIG3, + regbase + FLASHSS_MMC_CORE_CONFIG_3); + } else { + writel(STI_FLASHSS_SDCARD_CORE_CONFIG2, + regbase + FLASHSS_MMC_CORE_CONFIG_2); + writel(STI_FLASHSS_SDCARD_CORE_CONFIG3, + regbase + FLASHSS_MMC_CORE_CONFIG_3); + } + writel(STI_FLASHSS_MMC_CORE_CONFIG4, + regbase + FLASHSS_MMC_CORE_CONFIG_4); +} + +int sti_sdhci_probe(struct udevice *dev) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct sti_sdhci_plat *plat = dev_get_platdata(dev); + struct sdhci_host *host = dev_get_priv(dev); + int ret, count, mmc_instance; + + /* + * identify current mmc instance, mmc1 has a reset, not mmc0 + * MMC0 is wired to the SD slot, + * MMC1 is wired on the high speed connector + */ + + fdt_getprop(gd->fdt_blob, dev->of_offset, "resets", &count); + if (count < 0) + mmc_instance = 0; + else + mmc_instance = 1; + + sti_mmc_core_config((const u32) host->ioaddr, mmc_instance); + + host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | + SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_NO_HISPD_BIT; + + host->host_caps = MMC_MODE_DDR_52MHz; + + ret = sdhci_setup_cfg(&plat->cfg, host, 50000000, 400000); + + if (ret) + return ret; + + host->mmc = &plat->mmc; + host->mmc->priv = host; + host->mmc->dev = dev; + upriv->mmc = host->mmc; + + return sdhci_probe(dev); +} + +static int sti_sdhci_ofdata_to_platdata(struct udevice *dev) +{ + struct sdhci_host *host = dev_get_priv(dev); + + host->name = strdup(dev->name); + host->ioaddr = (void *)dev_get_addr(dev); + + host->bus_width = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "bus-width", 4); + + return 0; +} + +static int sti_sdhci_bind(struct udevice *dev) +{ + struct sti_sdhci_plat *plat = dev_get_platdata(dev); + + return sdhci_bind(dev, &plat->mmc, &plat->cfg); +} + +static const struct udevice_id sti_sdhci_ids[] = { + { .compatible = "st,sdhci" }, + { } +}; + +U_BOOT_DRIVER(sti_mmc) = { + .name = "sti_sdhci", + .id = UCLASS_MMC, + .of_match = sti_sdhci_ids, + .bind = sti_sdhci_bind, + .ops = &sdhci_ops, + .ofdata_to_platdata = sti_sdhci_ofdata_to_platdata, + .probe = sti_sdhci_probe, + .priv_auto_alloc_size = sizeof(struct sdhci_host), + .platdata_auto_alloc_size = sizeof(struct sti_sdhci_plat), +};

Hi Patrice,
On 2 February 2017 at 10:00, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add SDHCI host controller found on STMicroelctronics SoCs
Signed-off-by: Patrice Chotard patrice.chotard@st.com
arch/arm/Kconfig | 2 + arch/arm/include/asm/arch-stih410/sdhci.h | 69 +++++++++++++++ drivers/mmc/Kconfig | 7 ++ drivers/mmc/Makefile | 1 + drivers/mmc/sti_sdhci.c | 140 ++++++++++++++++++++++++++++++ 5 files changed, 219 insertions(+) create mode 100644 arch/arm/include/asm/arch-stih410/sdhci.h create mode 100644 drivers/mmc/sti_sdhci.c
Reviewed-by: Simon Glass sjg@chromium.org
nits below
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b91a5b7..477f36b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -987,6 +987,8 @@ config ARCH_STI select CPU_V7 select DM select DM_SERIAL
select BLK
select DM_MMC help Support for STMicroelectronics STiH407/10 SoC family. This SoC is used on Linaro 96Board STiH410-B2260
diff --git a/arch/arm/include/asm/arch-stih410/sdhci.h b/arch/arm/include/asm/arch-stih410/sdhci.h new file mode 100644 index 0000000..f45b961 --- /dev/null +++ b/arch/arm/include/asm/arch-stih410/sdhci.h @@ -0,0 +1,69 @@ +/*
- (C) Copyright 2017 Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __STI_SDHCI_H__ +#define __STI_SDHCI_H__
+#define FLASHSS_MMC_CORE_CONFIG_1 0x400 +#define FLASHSS_MMC_CORECFG_TIMEOUT_CLK_UNIT_MHZ BIT(24) +#define FLASHSS_MMC_CORECFG_TIMEOUT_CLK_FREQ_MIN BIT(12)
+#define STI_FLASHSS_MMC_CORE_CONFIG_1 \
(FLASHSS_MMC_CORECFG_TIMEOUT_CLK_UNIT_MHZ | \
FLASHSS_MMC_CORECFG_TIMEOUT_CLK_FREQ_MIN)
+#define FLASHSS_MMC_CORE_CONFIG_2 0x404 +#define FLASHSS_MMC_CORECFG_HIGH_SPEED BIT(28) +#define FLASHSS_MMC_CORECFG_8BIT_EMMC BIT(20) +#define MAX_BLK_LENGTH_1024 BIT(16) +#define BASE_CLK_FREQ_200 0xc8
+#define STI_FLASHSS_MMC_CORE_CONFIG2 \
(FLASHSS_MMC_CORECFG_HIGH_SPEED | \
FLASHSS_MMC_CORECFG_8BIT_EMMC | \
MAX_BLK_LENGTH_1024 | \
BASE_CLK_FREQ_200 << 0)
+#define STI_FLASHSS_SDCARD_CORE_CONFIG2 \
(FLASHSS_MMC_CORECFG_HIGH_SPEED | \
MAX_BLK_LENGTH_1024 | \
BASE_CLK_FREQ_200)
+#define FLASHSS_MMC_CORE_CONFIG_3 0x408 +#define FLASHSS_MMC_CORECFG_SLOT_TYPE_EMMC BIT(28) +#define FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT BIT(20) +#define FLASHSS_MMC_CORECFG_3P3_VOLT BIT(8) +#define FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT BIT(4) +#define FLASHSS_MMC_CORECFG_SDMA BIT(0)
+#define STI_FLASHSS_MMC_CORE_CONFIG3 \
(FLASHSS_MMC_CORECFG_SLOT_TYPE_EMMC | \
FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT | \
FLASHSS_MMC_CORECFG_3P3_VOLT | \
FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT | \
FLASHSS_MMC_CORECFG_SDMA)
+#define STI_FLASHSS_SDCARD_CORE_CONFIG3 \
(FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT | \
FLASHSS_MMC_CORECFG_3P3_VOLT | \
FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT | \
FLASHSS_MMC_CORECFG_SDMA)
+#define FLASHSS_MMC_CORE_CONFIG_4 0x40c +#define FLASHSS_MMC_CORECFG_D_DRIVER_SUPPORT BIT(20) +#define FLASHSS_MMC_CORECFG_C_DRIVER_SUPPORT BIT(16) +#define FLASHSS_MMC_CORECFG_A_DRIVER_SUPPORT BIT(12)
+#define STI_FLASHSS_MMC_CORE_CONFIG4 \
(FLASHSS_MMC_CORECFG_D_DRIVER_SUPPORT | \
FLASHSS_MMC_CORECFG_C_DRIVER_SUPPORT | \
FLASHSS_MMC_CORECFG_A_DRIVER_SUPPORT)
+#define ST_MMC_CCONFIG_REG_5 0x210 +#define SYSCONF_MMC1_ENABLE_BIT 3
+#endif /* _STI_SDHCI_H_ */ diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 0c07781..dfdec27 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -287,6 +287,13 @@ config MMC_SDHCI_SPEAR
If unsure, say N.
+config MMC_SDHCI_STI
bool "SDHCI support for STMicroelectronics SoC"
depends on MMC_SDHCI
help
This selects the Secure Digital Host Controller Interface (SDHCI)
on STMicroelectronics STiH410 SoC.
config MMC_SDHCI_XENON bool "SDHCI support for the Xenon SDHCI controller" depends on MMC_SDHCI && DM_MMC && OF_CONTROL diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index e78bd0d..fc24926 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_MMC_SDHCI_PIC32) += pic32_sdhci.o obj-$(CONFIG_MMC_SDHCI_ROCKCHIP) += rockchip_sdhci.o obj-$(CONFIG_MMC_SDHCI_S5P) += s5p_sdhci.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += spear_sdhci.o +obj-$(CONFIG_MMC_SDHCI_STI) += sti_sdhci.o obj-$(CONFIG_MMC_SDHCI_TEGRA) += tegra_mmc.o obj-$(CONFIG_MMC_SDHCI_XENON) += xenon_sdhci.o obj-$(CONFIG_MMC_SDHCI_ZYNQ) += zynq_sdhci.o diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c new file mode 100644 index 0000000..7a76983 --- /dev/null +++ b/drivers/mmc/sti_sdhci.c @@ -0,0 +1,140 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0
- */
+#include <common.h> +#include <dm.h> +#include <mmc.h> +#include <sdhci.h> +#include <asm/arch/gpio.h> +#include <asm/arch/sdhci.h> +#include <asm/arch/sti.h> +#include <asm/arch/syscfg.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct sti_sdhci_plat {
struct mmc_config cfg;
struct mmc mmc;
+};
+/**
- sti_mmc_core_config: configure the Arasan HC
- @regbase: base address
- @mmc_instance: mmc instance id
- Description: this function is to configure the Arasan MMC HC.
- This should be called when the system starts in case of, on the SoC,
- it is needed to configure the host controller.
- This happens on some SoCs, i.e. StiH410, where the MMC0 inside the flashSS
- needs to be configured as MMC 4.5 to have full capabilities.
- W/o these settings the SDHCI could configure and use the embedded controller
- with limited features.
- */
+static void sti_mmc_core_config(const u32 regbase, int mmc_instance) +{
unsigned long *sysconf;
/* only MMC1 has a reset line */
if (mmc_instance) {
sysconf = (unsigned long *)(STIH410_SYSCONF5_BASE +
ST_MMC_CCONFIG_REG_5);
generic_set_bit(SYSCONF_MMC1_ENABLE_BIT, sysconf);
}
writel(STI_FLASHSS_MMC_CORE_CONFIG_1,
regbase + FLASHSS_MMC_CORE_CONFIG_1);
if (mmc_instance) {
writel(STI_FLASHSS_MMC_CORE_CONFIG2,
regbase + FLASHSS_MMC_CORE_CONFIG_2);
writel(STI_FLASHSS_MMC_CORE_CONFIG3,
regbase + FLASHSS_MMC_CORE_CONFIG_3);
} else {
writel(STI_FLASHSS_SDCARD_CORE_CONFIG2,
regbase + FLASHSS_MMC_CORE_CONFIG_2);
writel(STI_FLASHSS_SDCARD_CORE_CONFIG3,
regbase + FLASHSS_MMC_CORE_CONFIG_3);
}
writel(STI_FLASHSS_MMC_CORE_CONFIG4,
regbase + FLASHSS_MMC_CORE_CONFIG_4);
+}
+int sti_sdhci_probe(struct udevice *dev) +{
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct sti_sdhci_plat *plat = dev_get_platdata(dev);
struct sdhci_host *host = dev_get_priv(dev);
int ret, count, mmc_instance;
/*
* identify current mmc instance, mmc1 has a reset, not mmc0
* MMC0 is wired to the SD slot,
* MMC1 is wired on the high speed connector
*/
fdt_getprop(gd->fdt_blob, dev->of_offset, "resets", &count);
How about
if (fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "resets", NULL); mmc_instance = 0; else mmc_instance = 1;
if (count < 0)
mmc_instance = 0;
else
mmc_instance = 1;
sti_mmc_core_config((const u32) host->ioaddr, mmc_instance);
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
SDHCI_QUIRK_32BIT_DMA_ADDR |
SDHCI_QUIRK_NO_HISPD_BIT;
host->host_caps = MMC_MODE_DDR_52MHz;
ret = sdhci_setup_cfg(&plat->cfg, host, 50000000, 400000);
drop blank line
if (ret)
return ret;
host->mmc = &plat->mmc;
host->mmc->priv = host;
host->mmc->dev = dev;
upriv->mmc = host->mmc;
return sdhci_probe(dev);
+}
+static int sti_sdhci_ofdata_to_platdata(struct udevice *dev) +{
struct sdhci_host *host = dev_get_priv(dev);
host->name = strdup(dev->name);
host->ioaddr = (void *)dev_get_addr(dev);
host->bus_width = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
"bus-width", 4);
return 0;
+}
+static int sti_sdhci_bind(struct udevice *dev) +{
struct sti_sdhci_plat *plat = dev_get_platdata(dev);
return sdhci_bind(dev, &plat->mmc, &plat->cfg);
+}
+static const struct udevice_id sti_sdhci_ids[] = {
{ .compatible = "st,sdhci" },
{ }
+};
+U_BOOT_DRIVER(sti_mmc) = {
.name = "sti_sdhci",
.id = UCLASS_MMC,
.of_match = sti_sdhci_ids,
.bind = sti_sdhci_bind,
.ops = &sdhci_ops,
.ofdata_to_platdata = sti_sdhci_ofdata_to_platdata,
.probe = sti_sdhci_probe,
.priv_auto_alloc_size = sizeof(struct sdhci_host),
.platdata_auto_alloc_size = sizeof(struct sti_sdhci_plat),
+};
1.9.1
Regards, Simon

Hi Simon
On 02/10/2017 05:22 PM, Simon Glass wrote:
Hi Patrice,
On 2 February 2017 at 10:00, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add SDHCI host controller found on STMicroelctronics SoCs
Signed-off-by: Patrice Chotard patrice.chotard@st.com
arch/arm/Kconfig | 2 + arch/arm/include/asm/arch-stih410/sdhci.h | 69 +++++++++++++++ drivers/mmc/Kconfig | 7 ++ drivers/mmc/Makefile | 1 + drivers/mmc/sti_sdhci.c | 140 ++++++++++++++++++++++++++++++ 5 files changed, 219 insertions(+) create mode 100644 arch/arm/include/asm/arch-stih410/sdhci.h create mode 100644 drivers/mmc/sti_sdhci.c
Reviewed-by: Simon Glass sjg@chromium.org
nits below
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b91a5b7..477f36b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -987,6 +987,8 @@ config ARCH_STI select CPU_V7 select DM select DM_SERIAL
select BLK
select DM_MMC help Support for STMicroelectronics STiH407/10 SoC family. This SoC is used on Linaro 96Board STiH410-B2260
diff --git a/arch/arm/include/asm/arch-stih410/sdhci.h b/arch/arm/include/asm/arch-stih410/sdhci.h new file mode 100644 index 0000000..f45b961 --- /dev/null +++ b/arch/arm/include/asm/arch-stih410/sdhci.h @@ -0,0 +1,69 @@ +/*
- (C) Copyright 2017 Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __STI_SDHCI_H__ +#define __STI_SDHCI_H__
+#define FLASHSS_MMC_CORE_CONFIG_1 0x400 +#define FLASHSS_MMC_CORECFG_TIMEOUT_CLK_UNIT_MHZ BIT(24) +#define FLASHSS_MMC_CORECFG_TIMEOUT_CLK_FREQ_MIN BIT(12)
+#define STI_FLASHSS_MMC_CORE_CONFIG_1 \
(FLASHSS_MMC_CORECFG_TIMEOUT_CLK_UNIT_MHZ | \
FLASHSS_MMC_CORECFG_TIMEOUT_CLK_FREQ_MIN)
+#define FLASHSS_MMC_CORE_CONFIG_2 0x404 +#define FLASHSS_MMC_CORECFG_HIGH_SPEED BIT(28) +#define FLASHSS_MMC_CORECFG_8BIT_EMMC BIT(20) +#define MAX_BLK_LENGTH_1024 BIT(16) +#define BASE_CLK_FREQ_200 0xc8
+#define STI_FLASHSS_MMC_CORE_CONFIG2 \
(FLASHSS_MMC_CORECFG_HIGH_SPEED | \
FLASHSS_MMC_CORECFG_8BIT_EMMC | \
MAX_BLK_LENGTH_1024 | \
BASE_CLK_FREQ_200 << 0)
+#define STI_FLASHSS_SDCARD_CORE_CONFIG2 \
(FLASHSS_MMC_CORECFG_HIGH_SPEED | \
MAX_BLK_LENGTH_1024 | \
BASE_CLK_FREQ_200)
+#define FLASHSS_MMC_CORE_CONFIG_3 0x408 +#define FLASHSS_MMC_CORECFG_SLOT_TYPE_EMMC BIT(28) +#define FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT BIT(20) +#define FLASHSS_MMC_CORECFG_3P3_VOLT BIT(8) +#define FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT BIT(4) +#define FLASHSS_MMC_CORECFG_SDMA BIT(0)
+#define STI_FLASHSS_MMC_CORE_CONFIG3 \
(FLASHSS_MMC_CORECFG_SLOT_TYPE_EMMC | \
FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT | \
FLASHSS_MMC_CORECFG_3P3_VOLT | \
FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT | \
FLASHSS_MMC_CORECFG_SDMA)
+#define STI_FLASHSS_SDCARD_CORE_CONFIG3 \
(FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT | \
FLASHSS_MMC_CORECFG_3P3_VOLT | \
FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT | \
FLASHSS_MMC_CORECFG_SDMA)
+#define FLASHSS_MMC_CORE_CONFIG_4 0x40c +#define FLASHSS_MMC_CORECFG_D_DRIVER_SUPPORT BIT(20) +#define FLASHSS_MMC_CORECFG_C_DRIVER_SUPPORT BIT(16) +#define FLASHSS_MMC_CORECFG_A_DRIVER_SUPPORT BIT(12)
+#define STI_FLASHSS_MMC_CORE_CONFIG4 \
(FLASHSS_MMC_CORECFG_D_DRIVER_SUPPORT | \
FLASHSS_MMC_CORECFG_C_DRIVER_SUPPORT | \
FLASHSS_MMC_CORECFG_A_DRIVER_SUPPORT)
+#define ST_MMC_CCONFIG_REG_5 0x210 +#define SYSCONF_MMC1_ENABLE_BIT 3
+#endif /* _STI_SDHCI_H_ */ diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 0c07781..dfdec27 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -287,6 +287,13 @@ config MMC_SDHCI_SPEAR
If unsure, say N.
+config MMC_SDHCI_STI
bool "SDHCI support for STMicroelectronics SoC"
depends on MMC_SDHCI
help
This selects the Secure Digital Host Controller Interface (SDHCI)
on STMicroelectronics STiH410 SoC.
config MMC_SDHCI_XENON bool "SDHCI support for the Xenon SDHCI controller" depends on MMC_SDHCI && DM_MMC && OF_CONTROL diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index e78bd0d..fc24926 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_MMC_SDHCI_PIC32) += pic32_sdhci.o obj-$(CONFIG_MMC_SDHCI_ROCKCHIP) += rockchip_sdhci.o obj-$(CONFIG_MMC_SDHCI_S5P) += s5p_sdhci.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += spear_sdhci.o +obj-$(CONFIG_MMC_SDHCI_STI) += sti_sdhci.o obj-$(CONFIG_MMC_SDHCI_TEGRA) += tegra_mmc.o obj-$(CONFIG_MMC_SDHCI_XENON) += xenon_sdhci.o obj-$(CONFIG_MMC_SDHCI_ZYNQ) += zynq_sdhci.o diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c new file mode 100644 index 0000000..7a76983 --- /dev/null +++ b/drivers/mmc/sti_sdhci.c @@ -0,0 +1,140 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0
- */
+#include <common.h> +#include <dm.h> +#include <mmc.h> +#include <sdhci.h> +#include <asm/arch/gpio.h> +#include <asm/arch/sdhci.h> +#include <asm/arch/sti.h> +#include <asm/arch/syscfg.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct sti_sdhci_plat {
struct mmc_config cfg;
struct mmc mmc;
+};
+/**
- sti_mmc_core_config: configure the Arasan HC
- @regbase: base address
- @mmc_instance: mmc instance id
- Description: this function is to configure the Arasan MMC HC.
- This should be called when the system starts in case of, on the SoC,
- it is needed to configure the host controller.
- This happens on some SoCs, i.e. StiH410, where the MMC0 inside the flashSS
- needs to be configured as MMC 4.5 to have full capabilities.
- W/o these settings the SDHCI could configure and use the embedded controller
- with limited features.
- */
+static void sti_mmc_core_config(const u32 regbase, int mmc_instance) +{
unsigned long *sysconf;
/* only MMC1 has a reset line */
if (mmc_instance) {
sysconf = (unsigned long *)(STIH410_SYSCONF5_BASE +
ST_MMC_CCONFIG_REG_5);
generic_set_bit(SYSCONF_MMC1_ENABLE_BIT, sysconf);
}
writel(STI_FLASHSS_MMC_CORE_CONFIG_1,
regbase + FLASHSS_MMC_CORE_CONFIG_1);
if (mmc_instance) {
writel(STI_FLASHSS_MMC_CORE_CONFIG2,
regbase + FLASHSS_MMC_CORE_CONFIG_2);
writel(STI_FLASHSS_MMC_CORE_CONFIG3,
regbase + FLASHSS_MMC_CORE_CONFIG_3);
} else {
writel(STI_FLASHSS_SDCARD_CORE_CONFIG2,
regbase + FLASHSS_MMC_CORE_CONFIG_2);
writel(STI_FLASHSS_SDCARD_CORE_CONFIG3,
regbase + FLASHSS_MMC_CORE_CONFIG_3);
}
writel(STI_FLASHSS_MMC_CORE_CONFIG4,
regbase + FLASHSS_MMC_CORE_CONFIG_4);
+}
+int sti_sdhci_probe(struct udevice *dev) +{
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct sti_sdhci_plat *plat = dev_get_platdata(dev);
struct sdhci_host *host = dev_get_priv(dev);
int ret, count, mmc_instance;
/*
* identify current mmc instance, mmc1 has a reset, not mmc0
* MMC0 is wired to the SD slot,
* MMC1 is wired on the high speed connector
*/
fdt_getprop(gd->fdt_blob, dev->of_offset, "resets", &count);
How about
if (fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "resets", NULL); mmc_instance = 0; else mmc_instance = 1;
ok , it's more elegant ;-)
if (count < 0)
mmc_instance = 0;
else
mmc_instance = 1;
sti_mmc_core_config((const u32) host->ioaddr, mmc_instance);
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
SDHCI_QUIRK_32BIT_DMA_ADDR |
SDHCI_QUIRK_NO_HISPD_BIT;
host->host_caps = MMC_MODE_DDR_52MHz;
ret = sdhci_setup_cfg(&plat->cfg, host, 50000000, 400000);
drop blank line
ok
if (ret)
return ret;
host->mmc = &plat->mmc;
host->mmc->priv = host;
host->mmc->dev = dev;
upriv->mmc = host->mmc;
return sdhci_probe(dev);
+}
+static int sti_sdhci_ofdata_to_platdata(struct udevice *dev) +{
struct sdhci_host *host = dev_get_priv(dev);
host->name = strdup(dev->name);
host->ioaddr = (void *)dev_get_addr(dev);
host->bus_width = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
"bus-width", 4);
return 0;
+}
+static int sti_sdhci_bind(struct udevice *dev) +{
struct sti_sdhci_plat *plat = dev_get_platdata(dev);
return sdhci_bind(dev, &plat->mmc, &plat->cfg);
+}
+static const struct udevice_id sti_sdhci_ids[] = {
{ .compatible = "st,sdhci" },
{ }
+};
+U_BOOT_DRIVER(sti_mmc) = {
.name = "sti_sdhci",
.id = UCLASS_MMC,
.of_match = sti_sdhci_ids,
.bind = sti_sdhci_bind,
.ops = &sdhci_ops,
.ofdata_to_platdata = sti_sdhci_ofdata_to_platdata,
.probe = sti_sdhci_probe,
.priv_auto_alloc_size = sizeof(struct sdhci_host),
.platdata_auto_alloc_size = sizeof(struct sti_sdhci_plat),
+};
1.9.1
Regards, Simon

From: Patrice Chotard patrice.chotard@st.com
Add STMicroelectronics STiH410 pinctrl driver
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- drivers/pinctrl/Kconfig | 10 ++ drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-sti.c | 315 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 326 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-sti.c
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index efcb4c0..0c832e1 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -175,6 +175,16 @@ config PIC32_PINCTRL by a device tree node which contains both GPIO defintion and pin control functions.
+config PINCTRL_STI + bool "STMicroelectronics STi pin-control and pin-mux driver" + depends on DM && ARCH_STI + default y + help + Support pin multiplexing control on STMicrolectronics STi SoCs. + The driver is controlled by a device tree node which contains both + the GPIO definitions and pin control functions for each available multiplex + function. + endif
source "drivers/pinctrl/meson/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 512112a..a2f8101 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_PIC32_PINCTRL) += pinctrl_pic32.o obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/ obj-$(CONFIG_PINCTRL_MESON) += meson/ obj-$(CONFIG_PINCTRL_MVEBU) += mvebu/ +obj-$(CONFIG_PINCTRL_STI) += pinctrl-sti.o diff --git a/drivers/pinctrl/pinctrl-sti.c b/drivers/pinctrl/pinctrl-sti.c new file mode 100644 index 0000000..721dc8e --- /dev/null +++ b/drivers/pinctrl/pinctrl-sti.c @@ -0,0 +1,315 @@ +/* + * Pinctrl driver for STMicroelectronics STi SoCs + * + * Copyright (c) 2017 + * Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <bitfield.h> +#include <dm.h> +#include <errno.h> +#include <regmap.h> +#include <syscon.h> +#include <asm/io.h> +#include <asm/arch/gpio.h> +#include <asm/arch/syscfg.h> +#include <dm/pinctrl.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define MAX_STI_PINCONF_ENTRIES 7 +/* Output enable */ +#define OE (1 << 27) +/* Pull Up */ +#define PU (1 << 26) +/* Open Drain */ +#define OD (1 << 25) + +/* User-frendly defines for Pin Direction */ + /* oe = 0, pu = 0, od = 0 */ +#define IN (0) + /* oe = 0, pu = 1, od = 0 */ +#define IN_PU (PU) + /* oe = 1, pu = 0, od = 0 */ +#define OUT (OE) + /* oe = 1, pu = 1, od = 0 */ +#define OUT_PU (OE | PU) + /* oe = 1, pu = 0, od = 1 */ +#define BIDIR (OE | OD) + /* oe = 1, pu = 1, od = 1 */ +#define BIDIR_PU (OE | PU | OD) + +struct sti_pinctrl_platdata { + struct regmap *regmap; +}; + +/* + * PIO alternative Function selector + */ +void sti_alternate_select(struct udevice *dev, struct sti_pin_desc *pin_desc) +{ + struct sti_pinctrl_platdata *plat = dev_get_platdata(dev); + unsigned long sysconf, *sysconfreg; + int alt = pin_desc->alt; + int bank = pin_desc->bank; + int pin = pin_desc->pin; + + sysconfreg = (unsigned long *)plat->regmap->base; + + switch (bank) { + case 0 ... 5: /* in "SBC Bank" */ + sysconfreg += bank; + break; + case 10 ... 20: /* in "FRONT Bank" */ + sysconfreg += bank - 10; + break; + case 30 ... 35: /* in "REAR Bank" */ + sysconfreg += bank - 30; + break; + case 40 ... 42: /* in "FLASH Bank" */ + sysconfreg += bank - 40; + break; + default: + BUG(); + return; + } + + sysconf = readl(sysconfreg); + bitfield_replace(sysconf, pin * 4, 3, alt); + writel(sysconf, sysconfreg); +} + +/* pin configuration */ +void sti_pin_configure(struct udevice *dev, struct sti_pin_desc *pin_desc) +{ + struct sti_pinctrl_platdata *plat = dev_get_platdata(dev); + int bit; + int oe = 0, pu = 0, od = 0; + unsigned long *sysconfreg; + int bank = pin_desc->bank; + + sysconfreg = (unsigned long *)plat->regmap->base + 40; + + /* + * NOTE: The PIO configuration for the PIO pins in the + * "FLASH Bank" are different from all the other banks! + * Specifically, the output-enable pin control register + * (SYS_CFG_3040) and the pull-up pin control register + * (SYS_CFG_3050), are both classed as being "reserved". + * Hence, we do not write to these registers to configure + * the OE and PU features for PIOs in this bank. However, + * the open-drain pin control register (SYS_CFG_3060) + * follows the style of the other banks, and so we can + * treat that register normally. + * + * Being pedantic, we should configure the PU and PD features + * in the "FLASH Bank" explicitly instead using the four + * SYS_CFG registers: 3080, 3081, 3085, and 3086. However, this + * would necessitate passing in the alternate function number + * to this function, and adding some horrible complexity here. + * Alternatively, we could just perform 4 32-bit "pokes" to + * these four SYS_CFG registers early in the initialization. + * In practice, these four SYS_CFG registers are correct + * after a reset, and U-Boot does not need to change them, so + * we (cheat and) rely on these registers being correct. + * WARNING: Please be aware of this (pragmatic) behaviour! + */ + int flashss = 0; /* bool: PIO in the Flash Sub-System ? */ + + switch (pin_desc->dir) { + case IN: + oe = 0; pu = 0; od = 0; + break; + case IN_PU: + oe = 0; pu = 1; od = 0; + break; + case OUT: + oe = 1; pu = 0; od = 0; + break; + case BIDIR: + oe = 1; pu = 0; od = 1; + break; + case BIDIR_PU: + oe = 1; pu = 1; od = 1; + break; + + default: + error("%s invalid direction value: 0x%x\n", + __func__, pin_desc->dir); + BUG(); + break; + } + + switch (bank) { + case 0 ... 5: /* in "SBC Bank" */ + sysconfreg += bank / 4; + break; + case 10 ... 20: /* in "FRONT Bank" */ + bank -= 10; + sysconfreg += bank / 4; + break; + case 30 ... 35: /* in "REAR Bank" */ + bank -= 30; + sysconfreg += bank / 4; + break; + case 40 ... 42: /* in "FLASH Bank" */ + bank -= 40; + sysconfreg += bank / 4; + flashss = 1; /* pin is in the Flash Sub-System */ + break; + default: + BUG(); + return; + } + + bit = ((bank * 8) + pin_desc->pin) % 32; + + /* + * set the "Output Enable" pin control + * but, do nothing if in the flashSS + */ + if (!flashss) { + if (oe) + generic_set_bit(bit, sysconfreg); + else + generic_clear_bit(bit, sysconfreg); + } + + sysconfreg += 10; /* skip to next set of syscfg registers */ + + /* + * set the "Pull Up" pin control + * but, do nothing if in the FlashSS + */ + + if (!flashss) { + if (pu) + generic_set_bit(bit, sysconfreg); + else + generic_clear_bit(bit, sysconfreg); + } + + sysconfreg += 10; /* skip to next set of syscfg registers */ + + /* set the "Open Drain Enable" pin control */ + if (od) + generic_set_bit(bit, sysconfreg); + else + generic_clear_bit(bit, sysconfreg); +} + + +static int sti_pinctrl_set_state(struct udevice *dev, struct udevice *config) +{ + struct fdtdec_phandle_args args; + const void *blob = gd->fdt_blob; + const char *prop_name; + int node = config->of_offset; + int property_offset, prop_len; + int pinconf_node, ret, count; + const char *bank_name; + u32 cells[MAX_STI_PINCONF_ENTRIES]; + + struct sti_pin_desc pin_desc; + + /* go to next node "st,pins" which contains the pins configuration */ + pinconf_node = fdt_subnode_offset(blob, node, "st,pins"); + + /* + * parse each pins configuration which looks like : + * pin_name = <bank_phandle pin_nb alt dir rt_type rt_delay rt_clk> + */ + + fdt_for_each_property_offset(property_offset, blob, pinconf_node) { + fdt_getprop_by_offset(blob, property_offset, &prop_name, + &prop_len); + + /* extract the bank of the pin description */ + ret = fdtdec_parse_phandle_with_args(blob, pinconf_node, + prop_name, "#gpio-cells", + 0, 0, &args); + if (ret < 0) { + error("Can't get the gpio bank phandle: %d\n", ret); + return ret; + } + + bank_name = fdt_getprop(blob, args.node, "st,bank-name", + &count); + if (count < 0) { + error("Can't find bank-name property %d\n", count); + return -EINVAL; + } + + pin_desc.bank = trailing_strtoln(bank_name, NULL); + + count = fdtdec_get_int_array_count(blob, pinconf_node, + prop_name, cells, + ARRAY_SIZE(cells)); + if (count < 0) { + error("Bad pin configuration array %d\n", count); + return -EINVAL; + } + + if (count > MAX_STI_PINCONF_ENTRIES) { + error("Unsupported pinconf array count %d\n", count); + return -EINVAL; + } + + pin_desc.pin = cells[1]; + pin_desc.alt = cells[2]; + pin_desc.dir = cells[3]; + + sti_alternate_select(dev, &pin_desc); + sti_pin_configure(dev, &pin_desc); + }; + + return 0; +} + +int sti_pinctrl_probe(struct udevice *dev) +{ + struct sti_pinctrl_platdata *plat = dev_get_platdata(dev); + struct udevice *syscon; + int err; + + /* get corresponding syscon phandle */ + err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, + "st,syscfg", &syscon); + if (err) { + error("unable to find syscon device\n"); + return err; + } + + plat->regmap = syscon_get_regmap(syscon); + if (!plat->regmap) { + error("unable to find regmap\n"); + return -ENODEV; + } + + return 0; +} + +static const struct udevice_id sti_pinctrl_ids[] = { + { .compatible = "st,stih407-sbc-pinctrl" }, + { .compatible = "st,stih407-front-pinctrl" }, + { .compatible = "st,stih407-rear-pinctrl" }, + { .compatible = "st,stih407-flash-pinctrl" }, + { } +}; + +const struct pinctrl_ops sti_pinctrl_ops = { + .set_state = sti_pinctrl_set_state, +}; + +U_BOOT_DRIVER(pinctrl_sti) = { + .name = "pinctrl_sti", + .id = UCLASS_PINCTRL, + .of_match = sti_pinctrl_ids, + .ops = &sti_pinctrl_ops, + .probe = sti_pinctrl_probe, + .platdata_auto_alloc_size = sizeof(struct sti_pinctrl_platdata), + .ops = &sti_pinctrl_ops, +};

Don't take care of this series, a correct one will be sent with the correct prefix
On 02/02/2017 06:00 PM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
This board is a 96board based on STiH410 SoC. This series adds basic support with serial, mmc and pinctrl support.
v2: _ fix remarks from Jaechon Chung on SDHCI patch _ fix remarks from Antonio Borneo on board patch _ replace some macro by U-boot generic's one _ add missing maintainers in recipients
Patrice Chotard (7): arm: Add support for STMicroelectronics STiH410 soc board: Add STMicroelectronics STiH410-B2260 support STiH410: Add STi serial driver STiH410: Add STi SDHCI driver STiH410: add STi pinctrl driver STiH410-B2260: add device tree STIH410-B2260: Add STiH410-B2260 defconfig
arch/arm/Kconfig | 13 + arch/arm/Makefile | 1 + arch/arm/dts/Makefile | 2 + arch/arm/dts/st-pincfg.h | 71 ++ arch/arm/dts/stih407-clock.dtsi | 326 ++++++ arch/arm/dts/stih407-family.dtsi | 977 +++++++++++++++ arch/arm/dts/stih407-pinctrl.dtsi | 1303 +++++++++++++++++++++ arch/arm/dts/stih410-b2260.dts | 225 ++++ arch/arm/dts/stih410-clock.dtsi | 347 ++++++ arch/arm/dts/stih410-pinctrl.dtsi | 34 + arch/arm/dts/stih410.dtsi | 454 +++++++ arch/arm/include/asm/arch-stih410/gpio.h | 20 + arch/arm/include/asm/arch-stih410/sdhci.h | 69 ++ arch/arm/include/asm/arch-stih410/sti.h | 20 + arch/arm/include/asm/arch-stih410/syscfg.h | 20 + arch/arm/mach-sti/Kconfig | 31 + arch/arm/mach-sti/Makefile | 8 + arch/arm/mach-sti/cpu.c | 16 + arch/arm/mach-sti/timer.c | 47 + board/st/stih410-b2260/Kconfig | 19 + board/st/stih410-b2260/MAINTAINERS | 6 + board/st/stih410-b2260/Makefile | 8 + board/st/stih410-b2260/board.c | 40 + configs/stih410-b2260_defconfig | 22 + drivers/mmc/Kconfig | 7 + drivers/mmc/Makefile | 1 + drivers/mmc/sti_sdhci.c | 140 +++ drivers/pinctrl/Kconfig | 10 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-sti.c | 315 +++++ drivers/serial/Kconfig | 7 + drivers/serial/Makefile | 1 + drivers/serial/serial_sti_asc.c | 219 ++++ include/configs/stih410-b2260.h | 59 + include/dm/platform_data/serial_sti_asc.h | 17 + include/dt-bindings/clock/stih407-clks.h | 90 ++ include/dt-bindings/clock/stih410-clks.h | 25 + include/dt-bindings/interrupt-controller/irq-st.h | 30 + include/dt-bindings/mfd/st-lpc.h | 16 + include/dt-bindings/reset/stih407-resets.h | 65 + 40 files changed, 5082 insertions(+) create mode 100644 arch/arm/dts/st-pincfg.h create mode 100644 arch/arm/dts/stih407-clock.dtsi create mode 100644 arch/arm/dts/stih407-family.dtsi create mode 100644 arch/arm/dts/stih407-pinctrl.dtsi create mode 100644 arch/arm/dts/stih410-b2260.dts create mode 100644 arch/arm/dts/stih410-clock.dtsi create mode 100644 arch/arm/dts/stih410-pinctrl.dtsi create mode 100644 arch/arm/dts/stih410.dtsi create mode 100644 arch/arm/include/asm/arch-stih410/gpio.h create mode 100644 arch/arm/include/asm/arch-stih410/sdhci.h create mode 100644 arch/arm/include/asm/arch-stih410/sti.h create mode 100644 arch/arm/include/asm/arch-stih410/syscfg.h create mode 100644 arch/arm/mach-sti/Kconfig create mode 100644 arch/arm/mach-sti/Makefile create mode 100644 arch/arm/mach-sti/cpu.c create mode 100644 arch/arm/mach-sti/timer.c create mode 100644 board/st/stih410-b2260/Kconfig create mode 100644 board/st/stih410-b2260/MAINTAINERS create mode 100644 board/st/stih410-b2260/Makefile create mode 100644 board/st/stih410-b2260/board.c create mode 100644 configs/stih410-b2260_defconfig create mode 100644 drivers/mmc/sti_sdhci.c create mode 100644 drivers/pinctrl/pinctrl-sti.c create mode 100644 drivers/serial/serial_sti_asc.c create mode 100644 include/configs/stih410-b2260.h create mode 100644 include/dm/platform_data/serial_sti_asc.h create mode 100644 include/dt-bindings/clock/stih407-clks.h create mode 100644 include/dt-bindings/clock/stih410-clks.h create mode 100644 include/dt-bindings/interrupt-controller/irq-st.h create mode 100644 include/dt-bindings/mfd/st-lpc.h create mode 100644 include/dt-bindings/reset/stih407-resets.h
participants (3)
-
Patrice CHOTARD
-
patrice.chotard@st.com
-
Simon Glass