[U-Boot] [PATCH v3 0/6] Add ARMv7M STM32F1 and STM3210E-EVAL board support

This series adds support for the STM32F1 SoC family and the STM3210E-EVAL board on top of the STM32F4 SoC family support [1].
Since this board has no DRAM the first patch fixes the build when CONFIG_NR_DRAM_BANKS is not set. A patch is also required to force the processor to stay in Thumb mode when 'go'ing to an application.
As the STM32F1 differs greatly from STM32F4 in flash and clock layout, there's a separate subdirectory for the STM32F1 family. The gpio and serial drivers are shared as these peripherals are mostly similar with only the pinmux bits being significantly different in the gpio driver.
The STM3210E-EVAL board is supported with 1MiB Flash and 96KiB of SRAM on the STM32F103ZGT6, USART1 for console, and four user LEDs.
[1] http://lists.denx.de/pipermail/u-boot/2015-March/206640.html
Matt Porter (6): image: fix build when CONFIG_NR_DRAM_BANKS is disabled on ARM common/cmd_boot: keep ARM v7M in thumb mode during do_go_exec() ARMv7M: add STM32F1 support gpio: stm32: add stm32f1 support serial: stm32: add stm32f1 support board: add stm3210e-eval board support
arch/arm/Kconfig | 5 + arch/arm/cpu/armv7m/Makefile | 1 + arch/arm/cpu/armv7m/stm32f1/Makefile | 14 +++ arch/arm/cpu/armv7m/stm32f1/clock.c | 196 ++++++++++++++++++++++++++++++ arch/arm/cpu/armv7m/stm32f1/flash.c | 180 +++++++++++++++++++++++++++ arch/arm/cpu/armv7m/stm32f1/soc.c | 36 ++++++ arch/arm/cpu/armv7m/stm32f1/timer.c | 121 ++++++++++++++++++ arch/arm/include/asm/arch-stm32f1/gpio.h | 118 ++++++++++++++++++ arch/arm/include/asm/arch-stm32f1/stm32.h | 116 ++++++++++++++++++ arch/arm/lib/Makefile | 1 + arch/arm/lib/cmd_boot.c | 44 +++++++ board/st/stm3210e-eval/Kconfig | 19 +++ board/st/stm3210e-eval/MAINTAINERS | 5 + board/st/stm3210e-eval/Makefile | 14 +++ board/st/stm3210e-eval/stm3210e-eval.c | 86 +++++++++++++ common/image.c | 2 +- configs/stm3210e-eval_defconfig | 3 + drivers/gpio/stm32_gpio.c | 110 ++++++++++++++++- drivers/serial/serial_stm32.c | 10 ++ include/configs/stm3210e-eval.h | 118 ++++++++++++++++++ include/flash.h | 1 + 21 files changed, 1198 insertions(+), 2 deletions(-) create mode 100644 arch/arm/cpu/armv7m/stm32f1/Makefile create mode 100644 arch/arm/cpu/armv7m/stm32f1/clock.c create mode 100644 arch/arm/cpu/armv7m/stm32f1/flash.c create mode 100644 arch/arm/cpu/armv7m/stm32f1/soc.c create mode 100644 arch/arm/cpu/armv7m/stm32f1/timer.c create mode 100644 arch/arm/include/asm/arch-stm32f1/gpio.h create mode 100644 arch/arm/include/asm/arch-stm32f1/stm32.h create mode 100644 arch/arm/lib/cmd_boot.c create mode 100644 board/st/stm3210e-eval/Kconfig create mode 100644 board/st/stm3210e-eval/MAINTAINERS create mode 100644 board/st/stm3210e-eval/Makefile create mode 100644 board/st/stm3210e-eval/stm3210e-eval.c create mode 100644 configs/stm3210e-eval_defconfig create mode 100644 include/configs/stm3210e-eval.h

common/image.c currently implicitly depends on CONFIG_NR_DRAM_BANKS when CONFIG_ARM is enabled. Make this requirement explicit.
Signed-off-by: Matt Porter mporter@konsulko.com --- common/image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/image.c b/common/image.c index 162b682..73c24f5 100644 --- a/common/image.c +++ b/common/image.c @@ -461,7 +461,7 @@ phys_size_t getenv_bootm_size(void) tmp = 0;
-#if defined(CONFIG_ARM) +#if defined(CONFIG_ARM) && defined(CONFIG_NR_DRAM_BANKS) return gd->bd->bi_dram[0].size - tmp; #else return gd->bd->bi_memsize - tmp;

On Tue, May 05, 2015 at 03:00:22PM -0400, Matt Porter wrote:
common/image.c currently implicitly depends on CONFIG_NR_DRAM_BANKS when CONFIG_ARM is enabled. Make this requirement explicit.
Signed-off-by: Matt Porter mporter@konsulko.com
Applied to u-boot/master, thanks!

On ARM v7M, the processor will return to ARM mode when executing a blx instruction with bit 0 of the address == 0. Always set it to 1 to stay in thumb mode.
Signed-off-by: Matt Porter mporter@konsulko.com --- v3: - Implement using an override of the weak do_go_exec() when building for ARMv7-M.
arch/arm/lib/Makefile | 1 + arch/arm/lib/cmd_boot.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 arch/arm/lib/cmd_boot.c
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 8288d2f..4c95a77 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -26,6 +26,7 @@ ifndef CONFIG_SYS_GENERIC_BOARD obj-y += board.o endif
+obj-$(CONFIG_CPU_V7M) += cmd_boot.o obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o diff --git a/arch/arm/lib/cmd_boot.c b/arch/arm/lib/cmd_boot.c new file mode 100644 index 0000000..37bb6a5 --- /dev/null +++ b/arch/arm/lib/cmd_boot.c @@ -0,0 +1,44 @@ +/* + * (C) Copyright 2008-2011 + * Graeme Russ, graeme.russ@gmail.com + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + * + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * Copyright 2015 ATS Advanced Telematics Systems GmbH + * Copyright 2015 Konsulko Group, Matt Porter mporter@konsulko.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * ARMv7M does not support ARM instruction mode. However, the + * interworking BLX and BX instructions do encode the ARM/Thumb + * field in bit 0. This means that when executing any Branch + * and eXchange instruction we must set bit 0 to one to guarantee + * that we keep the processor in Thumb instruction mode. From The + * ARMv7-M Instruction Set A4.1.1: + * "ARMv7-M only supports the Thumb instruction execution state, + * therefore the value of address bit [0] must be 1 in interworking + * instructions, otherwise a fault occurs." + */ +unsigned long do_go_exec(ulong (*entry)(int, char * const []), + int argc, char * const argv[]) +{ + ulong addr = (ulong)entry | 1; + entry = (void *)addr; + + return entry(argc, argv); +}

On Tue, May 05, 2015 at 03:00:23PM -0400, Matt Porter wrote:
On ARM v7M, the processor will return to ARM mode when executing a blx instruction with bit 0 of the address == 0. Always set it to 1 to stay in thumb mode.
Signed-off-by: Matt Porter mporter@konsulko.com
Applied to u-boot/master, thanks!

Add ARMv7M STM32F1 support including clocks, timer, gpio, and flash.
Signed-off-by: Matt Porter mporter@konsulko.com --- v3: - Update copyright notices
arch/arm/cpu/armv7m/Makefile | 1 + arch/arm/cpu/armv7m/stm32f1/Makefile | 14 +++ arch/arm/cpu/armv7m/stm32f1/clock.c | 196 ++++++++++++++++++++++++++++++ arch/arm/cpu/armv7m/stm32f1/flash.c | 180 +++++++++++++++++++++++++++ arch/arm/cpu/armv7m/stm32f1/soc.c | 36 ++++++ arch/arm/cpu/armv7m/stm32f1/timer.c | 121 ++++++++++++++++++ arch/arm/include/asm/arch-stm32f1/gpio.h | 118 ++++++++++++++++++ arch/arm/include/asm/arch-stm32f1/stm32.h | 116 ++++++++++++++++++ include/flash.h | 1 + 9 files changed, 783 insertions(+) create mode 100644 arch/arm/cpu/armv7m/stm32f1/Makefile create mode 100644 arch/arm/cpu/armv7m/stm32f1/clock.c create mode 100644 arch/arm/cpu/armv7m/stm32f1/flash.c create mode 100644 arch/arm/cpu/armv7m/stm32f1/soc.c create mode 100644 arch/arm/cpu/armv7m/stm32f1/timer.c create mode 100644 arch/arm/include/asm/arch-stm32f1/gpio.h create mode 100644 arch/arm/include/asm/arch-stm32f1/stm32.h
diff --git a/arch/arm/cpu/armv7m/Makefile b/arch/arm/cpu/armv7m/Makefile index b662e03..93a1956 100644 --- a/arch/arm/cpu/armv7m/Makefile +++ b/arch/arm/cpu/armv7m/Makefile @@ -8,4 +8,5 @@ extra-y := start.o obj-y += cpu.o
+obj-$(CONFIG_STM32F1) += stm32f1/ obj-$(CONFIG_STM32F4) += stm32f4/ diff --git a/arch/arm/cpu/armv7m/stm32f1/Makefile b/arch/arm/cpu/armv7m/stm32f1/Makefile new file mode 100644 index 0000000..4faf435 --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f1/Makefile @@ -0,0 +1,14 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2015 +# Kamil Lulko, rev13@wp.pl +# +# Copyright 2015 ATS Advanced Telematics Systems GmbH +# Copyright 2015 Konsulko Group, Matt Porter mporter@konsulko.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += soc.o clock.o timer.o flash.o diff --git a/arch/arm/cpu/armv7m/stm32f1/clock.c b/arch/arm/cpu/armv7m/stm32f1/clock.c new file mode 100644 index 0000000..acad116 --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f1/clock.c @@ -0,0 +1,196 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * Copyright 2015 ATS Advanced Telematics Systems GmbH + * Copyright 2015 Konsulko Group, Matt Porter mporter@konsulko.com + * + * (C) Copyright 2014 + * STMicroelectronics + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/stm32.h> + +#define RCC_CR_HSION (1 << 0) +#define RCC_CR_HSEON (1 << 16) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_CSSON (1 << 19) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_PLLRDY (1 << 25) + +#define RCC_CFGR_PLLMUL_MASK 0x3C0000 +#define RCC_CFGR_PLLMUL_SHIFT 18 +#define RCC_CFGR_PLLSRC_HSE (1 << 16) + +#define RCC_CFGR_AHB_PSC_MASK 0xF0 +#define RCC_CFGR_APB1_PSC_MASK 0x700 +#define RCC_CFGR_APB2_PSC_MASK 0x3800 +#define RCC_CFGR_SW0 (1 << 0) +#define RCC_CFGR_SW1 (1 << 1) +#define RCC_CFGR_SW_MASK 0x3 +#define RCC_CFGR_SW_HSI 0 +#define RCC_CFGR_SW_HSE RCC_CFGR_SW0 +#define RCC_CFGR_SW_PLL RCC_CFGR_SW1 +#define RCC_CFGR_SWS0 (1 << 2) +#define RCC_CFGR_SWS1 (1 << 3) +#define RCC_CFGR_SWS_MASK 0xC +#define RCC_CFGR_SWS_HSI 0 +#define RCC_CFGR_SWS_HSE RCC_CFGR_SWS0 +#define RCC_CFGR_SWS_PLL RCC_CFGR_SWS1 +#define RCC_CFGR_HPRE_SHIFT 4 +#define RCC_CFGR_PPRE1_SHIFT 8 +#define RCC_CFGR_PPRE2_SHIFT 11 + +#define RCC_APB1ENR_PWREN (1 << 28) + +#define PWR_CR_VOS0 (1 << 14) +#define PWR_CR_VOS1 (1 << 15) +#define PWR_CR_VOS_MASK 0xC000 +#define PWR_CR_VOS_SCALE_MODE_1 (PWR_CR_VOS0 | PWR_CR_VOS1) +#define PWR_CR_VOS_SCALE_MODE_2 (PWR_CR_VOS1) +#define PWR_CR_VOS_SCALE_MODE_3 (PWR_CR_VOS0) + +#define FLASH_ACR_WS(n) n +#define FLASH_ACR_PRFTEN (1 << 8) +#define FLASH_ACR_ICEN (1 << 9) +#define FLASH_ACR_DCEN (1 << 10) + +struct psc { + u8 ahb_psc; + u8 apb1_psc; + u8 apb2_psc; +}; + +#define AHB_PSC_1 0 +#define AHB_PSC_2 0x8 +#define AHB_PSC_4 0x9 +#define AHB_PSC_8 0xA +#define AHB_PSC_16 0xB +#define AHB_PSC_64 0xC +#define AHB_PSC_128 0xD +#define AHB_PSC_256 0xE +#define AHB_PSC_512 0xF + +#define APB_PSC_1 0 +#define APB_PSC_2 0x4 +#define APB_PSC_4 0x5 +#define APB_PSC_8 0x6 +#define APB_PSC_16 0x7 + +#if !defined(CONFIG_STM32_HSE_HZ) +#error "CONFIG_STM32_HSE_HZ not defined!" +#else +#if (CONFIG_STM32_HSE_HZ == 8000000) +#define RCC_CFGR_PLLMUL_CFG 0x7 +struct psc psc_hse = { + .ahb_psc = AHB_PSC_1, + .apb1_psc = APB_PSC_2, + .apb2_psc = APB_PSC_1 +}; +#else +#error "No PLL/Prescaler configuration for given CONFIG_STM32_HSE_HZ exists" +#endif +#endif + +int configure_clocks(void) +{ + /* Reset RCC configuration */ + setbits_le32(&STM32_RCC->cr, RCC_CR_HSION); + writel(0, &STM32_RCC->cfgr); /* Reset CFGR */ + clrbits_le32(&STM32_RCC->cr, (RCC_CR_HSEON | RCC_CR_CSSON + | RCC_CR_PLLON)); + clrbits_le32(&STM32_RCC->cr, RCC_CR_HSEBYP); + writel(0, &STM32_RCC->cir); /* Disable all interrupts */ + + /* Configure for HSE+PLL operation */ + setbits_le32(&STM32_RCC->cr, RCC_CR_HSEON); + while (!(readl(&STM32_RCC->cr) & RCC_CR_HSERDY)) + ; + + /* Enable high performance mode, System frequency up to 168 MHz */ + setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_PWREN); + writel(PWR_CR_VOS_SCALE_MODE_1, &STM32_PWR->cr); + + setbits_le32(&STM32_RCC->cfgr, + RCC_CFGR_PLLMUL_CFG << RCC_CFGR_PLLMUL_SHIFT); + setbits_le32(&STM32_RCC->cfgr, RCC_CFGR_PLLSRC_HSE); + setbits_le32(&STM32_RCC->cfgr, (( + psc_hse.ahb_psc << RCC_CFGR_HPRE_SHIFT) + | (psc_hse.apb1_psc << RCC_CFGR_PPRE1_SHIFT) + | (psc_hse.apb2_psc << RCC_CFGR_PPRE2_SHIFT))); + + setbits_le32(&STM32_RCC->cr, RCC_CR_PLLON); + + while (!(readl(&STM32_RCC->cr) & RCC_CR_PLLRDY)) + ; + + /* 5 wait states, Prefetch enabled, D-Cache enabled, I-Cache enabled */ + writel(FLASH_ACR_WS(5) | FLASH_ACR_PRFTEN | FLASH_ACR_ICEN + | FLASH_ACR_DCEN, &STM32_FLASH->acr); + + clrbits_le32(&STM32_RCC->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1)); + setbits_le32(&STM32_RCC->cfgr, RCC_CFGR_SW_PLL); + + while ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_PLL) + ; + + return 0; +} + +unsigned long clock_get(enum clock clck) +{ + u32 sysclk = 0; + u32 shift = 0; + /* PLL table lookups for clock computation */ + u8 pll_mul_table[16] = { + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16 + }; + /* Prescaler table lookups for clock computation */ + u8 ahb_psc_table[16] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9 + }; + u8 apb_psc_table[8] = { + 0, 0, 0, 0, 1, 2, 3, 4 + }; + + if ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) == + RCC_CFGR_SWS_PLL) { + u16 pll; + pll = ((readl(&STM32_RCC->cfgr) & RCC_CFGR_PLLMUL_MASK) + >> RCC_CFGR_PLLMUL_SHIFT); + sysclk = CONFIG_STM32_HSE_HZ * pll_mul_table[pll]; + } + + switch (clck) { + case CLOCK_CORE: + return sysclk; + break; + case CLOCK_AHB: + shift = ahb_psc_table[( + (readl(&STM32_RCC->cfgr) & RCC_CFGR_AHB_PSC_MASK) + >> RCC_CFGR_HPRE_SHIFT)]; + return sysclk >>= shift; + break; + case CLOCK_APB1: + shift = apb_psc_table[( + (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB1_PSC_MASK) + >> RCC_CFGR_PPRE1_SHIFT)]; + return sysclk >>= shift; + break; + case CLOCK_APB2: + shift = apb_psc_table[( + (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB2_PSC_MASK) + >> RCC_CFGR_PPRE2_SHIFT)]; + return sysclk >>= shift; + break; + default: + return 0; + break; + } +} diff --git a/arch/arm/cpu/armv7m/stm32f1/flash.c b/arch/arm/cpu/armv7m/stm32f1/flash.c new file mode 100644 index 0000000..bb88f23 --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f1/flash.c @@ -0,0 +1,180 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * Copyright 2015 ATS Advanced Telematics Systems GmbH + * Copyright 2015 Konsulko Group, Matt Porter mporter@konsulko.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/stm32.h> + +#define STM32_FLASH_KEY1 0x45670123 +#define STM32_FLASH_KEY2 0xcdef89ab + +#define STM32_NUM_BANKS 2 +#define STM32_MAX_BANK 0x200 + +flash_info_t flash_info[STM32_NUM_BANKS]; +static struct stm32_flash_bank_regs *flash_bank[STM32_NUM_BANKS]; + +static void stm32f1_flash_lock(u8 bank, u8 lock) +{ + if (lock) { + setbits_le32(&flash_bank[bank]->cr, STM32_FLASH_CR_LOCK); + } else { + writel(STM32_FLASH_KEY1, &flash_bank[bank]->keyr); + writel(STM32_FLASH_KEY2, &flash_bank[bank]->keyr); + } +} + +/* Only XL devices are supported (2 KiB sector size) */ +unsigned long flash_init(void) +{ + u8 i, banks; + u16 j, size; + + /* Set up accessors for XL devices with wonky register layout */ + flash_bank[0] = (struct stm32_flash_bank_regs *)&STM32_FLASH->keyr; + flash_bank[1] = (struct stm32_flash_bank_regs *)&STM32_FLASH->keyr2; + + /* + * Get total flash size (in KiB) and configure number of banks + * present and sector count per bank. + */ + size = readw(&STM32_DES->flash_size); + if (size <= STM32_MAX_BANK) { + banks = 1; + flash_info[0].sector_count = size >> 1; + } else if (size > STM32_MAX_BANK) { + banks = 2; + flash_info[0].sector_count = STM32_MAX_BANK >> 1; + flash_info[1].sector_count = (size - STM32_MAX_BANK) >> 1; + } + + /* Configure start/size for all sectors */ + for (i = 0; i < banks; i++) { + flash_info[i].flash_id = FLASH_STM32F1; + flash_info[i].start[0] = CONFIG_SYS_FLASH_BASE + (i << 19); + flash_info[i].size = 2048; + for (j = 1; (j < flash_info[i].sector_count); j++) { + flash_info[i].start[j] = flash_info[i].start[j - 1] + + 2048; + flash_info[i].size += 2048; + } + } + + return size << 10; +} + +void flash_print_info(flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf("Missing or unknown FLASH type\n"); + return; + } else if (info->flash_id == FLASH_STM32F1) { + printf("STM32F1 Embedded Flash\n"); + } + + printf(" Size: %ld MB in %d Sectors\n", + info->size >> 10, info->sector_count); + + printf(" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; ++i) { + if ((i % 5) == 0) + printf("\n "); + printf(" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " "); + } + printf("\n"); + return; +} + +int flash_erase(flash_info_t *info, int first, int last) +{ + u8 bank = 0xff; + int i; + + for (i = 0; i < STM32_NUM_BANKS; i++) { + if (info == &flash_info[i]) { + bank = i; + break; + } + } + if (bank == 0xff) + return -1; + + stm32f1_flash_lock(bank, 0); + + for (i = first; i <= last; i++) { + while (readl(&flash_bank[bank]->sr) & STM32_FLASH_SR_BSY) + ; + + setbits_le32(&flash_bank[bank]->cr, STM32_FLASH_CR_PER); + + writel(info->start[i], &flash_bank[bank]->ar); + + setbits_le32(&flash_bank[bank]->cr, STM32_FLASH_CR_STRT); + + while (readl(&flash_bank[bank]->sr) & STM32_FLASH_SR_BSY) + ; + } + + clrbits_le32(&flash_bank[bank]->cr, STM32_FLASH_CR_PER); + + stm32f1_flash_lock(bank, 1); + + return 0; +} + +int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong i; + u8 bank = 0xff; + + if (addr & 1) { + printf("Flash address must be half word aligned\n"); + return -1; + } + + if (cnt & 1) { + printf("Flash length must be half word aligned\n"); + return -1; + } + + for (i = 0; i < 2; i++) { + if (info == &flash_info[i]) { + bank = i; + break; + } + } + + if (bank == 0xff) + return -1; + + while (readl(&flash_bank[bank]->sr) & STM32_FLASH_SR_BSY) + ; + + stm32f1_flash_lock(bank, 0); + + setbits_le32(&flash_bank[bank]->cr, STM32_FLASH_CR_PG); + + /* STM32F1 requires half word writes */ + for (i = 0; i < cnt >> 1; i++) { + *(u16 *)(addr + i * 2) = ((u16 *)src)[i]; + while (readl(&flash_bank[bank]->sr) & STM32_FLASH_SR_BSY) + ; + } + + clrbits_le32(&flash_bank[bank]->cr, STM32_FLASH_CR_PG); + + stm32f1_flash_lock(bank, 1); + + return 0; +} diff --git a/arch/arm/cpu/armv7m/stm32f1/soc.c b/arch/arm/cpu/armv7m/stm32f1/soc.c new file mode 100644 index 0000000..8275ad7 --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f1/soc.c @@ -0,0 +1,36 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * Copyright 2015 ATS Advanced Telematics Systems GmbH + * Copyright 2015 Konsulko Group, Matt Porter mporter@konsulko.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/armv7m.h> +#include <asm/arch/stm32.h> + +u32 get_cpu_rev(void) +{ + return 0; +} + +int arch_cpu_init(void) +{ + configure_clocks(); + + /* + * Configure the memory protection unit (MPU) to allow full access to + * the whole 4GB address space. + */ + writel(0, &V7M_MPU->rnr); + writel(0, &V7M_MPU->rbar); + writel((V7M_MPU_RASR_AP_RW_RW | V7M_MPU_RASR_SIZE_4GB + | V7M_MPU_RASR_EN), &V7M_MPU->rasr); + writel(V7M_MPU_CTRL_ENABLE | V7M_MPU_CTRL_HFNMIENA, &V7M_MPU->ctrl); + + return 0; +} diff --git a/arch/arm/cpu/armv7m/stm32f1/timer.c b/arch/arm/cpu/armv7m/stm32f1/timer.c new file mode 100644 index 0000000..c6292b5 --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f1/timer.c @@ -0,0 +1,121 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * Copyright 2015 ATS Advanced Telematics Systems GmbH + * Copyright 2015 Konsulko Group, Matt Porter mporter@konsulko.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/armv7m.h> +#include <asm/arch/stm32.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define STM32_TIM2_BASE (STM32_APB1PERIPH_BASE + 0x0000) + +#define RCC_APB1ENR_TIM2EN (1 << 0) + +struct stm32_tim2_5 { + u32 cr1; + u32 cr2; + u32 smcr; + u32 dier; + u32 sr; + u32 egr; + u32 ccmr1; + u32 ccmr2; + u32 ccer; + u32 cnt; + u32 psc; + u32 arr; + u32 reserved1; + u32 ccr1; + u32 ccr2; + u32 ccr3; + u32 ccr4; + u32 reserved2; + u32 dcr; + u32 dmar; + u32 or; +}; + +#define TIM_CR1_CEN (1 << 0) + +#define TIM_EGR_UG (1 << 0) + +int timer_init(void) +{ + struct stm32_tim2_5 *tim = (struct stm32_tim2_5 *)STM32_TIM2_BASE; + + setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_TIM2EN); + + if (clock_get(CLOCK_AHB) == clock_get(CLOCK_APB1)) + writel((clock_get(CLOCK_APB1) / CONFIG_SYS_HZ_CLOCK) - 1, + &tim->psc); + else + writel(((clock_get(CLOCK_APB1) * 2) / CONFIG_SYS_HZ_CLOCK) - 1, + &tim->psc); + + writel(0xFFFFFFFF, &tim->arr); + writel(TIM_CR1_CEN, &tim->cr1); + setbits_le32(&tim->egr, TIM_EGR_UG); + + gd->arch.tbl = 0; + gd->arch.tbu = 0; + gd->arch.lastinc = 0; + + return 0; +} + +ulong get_timer(ulong base) +{ + return (get_ticks() / (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ)) - base; +} + +unsigned long long get_ticks(void) +{ + struct stm32_tim2_5 *tim = (struct stm32_tim2_5 *)STM32_TIM2_BASE; + u32 now; + + now = readl(&tim->cnt); + + if (now >= gd->arch.lastinc) + gd->arch.tbl += (now - gd->arch.lastinc); + else + gd->arch.tbl += (0xFFFFFFFF - gd->arch.lastinc) + now; + + gd->arch.lastinc = now; + + return gd->arch.tbl; +} + +void reset_timer(void) +{ + struct stm32_tim2_5 *tim = (struct stm32_tim2_5 *)STM32_TIM2_BASE; + + gd->arch.lastinc = readl(&tim->cnt); + gd->arch.tbl = 0; +} + +/* delay x useconds */ +void __udelay(ulong usec) +{ + unsigned long long start; + + start = get_ticks(); /* get current timestamp */ + while ((get_ticks() - start) < usec) + ; /* loop till time has passed */ +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ_CLOCK; +} diff --git a/arch/arm/include/asm/arch-stm32f1/gpio.h b/arch/arm/include/asm/arch-stm32f1/gpio.h new file mode 100644 index 0000000..6976e1f --- /dev/null +++ b/arch/arm/include/asm/arch-stm32f1/gpio.h @@ -0,0 +1,118 @@ +/* + * (C) Copyright 2011 + * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * Copyright 2015 ATS Advanced Telematics Systems GmbH + * Copyright 2015 Konsulko Group, Matt Porter mporter@konsulko.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _STM32_GPIO_H_ +#define _STM32_GPIO_H_ + +enum stm32_gpio_port { + STM32_GPIO_PORT_A = 0, + STM32_GPIO_PORT_B, + STM32_GPIO_PORT_C, + STM32_GPIO_PORT_D, + STM32_GPIO_PORT_E, + STM32_GPIO_PORT_F, + STM32_GPIO_PORT_G, +}; + +enum stm32_gpio_pin { + STM32_GPIO_PIN_0 = 0, + STM32_GPIO_PIN_1, + STM32_GPIO_PIN_2, + STM32_GPIO_PIN_3, + STM32_GPIO_PIN_4, + STM32_GPIO_PIN_5, + STM32_GPIO_PIN_6, + STM32_GPIO_PIN_7, + STM32_GPIO_PIN_8, + STM32_GPIO_PIN_9, + STM32_GPIO_PIN_10, + STM32_GPIO_PIN_11, + STM32_GPIO_PIN_12, + STM32_GPIO_PIN_13, + STM32_GPIO_PIN_14, + STM32_GPIO_PIN_15 +}; + +enum stm32_gpio_icnf { + STM32_GPIO_ICNF_AN = 0, + STM32_GPIO_ICNF_IN_FLT, + STM32_GPIO_ICNF_IN_PUD, + STM32_GPIO_ICNF_RSVD +}; + +enum stm32_gpio_ocnf { + STM32_GPIO_OCNF_GP_PP = 0, + STM32_GPIO_OCNF_GP_OD, + STM32_GPIO_OCNF_AF_PP, + STM32_GPIO_OCNF_AF_OD +}; + +enum stm32_gpio_pupd { + STM32_GPIO_PUPD_DOWN = 0, + STM32_GPIO_PUPD_UP, +}; + +enum stm32_gpio_mode { + STM32_GPIO_MODE_IN = 0, + STM32_GPIO_MODE_OUT_10M, + STM32_GPIO_MODE_OUT_2M, + STM32_GPIO_MODE_OUT_50M +}; + +enum stm32_gpio_af { + STM32_GPIO_AF0 = 0, + STM32_GPIO_AF1, + STM32_GPIO_AF2, + STM32_GPIO_AF3, + STM32_GPIO_AF4, + STM32_GPIO_AF5, + STM32_GPIO_AF6, + STM32_GPIO_AF7, + STM32_GPIO_AF8, + STM32_GPIO_AF9, + STM32_GPIO_AF10, + STM32_GPIO_AF11, + STM32_GPIO_AF12, + STM32_GPIO_AF13, + STM32_GPIO_AF14, + STM32_GPIO_AF15 +}; + +struct stm32_gpio_dsc { + enum stm32_gpio_port port; + enum stm32_gpio_pin pin; +}; + +struct stm32_gpio_ctl { + enum stm32_gpio_icnf icnf; + enum stm32_gpio_ocnf ocnf; + enum stm32_gpio_mode mode; + enum stm32_gpio_pupd pupd; + enum stm32_gpio_af af; +}; + +static inline unsigned stm32_gpio_to_port(unsigned gpio) +{ + return gpio / 16; +} + +static inline unsigned stm32_gpio_to_pin(unsigned gpio) +{ + return gpio % 16; +} + +int stm32_gpio_config(const struct stm32_gpio_dsc *gpio_dsc, + const struct stm32_gpio_ctl *gpio_ctl); +int stm32_gpout_set(const struct stm32_gpio_dsc *gpio_dsc, int state); + +#endif /* _STM32_GPIO_H_ */ diff --git a/arch/arm/include/asm/arch-stm32f1/stm32.h b/arch/arm/include/asm/arch-stm32f1/stm32.h new file mode 100644 index 0000000..686cb4f --- /dev/null +++ b/arch/arm/include/asm/arch-stm32f1/stm32.h @@ -0,0 +1,116 @@ +/* + * (C) Copyright 2011 + * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * Copyright 2015 ATS Advanced Telematics Systems GmbH + * Copyright 2015 Konsulko Group, Matt Porter mporter@konsulko.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _MACH_STM32_H_ +#define _MACH_STM32_H_ + +/* + * Peripheral memory map + */ +#define STM32_PERIPH_BASE 0x40000000 +#define STM32_APB1PERIPH_BASE (STM32_PERIPH_BASE + 0x00000000) +#define STM32_APB2PERIPH_BASE (STM32_PERIPH_BASE + 0x00010000) +#define STM32_AHB1PERIPH_BASE (STM32_PERIPH_BASE + 0x00018000) + +#define STM32_BUS_MASK 0xFFFF0000 + +/* + * Register maps + */ +struct stm32_des_regs { + u16 flash_size; + u16 pad1; + u32 pad2; + u32 uid0; + u32 uid1; + u32 uid2; +}; + +struct stm32_rcc_regs { + u32 cr; /* RCC clock control */ + u32 cfgr; /* RCC clock configuration */ + u32 cir; /* RCC clock interrupt */ + u32 apb2rstr; /* RCC APB2 peripheral reset */ + u32 apb1rstr; /* RCC APB1 peripheral reset */ + u32 ahbenr; /* RCC AHB peripheral clock enable */ + u32 apb2enr; /* RCC APB2 peripheral clock enable */ + u32 apb1enr; /* RCC APB1 peripheral clock enable */ + u32 bdcr; /* RCC Backup domain control */ + u32 csr; /* RCC clock control & status */ +}; + +struct stm32_pwr_regs { + u32 cr; + u32 csr; +}; + +struct stm32_flash_regs { + u32 acr; + u32 keyr; + u32 optkeyr; + u32 sr; + u32 cr; + u32 ar; + u32 rsvd1; /* Reserved */ + u32 obr; + u32 wrpr; + u32 rsvd2[8]; /* Reserved */ + u32 keyr2; + u32 rsvd3; + u32 sr2; + u32 cr2; + u32 ar2; +}; + +/* Per bank register set for XL devices */ +struct stm32_flash_bank_regs { + u32 keyr; + u32 rsvd; /* Reserved */ + u32 sr; + u32 cr; + u32 ar; +}; + +/* + * Registers access macros + */ +#define STM32_DES_BASE (0x1ffff7e0) +#define STM32_DES ((struct stm32_des_regs *)STM32_DES_BASE) + +#define STM32_RCC_BASE (STM32_AHB1PERIPH_BASE + 0x9000) +#define STM32_RCC ((struct stm32_rcc_regs *)STM32_RCC_BASE) + +#define STM32_PWR_BASE (STM32_APB1PERIPH_BASE + 0x7000) +#define STM32_PWR ((struct stm32_pwr_regs *)STM32_PWR_BASE) + +#define STM32_FLASH_BASE (STM32_AHB1PERIPH_BASE + 0xa000) +#define STM32_FLASH ((struct stm32_flash_regs *)STM32_FLASH_BASE) + +#define STM32_FLASH_SR_BSY (1 << 0) + +#define STM32_FLASH_CR_PG (1 << 0) +#define STM32_FLASH_CR_PER (1 << 1) +#define STM32_FLASH_CR_STRT (1 << 6) +#define STM32_FLASH_CR_LOCK (1 << 7) + +enum clock { + CLOCK_CORE, + CLOCK_AHB, + CLOCK_APB1, + CLOCK_APB2 +}; + +int configure_clocks(void); +unsigned long clock_get(enum clock clck); + +#endif /* _MACH_STM32_H_ */ diff --git a/include/flash.h b/include/flash.h index 48aa3a5..5754cf9 100644 --- a/include/flash.h +++ b/include/flash.h @@ -460,6 +460,7 @@ extern flash_info_t *flash_get_info(ulong base); #define FLASH_S29GL128N 0x00F1 /* Spansion S29GL128N */
#define FLASH_STM32F4 0x00F2 /* STM32F4 Embedded Flash */ +#define FLASH_STM32F1 0x00F3 /* STM32F1 Embedded Flash */
#define FLASH_UNKNOWN 0xFFFF /* unknown flash type */

On Tue, May 05, 2015 at 03:00:24PM -0400, Matt Porter wrote:
Add ARMv7M STM32F1 support including clocks, timer, gpio, and flash.
Signed-off-by: Matt Porter mporter@konsulko.com
Applied to u-boot/master, thanks!

Add support for the STM32F1 family to the STM32 gpio driver.
Signed-off-by: Matt Porter mporter@konsulko.com --- v3: - Update copyright notice v2: - Explicitly check for F4/F1 family and error if not set to a supported STM32 family.
drivers/gpio/stm32_gpio.c | 110 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c index d3497e9..86bb19e 100644 --- a/drivers/gpio/stm32_gpio.c +++ b/drivers/gpio/stm32_gpio.c @@ -5,6 +5,9 @@ * (C) Copyright 2015 * Kamil Lulko, rev13@wp.pl * + * Copyright 2015 ATS Advanced Telematics Systems GmbH + * Copyright 2015 Konsulko Group, Matt Porter mporter@konsulko.com + * * SPDX-License-Identifier: GPL-2.0+ */
@@ -16,6 +19,7 @@
DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_STM32F4) #define STM32_GPIOA_BASE (STM32_AHB1PERIPH_BASE + 0x0000) #define STM32_GPIOB_BASE (STM32_AHB1PERIPH_BASE + 0x0400) #define STM32_GPIOC_BASE (STM32_AHB1PERIPH_BASE + 0x0800) @@ -90,6 +94,92 @@ int stm32_gpio_config(const struct stm32_gpio_dsc *dsc, out: return rv; } +#elif defined(CONFIG_STM32F1) +#define STM32_GPIOA_BASE (STM32_APB2PERIPH_BASE + 0x0800) +#define STM32_GPIOB_BASE (STM32_APB2PERIPH_BASE + 0x0C00) +#define STM32_GPIOC_BASE (STM32_APB2PERIPH_BASE + 0x1000) +#define STM32_GPIOD_BASE (STM32_APB2PERIPH_BASE + 0x1400) +#define STM32_GPIOE_BASE (STM32_APB2PERIPH_BASE + 0x1800) +#define STM32_GPIOF_BASE (STM32_APB2PERIPH_BASE + 0x1C00) +#define STM32_GPIOG_BASE (STM32_APB2PERIPH_BASE + 0x2000) + +static const unsigned long io_base[] = { + STM32_GPIOA_BASE, STM32_GPIOB_BASE, STM32_GPIOC_BASE, + STM32_GPIOD_BASE, STM32_GPIOE_BASE, STM32_GPIOF_BASE, + STM32_GPIOG_BASE +}; + +#define STM32_GPIO_CR_MODE_MASK 0x3 +#define STM32_GPIO_CR_MODE_SHIFT(p) (p * 4) +#define STM32_GPIO_CR_CNF_MASK 0x3 +#define STM32_GPIO_CR_CNF_SHIFT(p) (p * 4 + 2) + +struct stm32_gpio_regs { + u32 crl; /* GPIO port configuration low */ + u32 crh; /* GPIO port configuration high */ + u32 idr; /* GPIO port input data */ + u32 odr; /* GPIO port output data */ + u32 bsrr; /* GPIO port bit set/reset */ + u32 brr; /* GPIO port bit reset */ + u32 lckr; /* GPIO port configuration lock */ +}; + +#define CHECK_DSC(x) (!x || x->port > 6 || x->pin > 15) +#define CHECK_CTL(x) (!x || x->mode > 3 || x->icnf > 3 || x->ocnf > 3 || \ + x->pupd > 1) + +int stm32_gpio_config(const struct stm32_gpio_dsc *dsc, + const struct stm32_gpio_ctl *ctl) +{ + struct stm32_gpio_regs *gpio_regs; + u32 *cr; + int p, crp; + int rv; + + if (CHECK_DSC(dsc)) { + rv = -EINVAL; + goto out; + } + if (CHECK_CTL(ctl)) { + rv = -EINVAL; + goto out; + } + + p = dsc->pin; + + gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; + + /* Enable clock for GPIO port */ + setbits_le32(&STM32_RCC->apb2enr, 0x04 << dsc->port); + + if (p < 8) { + cr = &gpio_regs->crl; + crp = p; + } else { + cr = &gpio_regs->crh; + crp = p - 8; + } + + clrbits_le32(cr, 0x3 << STM32_GPIO_CR_MODE_SHIFT(crp)); + setbits_le32(cr, ctl->mode << STM32_GPIO_CR_MODE_SHIFT(crp)); + + clrbits_le32(cr, 0x3 << STM32_GPIO_CR_CNF_SHIFT(crp)); + /* Inputs set the optional pull up / pull down */ + if (ctl->mode == STM32_GPIO_MODE_IN) { + setbits_le32(cr, ctl->icnf << STM32_GPIO_CR_CNF_SHIFT(crp)); + clrbits_le32(&gpio_regs->odr, 0x1 << p); + setbits_le32(&gpio_regs->odr, ctl->pupd << p); + } else { + setbits_le32(cr, ctl->ocnf << STM32_GPIO_CR_CNF_SHIFT(crp)); + } + + rv = 0; +out: + return rv; +} +#else +#error STM32 family not supported +#endif
int stm32_gpout_set(const struct stm32_gpio_dsc *dsc, int state) { @@ -148,10 +238,20 @@ int gpio_direction_input(unsigned gpio)
dsc.port = stm32_gpio_to_port(gpio); dsc.pin = stm32_gpio_to_pin(gpio); +#if defined(CONFIG_STM32F4) ctl.af = STM32_GPIO_AF0; ctl.mode = STM32_GPIO_MODE_IN; + ctl.otype = STM32_GPIO_OTYPE_PP; ctl.pupd = STM32_GPIO_PUPD_NO; ctl.speed = STM32_GPIO_SPEED_50M; +#elif defined(CONFIG_STM32F1) + ctl.mode = STM32_GPIO_MODE_IN; + ctl.icnf = STM32_GPIO_ICNF_IN_FLT; + ctl.ocnf = STM32_GPIO_OCNF_GP_PP; /* ignored for input */ + ctl.pupd = STM32_GPIO_PUPD_UP; /* ignored for floating */ +#else +#error STM32 family not supported +#endif
return stm32_gpio_config(&dsc, &ctl); } @@ -164,11 +264,19 @@ int gpio_direction_output(unsigned gpio, int value)
dsc.port = stm32_gpio_to_port(gpio); dsc.pin = stm32_gpio_to_pin(gpio); +#if defined(CONFIG_STM32F4) ctl.af = STM32_GPIO_AF0; ctl.mode = STM32_GPIO_MODE_OUT; - ctl.otype = STM32_GPIO_OTYPE_PP; ctl.pupd = STM32_GPIO_PUPD_NO; ctl.speed = STM32_GPIO_SPEED_50M; +#elif defined(CONFIG_STM32F1) + ctl.mode = STM32_GPIO_MODE_OUT_50M; + ctl.ocnf = STM32_GPIO_OCNF_GP_PP; + ctl.icnf = STM32_GPIO_ICNF_IN_FLT; /* ignored for output */ + ctl.pupd = STM32_GPIO_PUPD_UP; /* ignored for output */ +#else +#error STM32 family not supported +#endif
res = stm32_gpio_config(&dsc, &ctl); if (res < 0)

On Tue, May 05, 2015 at 03:00:25PM -0400, Matt Porter wrote:
Add support for the STM32F1 family to the STM32 gpio driver.
Signed-off-by: Matt Porter mporter@konsulko.com
Applied to u-boot/master, thanks!

Add support for the STM32F1 famly to the STM32 serial driver.
Signed-off-by: Matt Porter mporter@konsulko.com --- v3: - Update copyright notice v2: - Explicitly check for F4/F1 family and error if not set to a supported STM32 family.
drivers/serial/serial_stm32.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c index 3c80096..2a029ce 100644 --- a/drivers/serial/serial_stm32.c +++ b/drivers/serial/serial_stm32.c @@ -2,6 +2,9 @@ * (C) Copyright 2015 * Kamil Lulko, rev13@wp.pl * + * Copyright 2015 ATS Advanced Telematics Systems GmbH + * Copyright 2015 Konsulko Group, Matt Porter mporter@konsulko.com + * * SPDX-License-Identifier: GPL-2.0+ */
@@ -10,8 +13,15 @@ #include <serial.h> #include <asm/arch/stm32.h>
+#if defined(CONFIG_STM32F4) #define STM32_USART1_BASE (STM32_APB2PERIPH_BASE + 0x1000) #define RCC_APB2ENR_USART1EN (1 << 4) +#elif defined(CONFIG_STM32F1) +#define STM32_USART1_BASE (STM32_APB2PERIPH_BASE + 0x3800) +#define RCC_APB2ENR_USART1EN (1 << 14) +#else +#error STM32 family not supported +#endif
#define USART_BASE STM32_USART1_BASE #define RCC_USART_ENABLE RCC_APB2ENR_USART1EN

Add support for the STM32F1-based stm3210e-eval boards from ST. UART, Flash, GPIO, and LEDs are supported.
Signed-off-by: Matt Porter mporter@konsulko.com --- v3: - Update copyright notices
arch/arm/Kconfig | 5 ++ board/st/stm3210e-eval/Kconfig | 19 ++++++ board/st/stm3210e-eval/MAINTAINERS | 5 ++ board/st/stm3210e-eval/Makefile | 14 ++++ board/st/stm3210e-eval/stm3210e-eval.c | 86 ++++++++++++++++++++++++ configs/stm3210e-eval_defconfig | 3 + include/configs/stm3210e-eval.h | 118 +++++++++++++++++++++++++++++++++ 7 files changed, 250 insertions(+) create mode 100644 board/st/stm3210e-eval/Kconfig create mode 100644 board/st/stm3210e-eval/MAINTAINERS create mode 100644 board/st/stm3210e-eval/Makefile create mode 100644 board/st/stm3210e-eval/stm3210e-eval.c create mode 100644 configs/stm3210e-eval_defconfig create mode 100644 include/configs/stm3210e-eval.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4eb047c..bcf4e46 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -731,6 +731,10 @@ config ARCH_UNIPHIER select SPL select OF_CONTROL
+config TARGET_STM3210E_EVAL + bool "Support STM3210E-EVAL board" + select CPU_V7M + config TARGET_STM32F429_DISCOVERY bool "Support STM32F429 Discovery" select CPU_V7M @@ -872,6 +876,7 @@ source "board/spear/spear600/Kconfig" source "board/spear/x600/Kconfig" source "board/st-ericsson/snowball/Kconfig" source "board/st-ericsson/u8500/Kconfig" +source "board/st/stm3210e-eval/Kconfig" source "board/st/stm32f429-discovery/Kconfig" source "board/st/stv0991/Kconfig" source "board/sunxi/Kconfig" diff --git a/board/st/stm3210e-eval/Kconfig b/board/st/stm3210e-eval/Kconfig new file mode 100644 index 0000000..49bc770 --- /dev/null +++ b/board/st/stm3210e-eval/Kconfig @@ -0,0 +1,19 @@ +if TARGET_STM3210E_EVAL + +config SYS_BOARD + string + default "stm3210e-eval" + +config SYS_VENDOR + string + default "st" + +config SYS_SOC + string + default "stm32f1" + +config SYS_CONFIG_NAME + string + default "stm3210e-eval" + +endif diff --git a/board/st/stm3210e-eval/MAINTAINERS b/board/st/stm3210e-eval/MAINTAINERS new file mode 100644 index 0000000..0f9f31b --- /dev/null +++ b/board/st/stm3210e-eval/MAINTAINERS @@ -0,0 +1,5 @@ +M: Matt Porter mporter@konsulko.com +S: Maintained +F: board/st/stm3210e-eval/ +F: include/configs/stm3210e-eval.h +F: configs/stm3210e-eval_defconfig diff --git a/board/st/stm3210e-eval/Makefile b/board/st/stm3210e-eval/Makefile new file mode 100644 index 0000000..15e5ee3 --- /dev/null +++ b/board/st/stm3210e-eval/Makefile @@ -0,0 +1,14 @@ +# +# (C) Copyright 2000-2004 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2015 +# Kamil Lulko, rev13@wp.pl +# +# Copyright 2015 ATS Advanced Telematics Systems GmbH +# Copyright 2015 Konsulko Group, Matt Porter mporter@konsulko.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := stm3210e-eval.o diff --git a/board/st/stm3210e-eval/stm3210e-eval.c b/board/st/stm3210e-eval/stm3210e-eval.c new file mode 100644 index 0000000..43761aa --- /dev/null +++ b/board/st/stm3210e-eval/stm3210e-eval.c @@ -0,0 +1,86 @@ +/* + * (C) Copyright 2011, 2012, 2013 + * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com + * Alexander Potashev, Emcraft Systems, aspotashev@emcraft.com + * Vladimir Khusainov, Emcraft Systems, vlad@emcraft.com + * Pavel Boldin, Emcraft Systems, paboldin@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * Copyright 2015 ATS Advanced Telematics Systems GmbH + * Copyright 2015 Konsulko Group, Matt Porter mporter@konsulko.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/armv7m.h> +#include <asm/arch/stm32.h> +#include <asm/arch/gpio.h> + +DECLARE_GLOBAL_DATA_PTR; + +const struct stm32_gpio_ctl gpio_ctl_usart[] = { + /* TX */ + { + .mode = STM32_GPIO_MODE_OUT_50M, + .ocnf = STM32_GPIO_OCNF_AF_PP, + }, + /* RX */ + { + .mode = STM32_GPIO_MODE_IN, + .icnf = STM32_GPIO_ICNF_IN_FLT, + } +}; + +static const struct stm32_gpio_dsc usart1_gpio[] = { + {STM32_GPIO_PORT_A, STM32_GPIO_PIN_9}, /* TX */ + {STM32_GPIO_PORT_A, STM32_GPIO_PIN_10}, /* RX */ +}; + +int uart2_setup_gpio(void) +{ + int i; + int rv = 0; + + for (i = 0; i < ARRAY_SIZE(usart1_gpio); i++) { + rv = stm32_gpio_config(&usart1_gpio[i], &gpio_ctl_usart[i]); + if (rv) + goto out; + } + +out: + return rv; +} + +int dram_init(void) +{ + gd->ram_size = CONFIG_SYS_RAM_SIZE; + + return 0; +} + +u32 get_board_rev(void) +{ + return 0; +} + +int board_early_init_f(void) +{ + int res; + + res = uart2_setup_gpio(); + if (res) + return res; + + return 0; +} + +int board_init(void) +{ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; + + return 0; +} diff --git a/configs/stm3210e-eval_defconfig b/configs/stm3210e-eval_defconfig new file mode 100644 index 0000000..ac3cad3 --- /dev/null +++ b/configs/stm3210e-eval_defconfig @@ -0,0 +1,3 @@ +CONFIG_ARM=y +CONFIG_TARGET_STM3210E_EVAL=y +CONFIG_CMD_BOOTM=n diff --git a/include/configs/stm3210e-eval.h b/include/configs/stm3210e-eval.h new file mode 100644 index 0000000..af9e4c2 --- /dev/null +++ b/include/configs/stm3210e-eval.h @@ -0,0 +1,118 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * Copyright 2015 ATS Advanced Telematics Systems GmbH + * Copyright 2015 Konsulko Group, Matt Porter mporter@konsulko.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define CONFIG_STM32F1 +#define CONFIG_STM3210E_EVAL +#define CONFIG_SYS_GENERIC_BOARD + +#define CONFIG_BOARD_EARLY_INIT_F + +#define CONFIG_SYS_MAX_FLASH_BANKS 2 +#define CONFIG_SYS_MAX_FLASH_SECT 256 +#define CONFIG_SYS_FLASH_BASE 0x08000000 + +#define CONFIG_SYS_INIT_SP_ADDR 0x20010000 +#define CONFIG_SYS_TEXT_BASE 0x08000000 + +#define CONFIG_SYS_ICACHE_OFF +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_SYS_RAM_SIZE 0x00018000 +#define CONFIG_SYS_SDRAM_BASE 0x20000000 +#define CONFIG_SYS_LOAD_ADDR 0x20000000 +#define CONFIG_LOADADDR 0x20000000 + +#define CONFIG_ENV_IS_IN_FLASH +#define CONFIG_ENV_OFFSET (64 << 10) +#define CONFIG_ENV_SECT_SIZE (2 << 10) +#define CONFIG_ENV_SIZE (2 << 10) +#define CONFIG_ENV_MAX_ENTRIES 32 + +#define CONFIG_GPIO_LED +#define CONFIG_STATUS_LED +#define CONFIG_BOARD_SPECIFIC_LED +#define STATUS_LED_BOOT 0 +#define STATUS_LED_BIT 86 /* LD1 - Green */ +#define STATUS_LED_STATE STATUS_LED_OFF +#define STATUS_LED_PERIOD (CONFIG_SYS_HZ / 10) +#define STATUS_LED_BIT1 87 /* LD2 - Orange */ +#define STATUS_LED_STATE1 STATUS_LED_OFF +#define STATUS_LED_PERIOD1 (CONFIG_SYS_HZ / 10) +#define STATUS_LED_BIT2 88 /* LD3 - Red */ +#define STATUS_LED_STATE2 STATUS_LED_OFF +#define STATUS_LED_PERIOD2 (CONFIG_SYS_HZ / 10) +#define STATUS_LED_BIT3 89 /* LD4 - Blue */ +#define STATUS_LED_STATE3 STATUS_LED_OFF +#define STATUS_LED_PERIOD3 (CONFIG_SYS_HZ / 10) + +#define CONFIG_STM32_GPIO +#define CONFIG_STM32_SERIAL +#define CONFIG_STM32_USART1 + +#define CONFIG_STM32_HSE_HZ 8000000 + +#define CONFIG_SYS_HZ_CLOCK 1000000 /* Timer is clocked at 1MHz */ + +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE \ + + sizeof(CONFIG_SYS_PROMPT) + 16) + +#define CONFIG_SYS_MAXARGS 16 + +#define CONFIG_SYS_MALLOC_LEN (2048) + +#define CONFIG_STACKSIZE (2048) + +#define CONFIG_BAUDRATE 115200 + +#define CONFIG_SYS_BARGSIZE 64 + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_AUTOBOOT + +/* + * Command line configuration. + */ +#define CONFIG_SYS_LONGHELP +#undef CONFIG_CMD_BDI /* bdinfo */ +#undef CONFIG_CMD_BOOTD /* bootd */ +#define CONFIG_CMD_ECHO /* echo arguments */ +#define CONFIG_CMD_LOADB /* loadb */ +#define CONFIG_CMD_MEMORY /* md mm nm mw cp cmp crc base loop */ +#undef CONFIG_CMD_MISC /* Misc functions like sleep etc*/ +#undef CONFIG_CMD_RUN /* run command in env variable */ +#define CONFIG_CMD_SAVEENV /* saveenv */ +#define CONFIG_CRC32 + +#undef CONFIG_SYS_HUSH_PARSER +#define CONFIG_SYS_PROMPT "STM3210E-EVAL> " +#undef CONFIG_AUTO_COMPLETE +#undef CONFIG_CMDLINE_EDITING + +#define CONFIG_CMD_FLASH +#undef CONFIG_CMD_MISC +#undef CONFIG_CMD_TIMER +#define CONFIG_CMD_LED + +#undef CONFIG_BOOTM_LINUX +#undef CONFIG_BOOTM_NETBSD +#undef CONFIG_BOOTM_PLAN9 +#undef CONFIG_BOOTM_RTEMS +#undef CONFIG_BOOTM_VXWORKS + +#undef CONFIG_GZIP +#undef CONFIG_ZLIB +#undef CONFIG_PARTITIONS + + +#endif /* __CONFIG_H */
participants (2)
-
Matt Porter
-
Tom Rini