1 // SPDX-License-Identifier: GPL-2.0+
4 * Kamil Lulko, <kamil.lulko@gmail.com>
9 #include <asm/arch/stm32.h>
10 #include "stm32_flash.h"
12 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
];
14 #define STM32_FLASH ((struct stm32_flash_regs *)STM32_FLASH_CNTL_BASE)
16 void stm32_flash_latency_cfg(int latency
)
18 /* 5 wait states, Prefetch enabled, D-Cache enabled, I-Cache enabled */
19 writel(FLASH_ACR_WS(latency
) | FLASH_ACR_PRFTEN
| FLASH_ACR_ICEN
20 | FLASH_ACR_DCEN
, &STM32_FLASH
->acr
);
23 static void stm32_flash_lock(u8 lock
)
26 setbits_le32(&STM32_FLASH
->cr
, STM32_FLASH_CR_LOCK
);
28 writel(STM32_FLASH_KEY1
, &STM32_FLASH
->key
);
29 writel(STM32_FLASH_KEY2
, &STM32_FLASH
->key
);
33 unsigned long flash_init(void)
35 unsigned long total_size
= 0;
38 for (i
= 0; i
< CONFIG_SYS_MAX_FLASH_BANKS
; i
++) {
39 flash_info
[i
].flash_id
= FLASH_STM32
;
40 flash_info
[i
].sector_count
= CONFIG_SYS_MAX_FLASH_SECT
;
41 flash_info
[i
].start
[0] = CONFIG_SYS_FLASH_BASE
+ (i
<< 20);
42 flash_info
[i
].size
= sect_sz_kb
[0];
43 for (j
= 1; j
< CONFIG_SYS_MAX_FLASH_SECT
; j
++) {
44 flash_info
[i
].start
[j
] = flash_info
[i
].start
[j
- 1]
45 + (sect_sz_kb
[j
- 1]);
46 flash_info
[i
].size
+= sect_sz_kb
[j
];
48 total_size
+= flash_info
[i
].size
;
54 void flash_print_info(flash_info_t
*info
)
58 if (info
->flash_id
== FLASH_UNKNOWN
) {
59 printf("missing or unknown FLASH type\n");
61 } else if (info
->flash_id
== FLASH_STM32
) {
62 printf("stm32 Embedded Flash\n");
65 printf(" Size: %ld MB in %d Sectors\n",
66 info
->size
>> 20, info
->sector_count
);
68 printf(" Sector Start Addresses:");
69 for (i
= 0; i
< info
->sector_count
; ++i
) {
74 info
->protect
[i
] ? " (RO)" : " ");
80 int flash_erase(flash_info_t
*info
, int first
, int last
)
85 for (i
= 0; i
< CONFIG_SYS_MAX_FLASH_BANKS
; i
++) {
86 if (info
== &flash_info
[i
]) {
96 for (i
= first
; i
<= last
; i
++) {
97 while (readl(&STM32_FLASH
->sr
) & STM32_FLASH_SR_BSY
)
100 /* clear old sector number before writing a new one */
101 clrbits_le32(&STM32_FLASH
->cr
, STM32_FLASH_CR_SNB_MASK
);
104 setbits_le32(&STM32_FLASH
->cr
,
105 (i
<< STM32_FLASH_CR_SNB_OFFSET
));
106 } else if (bank
== 1) {
107 setbits_le32(&STM32_FLASH
->cr
,
108 ((0x10 | i
) << STM32_FLASH_CR_SNB_OFFSET
));
113 setbits_le32(&STM32_FLASH
->cr
, STM32_FLASH_CR_SER
);
114 setbits_le32(&STM32_FLASH
->cr
, STM32_FLASH_CR_STRT
);
116 while (readl(&STM32_FLASH
->sr
) & STM32_FLASH_SR_BSY
)
119 clrbits_le32(&STM32_FLASH
->cr
, STM32_FLASH_CR_SER
);
126 int write_buff(flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
130 while (readl(&STM32_FLASH
->sr
) & STM32_FLASH_SR_BSY
)
135 setbits_le32(&STM32_FLASH
->cr
, STM32_FLASH_CR_PG
);
136 /* To make things simple use byte writes only */
137 for (i
= 0; i
< cnt
; i
++) {
138 *(uchar
*)(addr
+ i
) = src
[i
];
139 /* avoid re-ordering flash data write and busy status
140 * check as flash memory space attributes are generally Normal
143 while (readl(&STM32_FLASH
->sr
) & STM32_FLASH_SR_BSY
)
146 clrbits_le32(&STM32_FLASH
->cr
, STM32_FLASH_CR_PG
);