From 9ecb0c416c68d3105bc9b6607bc8601cab2ecf35 Mon Sep 17 00:00:00 2001 From: Vikas Manocha Date: Wed, 9 Mar 2016 15:18:13 -0800 Subject: stm32: stm32f4: move flash driver to mtd driver location Same flash driver can be used by other stm32 families like stm32f7. Better place for this driver would be mtd driver location. Signed-off-by: Vikas Manocha --- arch/arm/include/asm/arch-stm32f4/stm32.h | 31 ++----- arch/arm/mach-stm32/stm32f4/Makefile | 2 +- arch/arm/mach-stm32/stm32f4/clock.c | 10 +- arch/arm/mach-stm32/stm32f4/flash.c | 146 ----------------------------- drivers/mtd/Makefile | 1 + drivers/mtd/stm32_flash.c | 147 ++++++++++++++++++++++++++++++ drivers/mtd/stm32_flash.h | 27 ++++++ include/configs/stm32f429-discovery.h | 1 + include/flash.h | 2 +- 9 files changed, 188 insertions(+), 179 deletions(-) delete mode 100644 arch/arm/mach-stm32/stm32f4/flash.c create mode 100644 drivers/mtd/stm32_flash.c create mode 100644 drivers/mtd/stm32_flash.h diff --git a/arch/arm/include/asm/arch-stm32f4/stm32.h b/arch/arm/include/asm/arch-stm32f4/stm32.h index 7d6331b6b2..6cc19664dd 100644 --- a/arch/arm/include/asm/arch-stm32f4/stm32.h +++ b/arch/arm/include/asm/arch-stm32f4/stm32.h @@ -82,16 +82,6 @@ struct stm32_pwr_regs { u32 csr; }; -struct stm32_flash_regs { - u32 acr; - u32 key; - u32 optkeyr; - u32 sr; - u32 cr; - u32 optcr; - u32 optcr1; -}; - /* * Registers access macros */ @@ -104,18 +94,6 @@ struct stm32_flash_regs { #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 -#define STM32_FLASH_CR_SNB_MASK (15 << STM32_FLASH_CR_SNB_OFFSET) - /* * Peripheral base addresses */ @@ -124,6 +102,14 @@ struct stm32_flash_regs { #define STM32_USART3_BASE (STM32_APB1PERIPH_BASE + 0x4800) #define STM32_USART6_BASE (STM32_APB2PERIPH_BASE + 0x1400) +#define FLASH_CNTL_BASE (STM32_AHB1PERIPH_BASE + 0x3C00) + +static const u32 sect_sz_kb[CONFIG_SYS_MAX_FLASH_SECT] = { + [0 ... 3] = 16 * 1024, + [4] = 64 * 1024, + [5 ... 11] = 128 * 1024 +}; + enum clock { CLOCK_CORE, CLOCK_AHB, @@ -133,5 +119,6 @@ enum clock { int configure_clocks(void); unsigned long clock_get(enum clock clck); +void stm32_flash_latency_cfg(int latency); #endif /* _MACH_STM32_H_ */ diff --git a/arch/arm/mach-stm32/stm32f4/Makefile b/arch/arm/mach-stm32/stm32f4/Makefile index 42d01db14d..020e78370c 100644 --- a/arch/arm/mach-stm32/stm32f4/Makefile +++ b/arch/arm/mach-stm32/stm32f4/Makefile @@ -8,4 +8,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y += soc.o clock.o timer.o flash.o +obj-y += soc.o clock.o timer.o diff --git a/arch/arm/mach-stm32/stm32f4/clock.c b/arch/arm/mach-stm32/stm32f4/clock.c index 631f36a5a1..15fcadbbe6 100644 --- a/arch/arm/mach-stm32/stm32f4/clock.c +++ b/arch/arm/mach-stm32/stm32f4/clock.c @@ -66,11 +66,6 @@ #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) - /* * RCC GPIO specific definitions */ @@ -181,10 +176,7 @@ int configure_clocks(void) 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); - + stm32_flash_latency_cfg(5); clrbits_le32(&STM32_RCC->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1)); setbits_le32(&STM32_RCC->cfgr, RCC_CFGR_SW_PLL); diff --git a/arch/arm/mach-stm32/stm32f4/flash.c b/arch/arm/mach-stm32/stm32f4/flash.c deleted file mode 100644 index a379f477df..0000000000 --- a/arch/arm/mach-stm32/stm32f4/flash.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * (C) Copyright 2015 - * Kamil Lulko, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -#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) - ; - - /* clear old sector number before writing a new one */ - clrbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_SNB_MASK); - - 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/drivers/mtd/Makefile b/drivers/mtd/Makefile index 7f018a4eca..703700aae0 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_FTSMC020) += ftsmc020.o obj-$(CONFIG_FLASH_CFI_LEGACY) += jedec_flash.o obj-$(CONFIG_MW_EEPROM) += mw_eeprom.o obj-$(CONFIG_ST_SMI) += st_smi.o +obj-$(CONFIG_STM32_FLASH) += stm32_flash.o diff --git a/drivers/mtd/stm32_flash.c b/drivers/mtd/stm32_flash.c new file mode 100644 index 0000000000..71f48543a3 --- /dev/null +++ b/drivers/mtd/stm32_flash.c @@ -0,0 +1,147 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include "stm32_flash.h" + +flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; + +#define STM32_FLASH ((struct stm32_flash_regs *)FLASH_CNTL_BASE) + +void stm32_flash_latency_cfg(int latency) +{ + /* 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); +} + +static void stm32_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_STM32; + 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_STM32) { + printf("stm32 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; + + stm32_flash_lock(0); + + for (i = first; i <= last; i++) { + while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY) + ; + + /* clear old sector number before writing a new one */ + clrbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_SNB_MASK); + + 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 { + stm32_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); + } + + stm32_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) + ; + + stm32_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); + stm32_flash_lock(1); + + return 0; +} diff --git a/drivers/mtd/stm32_flash.h b/drivers/mtd/stm32_flash.h new file mode 100644 index 0000000000..8cb81ef68c --- /dev/null +++ b/drivers/mtd/stm32_flash.h @@ -0,0 +1,27 @@ +struct stm32_flash_regs { + u32 acr; + u32 key; + u32 optkeyr; + u32 sr; + u32 cr; + u32 optcr; + u32 optcr1; +}; + +#define STM32_FLASH_KEY1 0x45670123 +#define STM32_FLASH_KEY2 0xCDEF89AB + +#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 +#define STM32_FLASH_CR_SNB_MASK (15 << STM32_FLASH_CR_SNB_OFFSET) + +/* Flash ACR: Access control register */ +#define FLASH_ACR_WS(n) n +#define FLASH_ACR_PRFTEN (1 << 8) +#define FLASH_ACR_ICEN (1 << 9) +#define FLASH_ACR_DCEN (1 << 10) diff --git a/include/configs/stm32f429-discovery.h b/include/configs/stm32f429-discovery.h index 41f1b6938d..05e2363c5d 100644 --- a/include/configs/stm32f429-discovery.h +++ b/include/configs/stm32f429-discovery.h @@ -47,6 +47,7 @@ #define CONFIG_GREEN_LED 109 #define CONFIG_STM32_GPIO +#define CONFIG_STM32_FLASH #define CONFIG_STM32_SERIAL #define CONFIG_STM32_HSE_HZ 8000000 diff --git a/include/flash.h b/include/flash.h index f53ace7889..c6321a02ef 100644 --- a/include/flash.h +++ b/include/flash.h @@ -465,7 +465,7 @@ 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_STM32 0x00F2 /* STM32 Embedded Flash */ #define FLASH_STM32F1 0x00F3 /* STM32F1 Embedded Flash */ #define FLASH_UNKNOWN 0xFFFF /* unknown flash type */ -- cgit v1.2.3