[U-Boot] [PATCH 0/4] Add support for stm32f429-discovery board

The following patches implement basic support for the ARMv7-M microcontroller architecture. Additionally, stm32f429-discovery board support is added with tested ability to boot uClinux from the embedded Flash memory.
Kamil Lulko (4): ARM: Add ARMv7-M support ARMv7M: Add STM32F4 support stm32f4: Add serial driver stm32f4: Add support for stm32f429-discovery board
arch/arm/Kconfig | 9 + arch/arm/cpu/armv7m/Makefile | 11 + arch/arm/cpu/armv7m/config.mk | 8 + arch/arm/cpu/armv7m/cpu.c | 35 +++ arch/arm/cpu/armv7m/start.S | 15 ++ arch/arm/cpu/armv7m/stm32f4/Makefile | 11 + arch/arm/cpu/armv7m/stm32f4/clock.c | 209 +++++++++++++++ arch/arm/cpu/armv7m/stm32f4/flash.c | 143 ++++++++++ arch/arm/cpu/armv7m/stm32f4/soc.c | 37 +++ arch/arm/cpu/armv7m/stm32f4/timer.c | 118 +++++++++ arch/arm/include/asm/arch-stm32f4/fmc.h | 75 ++++++ arch/arm/include/asm/arch-stm32f4/gpio.h | 116 +++++++++ arch/arm/include/asm/arch-stm32f4/stm32.h | 108 ++++++++ arch/arm/include/asm/armv7m.h | 60 +++++ arch/arm/lib/Makefile | 8 +- arch/arm/lib/crt0.S | 30 +++ arch/arm/lib/interrupts_m.c | 95 +++++++ arch/arm/lib/relocate.S | 13 + arch/arm/lib/vectors_m.S | 57 ++++ board/st/stm32f429-discovery/Kconfig | 19 ++ board/st/stm32f429-discovery/MAINTAINERS | 6 + board/st/stm32f429-discovery/Makefile | 12 + board/st/stm32f429-discovery/led.c | 35 +++ board/st/stm32f429-discovery/stm32f429-discovery.c | 288 +++++++++++++++++++++ configs/stm32f429-discovery_defconfig | 2 + drivers/gpio/Makefile | 1 + drivers/gpio/stm32_gpio.c | 199 ++++++++++++++ drivers/serial/Makefile | 1 + drivers/serial/serial.c | 2 + drivers/serial/serial_stm32.c | 117 +++++++++ include/configs/stm32f429-discovery.h | 106 ++++++++ include/flash.h | 2 + 32 files changed, 1946 insertions(+), 2 deletions(-) create mode 100644 arch/arm/cpu/armv7m/Makefile create mode 100644 arch/arm/cpu/armv7m/config.mk create mode 100644 arch/arm/cpu/armv7m/cpu.c create mode 100644 arch/arm/cpu/armv7m/start.S create mode 100644 arch/arm/cpu/armv7m/stm32f4/Makefile create mode 100644 arch/arm/cpu/armv7m/stm32f4/clock.c create mode 100644 arch/arm/cpu/armv7m/stm32f4/flash.c create mode 100644 arch/arm/cpu/armv7m/stm32f4/soc.c create mode 100644 arch/arm/cpu/armv7m/stm32f4/timer.c create mode 100644 arch/arm/include/asm/arch-stm32f4/fmc.h create mode 100644 arch/arm/include/asm/arch-stm32f4/gpio.h create mode 100644 arch/arm/include/asm/arch-stm32f4/stm32.h create mode 100644 arch/arm/include/asm/armv7m.h create mode 100644 arch/arm/lib/interrupts_m.c create mode 100644 arch/arm/lib/vectors_m.S create mode 100644 board/st/stm32f429-discovery/Kconfig create mode 100644 board/st/stm32f429-discovery/MAINTAINERS create mode 100644 board/st/stm32f429-discovery/Makefile create mode 100644 board/st/stm32f429-discovery/led.c create mode 100644 board/st/stm32f429-discovery/stm32f429-discovery.c create mode 100644 configs/stm32f429-discovery_defconfig create mode 100644 drivers/gpio/stm32_gpio.c create mode 100644 drivers/serial/serial_stm32.c create mode 100644 include/configs/stm32f429-discovery.h

Signed-off-by: Kamil Lulko rev13@wp.pl --- arch/arm/Kconfig | 4 ++ arch/arm/cpu/armv7m/Makefile | 10 +++++ arch/arm/cpu/armv7m/config.mk | 8 ++++ arch/arm/cpu/armv7m/cpu.c | 35 ++++++++++++++++ arch/arm/cpu/armv7m/start.S | 15 +++++++ arch/arm/include/asm/armv7m.h | 60 +++++++++++++++++++++++++++ arch/arm/lib/Makefile | 8 +++- arch/arm/lib/crt0.S | 30 ++++++++++++++ arch/arm/lib/interrupts_m.c | 95 +++++++++++++++++++++++++++++++++++++++++++ arch/arm/lib/relocate.S | 13 ++++++ arch/arm/lib/vectors_m.S | 57 ++++++++++++++++++++++++++ 11 files changed, 333 insertions(+), 2 deletions(-) create mode 100644 arch/arm/cpu/armv7m/Makefile create mode 100644 arch/arm/cpu/armv7m/config.mk create mode 100644 arch/arm/cpu/armv7m/cpu.c create mode 100644 arch/arm/cpu/armv7m/start.S create mode 100644 arch/arm/include/asm/armv7m.h create mode 100644 arch/arm/lib/interrupts_m.c create mode 100644 arch/arm/lib/vectors_m.S
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 41f3220..29ea8b4 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -33,6 +33,9 @@ config CPU_V7 bool select HAS_VBAR
+config CPU_V7M + bool + config CPU_PXA bool
@@ -47,6 +50,7 @@ config SYS_CPU default "arm1136" if CPU_ARM1136 default "arm1176" if CPU_ARM1176 default "armv7" if CPU_V7 + default "armv7m" if CPU_V7M default "pxa" if CPU_PXA default "sa1100" if CPU_SA1100 default "armv8" if ARM64 diff --git a/arch/arm/cpu/armv7m/Makefile b/arch/arm/cpu/armv7m/Makefile new file mode 100644 index 0000000..a187f6e --- /dev/null +++ b/arch/arm/cpu/armv7m/Makefile @@ -0,0 +1,10 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y := start.o +obj-y += cpu.o + diff --git a/arch/arm/cpu/armv7m/config.mk b/arch/arm/cpu/armv7m/config.mk new file mode 100644 index 0000000..0b31e44 --- /dev/null +++ b/arch/arm/cpu/armv7m/config.mk @@ -0,0 +1,8 @@ +# +# (C) Copyright 2015 +# Kamil Lulko, rev13@wp.pl +# +# SPDX-License-Identifier: GPL-2.0+ +# + +PLATFORM_CPPFLAGS += -march=armv7-m -mthumb diff --git a/arch/arm/cpu/armv7m/cpu.c b/arch/arm/cpu/armv7m/cpu.c new file mode 100644 index 0000000..d3ab862 --- /dev/null +++ b/arch/arm/cpu/armv7m/cpu.c @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2010,2011 + * Vladimir Khusainov, Emcraft Systems, vlad@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/armv7m.h> + +/* + * This is called right before passing control to + * the Linux kernel point. + */ +int cleanup_before_linux(void) +{ + return 0; +} + +/* + * Perform the low-level reset. + */ +void reset_cpu(ulong addr) +{ + /* + * Perform reset but keep priority group unchanged. + */ + writel((V7M_AIRCR_VECTKEY << V7M_AIRCR_VECTKEY_SHIFT) + | (V7M_SCB->aircr & V7M_AIRCR_PRIGROUP_MSK) + | V7M_AIRCR_SYSRESET, &V7M_SCB->aircr); +} diff --git a/arch/arm/cpu/armv7m/start.S b/arch/arm/cpu/armv7m/start.S new file mode 100644 index 0000000..e05e984 --- /dev/null +++ b/arch/arm/cpu/armv7m/start.S @@ -0,0 +1,15 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.globl reset +.type reset, %function +reset: + b _main + +.globl c_runtime_cpu_setup +c_runtime_cpu_setup: + mov pc, lr diff --git a/arch/arm/include/asm/armv7m.h b/arch/arm/include/asm/armv7m.h new file mode 100644 index 0000000..d2aa1c4 --- /dev/null +++ b/arch/arm/include/asm/armv7m.h @@ -0,0 +1,60 @@ +/* + * (C) Copyright 2010,2011 + * Vladimir Khusainov, Emcraft Systems, vlad@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef ARMV7M_H +#define ARMV7M_H + +#if defined(__ASSEMBLY__) +.syntax unified +.thumb +#endif + +#define V7M_SCB_BASE 0xE000ED00 +#define V7M_MPU_BASE 0xE000ED90 + +#define V7M_SCB_VTOR 0x08 + +#if !defined(__ASSEMBLY__) +struct v7m_scb { + uint32_t cpuid; /* CPUID Base Register */ + uint32_t icsr; /* Interrupt Control and State Register */ + uint32_t vtor; /* Vector Table Offset Register */ + uint32_t aircr; /* App Interrupt and Reset Control Register */ +}; +#define V7M_SCB ((struct v7m_scb *)V7M_SCB_BASE) + +#define V7M_AIRCR_VECTKEY 0x5fa +#define V7M_AIRCR_VECTKEY_SHIFT 16 +#define V7M_AIRCR_ENDIAN (1 << 15) +#define V7M_AIRCR_PRIGROUP_SHIFT 8 +#define V7M_AIRCR_PRIGROUP_MSK (0x7 << V7M_AIRCR_PRIGROUP_SHIFT) +#define V7M_AIRCR_SYSRESET (1 << 2) + +#define V7M_ICSR_VECTACT_MSK 0xFF + +struct v7m_mpu { + uint32_t type; /* Type Register */ + uint32_t ctrl; /* Control Register */ + uint32_t rnr; /* Region Number Register */ + uint32_t rbar; /* Region Base Address Register */ + uint32_t rasr; /* Region Attribute and Size Register */ +}; +#define V7M_MPU ((struct v7m_mpu *)V7M_MPU_BASE) + +#define V7M_MPU_CTRL_ENABLE (1 << 0) +#define V7M_MPU_CTRL_HFNMIENA (1 << 1) + +#define V7M_MPU_RASR_EN (1 << 0) +#define V7M_MPU_RASR_SIZE_BITS 1 +#define V7M_MPU_RASR_SIZE_4GB (31 << V7M_MPU_RASR_SIZE_BITS) +#define V7M_MPU_RASR_AP_RW_RW (3 << 24) + +#endif /* !defined(__ASSEMBLY__) */ +#endif /* ARMV7M_H */ diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index d74e4b8..3cfeb14 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -8,7 +8,9 @@ lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _ashldi3.o _ashrdi3.o _divsi3.o \ _lshrdi3.o _modsi3.o _udivsi3.o _umodsi3.o div0.o
-ifdef CONFIG_ARM64 +ifdef CONFIG_CPU_V7M +obj-y += vectors_m.o crt0.o +else ifdef CONFIG_ARM64 obj-y += crt0_64.o else obj-y += vectors.o crt0.o @@ -35,7 +37,9 @@ endif obj-$(CONFIG_SEMIHOSTING) += semihosting.o
obj-y += sections.o -ifdef CONFIG_ARM64 +ifdef CONFIG_CPU_V7M +obj-y += interrupts_m.o +else ifdef CONFIG_ARM64 obj-y += gic_64.o obj-y += interrupts_64.o else diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S index 22df3e5..51e6bb8 100644 --- a/arch/arm/lib/crt0.S +++ b/arch/arm/lib/crt0.S @@ -9,6 +9,9 @@ #include <config.h> #include <asm-offsets.h> #include <linux/linkage.h> +#ifdef CONFIG_CPU_V7M +#include <asm/armv7m.h> +#endif
/* * This file handles the target-independent stages of the U-Boot @@ -66,15 +69,30 @@ ENTRY(_main) #else ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif +#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */ + mov r3, sp + bic r3, r3, #7 + mov sp, r3 +#else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ +#endif mov r2, sp sub sp, sp, #GD_SIZE /* allocate one GD above SP */ +#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */ + mov r3, sp + bic r3, r3, #7 + mov sp, r3 +#else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ +#endif mov r9, sp /* GD is above SP */ mov r1, sp mov r0, #0 clr_gd: cmp r1, r2 /* while not at end of GD */ +#if defined(CONFIG_CPU_V7M) + itt lo +#endif strlo r0, [r1] /* clear 32-bit GD word */ addlo r1, r1, #4 /* move to next */ blo clr_gd @@ -94,13 +112,22 @@ clr_gd: */
ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */ +#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */ + mov r3, sp + bic r3, r3, #7 + mov sp, r3 +#else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ +#endif ldr r9, [r9, #GD_BD] /* r9 = gd->bd */ sub r9, r9, #GD_SIZE /* new GD is below bd */
adr lr, here ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */ add lr, lr, r0 +#if defined(CONFIG_CPU_V7M) + orr lr, #1 /* As required by Thumb-only */ +#endif ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ b relocate_code here: @@ -120,6 +147,9 @@ here: mov r2, #0x00000000 /* prepare zero to clear BSS */
clbss_l:cmp r0, r1 /* while not at end of BSS */ +#if defined(CONFIG_CPU_V7M) + itt lo +#endif strlo r2, [r0] /* clear 32-bit BSS word */ addlo r0, r0, #4 /* move to next */ blo clbss_l diff --git a/arch/arm/lib/interrupts_m.c b/arch/arm/lib/interrupts_m.c new file mode 100644 index 0000000..89ce493 --- /dev/null +++ b/arch/arm/lib/interrupts_m.c @@ -0,0 +1,95 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +/* + * Upon exception entry ARMv7-M processors automatically save stack + * frames containing some registers. For simplicity initial + * implementation uses only this auto-saved stack frame. + * This does not contain complete register set dump, + * only R0-R3, R12, LR, PC and xPSR are saved. + */ + +struct autosave_regs { + long uregs[8]; +}; + +#define ARM_XPSR uregs[7] +#define ARM_PC uregs[6] +#define ARM_LR uregs[5] +#define ARM_R12 uregs[4] +#define ARM_R3 uregs[3] +#define ARM_R2 uregs[2] +#define ARM_R1 uregs[1] +#define ARM_R0 uregs[0] + +int interrupt_init(void) +{ + return 0; +} + +void enable_interrupts(void) +{ + return; +} + +int disable_interrupts(void) +{ + return 0; +} + +void dump_regs(struct autosave_regs *regs) +{ + printf("pc : %08lx lr : %08lx xPSR : %08lx\n", + regs->ARM_PC, regs->ARM_LR, regs->ARM_XPSR); + printf("r12 : %08lx r3 : %08lx r2 : %08lx\n" + "r1 : %08lx r0 : %08lx\n", + regs->ARM_R12, regs->ARM_R3, regs->ARM_R2, + regs->ARM_R1, regs->ARM_R0); +} + +void bad_mode(void) +{ + panic("Resetting CPU ...\n"); + reset_cpu(0); +} + +void do_hard_fault(struct autosave_regs *autosave_regs) +{ + printf("Hard fault\n"); + dump_regs(autosave_regs); + bad_mode(); +} + +void do_mm_fault(struct autosave_regs *autosave_regs) +{ + printf("Memory management fault\n"); + dump_regs(autosave_regs); + bad_mode(); +} + +void do_bus_fault(struct autosave_regs *autosave_regs) +{ + printf("Bus fault\n"); + dump_regs(autosave_regs); + bad_mode(); +} + +void do_usage_fault(struct autosave_regs *autosave_regs) +{ + printf("Usage fault\n"); + dump_regs(autosave_regs); + bad_mode(); +} + +void do_invalid_entry(struct autosave_regs *autosave_regs) +{ + printf("Exception\n"); + dump_regs(autosave_regs); + bad_mode(); +} diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S index 92f5314..475d503 100644 --- a/arch/arm/lib/relocate.S +++ b/arch/arm/lib/relocate.S @@ -9,6 +9,9 @@ #include <asm-offsets.h> #include <config.h> #include <linux/linkage.h> +#ifdef CONFIG_CPU_V7M +#include <asm/armv7m.h> +#endif
/* * Default/weak exception vectors relocation routine @@ -23,6 +26,15 @@
ENTRY(relocate_vectors)
+#ifdef CONFIG_CPU_V7M + /* + * On ARMv7-M we only have to write the new vector address + * to VTOR register. + */ + ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ + ldr r1, =V7M_SCB_BASE + str r0, [r1, V7M_SCB_VTOR] +#else #ifdef CONFIG_HAS_VBAR /* * If the ARM processor has the security extensions, @@ -47,6 +59,7 @@ ENTRY(relocate_vectors) ldmia r0!, {r2-r8,r10} stmia r1!, {r2-r8,r10} #endif +#endif bx lr
ENDPROC(relocate_vectors) diff --git a/arch/arm/lib/vectors_m.S b/arch/arm/lib/vectors_m.S new file mode 100644 index 0000000..abc7f88 --- /dev/null +++ b/arch/arm/lib/vectors_m.S @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/armv7m.h> +#include <linux/linkage.h> + +.type __hard_fault_entry, %function +__hard_fault_entry: + mov r0, sp @ pass auto-saved registers as argument + b do_hard_fault + +.type __mm_fault_entry, %function +__mm_fault_entry: + mov r0, sp @ pass auto-saved registers as argument + b do_mm_fault + +.type __bus_fault_entry, %function +__bus_fault_entry: + mov r0, sp @ pass auto-saved registers as argument + b do_bus_fault + +.type __usage_fault_entry, %function +__usage_fault_entry: + mov r0, sp @ pass auto-saved registers as argument + b do_usage_fault + +.type __invalid_entry, %function +__invalid_entry: + mov r0, sp @ pass auto-saved registers as argument + b do_invalid_entry + + .section .vectors +ENTRY(_start) + .long CONFIG_SYS_INIT_SP_ADDR @ 0 - Reset stack pointer + .long reset @ 1 - Reset + .long __invalid_entry @ 2 - NMI + .long __hard_fault_entry @ 3 - HardFault + .long __mm_fault_entry @ 4 - MemManage + .long __bus_fault_entry @ 5 - BusFault + .long __usage_fault_entry @ 6 - UsageFault + .long __invalid_entry @ 7 - Reserved + .long __invalid_entry @ 8 - Reserved + .long __invalid_entry @ 9 - Reserved + .long __invalid_entry @ 10 - Reserved + .long __invalid_entry @ 11 - SVCall + .long __invalid_entry @ 12 - Debug Monitor + .long __invalid_entry @ 13 - Reserved + .long __invalid_entry @ 14 - PendSV + .long __invalid_entry @ 15 - SysTick + .rept 255 - 16 + .long __invalid_entry @ 16..255 - External Interrupts + .endr

On Sun, Mar 01, 2015 at 12:44:39PM +0100, Kamil Lulko wrote:
Signed-off-by: Kamil Lulko rev13@wp.pl
[snip]
diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
[snip]
@@ -66,15 +69,30 @@ ENTRY(_main) #else ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif +#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */
- mov r3, sp
- bic r3, r3, #7
- mov sp, r3
+#else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ +#endif
There's 4 places where this change comes in. Albert, what do you think about always just doing this in 3 instructions with a comment in the first instance about v7-M support?

Am 05.03.2015 um 16:32 schrieb Tom Rini:
On Sun, Mar 01, 2015 at 12:44:39PM +0100, Kamil Lulko wrote:
Signed-off-by: Kamil Lulko rev13@wp.pl
[snip]
diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
[snip]
@@ -66,15 +69,30 @@ ENTRY(_main) #else ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif +#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */
- mov r3, sp
- bic r3, r3, #7
- mov sp, r3
+#else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ +#endif
There's 4 places where this change comes in. Albert, what do you think about always just doing this in 3 instructions with a comment in the first instance about v7-M support?
I remember running into problems like these when working on STM32F429 support late last year and I adopted some helper macros from Linux, I believe. The same problem existed in U-Boot's private libgcc code.
Regards, Andreas

On Tue, Mar 31, 2015 at 12:06:29AM +0200, Andreas Färber wrote:
Am 05.03.2015 um 16:32 schrieb Tom Rini:
On Sun, Mar 01, 2015 at 12:44:39PM +0100, Kamil Lulko wrote:
Signed-off-by: Kamil Lulko rev13@wp.pl
[snip]
diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
[snip]
@@ -66,15 +69,30 @@ ENTRY(_main) #else ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif +#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */
- mov r3, sp
- bic r3, r3, #7
- mov sp, r3
+#else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ +#endif
There's 4 places where this change comes in. Albert, what do you think about always just doing this in 3 instructions with a comment in the first instance about v7-M support?
I remember running into problems like these when working on STM32F429 support late last year and I adopted some helper macros from Linux, I believe. The same problem existed in U-Boot's private libgcc code.
What macros did you use from the kernel? Thanks!

On Sun, Mar 01, 2015 at 12:44:39PM +0100, rev13@wp.pl wrote:
Signed-off-by: Kamil Lulko rev13@wp.pl
Applied to u-boot/master, thanks!

Signed-off-by: Kamil Lulko rev13@wp.pl --- arch/arm/cpu/armv7m/Makefile | 1 + arch/arm/cpu/armv7m/stm32f4/Makefile | 11 ++ arch/arm/cpu/armv7m/stm32f4/clock.c | 209 ++++++++++++++++++++++++++++++ arch/arm/cpu/armv7m/stm32f4/flash.c | 143 ++++++++++++++++++++ arch/arm/cpu/armv7m/stm32f4/soc.c | 37 ++++++ arch/arm/cpu/armv7m/stm32f4/timer.c | 118 +++++++++++++++++ arch/arm/include/asm/arch-stm32f4/fmc.h | 75 +++++++++++ arch/arm/include/asm/arch-stm32f4/gpio.h | 116 +++++++++++++++++ arch/arm/include/asm/arch-stm32f4/stm32.h | 108 +++++++++++++++ drivers/gpio/Makefile | 1 + drivers/gpio/stm32_gpio.c | 199 ++++++++++++++++++++++++++++ include/flash.h | 2 + 12 files changed, 1020 insertions(+) create mode 100644 arch/arm/cpu/armv7m/stm32f4/Makefile create mode 100644 arch/arm/cpu/armv7m/stm32f4/clock.c create mode 100644 arch/arm/cpu/armv7m/stm32f4/flash.c create mode 100644 arch/arm/cpu/armv7m/stm32f4/soc.c create mode 100644 arch/arm/cpu/armv7m/stm32f4/timer.c create mode 100644 arch/arm/include/asm/arch-stm32f4/fmc.h create mode 100644 arch/arm/include/asm/arch-stm32f4/gpio.h create mode 100644 arch/arm/include/asm/arch-stm32f4/stm32.h create mode 100644 drivers/gpio/stm32_gpio.c
diff --git a/arch/arm/cpu/armv7m/Makefile b/arch/arm/cpu/armv7m/Makefile index a187f6e..b662e03 100644 --- a/arch/arm/cpu/armv7m/Makefile +++ b/arch/arm/cpu/armv7m/Makefile @@ -8,3 +8,4 @@ extra-y := start.o obj-y += cpu.o
+obj-$(CONFIG_STM32F4) += stm32f4/ diff --git a/arch/arm/cpu/armv7m/stm32f4/Makefile b/arch/arm/cpu/armv7m/stm32f4/Makefile new file mode 100644 index 0000000..e982830 --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f4/Makefile @@ -0,0 +1,11 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2015 +# Kamil Lulko, rev13@wp.pl +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += soc.o clock.o timer.o flash.o diff --git a/arch/arm/cpu/armv7m/stm32f4/clock.c b/arch/arm/cpu/armv7m/stm32f4/clock.c new file mode 100644 index 0000000..2eded1f --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f4/clock.c @@ -0,0 +1,209 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * (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_PLLCFGR_PLLM_MASK 0x3F +#define RCC_PLLCFGR_PLLN_MASK 0x7FC0 +#define RCC_PLLCFGR_PLLP_MASK 0x30000 +#define RCC_PLLCFGR_PLLQ_MASK 0xF000000 +#define RCC_PLLCFGR_PLLSRC (1 << 22) +#define RCC_PLLCFGR_PLLN_SHIFT 6 +#define RCC_PLLCFGR_PLLP_SHIFT 16 +#define RCC_PLLCFGR_PLLQ_SHIFT 24 + +#define RCC_CFGR_AHB_PSC_MASK 0xF0 +#define RCC_CFGR_APB1_PSC_MASK 0x1C00 +#define RCC_CFGR_APB2_PSC_MASK 0xE000 +#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 10 +#define RCC_CFGR_PPRE2_SHIFT 13 + +#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 pll_psc { + u8 pll_m; + u16 pll_n; + u8 pll_p; + u8 pll_q; + 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) +struct pll_psc pll_psc_168 = { + .pll_m = 8, + .pll_n = 336, + .pll_p = 2, + .pll_q = 7, + .ahb_psc = AHB_PSC_1, + .apb1_psc = APB_PSC_4, + .apb2_psc = APB_PSC_2 +}; +#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)); + writel(0x24003010, &STM32_RCC->pllcfgr); /* Reset value from RM */ + 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, (( + pll_psc_168.ahb_psc << RCC_CFGR_HPRE_SHIFT) + | (pll_psc_168.apb1_psc << RCC_CFGR_PPRE1_SHIFT) + | (pll_psc_168.apb2_psc << RCC_CFGR_PPRE2_SHIFT))); + + writel(pll_psc_168.pll_m + | (pll_psc_168.pll_n << RCC_PLLCFGR_PLLN_SHIFT) + | (((pll_psc_168.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) + | (pll_psc_168.pll_q << RCC_PLLCFGR_PLLQ_SHIFT), + &STM32_RCC->pllcfgr); + setbits_le32(&STM32_RCC->pllcfgr, RCC_PLLCFGR_PLLSRC); + + 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; + /* 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 pllm, plln, pllp; + pllm = (readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLM_MASK); + plln = ((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLN_MASK) + >> RCC_PLLCFGR_PLLN_SHIFT); + pllp = ((((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLP_MASK) + >> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1); + sysclk = ((CONFIG_STM32_HSE_HZ / pllm) * plln) / pllp; + } + + 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/stm32f4/flash.c b/arch/arm/cpu/armv7m/stm32f4/flash.c new file mode 100644 index 0000000..e5c6111 --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f4/flash.c @@ -0,0 +1,143 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * 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 + +flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; + +const u32 sect_sz_kb[CONFIG_SYS_MAX_FLASH_SECT] = { + [0 ... 3] = 16 * 1024, + [4] = 64 * 1024, + [5 ... 11] = 128 * 1024 +}; + +static void stm32f4_flash_lock(u8 lock) +{ + if (lock) { + setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_LOCK); + } else { + writel(STM32_FLASH_KEY1, &STM32_FLASH->key); + writel(STM32_FLASH_KEY2, &STM32_FLASH->key); + } +} + +unsigned long flash_init(void) +{ + unsigned long total_size = 0; + u8 i, j; + + for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { + flash_info[i].flash_id = FLASH_STM32F4; + flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT; + flash_info[i].start[0] = CONFIG_SYS_FLASH_BASE + (i << 20); + flash_info[i].size = sect_sz_kb[0]; + for (j = 1; j < CONFIG_SYS_MAX_FLASH_SECT; j++) { + flash_info[i].start[j] = flash_info[i].start[j - 1] + + (sect_sz_kb[j - 1]); + flash_info[i].size += sect_sz_kb[j]; + } + total_size += flash_info[i].size; + } + + return total_size; +} + +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_STM32F4) { + printf("STM32F4 Embedded Flash\n"); + } + + printf(" Size: %ld MB in %d Sectors\n", + info->size >> 20, 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 < CONFIG_SYS_MAX_FLASH_BANKS; i++) { + if (info == &flash_info[i]) { + bank = i; + break; + } + } + if (bank == 0xFF) + return -1; + + stm32f4_flash_lock(0); + + for (i = first; i <= last; i++) { + while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY) + ; + + if (bank == 0) { + setbits_le32(&STM32_FLASH->cr, + (i << STM32_FLASH_CR_SNB_OFFSET)); + } else if (bank == 1) { + setbits_le32(&STM32_FLASH->cr, + ((0x10 | i) << STM32_FLASH_CR_SNB_OFFSET)); + } else { + stm32f4_flash_lock(1); + return -1; + } + setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_SER); + setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_STRT); + + while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY) + ; + + clrbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_SER); + stm32f4_flash_lock(1); + } + + return 0; +} + +int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong i; + + while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY) + ; + + stm32f4_flash_lock(0); + + setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_PG); + /* To make things simple use byte writes only */ + for (i = 0; i < cnt; i++) { + *(uchar *)(addr + i) = src[i]; + while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY) + ; + } + clrbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_PG); + stm32f4_flash_lock(1); + + return 0; +} diff --git a/arch/arm/cpu/armv7m/stm32f4/soc.c b/arch/arm/cpu/armv7m/stm32f4/soc.c new file mode 100644 index 0000000..202a126 --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f4/soc.c @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * 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; +} + +void s_init(void) +{ +} diff --git a/arch/arm/cpu/armv7m/stm32f4/timer.c b/arch/arm/cpu/armv7m/stm32f4/timer.c new file mode 100644 index 0000000..102ae6d --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f4/timer.c @@ -0,0 +1,118 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * 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-stm32f4/fmc.h b/arch/arm/include/asm/arch-stm32f4/fmc.h new file mode 100644 index 0000000..4ab3031 --- /dev/null +++ b/arch/arm/include/asm/arch-stm32f4/fmc.h @@ -0,0 +1,75 @@ +/* + * (C) Copyright 2013 + * Pavel Boldin, Emcraft Systems, paboldin@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _MACH_FMC_H_ +#define _MACH_FMC_H_ + +struct stm32_fmc_regs { + u32 sdcr1; /* Control register 1 */ + u32 sdcr2; /* Control register 2 */ + u32 sdtr1; /* Timing register 1 */ + u32 sdtr2; /* Timing register 2 */ + u32 sdcmr; /* Mode register */ + u32 sdrtr; /* Refresh timing register */ + u32 sdsr; /* Status register */ +}; + +/* + * FMC registers base + */ +#define STM32_SDRAM_FMC_BASE 0xA0000140 +#define STM32_SDRAM_FMC ((struct stm32_fmc_regs *)STM32_SDRAM_FMC_BASE) + +/* Control register SDCR */ +#define FMC_SDCR_RPIPE_SHIFT 13 /* RPIPE bit shift */ +#define FMC_SDCR_RBURST_SHIFT 12 /* RBURST bit shift */ +#define FMC_SDCR_SDCLK_SHIFT 10 /* SDRAM clock divisor shift */ +#define FMC_SDCR_WP_SHIFT 9 /* Write protection shift */ +#define FMC_SDCR_CAS_SHIFT 7 /* CAS latency shift */ +#define FMC_SDCR_NB_SHIFT 6 /* Number of banks shift */ +#define FMC_SDCR_MWID_SHIFT 4 /* Memory width shift */ +#define FMC_SDCR_NR_SHIFT 2 /* Number of row address bits shift */ +#define FMC_SDCR_NC_SHIFT 0 /* Number of col address bits shift */ + +/* Timings register SDTR */ +#define FMC_SDTR_TMRD_SHIFT 0 /* Load mode register to active */ +#define FMC_SDTR_TXSR_SHIFT 4 /* Exit self-refresh time */ +#define FMC_SDTR_TRAS_SHIFT 8 /* Self-refresh time */ +#define FMC_SDTR_TRC_SHIFT 12 /* Row cycle delay */ +#define FMC_SDTR_TWR_SHIFT 16 /* Recovery delay */ +#define FMC_SDTR_TRP_SHIFT 20 /* Row precharge delay */ +#define FMC_SDTR_TRCD_SHIFT 24 /* Row-to-column delay */ + + +#define FMC_SDCMR_NRFS_SHIFT 5 + +#define FMC_SDCMR_MODE_NORMAL 0 +#define FMC_SDCMR_MODE_START_CLOCK 1 +#define FMC_SDCMR_MODE_PRECHARGE 2 +#define FMC_SDCMR_MODE_AUTOREFRESH 3 +#define FMC_SDCMR_MODE_WRITE_MODE 4 +#define FMC_SDCMR_MODE_SELFREFRESH 5 +#define FMC_SDCMR_MODE_POWERDOWN 6 + +#define FMC_SDCMR_BANK_1 (1 << 4) +#define FMC_SDCMR_BANK_2 (1 << 3) + +#define FMC_SDCMR_MODE_REGISTER_SHIFT 9 + +#define FMC_SDSR_BUSY (1 << 5) + +#define FMC_BUSY_WAIT() do { \ + __asm__ __volatile__ ("dsb" : : : "memory"); \ + while (STM32_SDRAM_FMC->sdsr & FMC_SDSR_BUSY) \ + ; \ + } while (0) + + +#endif /* _MACH_FMC_H_ */ diff --git a/arch/arm/include/asm/arch-stm32f4/gpio.h b/arch/arm/include/asm/arch-stm32f4/gpio.h new file mode 100644 index 0000000..7cd866e --- /dev/null +++ b/arch/arm/include/asm/arch-stm32f4/gpio.h @@ -0,0 +1,116 @@ +/* + * (C) Copyright 2011 + * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * 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, + STM32_GPIO_PORT_H, + STM32_GPIO_PORT_I +}; + +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_mode { + STM32_GPIO_MODE_IN = 0, + STM32_GPIO_MODE_OUT, + STM32_GPIO_MODE_AF, + STM32_GPIO_MODE_AN +}; + +enum stm32_gpio_otype { + STM32_GPIO_OTYPE_PP = 0, + STM32_GPIO_OTYPE_OD +}; + +enum stm32_gpio_speed { + STM32_GPIO_SPEED_2M = 0, + STM32_GPIO_SPEED_25M, + STM32_GPIO_SPEED_50M, + STM32_GPIO_SPEED_100M +}; + +enum stm32_gpio_pupd { + STM32_GPIO_PUPD_NO = 0, + STM32_GPIO_PUPD_UP, + STM32_GPIO_PUPD_DOWN +}; + +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_mode mode; + enum stm32_gpio_otype otype; + enum stm32_gpio_speed speed; + 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-stm32f4/stm32.h b/arch/arm/include/asm/arch-stm32f4/stm32.h new file mode 100644 index 0000000..a9f88db --- /dev/null +++ b/arch/arm/include/asm/arch-stm32f4/stm32.h @@ -0,0 +1,108 @@ +/* + * (C) Copyright 2011 + * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * 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 + 0x00020000) +#define STM32_AHB2PERIPH_BASE (STM32_PERIPH_BASE + 0x10000000) + +#define STM32_BUS_MASK 0xFFFF0000 + +/* + * Register maps + */ +struct stm32_rcc_regs { + u32 cr; /* RCC clock control */ + u32 pllcfgr; /* RCC PLL configuration */ + u32 cfgr; /* RCC clock configuration */ + u32 cir; /* RCC clock interrupt */ + u32 ahb1rstr; /* RCC AHB1 peripheral reset */ + u32 ahb2rstr; /* RCC AHB2 peripheral reset */ + u32 ahb3rstr; /* RCC AHB3 peripheral reset */ + u32 rsv0; + u32 apb1rstr; /* RCC APB1 peripheral reset */ + u32 apb2rstr; /* RCC APB2 peripheral reset */ + u32 rsv1[2]; + u32 ahb1enr; /* RCC AHB1 peripheral clock enable */ + u32 ahb2enr; /* RCC AHB2 peripheral clock enable */ + u32 ahb3enr; /* RCC AHB3 peripheral clock enable */ + u32 rsv2; + u32 apb1enr; /* RCC APB1 peripheral clock enable */ + u32 apb2enr; /* RCC APB2 peripheral clock enable */ + u32 rsv3[2]; + u32 ahb1lpenr; /* RCC AHB1 periph clk enable in low pwr mode */ + u32 ahb2lpenr; /* RCC AHB2 periph clk enable in low pwr mode */ + u32 ahb3lpenr; /* RCC AHB3 periph clk enable in low pwr mode */ + u32 rsv4; + u32 apb1lpenr; /* RCC APB1 periph clk enable in low pwr mode */ + u32 apb2lpenr; /* RCC APB2 periph clk enable in low pwr mode */ + u32 rsv5[2]; + u32 bdcr; /* RCC Backup domain control */ + u32 csr; /* RCC clock control & status */ + u32 rsv6[2]; + u32 sscgr; /* RCC spread spectrum clock generation */ + u32 plli2scfgr; /* RCC PLLI2S configuration */ + u32 pllsaicfgr; + u32 dckcfgr; +}; + +struct stm32_pwr_regs { + u32 cr; + u32 csr; +}; + +struct stm32_flash_regs { + u32 acr; + u32 key; + u32 optkeyr; + u32 sr; + u32 cr; + u32 optcr; + u32 optcr1; +}; + +/* + * Registers access macros + */ +#define STM32_RCC_BASE (STM32_AHB1PERIPH_BASE + 0x3800) +#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 + 0x3C00) +#define STM32_FLASH ((struct stm32_flash_regs *)STM32_FLASH_BASE) + +#define STM32_FLASH_SR_BSY (1 << 16) + +#define STM32_FLASH_CR_PG (1 << 0) +#define STM32_FLASH_CR_SER (1 << 1) +#define STM32_FLASH_CR_STRT (1 << 16) +#define STM32_FLASH_CR_LOCK (1 << 31) +#define STM32_FLASH_CR_SNB_OFFSET 3 + +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/drivers/gpio/Makefile b/drivers/gpio/Makefile index aa11f15..93b0ef6 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -37,3 +37,4 @@ obj-$(CONFIG_ADI_GPIO2) += adi_gpio2.o obj-$(CONFIG_TCA642X) += tca642x.o oby-$(CONFIG_SX151X) += sx151x.o obj-$(CONFIG_SUNXI_GPIO) += sunxi_gpio.o +obj-$(CONFIG_STM32_GPIO) += stm32_gpio.o diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c new file mode 100644 index 0000000..d3497e9 --- /dev/null +++ b/drivers/gpio/stm32_gpio.c @@ -0,0 +1,199 @@ +/* + * (C) Copyright 2011 + * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/stm32.h> +#include <asm/arch/gpio.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define STM32_GPIOA_BASE (STM32_AHB1PERIPH_BASE + 0x0000) +#define STM32_GPIOB_BASE (STM32_AHB1PERIPH_BASE + 0x0400) +#define STM32_GPIOC_BASE (STM32_AHB1PERIPH_BASE + 0x0800) +#define STM32_GPIOD_BASE (STM32_AHB1PERIPH_BASE + 0x0C00) +#define STM32_GPIOE_BASE (STM32_AHB1PERIPH_BASE + 0x1000) +#define STM32_GPIOF_BASE (STM32_AHB1PERIPH_BASE + 0x1400) +#define STM32_GPIOG_BASE (STM32_AHB1PERIPH_BASE + 0x1800) +#define STM32_GPIOH_BASE (STM32_AHB1PERIPH_BASE + 0x1C00) +#define STM32_GPIOI_BASE (STM32_AHB1PERIPH_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, STM32_GPIOH_BASE, STM32_GPIOI_BASE +}; + +struct stm32_gpio_regs { + u32 moder; /* GPIO port mode */ + u32 otyper; /* GPIO port output type */ + u32 ospeedr; /* GPIO port output speed */ + u32 pupdr; /* GPIO port pull-up/pull-down */ + u32 idr; /* GPIO port input data */ + u32 odr; /* GPIO port output data */ + u32 bsrr; /* GPIO port bit set/reset */ + u32 lckr; /* GPIO port configuration lock */ + u32 afr[2]; /* GPIO alternate function */ +}; + +#define CHECK_DSC(x) (!x || x->port > 8 || x->pin > 15) +#define CHECK_CTL(x) (!x || x->af > 15 || x->mode > 3 || x->otype > 1 || \ + x->pupd > 2 || x->speed > 3) + +int stm32_gpio_config(const struct stm32_gpio_dsc *dsc, + const struct stm32_gpio_ctl *ctl) +{ + struct stm32_gpio_regs *gpio_regs; + u32 i; + int rv; + + if (CHECK_DSC(dsc)) { + rv = -EINVAL; + goto out; + } + if (CHECK_CTL(ctl)) { + rv = -EINVAL; + goto out; + } + + gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; + + setbits_le32(&STM32_RCC->ahb1enr, 1 << dsc->port); + + i = (dsc->pin & 0x07) * 4; + clrbits_le32(&gpio_regs->afr[dsc->pin >> 3], (0xF << i)); + setbits_le32(&gpio_regs->afr[dsc->pin >> 3], ctl->af << i); + + i = dsc->pin * 2; + + clrbits_le32(&gpio_regs->moder, (0x3 << i)); + setbits_le32(&gpio_regs->moder, ctl->mode << i); + + clrbits_le32(&gpio_regs->otyper, (0x3 << i)); + setbits_le32(&gpio_regs->otyper, ctl->otype << i); + + clrbits_le32(&gpio_regs->ospeedr, (0x3 << i)); + setbits_le32(&gpio_regs->ospeedr, ctl->speed << i); + + clrbits_le32(&gpio_regs->pupdr, (0x3 << i)); + setbits_le32(&gpio_regs->pupdr, ctl->pupd << i); + + rv = 0; +out: + return rv; +} + +int stm32_gpout_set(const struct stm32_gpio_dsc *dsc, int state) +{ + struct stm32_gpio_regs *gpio_regs; + int rv; + + if (CHECK_DSC(dsc)) { + rv = -EINVAL; + goto out; + } + + gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; + + if (state) + writel(1 << dsc->pin, &gpio_regs->bsrr); + else + writel(1 << (dsc->pin + 16), &gpio_regs->bsrr); + + rv = 0; +out: + return rv; +} + +int stm32_gpin_get(const struct stm32_gpio_dsc *dsc) +{ + struct stm32_gpio_regs *gpio_regs; + int rv; + + if (CHECK_DSC(dsc)) { + rv = -EINVAL; + goto out; + } + + gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; + rv = readl(&gpio_regs->idr) & (1 << dsc->pin); +out: + return rv; +} + +/* Common GPIO API */ + +int gpio_request(unsigned gpio, const char *label) +{ + return 0; +} + +int gpio_free(unsigned gpio) +{ + return 0; +} + +int gpio_direction_input(unsigned gpio) +{ + struct stm32_gpio_dsc dsc; + struct stm32_gpio_ctl ctl; + + dsc.port = stm32_gpio_to_port(gpio); + dsc.pin = stm32_gpio_to_pin(gpio); + ctl.af = STM32_GPIO_AF0; + ctl.mode = STM32_GPIO_MODE_IN; + ctl.pupd = STM32_GPIO_PUPD_NO; + ctl.speed = STM32_GPIO_SPEED_50M; + + return stm32_gpio_config(&dsc, &ctl); +} + +int gpio_direction_output(unsigned gpio, int value) +{ + struct stm32_gpio_dsc dsc; + struct stm32_gpio_ctl ctl; + int res; + + dsc.port = stm32_gpio_to_port(gpio); + dsc.pin = stm32_gpio_to_pin(gpio); + 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; + + res = stm32_gpio_config(&dsc, &ctl); + if (res < 0) + goto out; + res = stm32_gpout_set(&dsc, value); +out: + return res; +} + +int gpio_get_value(unsigned gpio) +{ + struct stm32_gpio_dsc dsc; + + dsc.port = stm32_gpio_to_port(gpio); + dsc.pin = stm32_gpio_to_pin(gpio); + + return stm32_gpin_get(&dsc); +} + +int gpio_set_value(unsigned gpio, int value) +{ + struct stm32_gpio_dsc dsc; + + dsc.port = stm32_gpio_to_port(gpio); + dsc.pin = stm32_gpio_to_pin(gpio); + + return stm32_gpout_set(&dsc, value); +} diff --git a/include/flash.h b/include/flash.h index 30aa080..48aa3a5 100644 --- a/include/flash.h +++ b/include/flash.h @@ -459,6 +459,8 @@ extern flash_info_t *flash_get_info(ulong base); #define FLASH_S29GL064M 0x00F0 /* Spansion S29GL064M-R6 */ #define FLASH_S29GL128N 0x00F1 /* Spansion S29GL128N */
+#define FLASH_STM32F4 0x00F2 /* STM32F4 Embedded Flash */ + #define FLASH_UNKNOWN 0xFFFF /* unknown flash type */

On Sun, Mar 01, 2015 at 12:44:40PM +0100, Kamil Lulko wrote:
Signed-off-by: Kamil Lulko rev13@wp.pl
Reviewed-by: Tom Rini trini@konsulko.com

On Sun, Mar 01, 2015 at 12:44:40PM +0100, rev13@wp.pl wrote:
Signed-off-by: Kamil Lulko rev13@wp.pl Reviewed-by: Tom Rini trini@konsulko.com
Applied to u-boot/master, thanks!

Signed-off-by: Kamil Lulko rev13@wp.pl --- drivers/serial/Makefile | 1 + drivers/serial/serial.c | 2 + drivers/serial/serial_stm32.c | 117 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 drivers/serial/serial_stm32.c
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 63b0cbf..eb935bf 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o obj-$(CONFIG_X86_SERIAL) += serial_x86.o +obj-$(CONFIG_STM32_SERIAL) += serial_stm32.o
ifndef CONFIG_SPL_BUILD obj-$(CONFIG_USB_TTY) += usbtty.o diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index 95c992a..9249a77 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -155,6 +155,7 @@ serial_initfunc(sa1100_serial_initialize); serial_initfunc(sandbox_serial_initialize); serial_initfunc(sconsole_serial_initialize); serial_initfunc(sh_serial_initialize); +serial_initfunc(stm32_serial_initialize); serial_initfunc(uartlite_serial_initialize); serial_initfunc(zynq_serial_initialize);
@@ -248,6 +249,7 @@ void serial_initialize(void) sandbox_serial_initialize(); sconsole_serial_initialize(); sh_serial_initialize(); + stm32_serial_initialize(); uartlite_serial_initialize(); zynq_serial_initialize();
diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c new file mode 100644 index 0000000..3c80096 --- /dev/null +++ b/drivers/serial/serial_stm32.c @@ -0,0 +1,117 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <serial.h> +#include <asm/arch/stm32.h> + +#define STM32_USART1_BASE (STM32_APB2PERIPH_BASE + 0x1000) +#define RCC_APB2ENR_USART1EN (1 << 4) + +#define USART_BASE STM32_USART1_BASE +#define RCC_USART_ENABLE RCC_APB2ENR_USART1EN + +struct stm32_serial { + u32 sr; + u32 dr; + u32 brr; + u32 cr1; + u32 cr2; + u32 cr3; + u32 gtpr; +}; + +#define USART_CR1_RE (1 << 2) +#define USART_CR1_TE (1 << 3) +#define USART_CR1_UE (1 << 13) + +#define USART_SR_FLAG_RXNE (1 << 5) +#define USART_SR_FLAG_TXE (1 << 7) + +#define USART_BRR_F_MASK 0xF +#define USART_BRR_M_SHIFT 4 +#define USART_BRR_M_MASK 0xFFF0 + +DECLARE_GLOBAL_DATA_PTR; + +static void stm32_serial_setbrg(void) +{ + serial_init(); +} + +static int stm32_serial_init(void) +{ + struct stm32_serial *usart = (struct stm32_serial *)USART_BASE; + u32 clock, int_div, frac_div, tmp; + + if ((USART_BASE & STM32_BUS_MASK) == STM32_APB1PERIPH_BASE) { + setbits_le32(&STM32_RCC->apb1enr, RCC_USART_ENABLE); + clock = clock_get(CLOCK_APB1); + } else if ((USART_BASE & STM32_BUS_MASK) == STM32_APB2PERIPH_BASE) { + setbits_le32(&STM32_RCC->apb2enr, RCC_USART_ENABLE); + clock = clock_get(CLOCK_APB2); + } else { + return -1; + } + + int_div = (25 * clock) / (4 * gd->baudrate); + tmp = ((int_div / 100) << USART_BRR_M_SHIFT) & USART_BRR_M_MASK; + frac_div = int_div - (100 * (tmp >> USART_BRR_M_SHIFT)); + tmp |= (((frac_div * 16) + 50) / 100) & USART_BRR_F_MASK; + + writel(tmp, &usart->brr); + setbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE); + + return 0; +} + +static int stm32_serial_getc(void) +{ + struct stm32_serial *usart = (struct stm32_serial *)USART_BASE; + while ((readl(&usart->sr) & USART_SR_FLAG_RXNE) == 0) + ; + return readl(&usart->dr); +} + +static void stm32_serial_putc(const char c) +{ + struct stm32_serial *usart = (struct stm32_serial *)USART_BASE; + while ((readl(&usart->sr) & USART_SR_FLAG_TXE) == 0) + ; + writel(c, &usart->dr); +} + +static int stm32_serial_tstc(void) +{ + struct stm32_serial *usart = (struct stm32_serial *)USART_BASE; + u8 ret; + + ret = readl(&usart->sr) & USART_SR_FLAG_RXNE; + return ret; +} + +static struct serial_device stm32_serial_drv = { + .name = "stm32_serial", + .start = stm32_serial_init, + .stop = NULL, + .setbrg = stm32_serial_setbrg, + .putc = stm32_serial_putc, + .puts = default_serial_puts, + .getc = stm32_serial_getc, + .tstc = stm32_serial_tstc, +}; + +void stm32_serial_initialize(void) +{ + serial_register(&stm32_serial_drv); +} + +__weak struct serial_device *default_serial_console(void) +{ + return &stm32_serial_drv; +}

On Sun, Mar 01, 2015 at 12:44:41PM +0100, Kamil Lulko wrote:
Signed-off-by: Kamil Lulko rev13@wp.pl
Reviewed-by: Tom Rini trini@konsulko.com

On Sun, Mar 01, 2015 at 12:44:41PM +0100, rev13@wp.pl wrote:
Signed-off-by: Kamil Lulko rev13@wp.pl Reviewed-by: Tom Rini trini@konsulko.com
Applied to u-boot/master, thanks!

Signed-off-by: Kamil Lulko rev13@wp.pl --- arch/arm/Kconfig | 5 + board/st/stm32f429-discovery/Kconfig | 19 ++ board/st/stm32f429-discovery/MAINTAINERS | 6 + board/st/stm32f429-discovery/Makefile | 12 + board/st/stm32f429-discovery/led.c | 35 +++ board/st/stm32f429-discovery/stm32f429-discovery.c | 288 +++++++++++++++++++++ configs/stm32f429-discovery_defconfig | 2 + include/configs/stm32f429-discovery.h | 106 ++++++++ 8 files changed, 473 insertions(+) create mode 100644 board/st/stm32f429-discovery/Kconfig create mode 100644 board/st/stm32f429-discovery/MAINTAINERS create mode 100644 board/st/stm32f429-discovery/Makefile create mode 100644 board/st/stm32f429-discovery/led.c create mode 100644 board/st/stm32f429-discovery/stm32f429-discovery.c create mode 100644 configs/stm32f429-discovery_defconfig create mode 100644 include/configs/stm32f429-discovery.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 29ea8b4..8835d17 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -839,6 +839,10 @@ config ARCH_UNIPHIER select SPL select OF_CONTROL if !SPL_BUILD
+config TARGET_STM32F429_DISCOVERY + bool "Support STM32F429 Discovery" + select CPU_V7M + endchoice
source "arch/arm/cpu/arm926ejs/davinci/Kconfig" @@ -1000,6 +1004,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/stm32f429-discovery/Kconfig" source "board/st/stv0991/Kconfig" source "board/sunxi/Kconfig" source "board/syteco/jadecpu/Kconfig" diff --git a/board/st/stm32f429-discovery/Kconfig b/board/st/stm32f429-discovery/Kconfig new file mode 100644 index 0000000..e73d11b --- /dev/null +++ b/board/st/stm32f429-discovery/Kconfig @@ -0,0 +1,19 @@ +if TARGET_STM32F429_DISCOVERY + +config SYS_BOARD + string + default "stm32f429-discovery" + +config SYS_VENDOR + string + default "st" + +config SYS_SOC + string + default "stm32f4" + +config SYS_CONFIG_NAME + string + default "stm32f429-discovery" + +endif diff --git a/board/st/stm32f429-discovery/MAINTAINERS b/board/st/stm32f429-discovery/MAINTAINERS new file mode 100644 index 0000000..27e9545 --- /dev/null +++ b/board/st/stm32f429-discovery/MAINTAINERS @@ -0,0 +1,6 @@ +M: Kamil Lulko rev13@wp.pl +S: Maintained +F: board/st/stm32f429-discovery/ +F: include/configs/stm32f429-discovery.h +F: configs/stm32f429-discovery_defconfig + diff --git a/board/st/stm32f429-discovery/Makefile b/board/st/stm32f429-discovery/Makefile new file mode 100644 index 0000000..7e764e3 --- /dev/null +++ b/board/st/stm32f429-discovery/Makefile @@ -0,0 +1,12 @@ +# +# (C) Copyright 2000-2004 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2015 +# Kamil Lulko, rev13@wp.pl +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := stm32f429-discovery.o +obj-y += led.o diff --git a/board/st/stm32f429-discovery/led.c b/board/st/stm32f429-discovery/led.c new file mode 100644 index 0000000..306e550 --- /dev/null +++ b/board/st/stm32f429-discovery/led.c @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm-generic/gpio.h> + +void coloured_LED_init(void) +{ + gpio_direction_output(CONFIG_RED_LED, 0); + gpio_direction_output(CONFIG_GREEN_LED, 0); +} + +void red_led_off(void) +{ + gpio_set_value(CONFIG_RED_LED, 0); +} + +void green_led_off(void) +{ + gpio_set_value(CONFIG_GREEN_LED, 0); +} + +void red_led_on(void) +{ + gpio_set_value(CONFIG_RED_LED, 1); +} + +void green_led_on(void) +{ + gpio_set_value(CONFIG_GREEN_LED, 1); +} diff --git a/board/st/stm32f429-discovery/stm32f429-discovery.c b/board/st/stm32f429-discovery/stm32f429-discovery.c new file mode 100644 index 0000000..91b4f2d --- /dev/null +++ b/board/st/stm32f429-discovery/stm32f429-discovery.c @@ -0,0 +1,288 @@ +/* + * (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 + * + * 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> +#include <asm/arch/fmc.h> + +DECLARE_GLOBAL_DATA_PTR; + +const struct stm32_gpio_ctl gpio_ctl_gpout = { + .mode = STM32_GPIO_MODE_OUT, + .otype = STM32_GPIO_OTYPE_PP, + .speed = STM32_GPIO_SPEED_50M, + .pupd = STM32_GPIO_PUPD_NO, + .af = STM32_GPIO_AF0 +}; + +const struct stm32_gpio_ctl gpio_ctl_usart = { + .mode = STM32_GPIO_MODE_AF, + .otype = STM32_GPIO_OTYPE_PP, + .speed = STM32_GPIO_SPEED_50M, + .pupd = STM32_GPIO_PUPD_UP, + .af = STM32_GPIO_AF7 +}; + +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 uart1_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); + if (rv) + goto out; + } + +out: + return rv; +} + +const struct stm32_gpio_ctl gpio_ctl_fmc = { + .mode = STM32_GPIO_MODE_AF, + .otype = STM32_GPIO_OTYPE_PP, + .speed = STM32_GPIO_SPEED_100M, + .pupd = STM32_GPIO_PUPD_NO, + .af = STM32_GPIO_AF12 +}; + +static const struct stm32_gpio_dsc ext_ram_fmc_gpio[] = { + /* Chip is LQFP144, see DM00077036.pdf for details */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_10}, /* 79, FMC_D15 */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_9}, /* 78, FMC_D14 */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_8}, /* 77, FMC_D13 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_15}, /* 68, FMC_D12 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_14}, /* 67, FMC_D11 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_13}, /* 66, FMC_D10 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_12}, /* 65, FMC_D9 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_11}, /* 64, FMC_D8 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_10}, /* 63, FMC_D7 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_9}, /* 60, FMC_D6 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_8}, /* 59, FMC_D5 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_7}, /* 58, FMC_D4 */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_1}, /* 115, FMC_D3 */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_0}, /* 114, FMC_D2 */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_15}, /* 86, FMC_D1 */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_14}, /* 85, FMC_D0 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_1}, /* 142, FMC_NBL1 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_0}, /* 141, FMC_NBL0 */ + {STM32_GPIO_PORT_G, STM32_GPIO_PIN_5}, /* 90, FMC_A15, BA1 */ + {STM32_GPIO_PORT_G, STM32_GPIO_PIN_4}, /* 89, FMC_A14, BA0 */ + {STM32_GPIO_PORT_G, STM32_GPIO_PIN_1}, /* 57, FMC_A11 */ + {STM32_GPIO_PORT_G, STM32_GPIO_PIN_0}, /* 56, FMC_A10 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_15}, /* 55, FMC_A9 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_14}, /* 54, FMC_A8 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_13}, /* 53, FMC_A7 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_12}, /* 50, FMC_A6 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_5}, /* 15, FMC_A5 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_4}, /* 14, FMC_A4 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_3}, /* 13, FMC_A3 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_2}, /* 12, FMC_A2 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_1}, /* 11, FMC_A1 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_0}, /* 10, FMC_A0 */ + {STM32_GPIO_PORT_B, STM32_GPIO_PIN_6}, /* 136, SDRAM_NE */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_11}, /* 49, SDRAM_NRAS */ + {STM32_GPIO_PORT_G, STM32_GPIO_PIN_15}, /* 132, SDRAM_NCAS */ + {STM32_GPIO_PORT_C, STM32_GPIO_PIN_0}, /* 26, SDRAM_NWE */ + {STM32_GPIO_PORT_B, STM32_GPIO_PIN_5}, /* 135, SDRAM_CKE */ + {STM32_GPIO_PORT_G, STM32_GPIO_PIN_8}, /* 93, SDRAM_CLK */ +}; + +static int fmc_setup_gpio(void) +{ + int rv = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(ext_ram_fmc_gpio); i++) { + rv = stm32_gpio_config(&ext_ram_fmc_gpio[i], + &gpio_ctl_fmc); + if (rv) + goto out; + } + +out: + return rv; +} + +/* + * STM32 RCC FMC specific definitions + */ +#define STM32_RCC_ENR_FMC (1 << 0) /* FMC module clock */ + +static inline u32 _ns2clk(u32 ns, u32 freq) +{ + u32 tmp = freq/1000000; + return (tmp * ns) / 1000; +} + +#define NS2CLK(ns) (_ns2clk(ns, freq)) + +/* + * Following are timings for IS42S16400J, from corresponding datasheet + */ +#define SDRAM_CAS 3 /* 3 cycles */ +#define SDRAM_NB 1 /* Number of banks */ +#define SDRAM_MWID 1 /* 16 bit memory */ + +#define SDRAM_NR 0x1 /* 12-bit row */ +#define SDRAM_NC 0x0 /* 8-bit col */ +#define SDRAM_RBURST 0x1 /* Single read requests always as bursts */ +#define SDRAM_RPIPE 0x0 /* No HCLK clock cycle delay */ + +#define SDRAM_TRRD (NS2CLK(14) - 1) +#define SDRAM_TRCD (NS2CLK(15) - 1) +#define SDRAM_TRP (NS2CLK(15) - 1) +#define SDRAM_TRAS (NS2CLK(42) - 1) +#define SDRAM_TRC (NS2CLK(63) - 1) +#define SDRAM_TRFC (NS2CLK(63) - 1) +#define SDRAM_TCDL (1 - 1) +#define SDRAM_TRDL (2 - 1) +#define SDRAM_TBDL (1 - 1) +#define SDRAM_TREF 1386 +#define SDRAM_TCCD (1 - 1) + +#define SDRAM_TXSR (NS2CLK(70) - 1)/* Row cycle time after precharge */ +#define SDRAM_TMRD (3 - 1) /* Page 10, Mode Register Set */ + +/* Last data-in to row precharge, need also comply ineq from RM 37.7.5 */ +#define SDRAM_TWR max(\ + (int)max((int)SDRAM_TRDL, (int)(SDRAM_TRAS - SDRAM_TRCD - 1)), \ + (int)(SDRAM_TRC - SDRAM_TRCD - SDRAM_TRP - 2)\ +) + +#define SDRAM_MODE_BL_SHIFT 0 +#define SDRAM_MODE_CAS_SHIFT 4 +#define SDRAM_MODE_BL 0 +#define SDRAM_MODE_CAS SDRAM_CAS + +int dram_init(void) +{ + u32 freq; + int rv; + + rv = fmc_setup_gpio(); + if (rv) + return rv; + + setbits_le32(&STM32_RCC->ahb3enr, STM32_RCC_ENR_FMC); + + /* + * Get frequency for NS2CLK calculation. + */ + freq = clock_get(CLOCK_AHB) / CONFIG_SYS_RAM_FREQ_DIV; + + writel(CONFIG_SYS_RAM_FREQ_DIV << FMC_SDCR_SDCLK_SHIFT + | SDRAM_RPIPE << FMC_SDCR_RPIPE_SHIFT + | SDRAM_RBURST << FMC_SDCR_RBURST_SHIFT, + &STM32_SDRAM_FMC->sdcr1); + + writel(CONFIG_SYS_RAM_FREQ_DIV << FMC_SDCR_SDCLK_SHIFT + | SDRAM_CAS << FMC_SDCR_CAS_SHIFT + | SDRAM_NB << FMC_SDCR_NB_SHIFT + | SDRAM_MWID << FMC_SDCR_MWID_SHIFT + | SDRAM_NR << FMC_SDCR_NR_SHIFT + | SDRAM_NC << FMC_SDCR_NC_SHIFT + | SDRAM_RPIPE << FMC_SDCR_RPIPE_SHIFT + | SDRAM_RBURST << FMC_SDCR_RBURST_SHIFT, + &STM32_SDRAM_FMC->sdcr2); + + writel(SDRAM_TRP << FMC_SDTR_TRP_SHIFT + | SDRAM_TRC << FMC_SDTR_TRC_SHIFT, + &STM32_SDRAM_FMC->sdtr1); + + writel(SDRAM_TRCD << FMC_SDTR_TRCD_SHIFT + | SDRAM_TRP << FMC_SDTR_TRP_SHIFT + | SDRAM_TWR << FMC_SDTR_TWR_SHIFT + | SDRAM_TRC << FMC_SDTR_TRC_SHIFT + | SDRAM_TRAS << FMC_SDTR_TRAS_SHIFT + | SDRAM_TXSR << FMC_SDTR_TXSR_SHIFT + | SDRAM_TMRD << FMC_SDTR_TMRD_SHIFT, + &STM32_SDRAM_FMC->sdtr2); + + writel(FMC_SDCMR_BANK_2 | FMC_SDCMR_MODE_START_CLOCK, + &STM32_SDRAM_FMC->sdcmr); + + udelay(200); /* 200 us delay, page 10, "Power-Up" */ + FMC_BUSY_WAIT(); + + writel(FMC_SDCMR_BANK_2 | FMC_SDCMR_MODE_PRECHARGE, + &STM32_SDRAM_FMC->sdcmr); + + udelay(100); + FMC_BUSY_WAIT(); + + writel((FMC_SDCMR_BANK_2 | FMC_SDCMR_MODE_AUTOREFRESH + | 7 << FMC_SDCMR_NRFS_SHIFT), &STM32_SDRAM_FMC->sdcmr); + + udelay(100); + FMC_BUSY_WAIT(); + + writel(FMC_SDCMR_BANK_2 | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT + | SDRAM_MODE_CAS << SDRAM_MODE_CAS_SHIFT) + << FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE, + &STM32_SDRAM_FMC->sdcmr); + + udelay(100); + + FMC_BUSY_WAIT(); + + writel(FMC_SDCMR_BANK_2 | FMC_SDCMR_MODE_NORMAL, + &STM32_SDRAM_FMC->sdcmr); + + FMC_BUSY_WAIT(); + + /* Refresh timer */ + writel(SDRAM_TREF, &STM32_SDRAM_FMC->sdrtr); + + /* + * Fill in global info with description of SRAM configuration + */ + gd->bd->bi_dram[0].start = CONFIG_SYS_RAM_BASE; + gd->bd->bi_dram[0].size = CONFIG_SYS_RAM_SIZE; + + gd->ram_size = CONFIG_SYS_RAM_SIZE; + + return rv; +} + +u32 get_board_rev(void) +{ + return 0; +} + +int board_early_init_f(void) +{ + int res; + + res = uart1_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/stm32f429-discovery_defconfig b/configs/stm32f429-discovery_defconfig new file mode 100644 index 0000000..6d74d73 --- /dev/null +++ b/configs/stm32f429-discovery_defconfig @@ -0,0 +1,2 @@ +CONFIG_ARM=y +CONFIG_TARGET_STM32F429_DISCOVERY=y diff --git a/include/configs/stm32f429-discovery.h b/include/configs/stm32f429-discovery.h new file mode 100644 index 0000000..7f569fd --- /dev/null +++ b/include/configs/stm32f429-discovery.h @@ -0,0 +1,106 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, rev13@wp.pl + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define CONFIG_STM32F4 +#define CONFIG_STM32F4DISCOVERY +#define CONFIG_SYS_GENERIC_BOARD + +#define CONFIG_OF_LIBFDT + +#define CONFIG_BOARD_EARLY_INIT_F + +#define CONFIG_SYS_FLASH_BASE 0x08000000 + +#define CONFIG_SYS_INIT_SP_ADDR 0x10010000 +#define CONFIG_SYS_TEXT_BASE 0x08000000 + +#define CONFIG_SYS_ICACHE_OFF +#define CONFIG_SYS_DCACHE_OFF + +/* + * Configuration of the external SDRAM memory + */ +#define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_SYS_RAM_SIZE (8 << 20) +#define CONFIG_SYS_RAM_CS 1 +#define CONFIG_SYS_RAM_FREQ_DIV 2 +#define CONFIG_SYS_RAM_BASE 0xD0000000 +#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_RAM_BASE +#define CONFIG_SYS_LOAD_ADDR 0xD0400000 +#define CONFIG_LOADADDR 0xD0400000 + +#define CONFIG_SYS_MAX_FLASH_SECT 12 +#define CONFIG_SYS_MAX_FLASH_BANKS 2 + +#define CONFIG_ENV_IS_IN_FLASH +#define CONFIG_ENV_OFFSET (256 << 10) +#define CONFIG_ENV_SECT_SIZE (128 << 10) +#define CONFIG_ENV_SIZE (8 << 10) + +#define CONFIG_BOARD_SPECIFIC_LED +#define CONFIG_RED_LED 110 +#define CONFIG_GREEN_LED 109 + +#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_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_INITRD_TAG +#define CONFIG_REVISION_TAG + +#define CONFIG_SYS_CBSIZE 1024 +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE \ + + sizeof(CONFIG_SYS_PROMPT) + 16) + +#define CONFIG_SYS_MAXARGS 16 + +#define CONFIG_SYS_MALLOC_LEN (2 << 20) + +#define CONFIG_STACKSIZE (64 << 10) + +#define CONFIG_BAUDRATE 115200 +#define CONFIG_BOOTARGS \ + "console=ttystm0,115200 earlyprintk consoleblank=0 ignore_loglevel" +#define CONFIG_BOOTCOMMAND \ + "run bootcmd_romfs" + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "bootargs_romfs=uclinux.physaddr=0x08180000 root=/dev/mtdblock0\0" \ + "bootcmd_romfs=setenv bootargs ${bootargs} ${bootargs_romfs};" \ + "bootm 0x08044000 - 0x08042000\0" + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_AUTOBOOT + +/* + * Command line configuration. + */ +#include <config_cmd_default.h> + +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_HUSH_PARSER +#define CONFIG_SYS_PROMPT "U-Boot > " +#define CONFIG_AUTO_COMPLETE +#define CONFIG_CMDLINE_EDITING + +#define CONFIG_CMD_FLASH +#define CONFIG_CMD_SAVEENV +#define CONFIG_CMD_MEM +#define CONFIG_CMD_MISC +#define CONFIG_CMD_TIMER + +#endif /* __CONFIG_H */

On Sun, Mar 01, 2015 at 12:44:42PM +0100, Kamil Lulko wrote:
Signed-off-by: Kamil Lulko rev13@wp.pl
Reviewed-by: Tom Rini trini@konsulko.com

On Sun, Mar 01, 2015 at 12:44:42PM +0100, rev13@wp.pl wrote:
Signed-off-by: Kamil Lulko rev13@wp.pl Reviewed-by: Tom Rini trini@konsulko.com
Applied to u-boot/master, thanks!

Hi Kamil,
I tested this patch-set in STM32 Discovery board. After applied this patch-set on latest u-boot, I could not see the normal u-boot log. I saw broken console log. I used the USART1 port (pa9, pa10 gpio pin).
Could you give me a tip to resolve this issue?
Best Regards, Chanwoo Choi
2015년 3월 1일 일요일, Kamil Lulkorev13@wp.pl님이 작성한 메시지:
The following patches implement basic support for the ARMv7-M microcontroller architecture. Additionally, stm32f429-discovery board support is added with tested ability to boot uClinux from the embedded Flash memory.
Kamil Lulko (4): ARM: Add ARMv7-M support ARMv7M: Add STM32F4 support stm32f4: Add serial driver stm32f4: Add support for stm32f429-discovery board
arch/arm/Kconfig | 9 + arch/arm/cpu/armv7m/Makefile | 11 + arch/arm/cpu/armv7m/config.mk | 8 + arch/arm/cpu/armv7m/cpu.c | 35 +++ arch/arm/cpu/armv7m/start.S | 15 ++ arch/arm/cpu/armv7m/stm32f4/Makefile | 11 + arch/arm/cpu/armv7m/stm32f4/clock.c | 209 +++++++++++++++ arch/arm/cpu/armv7m/stm32f4/flash.c | 143 ++++++++++ arch/arm/cpu/armv7m/stm32f4/soc.c | 37 +++ arch/arm/cpu/armv7m/stm32f4/timer.c | 118 +++++++++ arch/arm/include/asm/arch-stm32f4/fmc.h | 75 ++++++ arch/arm/include/asm/arch-stm32f4/gpio.h | 116 +++++++++ arch/arm/include/asm/arch-stm32f4/stm32.h | 108 ++++++++ arch/arm/include/asm/armv7m.h | 60 +++++ arch/arm/lib/Makefile | 8 +- arch/arm/lib/crt0.S | 30 +++ arch/arm/lib/interrupts_m.c | 95 +++++++ arch/arm/lib/relocate.S | 13 + arch/arm/lib/vectors_m.S | 57 ++++ board/st/stm32f429-discovery/Kconfig | 19 ++ board/st/stm32f429-discovery/MAINTAINERS | 6 + board/st/stm32f429-discovery/Makefile | 12 + board/st/stm32f429-discovery/led.c | 35 +++ board/st/stm32f429-discovery/stm32f429-discovery.c | 288 +++++++++++++++++++++ configs/stm32f429-discovery_defconfig | 2 + drivers/gpio/Makefile | 1 + drivers/gpio/stm32_gpio.c | 199 ++++++++++++++ drivers/serial/Makefile | 1 + drivers/serial/serial.c | 2 + drivers/serial/serial_stm32.c | 117 +++++++++ include/configs/stm32f429-discovery.h | 106 ++++++++ include/flash.h | 2 + 32 files changed, 1946 insertions(+), 2 deletions(-) create mode 100644 arch/arm/cpu/armv7m/Makefile create mode 100644 arch/arm/cpu/armv7m/config.mk create mode 100644 arch/arm/cpu/armv7m/cpu.c create mode 100644 arch/arm/cpu/armv7m/start.S create mode 100644 arch/arm/cpu/armv7m/stm32f4/Makefile create mode 100644 arch/arm/cpu/armv7m/stm32f4/clock.c create mode 100644 arch/arm/cpu/armv7m/stm32f4/flash.c create mode 100644 arch/arm/cpu/armv7m/stm32f4/soc.c create mode 100644 arch/arm/cpu/armv7m/stm32f4/timer.c create mode 100644 arch/arm/include/asm/arch-stm32f4/fmc.h create mode 100644 arch/arm/include/asm/arch-stm32f4/gpio.h create mode 100644 arch/arm/include/asm/arch-stm32f4/stm32.h create mode 100644 arch/arm/include/asm/armv7m.h create mode 100644 arch/arm/lib/interrupts_m.c create mode 100644 arch/arm/lib/vectors_m.S create mode 100644 board/st/stm32f429-discovery/Kconfig create mode 100644 board/st/stm32f429-discovery/MAINTAINERS create mode 100644 board/st/stm32f429-discovery/Makefile create mode 100644 board/st/stm32f429-discovery/led.c create mode 100644 board/st/stm32f429-discovery/stm32f429-discovery.c create mode 100644 configs/stm32f429-discovery_defconfig create mode 100644 drivers/gpio/stm32_gpio.c create mode 100644 drivers/serial/serial_stm32.c create mode 100644 include/configs/stm32f429-discovery.h
-- 1.9.1
U-Boot mailing list U-Boot@lists.denx.de javascript:; http://lists.denx.de/mailman/listinfo/u-boot

On Wed, Mar 25, 2015 at 01:07:47PM +0900, Chanwoo Choi wrote:
Hi Kamil,
I tested this patch-set in STM32 Discovery board. After applied this patch-set on latest u-boot, I could not see the normal u-boot log. I saw broken console log. I used the USART1 port (pa9, pa10 gpio pin).
Could you give me a tip to resolve this issue?
I bet this needs changes similar to b81bdf6 as that was a similar problem I believe. In short, DM needs to be enabled now.
Best Regards, Chanwoo Choi
2015년 3월 1일 일요일, Kamil Lulkorev13@wp.pl님이 작성한 메시지:
The following patches implement basic support for the ARMv7-M microcontroller architecture. Additionally, stm32f429-discovery board support is added with tested ability to boot uClinux from the embedded Flash memory.
Kamil Lulko (4): ARM: Add ARMv7-M support ARMv7M: Add STM32F4 support stm32f4: Add serial driver stm32f4: Add support for stm32f429-discovery board
arch/arm/Kconfig | 9 + arch/arm/cpu/armv7m/Makefile | 11 + arch/arm/cpu/armv7m/config.mk | 8 + arch/arm/cpu/armv7m/cpu.c | 35 +++ arch/arm/cpu/armv7m/start.S | 15 ++ arch/arm/cpu/armv7m/stm32f4/Makefile | 11 + arch/arm/cpu/armv7m/stm32f4/clock.c | 209 +++++++++++++++ arch/arm/cpu/armv7m/stm32f4/flash.c | 143 ++++++++++ arch/arm/cpu/armv7m/stm32f4/soc.c | 37 +++ arch/arm/cpu/armv7m/stm32f4/timer.c | 118 +++++++++ arch/arm/include/asm/arch-stm32f4/fmc.h | 75 ++++++ arch/arm/include/asm/arch-stm32f4/gpio.h | 116 +++++++++ arch/arm/include/asm/arch-stm32f4/stm32.h | 108 ++++++++ arch/arm/include/asm/armv7m.h | 60 +++++ arch/arm/lib/Makefile | 8 +- arch/arm/lib/crt0.S | 30 +++ arch/arm/lib/interrupts_m.c | 95 +++++++ arch/arm/lib/relocate.S | 13 + arch/arm/lib/vectors_m.S | 57 ++++ board/st/stm32f429-discovery/Kconfig | 19 ++ board/st/stm32f429-discovery/MAINTAINERS | 6 + board/st/stm32f429-discovery/Makefile | 12 + board/st/stm32f429-discovery/led.c | 35 +++ board/st/stm32f429-discovery/stm32f429-discovery.c | 288 +++++++++++++++++++++ configs/stm32f429-discovery_defconfig | 2 + drivers/gpio/Makefile | 1 + drivers/gpio/stm32_gpio.c | 199 ++++++++++++++ drivers/serial/Makefile | 1 + drivers/serial/serial.c | 2 + drivers/serial/serial_stm32.c | 117 +++++++++ include/configs/stm32f429-discovery.h | 106 ++++++++ include/flash.h | 2 + 32 files changed, 1946 insertions(+), 2 deletions(-) create mode 100644 arch/arm/cpu/armv7m/Makefile create mode 100644 arch/arm/cpu/armv7m/config.mk create mode 100644 arch/arm/cpu/armv7m/cpu.c create mode 100644 arch/arm/cpu/armv7m/start.S create mode 100644 arch/arm/cpu/armv7m/stm32f4/Makefile create mode 100644 arch/arm/cpu/armv7m/stm32f4/clock.c create mode 100644 arch/arm/cpu/armv7m/stm32f4/flash.c create mode 100644 arch/arm/cpu/armv7m/stm32f4/soc.c create mode 100644 arch/arm/cpu/armv7m/stm32f4/timer.c create mode 100644 arch/arm/include/asm/arch-stm32f4/fmc.h create mode 100644 arch/arm/include/asm/arch-stm32f4/gpio.h create mode 100644 arch/arm/include/asm/arch-stm32f4/stm32.h create mode 100644 arch/arm/include/asm/armv7m.h create mode 100644 arch/arm/lib/interrupts_m.c create mode 100644 arch/arm/lib/vectors_m.S create mode 100644 board/st/stm32f429-discovery/Kconfig create mode 100644 board/st/stm32f429-discovery/MAINTAINERS create mode 100644 board/st/stm32f429-discovery/Makefile create mode 100644 board/st/stm32f429-discovery/led.c create mode 100644 board/st/stm32f429-discovery/stm32f429-discovery.c create mode 100644 configs/stm32f429-discovery_defconfig create mode 100644 drivers/gpio/stm32_gpio.c create mode 100644 drivers/serial/serial_stm32.c create mode 100644 include/configs/stm32f429-discovery.h
-- 1.9.1
U-Boot mailing list U-Boot@lists.denx.de javascript:; http://lists.denx.de/mailman/listinfo/u-boot
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On 25/03/15 17:58, Tom Rini wrote:
On Wed, Mar 25, 2015 at 01:07:47PM +0900, Chanwoo Choi wrote:
Hi Kamil,
I tested this patch-set in STM32 Discovery board. After applied this patch-set on latest u-boot, I could not see the normal u-boot log. I saw broken console log. I used the USART1 port (pa9, pa10 gpio pin).
Could you give me a tip to resolve this issue?
I bet this needs changes similar to b81bdf6 as that was a similar problem I believe. In short, DM needs to be enabled now.
Best Regards, Chanwoo Choi
2015년 3월 1일 일요일, Kamil Lulkorev13@wp.pl님이 작성한 메시지:
I have tested this patch set again with 2015.04-rc4-gf643d92 and serial works without any problems.
Chanwoo, you mention STM32 Discovery board - this patch set supports only STM32F429 Discovery (it should work on SDRAM-less boards but not without modifications). Other than that the only thing I can think of is configuration of the UART<>USB converter.
Tom, does this mean changes are required for this patchset to be accepted? I have more things queued up (like moving some of SDRAM configuration bits out of the board code or LCD display support) but I would prefer to have some kind of assurance that this will not go into /dev/null eventually :)
/Kamil

On Thu, Mar 26, 2015 at 02:47:17PM +0100, Kamil Lulko wrote:
On 25/03/15 17:58, Tom Rini wrote:
On Wed, Mar 25, 2015 at 01:07:47PM +0900, Chanwoo Choi wrote:
Hi Kamil,
I tested this patch-set in STM32 Discovery board. After applied this patch-set on latest u-boot, I could not see the normal u-boot log. I saw broken console log. I used the USART1 port (pa9, pa10 gpio pin).
Could you give me a tip to resolve this issue?
I bet this needs changes similar to b81bdf6 as that was a similar problem I believe. In short, DM needs to be enabled now.
Best Regards, Chanwoo Choi
2015년 3월 1일 일요일, Kamil Lulkorev13@wp.pl님이 작성한 메시지:
I have tested this patch set again with 2015.04-rc4-gf643d92 and serial works without any problems.
Chanwoo, you mention STM32 Discovery board - this patch set supports only STM32F429 Discovery (it should work on SDRAM-less boards but not without modifications). Other than that the only thing I can think of is configuration of the UART<>USB converter.
Tom, does this mean changes are required for this patchset to be accepted? I have more things queued up (like moving some of SDRAM configuration bits out of the board code or LCD display support) but I would prefer to have some kind of assurance that this will not go into /dev/null eventually :)
Right now the patches don't apply cleanly due to 68145d4c but it's an easy enough fixup by hand. I plan to apply the current series after the 2015.04 release. If you want to start posting stuff that depends on the initial series being applied that's fine. Thanks!
participants (4)
-
Andreas Färber
-
Chanwoo Choi
-
Kamil Lulko
-
Tom Rini