summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c167
1 files changed, 126 insertions, 41 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
index 851472bf62..c9ca85cfaf 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
@@ -85,21 +85,20 @@ struct nand_param
85 * 85 *
86 */ 86 */
87 87
88#define NAND_DATAPORT 0xB8000000 88static volatile unsigned long nand_address;
89#define NAND_ADDRPORT 0xB8010000 89#define NAND_DATAPORT (nand_address)
90#define NAND_COMMPORT 0xB8008000 90#define NAND_ADDRPORT (nand_address+0x10000)
91#define NAND_COMMPORT (nand_address+0x08000)
91 92
92#define ECC_BLOCK 512 93#define ECC_BLOCK 512
93#define ECC_POS 6 94#define ECC_POS 6
94#define PAR_SIZE 9 95#define PAR_SIZE 9
95 96
96#define __nand_cmd(n) (REG8(NAND_COMMPORT) = (n)) 97#define __nand_cmd(n) (REG8(NAND_COMMPORT) = (n))
97#define __nand_addr(n) (REG8(NAND_ADDRPORT) = (n)) 98#define __nand_addr(n) (REG8(NAND_ADDRPORT) = (n))
98#define __nand_data8() (REG8(NAND_DATAPORT)) 99#define __nand_data8() (REG8(NAND_DATAPORT))
99#define __nand_data16() (REG16(NAND_DATAPORT)) 100#define __nand_data16() (REG16(NAND_DATAPORT))
100 101
101#define __nand_enable() (REG_EMC_NFCSR |= EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1)
102#define __nand_disable() (REG_EMC_NFCSR &= ~(EMC_NFCSR_NFCE1))
103#define __nand_ecc_rs_encoding() \ 102#define __nand_ecc_rs_encoding() \
104 (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING) 103 (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING)
105#define __nand_ecc_rs_decoding() \ 104#define __nand_ecc_rs_decoding() \
@@ -111,6 +110,9 @@ struct nand_param
111/*--------------------------------------------------------------*/ 110/*--------------------------------------------------------------*/
112 111
113static struct nand_info* chip_info = NULL; 112static struct nand_info* chip_info = NULL;
113static struct nand_info* banks[4];
114static unsigned int nr_banks = 1;
115static unsigned long bank_size;
114static struct nand_param internal_param; 116static struct nand_param internal_param;
115#ifdef USE_DMA 117#ifdef USE_DMA
116static struct mutex nand_mtx; 118static struct mutex nand_mtx;
@@ -344,6 +346,9 @@ static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst)
344 int i, j; 346 int i, j;
345 unsigned char *data_buf; 347 unsigned char *data_buf;
346 unsigned char oob_buf[nandp->oob_size]; 348 unsigned char oob_buf[nandp->oob_size];
349
350 if(nand_address == 0)
351 return -1;
347 352
348 page_size = nandp->page_size; 353 page_size = nandp->page_size;
349 oob_size = nandp->oob_size; 354 oob_size = nandp->oob_size;
@@ -463,44 +468,112 @@ static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst)
463} 468}
464 469
465/* 470/*
471 * Disable NAND controller
472 */
473static void jz_nand_disable(void)
474{
475 REG_EMC_NFCSR &= ~(EMC_NFCSR_NFCE1 | EMC_NFCSR_NFCE2 |
476 EMC_NFCSR_NFCE3 | EMC_NFCSR_NFCE4 |
477 EMC_NFCSR_NFE1 | EMC_NFCSR_NFE2 |
478 EMC_NFCSR_NFE3 | EMC_NFCSR_NFE4 );
479}
480
481/*
466 * Enable NAND controller 482 * Enable NAND controller
467 */ 483 */
468static void jz_nand_enable(void) 484static void jz_nand_enable(void)
485{
486#if 0
487 /* OF RE */
488 REG_GPIO_PXFUNS(1) = 0x1E018000; // __gpio_as_func0() start
489 REG_GPIO_PXSELC(1) = 0x1E018000; // __gpio_as_func0() end
490
491 REG_GPIO_PXFUNS(2) = 0x3000<<16; // __gpio_as_func0() start
492 REG_GPIO_PXSELC(2) = 0x3000<<16; // __gpio_as_func0() end
493
494 REG_GPIO_PXFUNC(2) = 0x4000<<16; // __gpio_port_as_input() start
495 REG_GPIO_PXSELC(2) = 0x4000<<16;
496 REG_GPIO_PXDIRC(2) = 0x4000<<16; // __gpio_port_as_input() end
497 REG_GPIO_PXPES(2) = 0x4000<<16; // __gpio_disable_pull()
498
499 REG_GPIO_PXFUNS(1) = 0x40<<16; // __gpio_as_func0() start
500 REG_GPIO_PXSELC(1) = 0x40<<16; // __gpio_as_func0() end
501
502 REG_EMC_SMCR1 = (REG_EMC_SMCR1 & 0xFF) | 0x4621200;
503 REG_EMC_SMCR2 = (REG_EMC_SMCR2 & 0xFF) | 0x4621200;
504 REG_EMC_SMCR3 = (REG_EMC_SMCR3 & 0xFF) | 0x4621200;
505 REG_EMC_SMCR4 = (REG_EMC_SMCR4 & 0xFF) | 0x4621200;
506
507 REG_EMC_SMCR1 = REG_EMC_SMCR2 = REG_EMC_SMCR3 = REG_EMC_SMCR4 = 0x6621200;
508#else
509 REG_EMC_SMCR1 = REG_EMC_SMCR2 = REG_EMC_SMCR3 = REG_EMC_SMCR4 = 0x04444400;
510#endif
511}
512
513static void jz_nand_select(int bank)
469{ 514{
470 __nand_enable(); 515 REG_EMC_NFCSR |= (EMC_NFCSR_NFE(bank+1) | EMC_NFCSR_NFCE(bank+1));
471 516
472 REG_EMC_SMCR1 = 0x04444400; 517 switch(bank)
518 {
519 case 0:
520 nand_address = 0xB8000000;
521 break;
522 case 1:
523 nand_address = 0xB4000000;
524 break;
525 case 2:
526 nand_address = 0xAC000000;
527 break;
528 case 3:
529 nand_address = 0xA8000000;
530 break;
531 }
473} 532}
474 533
475/* 534static void jz_nand_deselect(int bank)
476 * Disable NAND controller
477 */
478static void jz_nand_disable(void)
479{ 535{
480 __nand_disable(); 536 REG_EMC_NFCSR &= ~(EMC_NFCSR_NFE(bank+1) | EMC_NFCSR_NFCE(bank+1));
537 nand_address = 0;
481} 538}
482 539
483static int jz_nand_init(void) 540static int jz_nand_init(void)
484{ 541{
485 unsigned char cData[5]; 542 unsigned char cData[5];
543 int i;
486 544
487 jz_nand_enable(); 545 jz_nand_enable();
488 546
489 __nand_cmd(NAND_CMD_READID); 547 for(i=0; i<4; i++)
490 __nand_addr(NAND_CMD_READ0);
491 cData[0] = __nand_data8();
492 cData[1] = __nand_data8();
493 cData[2] = __nand_data8();
494 cData[3] = __nand_data8();
495 cData[4] = __nand_data8();
496
497 chip_info = nand_identify(cData);
498 if(chip_info == NULL)
499 { 548 {
500 panicf("Unknown NAND flash chip: 0x%x 0x%x 0x%x 0x%x 0x%x", cData[0], 549 jz_nand_select(i);
501 cData[1], cData[2], cData[3], cData[4]); 550
502 return -1; /* panicf() doesn't return though */ 551 __nand_cmd(NAND_CMD_READID);
552 __nand_addr(NAND_CMD_READ0);
553 cData[0] = __nand_data8();
554 cData[1] = __nand_data8();
555 cData[2] = __nand_data8();
556 cData[3] = __nand_data8();
557 cData[4] = __nand_data8();
558
559 jz_nand_deselect(i);
560
561 logf("NAND chip %d: 0x%x 0x%x 0x%x 0x%x 0x%x", i+1, cData[0], cData[1],
562 cData[2], cData[3], cData[4]);
563
564 banks[i] = nand_identify(cData);
565
566 if(banks[i] != NULL)
567 nr_banks++;
568
569 if(i == 0 && banks[i] == NULL)
570 {
571 panicf("Unknown NAND flash chip: 0x%x 0x%x 0x%x 0x%x 0x%x", cData[0],
572 cData[1], cData[2], cData[3], cData[4]);
573 return -1; /* panicf() doesn't return though */
574 }
503 } 575 }
576 chip_info = banks[0];
504 577
505 internal_param.bus_width = 8; 578 internal_param.bus_width = 8;
506 internal_param.row_cycle = chip_info->row_cycles; 579 internal_param.row_cycle = chip_info->row_cycles;
@@ -508,13 +581,17 @@ static int jz_nand_init(void)
508 internal_param.oob_size = chip_info->spare_size; 581 internal_param.oob_size = chip_info->spare_size;
509 internal_param.page_per_block = chip_info->pages_per_block; 582 internal_param.page_per_block = chip_info->pages_per_block;
510 583
584 bank_size = chip_info->page_size * chip_info->blocks_per_bank / 512 * chip_info->pages_per_block;
585
586 jz_nand_disable();
587
511 return 0; 588 return 0;
512} 589}
513 590
514static bool inited = false;
515int nand_init(void) 591int nand_init(void)
516{ 592{
517 int res = 0; 593 int res = 0;
594 static bool inited = false;
518 595
519 if(!inited) 596 if(!inited)
520 { 597 {
@@ -533,29 +610,37 @@ int nand_init(void)
533 610
534int nand_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf) 611int nand_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf)
535{ 612{
536 int i, ret = 0; 613 int i, ret = 0, chip_size = chip_info->page_size;
537 614
538 logf("nand_read_sectors(%ld, %d, 0x%x)", start, count, (int)buf); 615 logf("nand_read_sectors(%ld, %d, 0x%x)", start, count, (int)buf);
539 616
540 start *= 512; 617 start *= 512;
541 count *= 512; 618 count *= 512;
542 619
543 if(count <= chip_info->page_size) 620 if(count <= chip_size)
544 { 621 {
545 ret = jz_nand_read_page(start/chip_info->page_size, temp_page); 622 jz_nand_select(start / 512 / bank_size);
546 memcpy(buf, temp_page+(start%chip_info->page_size), count); 623
547 return ret; 624 ret = jz_nand_read_page(start/chip_size, temp_page);
625 memcpy(buf, temp_page+(start%chip_size), count);
626
627 jz_nand_deselect(start / 512 / bank_size);
548 } 628 }
549 else 629 else
550 { 630 {
551 for(i=0; i<count && ret==0; i+=chip_info->page_size) 631 for(i=0; i<count && ret==0; i+=chip_size)
552 { 632 {
553 ret = jz_nand_read_page((start+i)/chip_info->page_size, temp_page); 633 jz_nand_select((start/512+i) / bank_size);
554 memcpy(buf+i, temp_page+((start+i)%chip_info->page_size), 634
555 (count-i < chip_info->page_size ? count-i : chip_info->page_size)); 635 ret = jz_nand_read_page((start+i)/chip_size, temp_page);
636 memcpy(buf+i, temp_page+((start+i)%chip_size),
637 (count-i < chip_size ? count-i : chip_size));
638
639 jz_nand_deselect((start/512+i) / bank_size);
556 } 640 }
557 return ret;
558 } 641 }
642
643 return ret;
559} 644}
560 645
561/* TODO */ 646/* TODO */
@@ -605,6 +690,7 @@ void nand_enable(bool on)
605void nand_get_info(IF_MV2(int drive,) struct storage_info *info) 690void nand_get_info(IF_MV2(int drive,) struct storage_info *info)
606{ 691{
607 (void)drive; 692 (void)drive;
693
608 /* firmware version */ 694 /* firmware version */
609 info->revision="0.00"; 695 info->revision="0.00";
610 696
@@ -612,8 +698,7 @@ void nand_get_info(IF_MV2(int drive,) struct storage_info *info)
612 info->product="NAND Storage"; 698 info->product="NAND Storage";
613 699
614 /* blocks count */ 700 /* blocks count */
615 /* TODO: proper amount of sectors! */ 701 info->num_sectors = bank_size * nr_banks;
616 info->num_sectors = ((chip_info->page_size+chip_info->spare_size) / 512) * chip_info->pages_per_block * chip_info->blocks_per_bank;
617 info->sector_size = 512; 702 info->sector_size = 512;
618} 703}
619#endif 704#endif