Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / arch / arm / mach-at91 / arm926ejs / eflash.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2010
4  * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de
5  */
6
7 /*
8  * this driver supports the enhanced embedded flash in the Atmel
9  * AT91SAM9XE devices with the following geometry:
10  *
11  * AT91SAM9XE128: 1 plane of  8 regions of 32 pages (total  256 pages)
12  * AT91SAM9XE256: 1 plane of 16 regions of 32 pages (total  512 pages)
13  * AT91SAM9XE512: 1 plane of 32 regions of 32 pages (total 1024 pages)
14  * (the exact geometry is read from the flash at runtime, so any
15  *  future devices should already be covered)
16  *
17  * Regions can be write/erase protected.
18  * Whole (!) pages can be individually written with erase on the fly.
19  * Writing partial pages will corrupt the rest of the page.
20  *
21  * The flash is presented to u-boot with each region being a sector,
22  * having the following effects:
23  * Each sector can be hardware protected (protect on/off).
24  * Each page in a sector can be rewritten anytime.
25  * Since pages are erased when written, the "erase" does nothing.
26  * The first "CONFIG_EFLASH_PROTSECTORS" cannot be unprotected
27  * by u-Boot commands.
28  *
29  * Note: Redundant environment will not work in this flash since
30  * it does use partial page writes. Make sure the environment spans
31  * whole pages!
32  */
33
34 /*
35  * optional TODOs (nice to have features):
36  *
37  * make the driver coexist with other NOR flash drivers
38  *      (use an index into flash_info[], requires work
39  *      in those other drivers, too)
40  * Make the erase command fill the sectors with 0xff
41  *      (if the flashes grow larger in the future and
42  *      someone puts a jffs2 into them)
43  * do a read-modify-write for partially programmed pages
44  */
45 #include <common.h>
46 #include <flash.h>
47 #include <log.h>
48 #include <asm/io.h>
49 #include <asm/arch/hardware.h>
50 #include <asm/arch/at91_common.h>
51 #include <asm/arch/at91_eefc.h>
52 #include <asm/arch/at91_dbu.h>
53
54 /* checks to detect configuration errors */
55 #if CONFIG_SYS_MAX_FLASH_BANKS!=1
56 #error eflash: this driver can only handle 1 bank
57 #endif
58
59 /* global structure */
60 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
61 static u32 pagesize;
62
63 unsigned long flash_init(void)
64 {
65         at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC;
66         at91_dbu_t *dbu = (at91_dbu_t *) ATMEL_BASE_DBGU;
67         u32 id, size, nplanes, planesize, nlocks;
68         u32 addr, i, tmp=0;
69
70         debug("eflash: init\n");
71
72         flash_info[0].flash_id = FLASH_UNKNOWN;
73
74         /* check if its an AT91ARM9XE SoC */
75         if ((readl(&dbu->cidr) & AT91_DBU_CID_ARCH_MASK) != AT91_DBU_CID_ARCH_9XExx) {
76                 puts("eflash: not an AT91SAM9XE\n");
77                 return 0;
78         }
79
80         /* now query the eflash for its structure */
81         writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GETD, &eefc->fcr);
82         while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
83                 ;
84         id = readl(&eefc->frr);         /* word 0 */
85         size = readl(&eefc->frr);       /* word 1 */
86         pagesize = readl(&eefc->frr);   /* word 2 */
87         nplanes = readl(&eefc->frr);    /* word 3 */
88         planesize = readl(&eefc->frr);  /* word 4 */
89         debug("id=%08x size=%u pagesize=%u planes=%u planesize=%u\n",
90                 id, size, pagesize, nplanes, planesize);
91         for (i=1; i<nplanes; i++) {
92                 tmp = readl(&eefc->frr);        /* words 5..4+nplanes-1 */
93         };
94         nlocks = readl(&eefc->frr);     /* word 4+nplanes */
95         debug("nlocks=%u\n", nlocks);
96         /* since we are going to use the lock regions as sectors, check count */
97         if (nlocks > CONFIG_SYS_MAX_FLASH_SECT) {
98                 printf("eflash: number of lock regions(%u) "\
99                         "> CONFIG_SYS_MAX_FLASH_SECT. reducing...\n",
100                         nlocks);
101                 nlocks = CONFIG_SYS_MAX_FLASH_SECT;
102         }
103         flash_info[0].size = size;
104         flash_info[0].sector_count = nlocks;
105         flash_info[0].flash_id = id;
106
107         addr = ATMEL_BASE_FLASH;
108         for (i=0; i<nlocks; i++) {
109                 tmp = readl(&eefc->frr);        /* words 4+nplanes+1.. */
110                 flash_info[0].start[i] = addr;
111                 flash_info[0].protect[i] = 0;
112                 addr += tmp;
113         };
114
115         /* now read the protection information for all regions */
116         writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr);
117         while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
118                 ;
119         for (i=0; i<flash_info[0].sector_count; i++) {
120                 if (i%32 == 0)
121                         tmp = readl(&eefc->frr);
122                 flash_info[0].protect[i] = (tmp >> (i%32)) & 1;
123 #if defined(CONFIG_EFLASH_PROTSECTORS)
124                 if (i < CONFIG_EFLASH_PROTSECTORS)
125                         flash_info[0].protect[i] = 1;
126 #endif
127         }
128
129         return size;
130 }
131
132 void flash_print_info(flash_info_t *info)
133 {
134         int i;
135
136         puts("AT91SAM9XE embedded flash\n  Size: ");
137         print_size(info->size, " in ");
138         printf("%d Sectors\n", info->sector_count);
139
140         printf("  Sector Start Addresses:");
141         for (i=0; i<info->sector_count; ++i) {
142                 if ((i % 5) == 0)
143                         printf("\n   ");
144                 printf(" %08lX%s",
145                         info->start[i],
146                         info->protect[i] ? " (RO)" : "     "
147                 );
148         }
149         printf ("\n");
150         return;
151 }
152
153 int flash_real_protect (flash_info_t *info, long sector, int prot)
154 {
155         at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC;
156         u32 pagenum = (info->start[sector]-ATMEL_BASE_FLASH)/pagesize;
157         u32 i, tmp=0;
158
159         debug("protect sector=%ld prot=%d\n", sector, prot);
160
161 #if defined(CONFIG_EFLASH_PROTSECTORS)
162         if (sector < CONFIG_EFLASH_PROTSECTORS) {
163                 if (!prot) {
164                         printf("eflash: sector %lu cannot be unprotected\n",
165                                 sector);
166                 }
167                 return 1; /* return anyway, caller does not care for result */
168         }
169 #endif
170         if (prot) {
171                 writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_SLB |
172                         (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
173         } else {
174                 writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_CLB |
175                         (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
176         }
177         while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
178                 ;
179         /* now re-read the protection information for all regions */
180         writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr);
181         while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
182                 ;
183         for (i=0; i<info->sector_count; i++) {
184                 if (i%32 == 0)
185                         tmp = readl(&eefc->frr);
186                 info->protect[i] = (tmp >> (i%32)) & 1;
187         }
188         return 0;
189 }
190
191 static u32 erase_write_page (u32 pagenum)
192 {
193         at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC;
194
195         debug("erase+write page=%u\n", pagenum);
196
197         /* give erase and write page command */
198         writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_EWP |
199                 (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
200         while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
201                 ;
202         /* return status */
203         return readl(&eefc->fsr)
204                 & (AT91_EEFC_FSR_FCMDE | AT91_EEFC_FSR_FLOCKE);
205 }
206
207 int flash_erase(flash_info_t *info, int s_first, int s_last)
208 {
209         debug("erase first=%d last=%d\n", s_first, s_last);
210         puts("this flash does not need and support erasing!\n");
211         return 0;
212 }
213
214 /*
215  * Copy memory to flash, returns:
216  * 0 - OK
217  * 1 - write timeout
218  */
219
220 int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
221 {
222         u32 pagenum;
223         u32 *src32, *dst32;
224         u32 i;
225
226         debug("write src=%08lx addr=%08lx cnt=%lx\n",
227                 (ulong)src, addr, cnt);
228
229         /* REQUIRE addr to be on a page start, abort if not */
230         if (addr % pagesize) {
231                 printf ("eflash: start %08lx is not on page start\n"\
232                         "        write aborted\n", addr);
233                 return 1;
234         }
235
236         /* now start copying data */
237         pagenum = (addr-ATMEL_BASE_FLASH)/pagesize;
238         src32 = (u32 *) src;
239         dst32 = (u32 *) addr;
240         while (cnt > 0) {
241                 i = pagesize / 4;
242                 /* fill page buffer */
243                 while (i--)
244                         *dst32++ = *src32++;
245                 /* write page */
246                 if (erase_write_page(pagenum))
247                         return 1;
248                 pagenum++;
249                 if (cnt > pagesize)
250                         cnt -= pagesize;
251                 else
252                         cnt = 0;
253         }
254         return 0;
255 }