1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2009 by Michael Sparmann
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
29 #include "nand-target.h"
30 #include <pmu-target.h>
34 #include "ata_idle_notify.h"
37 #define NAND_CMD_READ 0x00
38 #define NAND_CMD_PROGCNFRM 0x10
39 #define NAND_CMD_READ2 0x30
40 #define NAND_CMD_BLOCKERASE 0x60
41 #define NAND_CMD_GET_STATUS 0x70
42 #define NAND_CMD_PROGRAM 0x80
43 #define NAND_CMD_ERASECNFRM 0xD0
44 #define NAND_CMD_RESET 0xFF
46 #define NAND_STATUS_READY 0x40
48 #define NAND_DEVICEINFOTABLE_ENTRIES 33
50 static const struct nand_device_info_type nand_deviceinfotable
[] =
52 {0x1580F1EC, 1024, 968, 0x40, 6, 2, 1, 2, 1},
53 {0x1580DAEC, 2048, 1936, 0x40, 6, 2, 1, 2, 1},
54 {0x15C1DAEC, 2048, 1936, 0x40, 6, 2, 1, 2, 1},
55 {0x1510DCEC, 4096, 3872, 0x40, 6, 2, 1, 2, 1},
56 {0x95C1DCEC, 4096, 3872, 0x40, 6, 2, 1, 2, 1},
57 {0x2514DCEC, 2048, 1936, 0x80, 7, 2, 1, 2, 1},
58 {0x2514D3EC, 4096, 3872, 0x80, 7, 2, 1, 2, 1},
59 {0x2555D3EC, 4096, 3872, 0x80, 7, 2, 1, 2, 1},
60 {0x2555D5EC, 8192, 7744, 0x80, 7, 2, 1, 2, 1},
61 {0x2585D3AD, 4096, 3872, 0x80, 7, 3, 2, 3, 2},
62 {0x9580DCAD, 4096, 3872, 0x40, 6, 3, 2, 3, 2},
63 {0xA514D3AD, 4096, 3872, 0x80, 7, 3, 2, 3, 2},
64 {0xA550D3AD, 4096, 3872, 0x80, 7, 3, 2, 3, 2},
65 {0xA560D5AD, 4096, 3872, 0x80, 7, 3, 2, 3, 2},
66 {0xA555D5AD, 8192, 7744, 0x80, 7, 3, 2, 3, 2},
67 {0xA585D598, 8320, 7744, 0x80, 7, 3, 1, 2, 1},
68 {0xA584D398, 4160, 3872, 0x80, 7, 3, 1, 2, 1},
69 {0x95D1D32C, 8192, 7744, 0x40, 6, 2, 1, 2, 1},
70 {0x1580DC2C, 4096, 3872, 0x40, 6, 2, 1, 2, 1},
71 {0x15C1D32C, 8192, 7744, 0x40, 6, 2, 1, 2, 1},
72 {0x9590DC2C, 4096, 3872, 0x40, 6, 2, 1, 2, 1},
73 {0xA594D32C, 4096, 3872, 0x80, 7, 2, 1, 2, 1},
74 {0x2584DC2C, 2048, 1936, 0x80, 7, 2, 1, 2, 1},
75 {0xA5D5D52C, 8192, 7744, 0x80, 7, 3, 2, 2, 1},
76 {0x95D1D389, 8192, 7744, 0x40, 6, 2, 1, 2, 1},
77 {0x1580DC89, 4096, 3872, 0x40, 6, 2, 1, 2, 1},
78 {0x15C1D389, 8192, 7744, 0x40, 6, 2, 1, 2, 1},
79 {0x9590DC89, 4096, 3872, 0x40, 6, 2, 1, 2, 1},
80 {0xA594D389, 4096, 3872, 0x80, 7, 2, 1, 2, 1},
81 {0x2584DC89, 2048, 1936, 0x80, 7, 2, 1, 2, 1},
82 {0xA5D5D589, 8192, 7744, 0x80, 7, 2, 1, 2, 1},
83 {0xA514D320, 4096, 3872, 0x80, 7, 2, 1, 2, 1},
84 {0xA555D520, 8192, 3872, 0x80, 7, 2, 1, 2, 1}
87 static uint8_t nand_tunk1
[4];
88 static uint8_t nand_twp
[4];
89 static uint8_t nand_tunk2
[4];
90 static uint8_t nand_tunk3
[4];
91 static uint32_t nand_type
[4];
92 static int nand_powered
= 0;
93 static int nand_interleaved
= 0;
94 static int nand_cached
= 0;
95 static long nand_last_activity_value
= -1;
96 static long nand_stack
[DEFAULT_STACK_SIZE
];
98 static struct mutex nand_mtx
;
99 static struct wakeup nand_wakeup
;
100 static struct mutex ecc_mtx
;
101 static struct wakeup ecc_wakeup
;
103 static uint8_t nand_data
[0x800] STORAGE_ALIGN_ATTR
;
104 static uint8_t nand_ctrl
[0x200] STORAGE_ALIGN_ATTR
;
105 static uint8_t nand_spare
[0x40] STORAGE_ALIGN_ATTR
;
106 static uint8_t nand_ecc
[0x30] STORAGE_ALIGN_ATTR
;
109 static uint32_t nand_unlock(uint32_t rc
)
112 nand_last_activity_value
= current_tick
;
113 mutex_unlock(&nand_mtx
);
117 static uint32_t ecc_unlock(uint32_t rc
)
119 mutex_unlock(&ecc_mtx
);
123 static uint32_t nand_timeout(long timeout
)
125 if (TIME_AFTER(current_tick
, timeout
)) return 1;
133 static uint32_t nand_wait_rbbdone(void)
135 long timeout
= current_tick
+ HZ
/ 50;
136 while (!(FMCSTAT
& FMCSTAT_RBBDONE
))
137 if (nand_timeout(timeout
)) return 1;
138 FMCSTAT
= FMCSTAT_RBBDONE
;
142 static uint32_t nand_wait_cmddone(void)
144 long timeout
= current_tick
+ HZ
/ 50;
145 while (!(FMCSTAT
& FMCSTAT_CMDDONE
))
146 if (nand_timeout(timeout
)) return 1;
147 FMCSTAT
= FMCSTAT_CMDDONE
;
151 static uint32_t nand_wait_addrdone(void)
153 long timeout
= current_tick
+ HZ
/ 50;
154 while (!(FMCSTAT
& FMCSTAT_ADDRDONE
))
155 if (nand_timeout(timeout
)) return 1;
156 FMCSTAT
= FMCSTAT_ADDRDONE
;
160 static uint32_t nand_wait_chip_ready(uint32_t bank
)
162 long timeout
= current_tick
+ HZ
/ 50;
163 while (!(FMCSTAT
& (FMCSTAT_BANK0READY
<< bank
)))
164 if (nand_timeout(timeout
)) return 1;
165 FMCSTAT
= (FMCSTAT_BANK0READY
<< bank
);
169 static void nand_set_fmctrl0(uint32_t bank
, uint32_t flags
)
171 FMCTRL0
= (nand_tunk1
[bank
] << 16) | (nand_twp
[bank
] << 12)
172 | (1 << 11) | 1 | (1 << (bank
+ 1)) | flags
;
175 static uint32_t nand_send_cmd(uint32_t cmd
)
178 return nand_wait_rbbdone();
181 static uint32_t nand_send_address(uint32_t page
, uint32_t offset
)
184 FMADDR0
= (page
<< 16) | offset
;
185 FMADDR1
= (page
>> 16) & 0xFF;
186 FMCTRL1
= FMCTRL1_DOTRANSADDR
;
187 return nand_wait_cmddone();
190 uint32_t nand_reset(uint32_t bank
)
192 nand_set_fmctrl0(bank
, 0);
193 if (nand_send_cmd(NAND_CMD_RESET
)) return 1;
194 if (nand_wait_chip_ready(bank
)) return 1;
195 FMCTRL1
= FMCTRL1_CLEARRFIFO
| FMCTRL1_CLEARWFIFO
;
200 static uint32_t nand_wait_status_ready(uint32_t bank
)
202 long timeout
= current_tick
+ HZ
/ 50;
203 nand_set_fmctrl0(bank
, 0);
204 if ((FMCSTAT
& (FMCSTAT_BANK0READY
<< bank
)))
205 FMCSTAT
= (FMCSTAT_BANK0READY
<< bank
);
206 FMCTRL1
= FMCTRL1_CLEARRFIFO
;
207 if (nand_send_cmd(NAND_CMD_GET_STATUS
)) return 1;
210 if (nand_timeout(timeout
)) return 1;
212 FMCTRL1
= FMCTRL1_DOREADDATA
;
213 if (nand_wait_addrdone()) return 1;
214 if ((FMFIFO
& NAND_STATUS_READY
)) break;
215 FMCTRL1
= FMCTRL1_CLEARRFIFO
;
217 FMCTRL1
= FMCTRL1_CLEARRFIFO
;
218 return nand_send_cmd(NAND_CMD_READ
);
221 static void nand_transfer_data_start(uint32_t bank
, uint32_t direction
,
222 void* buffer
, uint32_t size
)
224 nand_set_fmctrl0(bank
, FMCTRL0_ENABLEDMA
);
226 FMCTRL1
= FMCTRL1_DOREADDATA
<< direction
;
227 DMACON3
= (2 << DMACON_DEVICE_SHIFT
)
228 | (direction
<< DMACON_DIRECTION_SHIFT
)
229 | (2 << DMACON_DATA_SIZE_SHIFT
)
230 | (3 << DMACON_BURST_LEN_SHIFT
);
231 while ((DMAALLST
& DMAALLST_CHAN3_MASK
))
232 DMACOM3
= DMACOM_CLEARBOTHDONE
;
233 DMABASE3
= (uint32_t)buffer
;
234 DMATCNT3
= (size
>> 4) - 1;
239 static uint32_t nand_transfer_data_collect(uint32_t direction
)
241 long timeout
= current_tick
+ HZ
/ 50;
242 while ((DMAALLST
& DMAALLST_DMABUSY3
))
243 if (nand_timeout(timeout
)) return 1;
244 if (!direction
) invalidate_dcache();
245 if (nand_wait_addrdone()) return 1;
246 if (!direction
) FMCTRL1
= FMCTRL1_CLEARRFIFO
| FMCTRL1_CLEARWFIFO
;
247 else FMCTRL1
= FMCTRL1_CLEARRFIFO
;
251 static uint32_t nand_transfer_data(uint32_t bank
, uint32_t direction
,
252 void* buffer
, uint32_t size
)
254 nand_transfer_data_start(bank
, direction
, buffer
, size
);
255 uint32_t rc
= nand_transfer_data_collect(direction
);
259 static void ecc_start(uint32_t size
, void* databuffer
, void* sparebuffer
,
262 mutex_lock(&ecc_mtx
);
266 ECC_DATA_PTR
= (uint32_t)databuffer
;
267 ECC_SPARE_PTR
= (uint32_t)sparebuffer
;
272 static uint32_t ecc_collect(void)
274 long timeout
= current_tick
+ HZ
/ 50;
275 while (!(SRCPND
& INTMSK_ECC
))
276 if (nand_timeout(timeout
)) return ecc_unlock(1);
280 return ecc_unlock(ECC_RESULT
);
283 static uint32_t ecc_decode(uint32_t size
, void* databuffer
, void* sparebuffer
)
285 ecc_start(size
, databuffer
, sparebuffer
, ECCCTRL_STARTDECODING
);
286 uint32_t rc
= ecc_collect();
290 static uint32_t ecc_encode(uint32_t size
, void* databuffer
, void* sparebuffer
)
292 ecc_start(size
, databuffer
, sparebuffer
, ECCCTRL_STARTENCODING
);
297 static uint32_t nand_check_empty(uint8_t* buffer
)
301 for (i
= 0; i
< 0x40; i
++) if (buffer
[i
] != 0xFF) count
++;
302 if (count
< 2) return 1;
306 static uint32_t nand_get_chip_type(uint32_t bank
)
308 mutex_lock(&nand_mtx
);
310 if (nand_reset(bank
)) return nand_unlock(0xFFFFFFFF);
311 if (nand_send_cmd(0x90)) return nand_unlock(0xFFFFFFFF);
314 FMCTRL1
= FMCTRL1_DOTRANSADDR
;
315 if (nand_wait_cmddone()) return nand_unlock(0xFFFFFFFF);
317 FMCTRL1
= FMCTRL1_DOREADDATA
;
318 if (nand_wait_addrdone()) return nand_unlock(0xFFFFFFFF);
320 FMCTRL1
= FMCTRL1_CLEARRFIFO
;
321 return nand_unlock(result
);
324 void nand_set_active(void)
326 nand_last_activity_value
= current_tick
;
329 long nand_last_activity(void)
331 return nand_last_activity_value
;
334 void nand_power_up(void)
337 mutex_lock(&nand_mtx
);
338 nand_last_activity_value
= current_tick
;
347 PCON5
= (PCON5
& ~0xF) | 3;
349 pmu_ldo_set_voltage(4, 0x15);
352 nand_last_activity_value
= current_tick
;
353 for (i
= 0; i
< 4; i
++)
355 if(nand_type
[i
] != 0xFFFFFFFF)
358 panicf("nand_power_up: nand_reset(bank=%d) failed.",(unsigned int)i
);
362 nand_last_activity_value
= current_tick
;
363 mutex_unlock(&nand_mtx
);
366 void nand_power_down(void)
368 if (!nand_powered
) return;
369 mutex_lock(&nand_mtx
);
370 pmu_ldo_power_off(4);
377 PCON5
= (PCON5
& ~0xF) | 1;
382 mutex_unlock(&nand_mtx
);
385 uint32_t nand_read_page(uint32_t bank
, uint32_t page
, void* databuffer
,
386 void* sparebuffer
, uint32_t doecc
,
389 uint8_t* data
= nand_data
;
390 uint8_t* spare
= nand_spare
;
391 if (databuffer
&& !((uint32_t)databuffer
& 0xf))
392 data
= (uint8_t*)databuffer
;
393 if (sparebuffer
&& !((uint32_t)sparebuffer
& 0xf))
394 spare
= (uint8_t*)sparebuffer
;
395 mutex_lock(&nand_mtx
);
396 nand_last_activity_value
= current_tick
;
398 if (!nand_powered
) nand_power_up();
399 uint32_t rc
, eccresult
;
400 nand_set_fmctrl0(bank
, FMCTRL0_ENABLEDMA
);
401 if (nand_send_cmd(NAND_CMD_READ
)) return nand_unlock(1);
402 if (nand_send_address(page
, databuffer
? 0 : 0x800))
403 return nand_unlock(1);
404 if (nand_send_cmd(NAND_CMD_READ2
)) return nand_unlock(1);
405 if (nand_wait_status_ready(bank
)) return nand_unlock(1);
407 if (nand_transfer_data(bank
, 0, data
, 0x800))
408 return nand_unlock(1);
412 if (databuffer
&& data
!= databuffer
) memcpy(databuffer
, data
, 0x800);
415 if (nand_transfer_data(bank
, 0, spare
, 0x40))
416 return nand_unlock(1);
417 if (sparebuffer
&& spare
!= sparebuffer
)
418 memcpy(sparebuffer
, spare
, 0x800);
420 rc
= nand_check_empty((uint8_t*)sparebuffer
) << 1;
422 return nand_unlock(rc
);
424 if (nand_transfer_data(bank
, 0, spare
, 0x40)) return nand_unlock(1);
427 memcpy(nand_ecc
, &spare
[0xC], 0x28);
428 rc
|= (ecc_decode(3, data
, nand_ecc
) & 0xF) << 4;
429 if (data
!= databuffer
) memcpy(databuffer
, data
, 0x800);
431 memset(nand_ctrl
, 0xFF, 0x200);
432 memcpy(nand_ctrl
, spare
, 0xC);
433 memcpy(nand_ecc
, &spare
[0x34], 0xC);
434 eccresult
= ecc_decode(0, nand_ctrl
, nand_ecc
);
435 rc
|= (eccresult
& 0xF) << 8;
438 if (spare
!= sparebuffer
) memcpy(sparebuffer
, spare
, 0x40);
439 if (eccresult
& 1) memset(sparebuffer
, 0xFF, 0xC);
440 else memcpy(sparebuffer
, nand_ctrl
, 0xC);
442 if (checkempty
) rc
|= nand_check_empty(spare
) << 1;
444 return nand_unlock(rc
);
447 static uint32_t nand_write_page_int(uint32_t bank
, uint32_t page
,
448 void* databuffer
, void* sparebuffer
,
449 uint32_t doecc
, uint32_t wait
)
451 uint8_t* data
= nand_data
;
452 uint8_t* spare
= nand_spare
;
453 if (databuffer
&& !((uint32_t)databuffer
& 0xf))
454 data
= (uint8_t*)databuffer
;
455 if (sparebuffer
&& !((uint32_t)sparebuffer
& 0xf))
456 spare
= (uint8_t*)sparebuffer
;
457 mutex_lock(&nand_mtx
);
458 nand_last_activity_value
= current_tick
;
460 if (!nand_powered
) nand_power_up();
463 if (spare
!= sparebuffer
) memcpy(spare
, sparebuffer
, 0x40);
465 else memset(spare
, 0xFF, 0x40);
466 nand_set_fmctrl0(bank
, FMCTRL0_ENABLEDMA
);
467 if (nand_send_cmd(NAND_CMD_PROGRAM
)) return nand_unlock(1);
468 if (nand_send_address(page
, databuffer
? 0 : 0x800))
469 return nand_unlock(1);
470 if (databuffer
&& data
!= databuffer
) memcpy(data
, databuffer
, 0x800);
471 if (databuffer
) nand_transfer_data_start(bank
, 1, data
, 0x800);
474 if (ecc_encode(3, data
, nand_ecc
)) return nand_unlock(1);
475 memcpy(&spare
[0xC], nand_ecc
, 0x28);
476 memset(nand_ctrl
, 0xFF, 0x200);
477 memcpy(nand_ctrl
, spare
, 0xC);
478 if (ecc_encode(0, nand_ctrl
, nand_ecc
)) return nand_unlock(1);
479 memcpy(&spare
[0x34], nand_ecc
, 0xC);
482 if (nand_transfer_data_collect(1))
483 return nand_unlock(1);
484 if (sparebuffer
|| doecc
)
485 if (nand_transfer_data(bank
, 1, spare
, 0x40))
486 return nand_unlock(1);
487 if (nand_send_cmd(NAND_CMD_PROGCNFRM
)) return nand_unlock(1);
488 if (wait
) if (nand_wait_status_ready(bank
)) return nand_unlock(1);
489 return nand_unlock(0);
492 uint32_t nand_block_erase(uint32_t bank
, uint32_t page
)
494 mutex_lock(&nand_mtx
);
495 nand_last_activity_value
= current_tick
;
497 if (!nand_powered
) nand_power_up();
498 nand_set_fmctrl0(bank
, 0);
499 if (nand_send_cmd(NAND_CMD_BLOCKERASE
)) return nand_unlock(1);
502 FMCTRL1
= FMCTRL1_DOTRANSADDR
;
503 if (nand_wait_cmddone()) return nand_unlock(1);
504 if (nand_send_cmd(NAND_CMD_ERASECNFRM
)) return nand_unlock(1);
505 if (nand_wait_status_ready(bank
)) return nand_unlock(1);
506 return nand_unlock(0);
509 uint32_t nand_read_page_fast(uint32_t page
, void* databuffer
,
510 void* sparebuffer
, uint32_t doecc
,
514 if (((uint32_t)databuffer
& 0xf) || ((uint32_t)sparebuffer
& 0xf)
515 || !databuffer
|| !sparebuffer
|| !doecc
)
517 for (i
= 0; i
< 4; i
++)
519 if (nand_type
[i
] == 0xFFFFFFFF) continue;
520 void* databuf
= (void*)0;
521 void* sparebuf
= (void*)0;
522 if (databuffer
) databuf
= (void*)((uint32_t)databuffer
+ 0x800 * i
);
523 if (sparebuffer
) sparebuf
= (void*)((uint32_t)sparebuffer
+ 0x40 * i
);
524 uint32_t ret
= nand_read_page(i
, page
, databuf
, sparebuf
, doecc
, checkempty
);
525 if (ret
& 1) rc
|= 1 << (i
<< 2);
526 if (ret
& 2) rc
|= 2 << (i
<< 2);
527 if (ret
& 0x10) rc
|= 4 << (i
<< 2);
528 if (ret
& 0x100) rc
|= 8 << (i
<< 2);
532 mutex_lock(&nand_mtx
);
533 nand_last_activity_value
= current_tick
;
535 if (!nand_powered
) nand_power_up();
537 for (i
= 0; i
< 4; i
++) status
[i
] = (nand_type
[i
] == 0xFFFFFFFF);
538 for (i
= 0; i
< 4; i
++)
542 nand_set_fmctrl0(i
, FMCTRL0_ENABLEDMA
);
543 if (nand_send_cmd(NAND_CMD_READ
))
547 if (nand_send_address(page
, 0))
550 if (nand_send_cmd(NAND_CMD_READ2
))
554 if (nand_wait_status_ready(0))
557 if (nand_transfer_data(0, 0, databuffer
, 0x800))
560 if (nand_transfer_data(0, 0, sparebuffer
, 0x40))
562 for (i
= 1; i
< 4; i
++)
565 if (nand_wait_status_ready(i
))
568 nand_transfer_data_start(i
, 0, (void*)((uint32_t)databuffer
569 + 0x800 * i
), 0x800);
572 memcpy(nand_ecc
, (void*)((uint32_t)sparebuffer
+ 0x40 * (i
- 1) + 0xC), 0x28);
573 ecc_start(3, (void*)((uint32_t)databuffer
574 + 0x800 * (i
- 1)), nand_ecc
, ECCCTRL_STARTDECODING
);
577 if (nand_transfer_data_collect(0))
580 nand_transfer_data_start(i
, 0, (void*)((uint32_t)sparebuffer
583 if (ecc_collect() & 1)
587 memset(nand_ctrl
, 0xFF, 0x200);
588 memcpy(nand_ctrl
, (void*)((uint32_t)sparebuffer
+ 0x40 * (i
- 1)), 0xC);
589 memcpy(nand_ecc
, (void*)((uint32_t)sparebuffer
+ 0x40 * (i
- 1) + 0x34), 0xC);
590 ecc_start(0, nand_ctrl
, nand_ecc
, ECCCTRL_STARTDECODING
);
593 if (nand_transfer_data_collect(0))
597 if (ecc_collect() & 1)
600 memset((void*)((uint32_t)sparebuffer
+ 0x40 * (i
- 1)), 0xFF, 0xC);
602 else memcpy((void*)((uint32_t)sparebuffer
+ 0x40 * (i
- 1)), nand_ctrl
, 0xC);
604 status
[i
- 1] |= nand_check_empty((void*)((uint32_t)sparebuffer
605 + 0x40 * (i
- 1))) << 1;
610 memcpy(nand_ecc
,(void*)((uint32_t)sparebuffer
+ 0x40 * (i
- 1) + 0xC), 0x28);
611 if (ecc_decode(3, (void*)((uint32_t)databuffer
612 + 0x800 * (i
- 1)), nand_ecc
) & 1)
617 memset(nand_ctrl
, 0xFF, 0x200);
618 memcpy(nand_ctrl
, (void*)((uint32_t)sparebuffer
+ 0x40 * (i
- 1)), 0xC);
619 memcpy(nand_ecc
, (void*)((uint32_t)sparebuffer
+ 0x40 * (i
- 1) + 0x34), 0xC);
620 if (ecc_decode(0, nand_ctrl
, nand_ecc
) & 1)
623 memset((void*)((uint32_t)sparebuffer
+ 0x40 * (i
- 1)), 0xFF, 0xC);
625 else memcpy((void*)((uint32_t)sparebuffer
+ 0x40 * (i
- 1)), nand_ctrl
, 0xC);
627 status
[i
- 1] |= nand_check_empty((void*)((uint32_t)sparebuffer
628 + 0x40 * (i
- 1))) << 1;
630 for (i
= 0; i
< 4; i
++)
631 if (nand_type
[i
] != 0xFFFFFFFF)
632 rc
|= status
[i
] << (i
<< 2);
633 return nand_unlock(rc
);
636 uint32_t nand_write_page(uint32_t bank
, uint32_t page
, void* databuffer
,
637 void* sparebuffer
, uint32_t doecc
)
639 return nand_write_page_int(bank
, page
, databuffer
, sparebuffer
, doecc
, 1);
642 uint32_t nand_write_page_start(uint32_t bank
, uint32_t page
, void* databuffer
,
643 void* sparebuffer
, uint32_t doecc
)
645 if (((uint32_t)databuffer
& 0xf) || ((uint32_t)sparebuffer
& 0xf)
646 || !databuffer
|| !sparebuffer
|| !doecc
|| !nand_interleaved
)
647 return nand_write_page_int(bank
, page
, databuffer
, sparebuffer
, doecc
, !nand_interleaved
);
649 mutex_lock(&nand_mtx
);
650 nand_last_activity_value
= current_tick
;
652 if (!nand_powered
) nand_power_up();
653 nand_set_fmctrl0(bank
, FMCTRL0_ENABLEDMA
);
654 if (nand_send_cmd(NAND_CMD_PROGRAM
))
655 return nand_unlock(1);
656 if (nand_send_address(page
, 0))
657 return nand_unlock(1);
658 nand_transfer_data_start(bank
, 1, databuffer
, 0x800);
659 if (ecc_encode(3, databuffer
, nand_ecc
))
660 return nand_unlock(1);
661 memcpy((void*)((uint32_t)sparebuffer
+ 0xC), nand_ecc
, 0x28);
662 memset(nand_ctrl
, 0xFF, 0x200);
663 memcpy(nand_ctrl
, sparebuffer
, 0xC);
664 if (ecc_encode(0, nand_ctrl
, nand_ecc
))
665 return nand_unlock(1);
666 memcpy((void*)((uint32_t)sparebuffer
+ 0x34), nand_ecc
, 0xC);
667 if (nand_transfer_data_collect(0))
668 return nand_unlock(1);
669 if (nand_transfer_data(bank
, 1, sparebuffer
, 0x40))
670 return nand_unlock(1);
671 return nand_unlock(nand_send_cmd(NAND_CMD_PROGCNFRM
));
674 uint32_t nand_write_page_collect(uint32_t bank
)
676 return nand_wait_status_ready(bank
);
679 #if 0 /* currently unused */
680 static uint32_t nand_block_erase_fast(uint32_t page
)
683 mutex_lock(&nand_mtx
);
684 nand_last_activity_value
= current_tick
;
686 if (!nand_powered
) nand_power_up();
687 for (i
= 0; i
< 4; i
++)
689 if (nand_type
[i
] == 0xFFFFFFFF) continue;
690 nand_set_fmctrl0(i
, 0);
691 if (nand_send_cmd(NAND_CMD_BLOCKERASE
))
698 FMCTRL1
= FMCTRL1_DOTRANSADDR
;
699 if (nand_wait_cmddone())
704 if (nand_send_cmd(NAND_CMD_ERASECNFRM
)) rc
|= 1 << i
;
706 for (i
= 0; i
< 4; i
++)
708 if (nand_type
[i
] == 0xFFFFFFFF) continue;
709 if (rc
& (1 << i
)) continue;
710 if (nand_wait_status_ready(i
)) rc
|= 1 << i
;
712 return nand_unlock(rc
);
716 const struct nand_device_info_type
* nand_get_device_type(uint32_t bank
)
718 if (nand_type
[bank
] == 0xFFFFFFFF)
719 return (struct nand_device_info_type
*)0;
720 return &nand_deviceinfotable
[nand_type
[bank
]];
723 static void nand_thread(void)
727 if (TIME_AFTER(current_tick
, nand_last_activity_value
+ HZ
/ 5)
730 call_storage_idle_notifys(false);
737 uint32_t nand_device_init(void)
739 mutex_init(&nand_mtx
);
740 wakeup_init(&nand_wakeup
);
741 mutex_init(&ecc_mtx
);
742 wakeup_init(&ecc_wakeup
);
747 /* Assume there are 0 banks, to prevent
748 nand_power_up from talking with them yet. */
749 for(i
= 0; i
< 4; i
++) nand_type
[i
] = 0xFFFFFFFF;
752 /* Now that the flash is powered on, detect how
753 many banks we really have and initialize them. */
754 for (i
= 0; i
< 4; i
++)
760 type
= nand_get_chip_type(i
);
761 if (type
== 0xFFFFFFFF) continue;
764 if (j
== ARRAYLEN(nand_deviceinfotable
)) break;
765 else if (nand_deviceinfotable
[j
].id
== type
)
771 nand_tunk1
[i
] = nand_deviceinfotable
[nand_type
[i
]].tunk1
;
772 nand_twp
[i
] = nand_deviceinfotable
[nand_type
[i
]].twp
;
773 nand_tunk2
[i
] = nand_deviceinfotable
[nand_type
[i
]].tunk2
;
774 nand_tunk3
[i
] = nand_deviceinfotable
[nand_type
[i
]].tunk3
;
776 if (nand_type
[0] == 0xFFFFFFFF) return 1;
777 nand_interleaved
= ((nand_type
[0] >> 22) & 1);
778 nand_cached
= ((nand_type
[0] >> 23) & 1);
780 nand_last_activity_value
= current_tick
;
781 create_thread(nand_thread
, nand_stack
,
782 sizeof(nand_stack
), 0, "nand"
783 IF_PRIO(, PRIORITY_USER_INTERFACE
)