3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * SPDX-License-Identifier: GPL-2.0+
9 #include <board/cogent/flash.h>
10 #include <linux/compiler.h>
12 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
]; /* info for FLASH chips */
14 #if defined(CONFIG_ENV_IS_IN_FLASH)
15 # ifndef CONFIG_ENV_ADDR
16 # define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
18 # ifndef CONFIG_ENV_SIZE
19 # define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE
21 # ifndef CONFIG_ENV_SECT_SIZE
22 # define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE
26 /*-----------------------------------------------------------------------
29 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
);
31 /*-----------------------------------------------------------------------
35 #if defined(CONFIG_CMA302)
38 * probe for the existence of flash at address "addr"
39 * 0 = yes, 1 = bad Manufacturer's Id, 2 = bad Device Id
42 c302f_probe_word(c302f_addr_t addr
)
45 *addr
= C302F_BNK_CMD_RST
;
47 /* check the manufacturer id */
48 *addr
= C302F_BNK_CMD_RD_ID
;
49 if (*C302F_BNK_ADDR_MAN(addr
) != C302F_BNK_RD_ID_MAN
)
52 /* check the device id */
53 *addr
= C302F_BNK_CMD_RD_ID
;
54 if (*C302F_BNK_ADDR_DEV(addr
) != C302F_BNK_RD_ID_DEV
)
61 printf("\nMaster Lock Config = 0x%08lx\n",
62 *C302F_BNK_ADDR_CFGM(addr
));
63 for (i
= 0; i
< C302F_BNK_NBLOCKS
; i
++)
64 printf("Block %2d Lock Config = 0x%08lx\n",
65 i
, *C302F_BNK_ADDR_CFG(i
, addr
));
69 /* reset the flash again */
70 *addr
= C302F_BNK_CMD_RST
;
76 * probe for Cogent CMA302 flash module at address "base" and store
77 * info for any found into flash_info entry "fip". Must find at least
81 c302f_probe(flash_info_t
*fip
, c302f_addr_t base
)
83 c302f_addr_t addr
, eaddr
;
87 fip
->sector_count
= 0;
90 eaddr
= C302F_BNK_ADDR_BASE(addr
, C302F_MAX_BANKS
);
93 while (addr
< eaddr
) {
94 c302f_addr_t addrw
, eaddrw
, addrb
;
98 eaddrw
= C302F_BNK_ADDR_NEXT_WORD(addrw
);
100 while (addrw
< eaddrw
)
101 if (c302f_probe_word(addrw
++) != 0)
104 /* bank exists - append info for this bank to *fip */
105 fip
->flash_id
= FLASH_MAN_INTEL
|FLASH_28F008S5
;
106 fip
->size
+= C302F_BNK_SIZE
;
107 osc
= fip
->sector_count
;
108 fip
->sector_count
+= C302F_BNK_NBLOCKS
;
109 if ((nsc
= fip
->sector_count
) >= CONFIG_SYS_MAX_FLASH_SECT
)
110 panic("Too many sectors in flash at address 0x%08lx\n",
111 (unsigned long)base
);
114 for (i
= osc
; i
< nsc
; i
++) {
115 fip
->start
[i
] = (ulong
)addrb
;
117 addrb
= C302F_BNK_ADDR_NEXT_BLK(addrb
);
120 addr
= C302F_BNK_ADDR_NEXT_BNK(addr
);
126 panic("ERROR: no flash found at address 0x%08lx\n",
127 (unsigned long)base
);
131 c302f_reset(flash_info_t
*info
, int sect
)
133 c302f_addr_t addrw
, eaddrw
;
135 addrw
= (c302f_addr_t
)info
->start
[sect
];
136 eaddrw
= C302F_BNK_ADDR_NEXT_WORD(addrw
);
138 while (addrw
< eaddrw
) {
140 printf(" writing reset cmd to addr 0x%08lx\n",
141 (unsigned long)addrw
);
143 *addrw
= C302F_BNK_CMD_RST
;
149 c302f_erase_init(flash_info_t
*info
, int sect
)
151 c302f_addr_t addrw
, saddrw
, eaddrw
;
155 printf("0x%08lx C302F_BNK_CMD_PROG\n", C302F_BNK_CMD_PROG
);
156 printf("0x%08lx C302F_BNK_CMD_ERASE1\n", C302F_BNK_CMD_ERASE1
);
157 printf("0x%08lx C302F_BNK_CMD_ERASE2\n", C302F_BNK_CMD_ERASE2
);
158 printf("0x%08lx C302F_BNK_CMD_CLR_STAT\n", C302F_BNK_CMD_CLR_STAT
);
159 printf("0x%08lx C302F_BNK_CMD_RST\n", C302F_BNK_CMD_RST
);
160 printf("0x%08lx C302F_BNK_STAT_RDY\n", C302F_BNK_STAT_RDY
);
161 printf("0x%08lx C302F_BNK_STAT_ERR\n", C302F_BNK_STAT_ERR
);
164 saddrw
= (c302f_addr_t
)info
->start
[sect
];
165 eaddrw
= C302F_BNK_ADDR_NEXT_WORD(saddrw
);
168 printf("erasing sector %d, start addr = 0x%08lx "
169 "(bank next word addr = 0x%08lx)\n", sect
,
170 (unsigned long)saddrw
, (unsigned long)eaddrw
);
173 /* Disable intrs which might cause a timeout here */
174 flag
= disable_interrupts();
176 for (addrw
= saddrw
; addrw
< eaddrw
; addrw
++) {
178 printf(" writing erase cmd to addr 0x%08lx\n",
179 (unsigned long)addrw
);
181 *addrw
= C302F_BNK_CMD_ERASE1
;
182 *addrw
= C302F_BNK_CMD_ERASE2
;
185 /* re-enable interrupts if necessary */
191 c302f_erase_poll(flash_info_t
*info
, int sect
)
193 c302f_addr_t addrw
, saddrw
, eaddrw
;
194 int sectdone
, haderr
;
196 saddrw
= (c302f_addr_t
)info
->start
[sect
];
197 eaddrw
= C302F_BNK_ADDR_NEXT_WORD(saddrw
);
202 for (addrw
= saddrw
; addrw
< eaddrw
; addrw
++) {
203 c302f_word_t stat
= *addrw
;
206 printf(" checking status at addr "
207 "0x%08lx [0x%08lx]\n",
208 (unsigned long)addrw
, stat
);
210 if ((stat
& C302F_BNK_STAT_RDY
) != C302F_BNK_STAT_RDY
)
212 else if ((stat
& C302F_BNK_STAT_ERR
) != 0) {
213 printf(" failed on sector %d "
214 "(stat = 0x%08lx) at "
217 (unsigned long)addrw
);
218 *addrw
= C302F_BNK_CMD_CLR_STAT
;
230 c302f_write_word(c302f_addr_t addr
, c302f_word_t value
)
236 /* Disable interrupts which might cause a timeout here */
237 flag
= disable_interrupts();
239 *addr
= C302F_BNK_CMD_PROG
;
243 /* re-enable interrupts if necessary */
249 /* data polling for D7 */
250 start
= get_timer (0);
252 if (get_timer(start
) > CONFIG_SYS_FLASH_WRITE_TOUT
) {
257 } while ((stat
& C302F_BNK_STAT_RDY
) != C302F_BNK_STAT_RDY
);
259 if ((stat
& C302F_BNK_STAT_ERR
) != 0) {
260 printf("flash program failed (stat = 0x%08lx) "
261 "at address 0x%08lx\n", (ulong
)stat
, (ulong
)addr
);
262 *addr
= C302F_BNK_CMD_CLR_STAT
;
267 /* reset to read mode */
268 *addr
= C302F_BNK_CMD_RST
;
273 #endif /* CONFIG_CMA302 */
280 __maybe_unused flash_info_t
*fip
;
282 /* Init: no FLASHes known */
283 for (i
=0; i
<CONFIG_SYS_MAX_FLASH_BANKS
; ++i
) {
284 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
287 fip
= &flash_info
[0];
290 #if defined(CONFIG_CMA302)
291 c302f_probe(fip
, (c302f_addr_t
)CONFIG_SYS_FLASH_BASE
);
296 #if (CMA_MB_CAPS & CMA_MB_CAP_FLASH)
298 cmbf_probe(fip, (cmbf_addr_t)CMA_MB_FLASH_BASE);
305 * protect monitor and environment sectors
308 #if CONFIG_SYS_MONITOR_BASE == CONFIG_SYS_FLASH_BASE
309 flash_protect(FLAG_PROTECT_SET
,
310 CONFIG_SYS_MONITOR_BASE
,
311 CONFIG_SYS_MONITOR_BASE
+monitor_flash_len
-1,
315 #ifdef CONFIG_ENV_IS_IN_FLASH
316 /* ENV protection ON by default */
317 flash_protect(FLAG_PROTECT_SET
,
319 CONFIG_ENV_ADDR
+CONFIG_ENV_SECT_SIZE
-1,
325 /*-----------------------------------------------------------------------
328 flash_print_info(flash_info_t
*info
)
332 if (info
->flash_id
== FLASH_UNKNOWN
) {
333 printf ("missing or unknown FLASH type\n");
337 switch (info
->flash_id
& FLASH_VENDMASK
) {
338 case FLASH_MAN_INTEL
: printf ("INTEL "); break;
339 default: printf ("Unknown Vendor "); break;
342 switch (info
->flash_id
& FLASH_TYPEMASK
) {
343 case FLASH_28F008S5
: printf ("28F008S5\n");
345 default: printf ("Unknown Chip Type\n");
349 printf (" Size: %ld MB in %d Sectors\n",
350 info
->size
>> 20, info
->sector_count
);
352 printf (" Sector Start Addresses:");
353 for (i
=0; i
<info
->sector_count
; ++i
) {
356 printf (" %2d - %08lX%s", i
,
358 info
->protect
[i
] ? " (RO)" : " "
365 /*-----------------------------------------------------------------------
369 /*-----------------------------------------------------------------------
373 * The following code cannot be run from FLASH!
377 flash_erase(flash_info_t
*info
, int s_first
, int s_last
)
379 int prot
, sect
, haderr
;
380 ulong start
, now
, last
;
381 void (*erase_init
)(flash_info_t
*, int);
382 int (*erase_poll
)(flash_info_t
*, int);
383 void (*reset
)(flash_info_t
*, int);
387 printf("\nflash_erase: erase %d sectors (%d to %d incl.) from\n"
388 " Bank # %d: ", s_last
- s_first
+ 1, s_first
, s_last
,
389 (info
- flash_info
) + 1);
390 flash_print_info(info
);
393 if ((s_first
< 0) || (s_first
> s_last
)) {
394 if (info
->flash_id
== FLASH_UNKNOWN
) {
395 printf ("- missing\n");
397 printf ("- no sectors to erase\n");
402 switch (info
->flash_id
) {
404 #if defined(CONFIG_CMA302)
405 case FLASH_MAN_INTEL
|FLASH_28F008S5
:
406 erase_init
= c302f_erase_init
;
407 erase_poll
= c302f_erase_poll
;
412 #if (CMA_MB_CAPS & CMA_MB_CAP_FLASH)
413 case FLASH_MAN_INTEL
|FLASH_28F800_B
:
414 case FLASH_MAN_AMD
|FLASH_AM29F800B
:
416 erase_init = cmbf_erase_init;
417 erase_poll = cmbf_erase_poll;
424 printf ("Flash type %08lx not supported - aborted\n",
430 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
431 if (info
->protect
[sect
]) {
437 printf("- Warning: %d protected sector%s will not be erased!\n",
438 prot
, (prot
> 1 ? "s" : ""));
441 start
= get_timer (0);
445 for (sect
= s_first
; sect
<= s_last
; sect
++) {
446 if (info
->protect
[sect
] == 0) { /* not protected */
450 (*erase_init
)(info
, sect
);
452 /* wait at least 80us - let's wait 1 ms */
455 estart
= get_timer(start
);
458 now
= get_timer(start
);
460 if (now
- estart
> CONFIG_SYS_FLASH_ERASE_TOUT
) {
461 printf ("Timeout (sect %d)\n", sect
);
467 /* show that we're waiting */
468 if ((now
- last
) > 1000) { /* every second */
474 sectdone
= (*erase_poll
)(info
, sect
);
489 printf (" failed\n");
495 /* reset to read mode */
496 for (sect
= s_first
; sect
<= s_last
; sect
++) {
497 if (info
->protect
[sect
] == 0) { /* not protected */
498 (*reset
)(info
, sect
);
504 /*-----------------------------------------------------------------------
505 * Copy memory to flash, returns:
508 * 2 - Flash not erased
513 write_buff(flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
517 ulong start
, now
, last
;
519 wp
= (addr
& ~3); /* get lower word aligned address */
522 * handle unaligned start bytes
524 if ((l
= addr
- wp
) != 0) {
526 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
527 data
= (data
<< 8) | (*(uchar
*)cp
);
529 for (; i
<4 && cnt
>0; ++i
) {
530 data
= (data
<< 8) | *src
++;
534 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
535 data
= (data
<< 8) | (*(uchar
*)cp
);
538 if ((rc
= write_word(info
, wp
, data
)) != 0) {
545 * handle word aligned part
547 start
= get_timer (0);
551 for (i
=0; i
<4; ++i
) {
552 data
= (data
<< 8) | *src
++;
554 if ((rc
= write_word(info
, wp
, data
)) != 0) {
560 /* show that we're waiting */
561 now
= get_timer(start
);
562 if ((now
- last
) > 1000) { /* every second */
573 * handle unaligned tail bytes
576 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
577 data
= (data
<< 8) | *src
++;
580 for (; i
<4; ++i
, ++cp
) {
581 data
= (data
<< 8) | (*(uchar
*)cp
);
584 return (write_word(info
, wp
, data
));
587 /*-----------------------------------------------------------------------
588 * Write a word to Flash, returns:
591 * 2 - Flash not erased
595 write_word(flash_info_t
*info
, ulong dest
, ulong data
)
599 /* Check if Flash is (sufficiently) erased */
600 if ((*(ulong
*)dest
& data
) != data
) {
604 switch (info
->flash_id
) {
606 #if defined(CONFIG_CMA302)
607 case FLASH_MAN_INTEL
|FLASH_28F008S5
:
608 retval
= c302f_write_word((c302f_addr_t
)dest
, (c302f_word_t
)data
);
612 #if (CMA_MB_CAPS & CMA_MB_CAP_FLASH)
613 case FLASH_MAN_INTEL
|FLASH_28F800_B
:
614 case FLASH_MAN_AMD
|FLASH_AM29F800B
:
616 retval = cmbf_write_word((cmbf_addr_t)dest, (cmbf_word_t)data);
623 printf ("Flash type %08lx not supported - aborted\n",
632 /*-----------------------------------------------------------------------