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 <vikas.manocha@st.com>
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_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
*/
#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,
int configure_clocks(void);
unsigned long clock_get(enum clock clck);
+void stm32_flash_latency_cfg(int latency);
#endif /* _MACH_STM32_H_ */
# SPDX-License-Identifier: GPL-2.0+
#
-obj-y += soc.o clock.o timer.o flash.o
+obj-y += soc.o clock.o timer.o
#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
*/
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);
+++ /dev/null
-/*
- * (C) Copyright 2015
- * Kamil Lulko, <kamil.lulko@gmail.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <asm/arch/stm32.h>
-
-#define STM32_FLASH_KEY1 0x45670123
-#define STM32_FLASH_KEY2 0xCDEF89AB
-
-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;
-}
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
--- /dev/null
+/*
+ * (C) Copyright 2015
+ * Kamil Lulko, <kamil.lulko@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/stm32.h>
+#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;
+}
--- /dev/null
+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)
#define CONFIG_GREEN_LED 109
#define CONFIG_STM32_GPIO
+#define CONFIG_STM32_FLASH
#define CONFIG_STM32_SERIAL
#define CONFIG_STM32_HSE_HZ 8000000
#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 */