diff options
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c')
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c | 104 |
1 files changed, 52 insertions, 52 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c index 1ae3bb2cc8..a582db82cc 100644 --- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c | |||
@@ -149,20 +149,20 @@ static inline void jz_nand_read_buf8(void *buf, int count) | |||
149 | static void jz_nand_write_dma(void *source, unsigned int len, int bw) | 149 | static void jz_nand_write_dma(void *source, unsigned int len, int bw) |
150 | { | 150 | { |
151 | mutex_lock(&nand_dma_mtx); | 151 | mutex_lock(&nand_dma_mtx); |
152 | 152 | ||
153 | if(((unsigned int)source < 0xa0000000) && len) | 153 | if(((unsigned int)source < 0xa0000000) && len) |
154 | dma_cache_wback_inv((unsigned long)source, len); | 154 | dma_cache_wback_inv((unsigned long)source, len); |
155 | 155 | ||
156 | dma_enable(); | 156 | dma_enable(); |
157 | 157 | ||
158 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES; | 158 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES; |
159 | REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)source); | 159 | REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)source); |
160 | REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT); | 160 | REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT); |
161 | REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 16; | 161 | REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 16; |
162 | REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO; | 162 | REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO; |
163 | REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_16BYTE | | 163 | REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_16BYTE | |
164 | (bw == 8 ? DMAC_DCMD_DWDH_8 : DMAC_DCMD_DWDH_16)); | 164 | (bw == 8 ? DMAC_DCMD_DWDH_8 : DMAC_DCMD_DWDH_16)); |
165 | 165 | ||
166 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */ | 166 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */ |
167 | #if 1 | 167 | #if 1 |
168 | while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) ) | 168 | while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) ) |
@@ -173,26 +173,26 @@ static void jz_nand_write_dma(void *source, unsigned int len, int bw) | |||
173 | #endif | 173 | #endif |
174 | 174 | ||
175 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */ | 175 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */ |
176 | 176 | ||
177 | dma_disable(); | 177 | dma_disable(); |
178 | 178 | ||
179 | mutex_unlock(&nand_dma_mtx); | 179 | mutex_unlock(&nand_dma_mtx); |
180 | } | 180 | } |
181 | 181 | ||
182 | static void jz_nand_read_dma(void *target, unsigned int len, int bw) | 182 | static void jz_nand_read_dma(void *target, unsigned int len, int bw) |
183 | { | 183 | { |
184 | mutex_lock(&nand_dma_mtx); | 184 | mutex_lock(&nand_dma_mtx); |
185 | 185 | ||
186 | if(((unsigned int)target < 0xa0000000) && len) | 186 | if(((unsigned int)target < 0xa0000000) && len) |
187 | dma_cache_wback_inv((unsigned long)target, len); | 187 | dma_cache_wback_inv((unsigned long)target, len); |
188 | 188 | ||
189 | dma_enable(); | 189 | dma_enable(); |
190 | 190 | ||
191 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES ; | 191 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES ; |
192 | REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT); | 192 | REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT); |
193 | REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)target); | 193 | REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)target); |
194 | REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 4; | 194 | REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 4; |
195 | REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO; | 195 | REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO; |
196 | REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT | | 196 | REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT | |
197 | (bw == 8 ? DMAC_DCMD_SWDH_8 : DMAC_DCMD_SWDH_16)); | 197 | (bw == 8 ? DMAC_DCMD_SWDH_8 : DMAC_DCMD_SWDH_16)); |
198 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */ | 198 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */ |
@@ -205,9 +205,9 @@ static void jz_nand_read_dma(void *target, unsigned int len, int bw) | |||
205 | #endif | 205 | #endif |
206 | 206 | ||
207 | //REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */ | 207 | //REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */ |
208 | 208 | ||
209 | dma_disable(); | 209 | dma_disable(); |
210 | 210 | ||
211 | mutex_unlock(&nand_dma_mtx); | 211 | mutex_unlock(&nand_dma_mtx); |
212 | } | 212 | } |
213 | 213 | ||
@@ -224,7 +224,7 @@ void DMA_CALLBACK(DMA_NAND_CHANNEL)(void) | |||
224 | 224 | ||
225 | if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_TT) | 225 | if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_TT) |
226 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_TT; | 226 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_TT; |
227 | 227 | ||
228 | semaphore_release(&nand_dma_complete); | 228 | semaphore_release(&nand_dma_complete); |
229 | } | 229 | } |
230 | #endif /* USE_DMA */ | 230 | #endif /* USE_DMA */ |
@@ -246,7 +246,7 @@ static inline void jz_nand_read_buf(void *buf, int count, int bw) | |||
246 | 246 | ||
247 | #ifdef USE_ECC | 247 | #ifdef USE_ECC |
248 | /* | 248 | /* |
249 | * Correct 1~9-bit errors in 512-bytes data | 249 | * Correct 1~9-bit errors in 512-bytes data |
250 | */ | 250 | */ |
251 | static void jz_rs_correct(unsigned char *dat, int idx, int mask) | 251 | static void jz_rs_correct(unsigned char *dat, int idx, int mask) |
252 | { | 252 | { |
@@ -349,7 +349,7 @@ static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst) | |||
349 | #endif | 349 | #endif |
350 | unsigned char *data_buf; | 350 | unsigned char *data_buf; |
351 | unsigned char oob_buf[nandp->oob_size]; | 351 | unsigned char oob_buf[nandp->oob_size]; |
352 | 352 | ||
353 | if(nand_address == 0) | 353 | if(nand_address == 0) |
354 | return -1; | 354 | return -1; |
355 | 355 | ||
@@ -484,28 +484,28 @@ static void jz_nand_disable(void) | |||
484 | * Enable NAND controller | 484 | * Enable NAND controller |
485 | */ | 485 | */ |
486 | static void jz_nand_enable(void) | 486 | static void jz_nand_enable(void) |
487 | { | 487 | { |
488 | #if 0 | 488 | #if 0 |
489 | /* OF RE */ | 489 | /* OF RE */ |
490 | REG_GPIO_PXFUNS(1) = 0x1E018000; // __gpio_as_func0() start | 490 | REG_GPIO_PXFUNS(1) = 0x1E018000; // __gpio_as_func0() start |
491 | REG_GPIO_PXSELC(1) = 0x1E018000; // __gpio_as_func0() end | 491 | REG_GPIO_PXSELC(1) = 0x1E018000; // __gpio_as_func0() end |
492 | 492 | ||
493 | REG_GPIO_PXFUNS(2) = 0x3000<<16; // __gpio_as_func0() start | 493 | REG_GPIO_PXFUNS(2) = 0x3000<<16; // __gpio_as_func0() start |
494 | REG_GPIO_PXSELC(2) = 0x3000<<16; // __gpio_as_func0() end | 494 | REG_GPIO_PXSELC(2) = 0x3000<<16; // __gpio_as_func0() end |
495 | 495 | ||
496 | REG_GPIO_PXFUNC(2) = 0x4000<<16; // __gpio_port_as_input() start | 496 | REG_GPIO_PXFUNC(2) = 0x4000<<16; // __gpio_port_as_input() start |
497 | REG_GPIO_PXSELC(2) = 0x4000<<16; | 497 | REG_GPIO_PXSELC(2) = 0x4000<<16; |
498 | REG_GPIO_PXDIRC(2) = 0x4000<<16; // __gpio_port_as_input() end | 498 | REG_GPIO_PXDIRC(2) = 0x4000<<16; // __gpio_port_as_input() end |
499 | REG_GPIO_PXPES(2) = 0x4000<<16; // __gpio_disable_pull() | 499 | REG_GPIO_PXPES(2) = 0x4000<<16; // __gpio_disable_pull() |
500 | 500 | ||
501 | REG_GPIO_PXFUNS(1) = 0x40<<16; // __gpio_as_func0() start | 501 | REG_GPIO_PXFUNS(1) = 0x40<<16; // __gpio_as_func0() start |
502 | REG_GPIO_PXSELC(1) = 0x40<<16; // __gpio_as_func0() end | 502 | REG_GPIO_PXSELC(1) = 0x40<<16; // __gpio_as_func0() end |
503 | 503 | ||
504 | REG_EMC_SMCR1 = (REG_EMC_SMCR1 & 0xFF) | 0x4621200; | 504 | REG_EMC_SMCR1 = (REG_EMC_SMCR1 & 0xFF) | 0x4621200; |
505 | REG_EMC_SMCR2 = (REG_EMC_SMCR2 & 0xFF) | 0x4621200; | 505 | REG_EMC_SMCR2 = (REG_EMC_SMCR2 & 0xFF) | 0x4621200; |
506 | REG_EMC_SMCR3 = (REG_EMC_SMCR3 & 0xFF) | 0x4621200; | 506 | REG_EMC_SMCR3 = (REG_EMC_SMCR3 & 0xFF) | 0x4621200; |
507 | REG_EMC_SMCR4 = (REG_EMC_SMCR4 & 0xFF) | 0x4621200; | 507 | REG_EMC_SMCR4 = (REG_EMC_SMCR4 & 0xFF) | 0x4621200; |
508 | 508 | ||
509 | REG_EMC_SMCR1 = REG_EMC_SMCR2 = REG_EMC_SMCR3 = REG_EMC_SMCR4 = 0x6621200; | 509 | REG_EMC_SMCR1 = REG_EMC_SMCR2 = REG_EMC_SMCR3 = REG_EMC_SMCR4 = 0x6621200; |
510 | #else | 510 | #else |
511 | REG_EMC_SMCR1 = REG_EMC_SMCR2 = REG_EMC_SMCR3 = REG_EMC_SMCR4 = 0x04444400; | 511 | REG_EMC_SMCR1 = REG_EMC_SMCR2 = REG_EMC_SMCR3 = REG_EMC_SMCR4 = 0x04444400; |
@@ -543,13 +543,13 @@ static int jz_nand_init(void) | |||
543 | { | 543 | { |
544 | unsigned char cData[5]; | 544 | unsigned char cData[5]; |
545 | int i; | 545 | int i; |
546 | 546 | ||
547 | jz_nand_enable(); | 547 | jz_nand_enable(); |
548 | 548 | ||
549 | for(i=0; i<4; i++) | 549 | for(i=0; i<4; i++) |
550 | { | 550 | { |
551 | jz_nand_select(i); | 551 | jz_nand_select(i); |
552 | 552 | ||
553 | __nand_cmd(NAND_CMD_READID); | 553 | __nand_cmd(NAND_CMD_READID); |
554 | __nand_addr(NAND_CMD_READ0); | 554 | __nand_addr(NAND_CMD_READ0); |
555 | cData[0] = __nand_data8(); | 555 | cData[0] = __nand_data8(); |
@@ -557,17 +557,17 @@ static int jz_nand_init(void) | |||
557 | cData[2] = __nand_data8(); | 557 | cData[2] = __nand_data8(); |
558 | cData[3] = __nand_data8(); | 558 | cData[3] = __nand_data8(); |
559 | cData[4] = __nand_data8(); | 559 | cData[4] = __nand_data8(); |
560 | 560 | ||
561 | jz_nand_deselect(i); | 561 | jz_nand_deselect(i); |
562 | 562 | ||
563 | logf("NAND chip %d: 0x%x 0x%x 0x%x 0x%x 0x%x", i+1, cData[0], cData[1], | 563 | logf("NAND chip %d: 0x%x 0x%x 0x%x 0x%x 0x%x", i+1, cData[0], cData[1], |
564 | cData[2], cData[3], cData[4]); | 564 | cData[2], cData[3], cData[4]); |
565 | 565 | ||
566 | banks[i] = nand_identify(cData); | 566 | banks[i] = nand_identify(cData); |
567 | 567 | ||
568 | if(banks[i] != NULL) | 568 | if(banks[i] != NULL) |
569 | nr_banks++; | 569 | nr_banks++; |
570 | 570 | ||
571 | if(i == 0 && banks[i] == NULL) | 571 | if(i == 0 && banks[i] == NULL) |
572 | { | 572 | { |
573 | panicf("Unknown NAND flash chip: 0x%x 0x%x 0x%x 0x%x 0x%x", cData[0], | 573 | panicf("Unknown NAND flash chip: 0x%x 0x%x 0x%x 0x%x 0x%x", cData[0], |
@@ -576,17 +576,17 @@ static int jz_nand_init(void) | |||
576 | } | 576 | } |
577 | } | 577 | } |
578 | chip_info = banks[0]; | 578 | chip_info = banks[0]; |
579 | 579 | ||
580 | internal_param.bus_width = 8; | 580 | internal_param.bus_width = 8; |
581 | internal_param.row_cycle = chip_info->row_cycles; | 581 | internal_param.row_cycle = chip_info->row_cycles; |
582 | internal_param.page_size = chip_info->page_size; | 582 | internal_param.page_size = chip_info->page_size; |
583 | internal_param.oob_size = chip_info->spare_size; | 583 | internal_param.oob_size = chip_info->spare_size; |
584 | internal_param.page_per_block = chip_info->pages_per_block; | 584 | internal_param.page_per_block = chip_info->pages_per_block; |
585 | 585 | ||
586 | bank_size = chip_info->page_size * chip_info->blocks_per_bank / 512 * chip_info->pages_per_block; | 586 | bank_size = chip_info->page_size * chip_info->blocks_per_bank / 512 * chip_info->pages_per_block; |
587 | 587 | ||
588 | jz_nand_disable(); | 588 | jz_nand_disable(); |
589 | 589 | ||
590 | return 0; | 590 | return 0; |
591 | } | 591 | } |
592 | 592 | ||
@@ -594,7 +594,7 @@ int nand_init(void) | |||
594 | { | 594 | { |
595 | int res = 0; | 595 | int res = 0; |
596 | static bool inited = false; | 596 | static bool inited = false; |
597 | 597 | ||
598 | if(!inited) | 598 | if(!inited) |
599 | { | 599 | { |
600 | res = jz_nand_init(); | 600 | res = jz_nand_init(); |
@@ -604,7 +604,7 @@ int nand_init(void) | |||
604 | semaphore_init(&nand_dma_complete, 1, 0); | 604 | semaphore_init(&nand_dma_complete, 1, 0); |
605 | system_enable_irq(DMA_IRQ(DMA_NAND_CHANNEL)); | 605 | system_enable_irq(DMA_IRQ(DMA_NAND_CHANNEL)); |
606 | #endif | 606 | #endif |
607 | 607 | ||
608 | inited = true; | 608 | inited = true; |
609 | } | 609 | } |
610 | 610 | ||
@@ -615,7 +615,7 @@ static inline int read_sector(unsigned long start, unsigned int count, | |||
615 | void* buf, unsigned int chip_size) | 615 | void* buf, unsigned int chip_size) |
616 | { | 616 | { |
617 | register int ret; | 617 | register int ret; |
618 | 618 | ||
619 | if(UNLIKELY(start % chip_size == 0 && count == chip_size)) | 619 | if(UNLIKELY(start % chip_size == 0 && count == chip_size)) |
620 | ret = jz_nand_read_page(start / chip_size, buf); | 620 | ret = jz_nand_read_page(start / chip_size, buf); |
621 | else | 621 | else |
@@ -623,7 +623,7 @@ static inline int read_sector(unsigned long start, unsigned int count, | |||
623 | ret = jz_nand_read_page(start / chip_size, temp_page); | 623 | ret = jz_nand_read_page(start / chip_size, temp_page); |
624 | memcpy(buf, temp_page + (start % chip_size), count); | 624 | memcpy(buf, temp_page + (start % chip_size), count); |
625 | } | 625 | } |
626 | 626 | ||
627 | return ret; | 627 | return ret; |
628 | } | 628 | } |
629 | 629 | ||
@@ -635,13 +635,13 @@ int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* bu | |||
635 | int ret = 0; | 635 | int ret = 0; |
636 | unsigned int i, _count, chip_size = chip_info->page_size; | 636 | unsigned int i, _count, chip_size = chip_info->page_size; |
637 | unsigned long _start; | 637 | unsigned long _start; |
638 | 638 | ||
639 | logf("start"); | 639 | logf("start"); |
640 | mutex_lock(&nand_mtx); | 640 | mutex_lock(&nand_mtx); |
641 | 641 | ||
642 | _start = start << 9; | 642 | _start = start << 9; |
643 | _count = count << 9; | 643 | _count = count << 9; |
644 | 644 | ||
645 | if(_count <= chip_size) | 645 | if(_count <= chip_size) |
646 | { | 646 | { |
647 | jz_nand_select(start / bank_size); | 647 | jz_nand_select(start / bank_size); |
@@ -653,19 +653,19 @@ int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* bu | |||
653 | for(i=0; i<_count && ret==0; i+=chip_size) | 653 | for(i=0; i<_count && ret==0; i+=chip_size) |
654 | { | 654 | { |
655 | jz_nand_select((start+(i>>9)) / bank_size); | 655 | jz_nand_select((start+(i>>9)) / bank_size); |
656 | 656 | ||
657 | ret = read_sector(_start+i, (_count-i < chip_size ? | 657 | ret = read_sector(_start+i, (_count-i < chip_size ? |
658 | _count-i : chip_size), | 658 | _count-i : chip_size), |
659 | buf+i, chip_size); | 659 | buf+i, chip_size); |
660 | 660 | ||
661 | jz_nand_deselect((start+(i>>9)) / bank_size); | 661 | jz_nand_deselect((start+(i>>9)) / bank_size); |
662 | } | 662 | } |
663 | } | 663 | } |
664 | 664 | ||
665 | mutex_unlock(&nand_mtx); | 665 | mutex_unlock(&nand_mtx); |
666 | 666 | ||
667 | logf("nand_read_sectors(%ld, %d, 0x%x): %d", start, count, (int)buf, ret); | 667 | logf("nand_read_sectors(%ld, %d, 0x%x): %d", start, count, (int)buf, ret); |
668 | 668 | ||
669 | return ret; | 669 | return ret; |
670 | } | 670 | } |
671 | 671 | ||
@@ -732,7 +732,7 @@ void nand_get_info(IF_MV(int drive,) struct storage_info *info) | |||
732 | #ifdef HAVE_MULTIVOLUME | 732 | #ifdef HAVE_MULTIVOLUME |
733 | (void)drive; | 733 | (void)drive; |
734 | #endif | 734 | #endif |
735 | 735 | ||
736 | /* firmware version */ | 736 | /* firmware version */ |
737 | info->revision="0.00"; | 737 | info->revision="0.00"; |
738 | 738 | ||
@@ -750,7 +750,7 @@ int nand_num_drives(int first_drive) | |||
750 | { | 750 | { |
751 | /* We don't care which logical drive number(s) we have been assigned */ | 751 | /* We don't care which logical drive number(s) we have been assigned */ |
752 | (void)first_drive; | 752 | (void)first_drive; |
753 | 753 | ||
754 | return 1; | 754 | return 1; |
755 | } | 755 | } |
756 | #endif | 756 | #endif |