diff options
Diffstat (limited to 'arch/arm/mach-stm32')
-rw-r--r-- | arch/arm/mach-stm32/Kconfig | 4 | ||||
-rw-r--r-- | arch/arm/mach-stm32/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-stm32/stm32f4/clock.c | 48 | ||||
-rw-r--r-- | arch/arm/mach-stm32/stm32f7/Kconfig | 8 | ||||
-rw-r--r-- | arch/arm/mach-stm32/stm32f7/Makefile | 8 | ||||
-rw-r--r-- | arch/arm/mach-stm32/stm32f7/clock.c | 56 | ||||
-rw-r--r-- | arch/arm/mach-stm32/stm32f7/timer.c | 112 |
7 files changed, 237 insertions, 0 deletions
diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig index 7dbeb04..ec6b3ff 100644 --- a/arch/arm/mach-stm32/Kconfig +++ b/arch/arm/mach-stm32/Kconfig @@ -6,7 +6,11 @@ config STM32F4 config STM32F1 bool "stm32f1 family" +config STM32F7 + bool "stm32f7 family" + source "arch/arm/mach-stm32/stm32f4/Kconfig" source "arch/arm/mach-stm32/stm32f1/Kconfig" +source "arch/arm/mach-stm32/stm32f7/Kconfig" endif diff --git a/arch/arm/mach-stm32/Makefile b/arch/arm/mach-stm32/Makefile index ea06034..ffc537f 100644 --- a/arch/arm/mach-stm32/Makefile +++ b/arch/arm/mach-stm32/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_STM32F1) += stm32f1/ obj-$(CONFIG_STM32F4) += stm32f4/ +obj-$(CONFIG_STM32F7) += stm32f7/ diff --git a/arch/arm/mach-stm32/stm32f4/clock.c b/arch/arm/mach-stm32/stm32f4/clock.c index 576d3e6..631f36a 100644 --- a/arch/arm/mach-stm32/stm32f4/clock.c +++ b/arch/arm/mach-stm32/stm32f4/clock.c @@ -71,6 +71,21 @@ #define FLASH_ACR_ICEN (1 << 9) #define FLASH_ACR_DCEN (1 << 10) +/* + * RCC GPIO specific definitions + */ +#define RCC_ENR_GPIO_A_EN (1 << 0) +#define RCC_ENR_GPIO_B_EN (1 << 1) +#define RCC_ENR_GPIO_C_EN (1 << 2) +#define RCC_ENR_GPIO_D_EN (1 << 3) +#define RCC_ENR_GPIO_E_EN (1 << 4) +#define RCC_ENR_GPIO_F_EN (1 << 5) +#define RCC_ENR_GPIO_G_EN (1 << 6) +#define RCC_ENR_GPIO_H_EN (1 << 7) +#define RCC_ENR_GPIO_I_EN (1 << 8) +#define RCC_ENR_GPIO_J_EN (1 << 9) +#define RCC_ENR_GPIO_K_EN (1 << 10) + struct pll_psc { u8 pll_m; u16 pll_n; @@ -237,6 +252,39 @@ void clock_setup(int peripheral) case USART1_CLOCK_CFG: setbits_le32(&STM32_RCC->apb2enr, RCC_ENR_USART1EN); break; + case GPIO_A_CLOCK_CFG: + setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_A_EN); + break; + case GPIO_B_CLOCK_CFG: + setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_B_EN); + break; + case GPIO_C_CLOCK_CFG: + setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_C_EN); + break; + case GPIO_D_CLOCK_CFG: + setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_D_EN); + break; + case GPIO_E_CLOCK_CFG: + setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_E_EN); + break; + case GPIO_F_CLOCK_CFG: + setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_F_EN); + break; + case GPIO_G_CLOCK_CFG: + setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_G_EN); + break; + case GPIO_H_CLOCK_CFG: + setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_H_EN); + break; + case GPIO_I_CLOCK_CFG: + setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_I_EN); + break; + case GPIO_J_CLOCK_CFG: + setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_J_EN); + break; + case GPIO_K_CLOCK_CFG: + setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_K_EN); + break; default: break; } diff --git a/arch/arm/mach-stm32/stm32f7/Kconfig b/arch/arm/mach-stm32/stm32f7/Kconfig new file mode 100644 index 0000000..287e5ad --- /dev/null +++ b/arch/arm/mach-stm32/stm32f7/Kconfig @@ -0,0 +1,8 @@ +if STM32F7 + +config TARGET_STM32F746_DISCO + bool "STM32F746 Discovery board" + +source "board/st/stm32f746-disco/Kconfig" + +endif diff --git a/arch/arm/mach-stm32/stm32f7/Makefile b/arch/arm/mach-stm32/stm32f7/Makefile new file mode 100644 index 0000000..40f1ad3 --- /dev/null +++ b/arch/arm/mach-stm32/stm32f7/Makefile @@ -0,0 +1,8 @@ +# +# (C) Copyright 2016 +# Vikas Manocha, <vikas.manocha@gmail.com> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += timer.o clock.o diff --git a/arch/arm/mach-stm32/stm32f7/clock.c b/arch/arm/mach-stm32/stm32f7/clock.c new file mode 100644 index 0000000..17a715b --- /dev/null +++ b/arch/arm/mach-stm32/stm32f7/clock.c @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2016 + * Vikas Manocha, <vikas.manocha@st.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/rcc.h> +#include <asm/arch/stm32.h> +#include <asm/arch/stm32_periph.h> + +void clock_setup(int peripheral) +{ + switch (peripheral) { + case USART1_CLOCK_CFG: + setbits_le32(RCC_BASE + RCC_APB2ENR, RCC_ENR_USART1EN); + break; + case GPIO_A_CLOCK_CFG: + setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_A_EN); + break; + case GPIO_B_CLOCK_CFG: + setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_B_EN); + break; + case GPIO_C_CLOCK_CFG: + setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_C_EN); + break; + case GPIO_D_CLOCK_CFG: + setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_D_EN); + break; + case GPIO_E_CLOCK_CFG: + setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_E_EN); + break; + case GPIO_F_CLOCK_CFG: + setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_F_EN); + break; + case GPIO_G_CLOCK_CFG: + setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_G_EN); + break; + case GPIO_H_CLOCK_CFG: + setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_H_EN); + break; + case GPIO_I_CLOCK_CFG: + setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_I_EN); + break; + case GPIO_J_CLOCK_CFG: + setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_J_EN); + break; + case GPIO_K_CLOCK_CFG: + setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_K_EN); + break; + default: + break; + } +} diff --git a/arch/arm/mach-stm32/stm32f7/timer.c b/arch/arm/mach-stm32/stm32f7/timer.c new file mode 100644 index 0000000..a7dee10 --- /dev/null +++ b/arch/arm/mach-stm32/stm32f7/timer.c @@ -0,0 +1,112 @@ +/* + * (C) Copyright 2016 + * Vikas Manocha, ST Micoelectronics, vikas.manocha@st.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/stm32.h> +#include <asm/arch/gpt.h> +#include <asm/arch/rcc.h> + +#define READ_TIMER() (readl(&gpt1_regs_ptr->cnt) & GPT_FREE_RUNNING) +#define GPT_RESOLUTION (CONFIG_SYS_HZ_CLOCK/CONFIG_STM32_HZ) + +DECLARE_GLOBAL_DATA_PTR; + +#define timestamp gd->arch.tbl +#define lastdec gd->arch.lastinc + +int timer_init(void) +{ + /* Timer2 clock configuration */ + setbits_le32(RCC_BASE + RCC_APB1ENR, RCC_APB1ENR_TIM2EN); + /* Stop the timer */ + writel(readl(&gpt1_regs_ptr->cr1) & ~GPT_CR1_CEN, &gpt1_regs_ptr->cr1); + + writel((CONFIG_SYS_CLK_FREQ/CONFIG_SYS_HZ_CLOCK) - 1, + &gpt1_regs_ptr->psc); + + /* Configure timer for auto-reload */ + writel(readl(&gpt1_regs_ptr->cr1) | GPT_MODE_AUTO_RELOAD, + &gpt1_regs_ptr->cr1); + + /* load value for free running */ + writel(GPT_FREE_RUNNING, &gpt1_regs_ptr->arr); + + /* start timer */ + writel(readl(&gpt1_regs_ptr->cr1) | GPT_CR1_CEN, &gpt1_regs_ptr->cr1); + + writel(readl(&gpt1_regs_ptr->egr) | TIM_EGR_UG, &gpt1_regs_ptr->egr); + + /* Reset the timer */ + lastdec = READ_TIMER(); + timestamp = 0; + + return 0; +} + +/* + * timer without interrupts + */ +ulong get_timer(ulong base) +{ + return (get_timer_masked() / GPT_RESOLUTION) - base; +} + +void __udelay(unsigned long usec) +{ + ulong tmo; + ulong start = get_timer_masked(); + ulong tenudelcnt = CONFIG_SYS_HZ_CLOCK / (1000 * 100); + ulong rndoff; + + rndoff = (usec % 10) ? 1 : 0; + + /* tenudelcnt timer tick gives 10 microsecconds delay */ + tmo = ((usec / 10) + rndoff) * tenudelcnt; + + while ((ulong) (get_timer_masked() - start) < tmo) + ; +} + +ulong get_timer_masked(void) +{ + ulong now = READ_TIMER(); + + if (now >= lastdec) { + /* normal mode */ + timestamp += now - lastdec; + } else { + /* we have an overflow ... */ + timestamp += now + GPT_FREE_RUNNING - lastdec; + } + lastdec = now; + + return timestamp; +} + +void udelay_masked(unsigned long usec) +{ + return udelay(usec); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * 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_STM32_HZ; +} |