]> git.sur5r.net Git - u-boot/blob - drivers/mtd/stm32_flash.c
Merge branch 'master' of git://git.denx.de/u-boot-sunxi
[u-boot] / drivers / mtd / stm32_flash.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2015
4  * Kamil Lulko, <kamil.lulko@gmail.com>
5  */
6
7 #include <common.h>
8 #include <asm/io.h>
9 #include <asm/arch/stm32.h>
10 #include "stm32_flash.h"
11
12 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
13
14 #define STM32_FLASH     ((struct stm32_flash_regs *)STM32_FLASH_CNTL_BASE)
15
16 void stm32_flash_latency_cfg(int latency)
17 {
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);
21 }
22
23 static void stm32_flash_lock(u8 lock)
24 {
25         if (lock) {
26                 setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_LOCK);
27         } else {
28                 writel(STM32_FLASH_KEY1, &STM32_FLASH->key);
29                 writel(STM32_FLASH_KEY2, &STM32_FLASH->key);
30         }
31 }
32
33 unsigned long flash_init(void)
34 {
35         unsigned long total_size = 0;
36         u8 i, j;
37
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];
47                 }
48                 total_size += flash_info[i].size;
49         }
50
51         return total_size;
52 }
53
54 void flash_print_info(flash_info_t *info)
55 {
56         int i;
57
58         if (info->flash_id == FLASH_UNKNOWN) {
59                 printf("missing or unknown FLASH type\n");
60                 return;
61         } else if (info->flash_id == FLASH_STM32) {
62                 printf("stm32 Embedded Flash\n");
63         }
64
65         printf("  Size: %ld MB in %d Sectors\n",
66                info->size >> 20, info->sector_count);
67
68         printf("  Sector Start Addresses:");
69         for (i = 0; i < info->sector_count; ++i) {
70                 if ((i % 5) == 0)
71                         printf("\n   ");
72                 printf(" %08lX%s",
73                        info->start[i],
74                         info->protect[i] ? " (RO)" : "     ");
75         }
76         printf("\n");
77         return;
78 }
79
80 int flash_erase(flash_info_t *info, int first, int last)
81 {
82         u8 bank = 0xFF;
83         int i;
84
85         for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
86                 if (info == &flash_info[i]) {
87                         bank = i;
88                         break;
89                 }
90         }
91         if (bank == 0xFF)
92                 return -1;
93
94         stm32_flash_lock(0);
95
96         for (i = first; i <= last; i++) {
97                 while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY)
98                         ;
99
100                 /* clear old sector number before writing a new one */
101                 clrbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_SNB_MASK);
102
103                 if (bank == 0) {
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));
109                 } else {
110                         stm32_flash_lock(1);
111                         return -1;
112                 }
113                 setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_SER);
114                 setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_STRT);
115
116                 while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY)
117                         ;
118
119                 clrbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_SER);
120         }
121
122         stm32_flash_lock(1);
123         return 0;
124 }
125
126 int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
127 {
128         ulong i;
129
130         while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY)
131                 ;
132
133         stm32_flash_lock(0);
134
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
141                  */
142                 mb();
143                 while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY)
144                         ;
145         }
146         clrbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_PG);
147         stm32_flash_lock(1);
148
149         return 0;
150 }