1 // SPDX-License-Identifier: GPL-2.0+
4 * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de
8 * this driver supports the enhanced embedded flash in the Atmel
9 * AT91SAM9XE devices with the following geometry:
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)
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.
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
29 * Note: Redundant environment will not work in this flash since
30 * it does use partial page writes. Make sure the environment spans
35 * optional TODOs (nice to have features):
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
47 #include <asm/arch/hardware.h>
48 #include <asm/arch/at91_common.h>
49 #include <asm/arch/at91_eefc.h>
50 #include <asm/arch/at91_dbu.h>
52 /* checks to detect configuration errors */
53 #if CONFIG_SYS_MAX_FLASH_BANKS!=1
54 #error eflash: this driver can only handle 1 bank
57 /* global structure */
58 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
61 unsigned long flash_init (void)
63 at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC;
64 at91_dbu_t *dbu = (at91_dbu_t *) ATMEL_BASE_DBGU;
65 u32 id, size, nplanes, planesize, nlocks;
68 debug("eflash: init\n");
70 flash_info[0].flash_id = FLASH_UNKNOWN;
72 /* check if its an AT91ARM9XE SoC */
73 if ((readl(&dbu->cidr) & AT91_DBU_CID_ARCH_MASK) != AT91_DBU_CID_ARCH_9XExx) {
74 puts("eflash: not an AT91SAM9XE\n");
78 /* now query the eflash for its structure */
79 writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GETD, &eefc->fcr);
80 while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
82 id = readl(&eefc->frr); /* word 0 */
83 size = readl(&eefc->frr); /* word 1 */
84 pagesize = readl(&eefc->frr); /* word 2 */
85 nplanes = readl(&eefc->frr); /* word 3 */
86 planesize = readl(&eefc->frr); /* word 4 */
87 debug("id=%08x size=%u pagesize=%u planes=%u planesize=%u\n",
88 id, size, pagesize, nplanes, planesize);
89 for (i=1; i<nplanes; i++) {
90 tmp = readl(&eefc->frr); /* words 5..4+nplanes-1 */
92 nlocks = readl(&eefc->frr); /* word 4+nplanes */
93 debug("nlocks=%u\n", nlocks);
94 /* since we are going to use the lock regions as sectors, check count */
95 if (nlocks > CONFIG_SYS_MAX_FLASH_SECT) {
96 printf("eflash: number of lock regions(%u) "\
97 "> CONFIG_SYS_MAX_FLASH_SECT. reducing...\n",
99 nlocks = CONFIG_SYS_MAX_FLASH_SECT;
101 flash_info[0].size = size;
102 flash_info[0].sector_count = nlocks;
103 flash_info[0].flash_id = id;
105 addr = ATMEL_BASE_FLASH;
106 for (i=0; i<nlocks; i++) {
107 tmp = readl(&eefc->frr); /* words 4+nplanes+1.. */
108 flash_info[0].start[i] = addr;
109 flash_info[0].protect[i] = 0;
113 /* now read the protection information for all regions */
114 writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr);
115 while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
117 for (i=0; i<flash_info[0].sector_count; i++) {
119 tmp = readl(&eefc->frr);
120 flash_info[0].protect[i] = (tmp >> (i%32)) & 1;
121 #if defined(CONFIG_EFLASH_PROTSECTORS)
122 if (i < CONFIG_EFLASH_PROTSECTORS)
123 flash_info[0].protect[i] = 1;
130 void flash_print_info (flash_info_t *info)
134 puts("AT91SAM9XE embedded flash\n Size: ");
135 print_size(info->size, " in ");
136 printf("%d Sectors\n", info->sector_count);
138 printf(" Sector Start Addresses:");
139 for (i=0; i<info->sector_count; ++i) {
144 info->protect[i] ? " (RO)" : " "
151 int flash_real_protect (flash_info_t *info, long sector, int prot)
153 at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC;
154 u32 pagenum = (info->start[sector]-ATMEL_BASE_FLASH)/pagesize;
157 debug("protect sector=%ld prot=%d\n", sector, prot);
159 #if defined(CONFIG_EFLASH_PROTSECTORS)
160 if (sector < CONFIG_EFLASH_PROTSECTORS) {
162 printf("eflash: sector %lu cannot be unprotected\n",
165 return 1; /* return anyway, caller does not care for result */
169 writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_SLB |
170 (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
172 writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_CLB |
173 (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
175 while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
177 /* now re-read the protection information for all regions */
178 writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr);
179 while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
181 for (i=0; i<info->sector_count; i++) {
183 tmp = readl(&eefc->frr);
184 info->protect[i] = (tmp >> (i%32)) & 1;
189 static u32 erase_write_page (u32 pagenum)
191 at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC;
193 debug("erase+write page=%u\n", pagenum);
195 /* give erase and write page command */
196 writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_EWP |
197 (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
198 while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
201 return readl(&eefc->fsr)
202 & (AT91_EEFC_FSR_FCMDE | AT91_EEFC_FSR_FLOCKE);
205 int flash_erase (flash_info_t *info, int s_first, int s_last)
207 debug("erase first=%d last=%d\n", s_first, s_last);
208 puts("this flash does not need and support erasing!\n");
213 * Copy memory to flash, returns:
218 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
224 debug("write src=%08lx addr=%08lx cnt=%lx\n",
225 (ulong)src, addr, cnt);
227 /* REQUIRE addr to be on a page start, abort if not */
228 if (addr % pagesize) {
229 printf ("eflash: start %08lx is not on page start\n"\
230 " write aborted\n", addr);
234 /* now start copying data */
235 pagenum = (addr-ATMEL_BASE_FLASH)/pagesize;
237 dst32 = (u32 *) addr;
240 /* fill page buffer */
244 if (erase_write_page(pagenum))