summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorRob Purchase <shotofadds@rockbox.org>2008-09-07 19:44:23 +0000
committerRob Purchase <shotofadds@rockbox.org>2008-09-07 19:44:23 +0000
commite682143af578d9643f45712f0dcbcc13e94597d4 (patch)
treedaba1a7754cf88bf3e864b13949f55368cd181a1 /firmware
parentb6058de5f94956c3df7ef5efa05337d5403a7ac9 (diff)
downloadrockbox-e682143af578d9643f45712f0dcbcc13e94597d4.tar.gz
rockbox-e682143af578d9643f45712f0dcbcc13e94597d4.zip
Telechips NAND: split out a couple of small functions to help readability, and add a note about LPT blocks. No functional changes.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18440 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/target/arm/ata-nand-telechips.c81
1 files changed, 54 insertions, 27 deletions
diff --git a/firmware/target/arm/ata-nand-telechips.c b/firmware/target/arm/ata-nand-telechips.c
index 668c8a9d69..316780d417 100644
--- a/firmware/target/arm/ata-nand-telechips.c
+++ b/firmware/target/arm/ata-nand-telechips.c
@@ -184,11 +184,7 @@ static void nand_chip_select(int bank)
184 else 184 else
185 { 185 {
186 /* NFC chip select */ 186 /* NFC chip select */
187#ifdef USE_TCC_LPT
188 if (!(bank & 1))
189#else
190 if (bank & 1) 187 if (bank & 1)
191#endif
192 { 188 {
193 NFC_CTRL &= ~NFC_CS0; 189 NFC_CTRL &= ~NFC_CS0;
194 NFC_CTRL |= NFC_CS1; 190 NFC_CTRL |= NFC_CS1;
@@ -524,11 +520,44 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector,
524} 520}
525 521
526 522
523/* Miscellaneous helper functions */
524
525static inline char get_segment_type(char* spare_buf)
526{
527 return spare_buf[OFF_SEGMENT_TYPE];
528}
529
530static inline unsigned short get_log_segment_id(char* spare_buf)
531{
532 return (spare_buf[OFF_LOG_SEG_HIBYTE] << 8) |
533 spare_buf[OFF_LOG_SEG_LOBYTE];
534}
535
536static inline unsigned short get_cached_page_id(char* spare_buf)
537{
538 return (spare_buf[OFF_CACHE_PAGE_HIBYTE] << 8) |
539 spare_buf[OFF_CACHE_PAGE_LOBYTE];
540}
541
542
543
527#ifdef USE_TCC_LPT 544#ifdef USE_TCC_LPT
528 545
529/* Reading the LPT from NAND is not yet fully understood. This code is therefore 546/* Reading the LPT from NAND is not yet fully understood. This code is therefore
530 not enabled by default, as it gives much worse results than the bank-scanning 547 not enabled by default, as it gives much worse results than the bank-scanning
531 approach currently used. */ 548 approach currently used.
549
550 The LPT is stored in a number of physical segments marked with type 0x12.
551 These are spread non-contiguously across the NAND, and are not stored in
552 sequential order.
553
554 The LPT data is stored in Sector 0 of the first <n> pages of each segment.
555 Each 32-bit value in sequence represents the physical location of a logical
556 segment. This is stored as (physical segment number * bank number).
557
558 NOTE: The bank numbers stored appear to be in reverse order to that required
559 by the nand_chip_select() function. The reason for this anomoly is unknown.
560*/
532 561
533static void read_lpt_block(int bank, int phys_segment) 562static void read_lpt_block(int bank, int phys_segment)
534{ 563{
@@ -553,6 +582,10 @@ static void read_lpt_block(int bank, int phys_segment)
553 int first_bank = int_buf[0] / segments_per_bank; 582 int first_bank = int_buf[0] / segments_per_bank;
554 int first_phys_segment = int_buf[0] % segments_per_bank; 583 int first_phys_segment = int_buf[0] % segments_per_bank;
555 584
585 /* Reverse the stored bank number */
586 if (total_banks > 1)
587 first_bank = (total_banks-1) - first_bank;
588
556 unsigned char spare_buf[16]; 589 unsigned char spare_buf[16];
557 590
558 nand_read_raw(first_bank, 591 nand_read_raw(first_bank,
@@ -560,23 +593,24 @@ static void read_lpt_block(int bank, int phys_segment)
560 SECTOR_SIZE, /* offset */ 593 SECTOR_SIZE, /* offset */
561 16, spare_buf); 594 16, spare_buf);
562 595
563 int first_log_segment = (spare_buf[OFF_LOG_SEG_HIBYTE] << 8) | 596 int first_log_segment = get_log_segment_id(spare_buf);
564 spare_buf[OFF_LOG_SEG_LOBYTE];
565 597
566 lpt_ptr = &lpt_lookup[first_log_segment]; 598 lpt_ptr = &lpt_lookup[first_log_segment];
567
568#if defined(BOOTLOADER) && 1
569 printf("lpt @ %lx:%lx (ls:%lx)",
570 first_bank, first_phys_segment, first_log_segment);
571#endif
572 } 599 }
573 600
574 while (cont && (i < SECTOR_SIZE/4)) 601 while (cont && (i < SECTOR_SIZE/4))
575 { 602 {
576 if (int_buf[i] != 0xFFFFFFFF) 603 if (int_buf[i] != 0xFFFFFFFF)
577 { 604 {
578 lpt_ptr->bank = int_buf[i] / segments_per_bank; 605 int bank = int_buf[i] / segments_per_bank;
579 lpt_ptr->phys_segment = int_buf[i] % segments_per_bank; 606 int phys_segment = int_buf[i] % segments_per_bank;
607
608 /* Reverse the stored bank number */
609 if (total_banks > 1)
610 bank = (total_banks-1) - bank;
611
612 lpt_ptr->bank = bank;
613 lpt_ptr->phys_segment = phys_segment;
580 614
581 lpt_ptr++; 615 lpt_ptr++;
582 i++; 616 i++;
@@ -612,11 +646,8 @@ static void read_write_cache_segment(int bank, int phys_segment)
612 SECTOR_SIZE, /* offset to first sector's spare */ 646 SECTOR_SIZE, /* offset to first sector's spare */
613 16, spare_buf); 647 16, spare_buf);
614 648
615 cached_page = (spare_buf[OFF_CACHE_PAGE_HIBYTE] << 8) | 649 cached_page = get_cached_page_id(spare_buf);
616 spare_buf[OFF_CACHE_PAGE_LOBYTE]; 650 log_segment = get_log_segment_id(spare_buf);
617
618 log_segment = (spare_buf[OFF_LOG_SEG_HIBYTE] << 8) |
619 spare_buf[OFF_LOG_SEG_LOBYTE];
620 651
621 if (cached_page != 0xFFFF) 652 if (cached_page != 0xFFFF)
622 { 653 {
@@ -775,7 +806,7 @@ int ata_init(void)
775 SECTOR_SIZE, /* offset */ 806 SECTOR_SIZE, /* offset */
776 16, spare_buf); 807 16, spare_buf);
777 808
778 switch (spare_buf[4]) /* block type */ 809 switch (get_segment_type(spare_buf))
779 { 810 {
780#ifdef USE_TCC_LPT 811#ifdef USE_TCC_LPT
781 case SEGMENT_MAIN_LPT: 812 case SEGMENT_MAIN_LPT:
@@ -788,9 +819,7 @@ int ata_init(void)
788 case SEGMENT_MAIN_DATA2: 819 case SEGMENT_MAIN_DATA2:
789 { 820 {
790 /* Main data area segment */ 821 /* Main data area segment */
791 unsigned short log_segment 822 unsigned short log_segment = get_log_segment_id(spare_buf);
792 = (spare_buf[OFF_LOG_SEG_HIBYTE] << 8) |
793 spare_buf[OFF_LOG_SEG_LOBYTE];
794 823
795 if (log_segment < MAX_SEGMENTS) 824 if (log_segment < MAX_SEGMENTS)
796 { 825 {
@@ -822,14 +851,12 @@ int ata_init(void)
822 SECTOR_SIZE, /* offset */ 851 SECTOR_SIZE, /* offset */
823 16, spare_buf); 852 16, spare_buf);
824 853
825 switch (spare_buf[4]) /* block type */ 854 switch (get_segment_type(spare_buf)) /* block type */
826 { 855 {
827 case SEGMENT_MAIN_DATA1: 856 case SEGMENT_MAIN_DATA1:
828 { 857 {
829 /* Main data area segment */ 858 /* Main data area segment */
830 unsigned short log_segment 859 unsigned short log_segment = get_log_segment_id(spare_buf);
831 = (spare_buf[OFF_LOG_SEG_HIBYTE] << 8) |
832 spare_buf[OFF_LOG_SEG_LOBYTE];
833 860
834 if (log_segment < MAX_SEGMENTS) 861 if (log_segment < MAX_SEGMENTS)
835 { 862 {