3 * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de
5 * SPDX-License-Identifier: GPL-2.0+
9 * this driver supports the enhanced embedded flash in the Atmel
10 * AT91SAM9XE devices with the following geometry:
12 * AT91SAM9XE128: 1 plane of 8 regions of 32 pages (total 256 pages)
13 * AT91SAM9XE256: 1 plane of 16 regions of 32 pages (total 512 pages)
14 * AT91SAM9XE512: 1 plane of 32 regions of 32 pages (total 1024 pages)
15 * (the exact geometry is read from the flash at runtime, so any
16 * future devices should already be covered)
18 * Regions can be write/erase protected.
19 * Whole (!) pages can be individually written with erase on the fly.
20 * Writing partial pages will corrupt the rest of the page.
22 * The flash is presented to u-boot with each region being a sector,
23 * having the following effects:
24 * Each sector can be hardware protected (protect on/off).
25 * Each page in a sector can be rewritten anytime.
26 * Since pages are erased when written, the "erase" does nothing.
27 * The first "CONFIG_EFLASH_PROTSECTORS" cannot be unprotected
30 * Note: Redundant environment will not work in this flash since
31 * it does use partial page writes. Make sure the environment spans
36 * optional TODOs (nice to have features):
38 * make the driver coexist with other NOR flash drivers
39 * (use an index into flash_info[], requires work
40 * in those other drivers, too)
41 * Make the erase command fill the sectors with 0xff
42 * (if the flashes grow larger in the future and
43 * someone puts a jffs2 into them)
44 * do a read-modify-write for partially programmed pages
48 #include <asm/arch/hardware.h>
49 #include <asm/arch/at91_common.h>
50 #include <asm/arch/at91_eefc.h>
51 #include <asm/arch/at91_dbu.h>
53 /* checks to detect configuration errors */
54 #if CONFIG_SYS_MAX_FLASH_BANKS!=1
55 #error eflash: this driver can only handle 1 bank
58 /* global structure */
59 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
];
62 unsigned long flash_init (void)
64 at91_eefc_t
*eefc
= (at91_eefc_t
*) ATMEL_BASE_EEFC
;
65 at91_dbu_t
*dbu
= (at91_dbu_t
*) ATMEL_BASE_DBGU
;
66 u32 id
, size
, nplanes
, planesize
, nlocks
;
69 debug("eflash: init\n");
71 flash_info
[0].flash_id
= FLASH_UNKNOWN
;
73 /* check if its an AT91ARM9XE SoC */
74 if ((readl(&dbu
->cidr
) & AT91_DBU_CID_ARCH_MASK
) != AT91_DBU_CID_ARCH_9XExx
) {
75 puts("eflash: not an AT91SAM9XE\n");
79 /* now query the eflash for its structure */
80 writel(AT91_EEFC_FCR_KEY
| AT91_EEFC_FCR_FCMD_GETD
, &eefc
->fcr
);
81 while ((readl(&eefc
->fsr
) & AT91_EEFC_FSR_FRDY
) == 0)
83 id
= readl(&eefc
->frr
); /* word 0 */
84 size
= readl(&eefc
->frr
); /* word 1 */
85 pagesize
= readl(&eefc
->frr
); /* word 2 */
86 nplanes
= readl(&eefc
->frr
); /* word 3 */
87 planesize
= readl(&eefc
->frr
); /* word 4 */
88 debug("id=%08x size=%u pagesize=%u planes=%u planesize=%u\n",
89 id
, size
, pagesize
, nplanes
, planesize
);
90 for (i
=1; i
<nplanes
; i
++) {
91 tmp
= readl(&eefc
->frr
); /* words 5..4+nplanes-1 */
93 nlocks
= readl(&eefc
->frr
); /* word 4+nplanes */
94 debug("nlocks=%u\n", nlocks
);
95 /* since we are going to use the lock regions as sectors, check count */
96 if (nlocks
> CONFIG_SYS_MAX_FLASH_SECT
) {
97 printf("eflash: number of lock regions(%u) "\
98 "> CONFIG_SYS_MAX_FLASH_SECT. reducing...\n",
100 nlocks
= CONFIG_SYS_MAX_FLASH_SECT
;
102 flash_info
[0].size
= size
;
103 flash_info
[0].sector_count
= nlocks
;
104 flash_info
[0].flash_id
= id
;
106 addr
= ATMEL_BASE_FLASH
;
107 for (i
=0; i
<nlocks
; i
++) {
108 tmp
= readl(&eefc
->frr
); /* words 4+nplanes+1.. */
109 flash_info
[0].start
[i
] = addr
;
110 flash_info
[0].protect
[i
] = 0;
114 /* now read the protection information for all regions */
115 writel(AT91_EEFC_FCR_KEY
| AT91_EEFC_FCR_FCMD_GLB
, &eefc
->fcr
);
116 while ((readl(&eefc
->fsr
) & AT91_EEFC_FSR_FRDY
) == 0)
118 for (i
=0; i
<flash_info
[0].sector_count
; i
++) {
120 tmp
= readl(&eefc
->frr
);
121 flash_info
[0].protect
[i
] = (tmp
>> (i
%32)) & 1;
122 #if defined(CONFIG_EFLASH_PROTSECTORS)
123 if (i
< CONFIG_EFLASH_PROTSECTORS
)
124 flash_info
[0].protect
[i
] = 1;
131 void flash_print_info (flash_info_t
*info
)
135 puts("AT91SAM9XE embedded flash\n Size: ");
136 print_size(info
->size
, " in ");
137 printf("%d Sectors\n", info
->sector_count
);
139 printf(" Sector Start Addresses:");
140 for (i
=0; i
<info
->sector_count
; ++i
) {
145 info
->protect
[i
] ? " (RO)" : " "
152 int flash_real_protect (flash_info_t
*info
, long sector
, int prot
)
154 at91_eefc_t
*eefc
= (at91_eefc_t
*) ATMEL_BASE_EEFC
;
155 u32 pagenum
= (info
->start
[sector
]-ATMEL_BASE_FLASH
)/pagesize
;
158 debug("protect sector=%ld prot=%d\n", sector
, prot
);
160 #if defined(CONFIG_EFLASH_PROTSECTORS)
161 if (sector
< CONFIG_EFLASH_PROTSECTORS
) {
163 printf("eflash: sector %lu cannot be unprotected\n",
166 return 1; /* return anyway, caller does not care for result */
170 writel(AT91_EEFC_FCR_KEY
| AT91_EEFC_FCR_FCMD_SLB
|
171 (pagenum
<< AT91_EEFC_FCR_FARG_SHIFT
), &eefc
->fcr
);
173 writel(AT91_EEFC_FCR_KEY
| AT91_EEFC_FCR_FCMD_CLB
|
174 (pagenum
<< AT91_EEFC_FCR_FARG_SHIFT
), &eefc
->fcr
);
176 while ((readl(&eefc
->fsr
) & AT91_EEFC_FSR_FRDY
) == 0)
178 /* now re-read the protection information for all regions */
179 writel(AT91_EEFC_FCR_KEY
| AT91_EEFC_FCR_FCMD_GLB
, &eefc
->fcr
);
180 while ((readl(&eefc
->fsr
) & AT91_EEFC_FSR_FRDY
) == 0)
182 for (i
=0; i
<info
->sector_count
; i
++) {
184 tmp
= readl(&eefc
->frr
);
185 info
->protect
[i
] = (tmp
>> (i
%32)) & 1;
190 static u32
erase_write_page (u32 pagenum
)
192 at91_eefc_t
*eefc
= (at91_eefc_t
*) ATMEL_BASE_EEFC
;
194 debug("erase+write page=%u\n", pagenum
);
196 /* give erase and write page command */
197 writel(AT91_EEFC_FCR_KEY
| AT91_EEFC_FCR_FCMD_EWP
|
198 (pagenum
<< AT91_EEFC_FCR_FARG_SHIFT
), &eefc
->fcr
);
199 while ((readl(&eefc
->fsr
) & AT91_EEFC_FSR_FRDY
) == 0)
202 return readl(&eefc
->fsr
)
203 & (AT91_EEFC_FSR_FCMDE
| AT91_EEFC_FSR_FLOCKE
);
206 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
208 debug("erase first=%d last=%d\n", s_first
, s_last
);
209 puts("this flash does not need and support erasing!\n");
214 * Copy memory to flash, returns:
219 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
225 debug("write src=%08lx addr=%08lx cnt=%lx\n",
226 (ulong
)src
, addr
, cnt
);
228 /* REQUIRE addr to be on a page start, abort if not */
229 if (addr
% pagesize
) {
230 printf ("eflash: start %08lx is not on page start\n"\
231 " write aborted\n", addr
);
235 /* now start copying data */
236 pagenum
= (addr
-ATMEL_BASE_FLASH
)/pagesize
;
238 dst32
= (u32
*) addr
;
241 /* fill page buffer */
245 if (erase_write_page(pagenum
))