summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Purchase <shotofadds@rockbox.org>2008-05-21 21:07:49 +0000
committerRob Purchase <shotofadds@rockbox.org>2008-05-21 21:07:49 +0000
commit03de6c67abed0da759b247ef45785facf6445bd9 (patch)
treed4bb8455597d1b42072b49953fb7ecf298cbab37
parent804bb8e38d3ba1c19c1c651ab674e864312097c8 (diff)
downloadrockbox-03de6c67abed0da759b247ef45785facf6445bd9.tar.gz
rockbox-03de6c67abed0da759b247ef45785facf6445bd9.zip
TCC78x NAND driver: Split the initial bank scan into two passes (appears to improve block translation reliability). Also some cleanups for readability, eg remove chip vs. bank ambiguity and remove leftover debug code.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17598 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/tcc780x/ata-nand-tcc780x.c270
1 files changed, 123 insertions, 147 deletions
diff --git a/firmware/target/arm/tcc780x/ata-nand-tcc780x.c b/firmware/target/arm/tcc780x/ata-nand-tcc780x.c
index 2a22ec76a7..0bf83da1f3 100644
--- a/firmware/target/arm/tcc780x/ata-nand-tcc780x.c
+++ b/firmware/target/arm/tcc780x/ata-nand-tcc780x.c
@@ -25,11 +25,13 @@
25 25
26/* The NAND driver is currently work-in-progress and as such contains 26/* The NAND driver is currently work-in-progress and as such contains
27 some dead code and debug stuff, such as the next few lines. */ 27 some dead code and debug stuff, such as the next few lines. */
28#include "lcd.h"
29#include "font.h"
30#include "button.h"
31#include <sprintf.h>
28 32
29#if defined(BOOTLOADER) 33/* #define USE_TCC_LPT */
30#include "../../../../bootloader/common.h" /* for printf */ 34/* #define USE_ECC_CORRECTION */
31extern int line;
32#endif
33 35
34/* for compatibility */ 36/* for compatibility */
35int ata_spinup_time = 0; 37int ata_spinup_time = 0;
@@ -50,29 +52,27 @@ static struct mutex ata_mtx SHAREDBSS_ATTR;
50#define NFC_SDATA (*(volatile unsigned long *)0xF0053040) 52#define NFC_SDATA (*(volatile unsigned long *)0xF0053040)
51#define NFC_WDATA (*(volatile unsigned long *)0xF0053010) 53#define NFC_WDATA (*(volatile unsigned long *)0xF0053010)
52#define NFC_CTRL (*(volatile unsigned long *)0xF0053050) 54#define NFC_CTRL (*(volatile unsigned long *)0xF0053050)
55 #define NFC_16BIT (1<<26)
56 #define NFC_CS0 (1<<23)
57 #define NFC_CS1 (1<<22)
58 #define NFC_READY (1<<20)
53#define NFC_IREQ (*(volatile unsigned long *)0xF0053060) 59#define NFC_IREQ (*(volatile unsigned long *)0xF0053060)
54#define NFC_RST (*(volatile unsigned long *)0xF0053064) 60#define NFC_RST (*(volatile unsigned long *)0xF0053064)
55 61
56/* NFC_CTRL flags */ 62/* TCC780x ECC Controller */
57#define NFC_16BIT (1<<26)
58#define NFC_CS0 (1<<23)
59#define NFC_CS1 (1<<22)
60#define NFC_READY (1<<20)
61 63
62#define ECC_CTRL (*(volatile unsigned long *)0xF005B000) 64#define ECC_CTRL (*(volatile unsigned long *)0xF005B000)
65 #define ECC_M4EN (1<<6)
66 #define ECC_ENC (1<<27)
67 #define ECC_READY (1<<26)
63#define ECC_BASE (*(volatile unsigned long *)0xF005B004) 68#define ECC_BASE (*(volatile unsigned long *)0xF005B004)
64#define ECC_CLR (*(volatile unsigned long *)0xF005B00C) 69#define ECC_CLR (*(volatile unsigned long *)0xF005B00C)
65#define ECC_MLC0W (*(volatile unsigned long *)0xF005B030) 70#define ECC_MLC0W (*(volatile unsigned long *)0xF005B030)
66#define ECC_MLC1W (*(volatile unsigned long *)0xF005B034) 71#define ECC_MLC1W (*(volatile unsigned long *)0xF005B034)
67#define ECC_MLC2W (*(volatile unsigned long *)0xF005B038) 72#define ECC_MLC2W (*(volatile unsigned long *)0xF005B038)
68#define ECC_ERR (*(volatile unsigned long *)0xF005B070)
69#define ECC_ERRADDR (*(volatile unsigned long *)0xF005B050) 73#define ECC_ERRADDR (*(volatile unsigned long *)0xF005B050)
70#define ECC_ERRDATA (*(volatile unsigned long *)0xF005B060) 74#define ECC_ERRDATA (*(volatile unsigned long *)0xF005B060)
71 75#define ECC_ERR (*(volatile unsigned long *)0xF005B070)
72/* ECC_CTRL flags */
73#define ECC_M4EN (1<<6)
74#define ECC_ENC (1<<27)
75#define ECC_READY (1<<26)
76 76
77/* Chip characteristics, initialised by nand_get_chip_info() */ 77/* Chip characteristics, initialised by nand_get_chip_info() */
78 78
@@ -95,23 +95,23 @@ static int segments_per_bank = 0;
95#define MAX_SPARE_SIZE 128 95#define MAX_SPARE_SIZE 128
96#define MAX_BLOCKS_PER_BANK 8192 96#define MAX_BLOCKS_PER_BANK 8192
97#define MAX_PAGES_PER_BLOCK 128 97#define MAX_PAGES_PER_BLOCK 128
98#define BLOCKS_PER_SEGMENT 4
98 99
99/* In theory we can support 4 banks, but only 2 have been seen on 2/4/8Gb D2s. */ 100/* In theory we can support 4 banks, but only 2 have been seen on 2/4/8Gb D2s */
100#ifdef COWON_D2 101#ifdef COWON_D2
101#define MAX_BANKS 2 102#define MAX_BANKS 2
102#else 103#else
103#define MAX_BANKS 4 104#define MAX_BANKS 4
104#endif 105#endif
105 106
106#define MAX_SEGMENTS (MAX_BLOCKS_PER_BANK * MAX_BANKS / 4) 107#define MAX_SEGMENTS (MAX_BLOCKS_PER_BANK * MAX_BANKS / BLOCKS_PER_SEGMENT)
107 108
108/* Logical/Physical translation table */ 109/* Logical/Physical translation table */
109 110
110struct lpt_entry 111struct lpt_entry
111{ 112{
112 short chip; 113 short bank;
113 short phys_segment; 114 short phys_segment;
114 //short segment_flag;
115}; 115};
116static struct lpt_entry lpt_lookup[MAX_SEGMENTS]; 116static struct lpt_entry lpt_lookup[MAX_SEGMENTS];
117 117
@@ -121,18 +121,26 @@ static struct lpt_entry lpt_lookup[MAX_SEGMENTS];
121 121
122struct write_cache 122struct write_cache
123{ 123{
124 short chip; 124 short bank;
125 short phys_segment; 125 short phys_segment;
126 short log_segment; 126 short log_segment;
127 short page_map[MAX_PAGES_PER_BLOCK * 4]; 127 short page_map[MAX_PAGES_PER_BLOCK * BLOCKS_PER_SEGMENT];
128}; 128};
129static struct write_cache write_caches[MAX_WRITE_CACHES]; 129static struct write_cache write_caches[MAX_WRITE_CACHES];
130 130
131static int write_caches_in_use = 0; 131static int write_caches_in_use = 0;
132 132
133/* Read buffer */ 133#ifdef USE_TCC_LPT
134/* Read buffer (used for reading LPT blocks only) */
135static unsigned char page_buf[MAX_PAGE_SIZE + MAX_SPARE_SIZE]
136 __attribute__ ((aligned (4)));
137#endif
134 138
135unsigned int page_buf[(MAX_PAGE_SIZE + MAX_SPARE_SIZE) / 4]; 139#ifdef USE_ECC_CORRECTION
140static unsigned int ecc_sectors_corrected = 0;
141static unsigned int ecc_bits_corrected = 0;
142static unsigned int ecc_fail_count = 0;
143#endif
136 144
137 145
138/* Conversion functions */ 146/* Conversion functions */
@@ -161,9 +169,9 @@ static inline int phys_segment_to_page_addr(int phys_segment, int page_in_seg)
161 169
162/* NAND physical access functions */ 170/* NAND physical access functions */
163 171
164static void nand_chip_select(int chip) 172static void nand_chip_select(int bank)
165{ 173{
166 if (chip == -1) 174 if (bank == -1)
167 { 175 {
168 /* Disable both chip selects */ 176 /* Disable both chip selects */
169 GPIOB_CLEAR = (1<<21); 177 GPIOB_CLEAR = (1<<21);
@@ -172,7 +180,11 @@ static void nand_chip_select(int chip)
172 else 180 else
173 { 181 {
174 /* NFC chip select */ 182 /* NFC chip select */
175 if (chip & 1) 183#ifdef USE_TCC_LPT
184 if (!(bank & 1))
185#else
186 if (bank & 1)
187#endif
176 { 188 {
177 NFC_CTRL &= ~NFC_CS0; 189 NFC_CTRL &= ~NFC_CS0;
178 NFC_CTRL |= NFC_CS1; 190 NFC_CTRL |= NFC_CS1;
@@ -184,7 +196,7 @@ static void nand_chip_select(int chip)
184 } 196 }
185 197
186 /* Secondary chip select */ 198 /* Secondary chip select */
187 if (chip & 2) 199 if (bank & 2)
188 { 200 {
189 GPIOB_SET = (1<<21); 201 GPIOB_SET = (1<<21);
190 } 202 }
@@ -196,7 +208,7 @@ static void nand_chip_select(int chip)
196} 208}
197 209
198 210
199static void nand_read_id(int chip, unsigned char* id_buf) 211static void nand_read_id(int bank, unsigned char* id_buf)
200{ 212{
201 int i; 213 int i;
202 214
@@ -209,7 +221,7 @@ static void nand_read_id(int chip, unsigned char* id_buf)
209 /* Set slow cycle timings since the chip is as yet unidentified */ 221 /* Set slow cycle timings since the chip is as yet unidentified */
210 NFC_CTRL = (NFC_CTRL &~0xFFF) | 0x353; 222 NFC_CTRL = (NFC_CTRL &~0xFFF) | 0x353;
211 223
212 nand_chip_select(chip); 224 nand_chip_select(bank);
213 225
214 /* Set write protect */ 226 /* Set write protect */
215 GPIOB_CLEAR = (1<<19); 227 GPIOB_CLEAR = (1<<19);
@@ -237,7 +249,7 @@ static void nand_read_id(int chip, unsigned char* id_buf)
237} 249}
238 250
239 251
240static void nand_read_uid(int chip, unsigned int* uid_buf) 252static void nand_read_uid(int bank, unsigned int* uid_buf)
241{ 253{
242 int i; 254 int i;
243 255
@@ -247,7 +259,7 @@ static void nand_read_uid(int chip, unsigned int* uid_buf)
247 /* Set cycle timing (stp = 1, pw = 3, hold = 1) */ 259 /* Set cycle timing (stp = 1, pw = 3, hold = 1) */
248 NFC_CTRL = (NFC_CTRL &~0xFFF) | 0x131; 260 NFC_CTRL = (NFC_CTRL &~0xFFF) | 0x131;
249 261
250 nand_chip_select(chip); 262 nand_chip_select(bank);
251 263
252 /* Set write protect */ 264 /* Set write protect */
253 GPIOB_CLEAR = 1<<19; 265 GPIOB_CLEAR = 1<<19;
@@ -289,7 +301,7 @@ static void nand_read_uid(int chip, unsigned int* uid_buf)
289} 301}
290 302
291 303
292static void nand_read_raw(int chip, int row, int column, int size, void* buf) 304static void nand_read_raw(int bank, int row, int column, int size, void* buf)
293{ 305{
294 int i; 306 int i;
295 307
@@ -299,7 +311,7 @@ static void nand_read_raw(int chip, int row, int column, int size, void* buf)
299 /* Set cycle timing (stp = 1, pw = 3, hold = 1) */ 311 /* Set cycle timing (stp = 1, pw = 3, hold = 1) */
300 NFC_CTRL = (NFC_CTRL &~0xFFF) | 0x131; 312 NFC_CTRL = (NFC_CTRL &~0xFFF) | 0x131;
301 313
302 nand_chip_select(chip); 314 nand_chip_select(bank);
303 315
304 /* Set write protect */ 316 /* Set write protect */
305 GPIOB_CLEAR = (1<<19); 317 GPIOB_CLEAR = (1<<19);
@@ -407,8 +419,8 @@ static void nand_get_chip_info(void)
407 } 419 }
408 420
409 pages_per_bank = blocks_per_bank * pages_per_block; 421 pages_per_bank = blocks_per_bank * pages_per_block;
410 segments_per_bank = blocks_per_bank / 4; 422 segments_per_bank = blocks_per_bank / BLOCKS_PER_SEGMENT;
411 bytes_per_segment = page_size * pages_per_block * 4; 423 bytes_per_segment = page_size * pages_per_block * BLOCKS_PER_SEGMENT;
412 sectors_per_page = page_size / SECTOR_SIZE; 424 sectors_per_page = page_size / SECTOR_SIZE;
413 sectors_per_segment = bytes_per_segment / SECTOR_SIZE; 425 sectors_per_segment = bytes_per_segment / SECTOR_SIZE;
414 426
@@ -476,27 +488,29 @@ static void nand_get_chip_info(void)
476} 488}
477 489
478 490
479static bool nand_read_sector_of_phys_page(int chip, int page, 491static bool nand_read_sector_of_phys_page(int bank, int page,
480 int sector, void* buf) 492 int sector, void* buf)
481{ 493{
482 nand_read_raw(chip, page, 494#ifndef USE_ECC_CORRECTION
495 nand_read_raw(bank, page,
483 sector * (SECTOR_SIZE+16), 496 sector * (SECTOR_SIZE+16),
484 SECTOR_SIZE, buf); 497 SECTOR_SIZE, buf);
485
486 /* TODO: Read the 16 spare bytes, perform ECC correction */
487
488 return true; 498 return true;
499#else
500 /* Not yet implemented */
501 return false;
502#endif
489} 503}
490 504
491 505
492static bool nand_read_sector_of_phys_segment(int chip, int phys_segment, 506static bool nand_read_sector_of_phys_segment(int bank, int phys_segment,
493 int page_in_seg, int sector, 507 int page_in_seg, int sector,
494 void* buf) 508 void* buf)
495{ 509{
496 int page_addr = phys_segment_to_page_addr(phys_segment, 510 int page_addr = phys_segment_to_page_addr(phys_segment,
497 page_in_seg); 511 page_in_seg);
498 512
499 return nand_read_sector_of_phys_page(chip, page_addr, sector, buf); 513 return nand_read_sector_of_phys_page(bank, page_addr, sector, buf);
500} 514}
501 515
502 516
@@ -506,7 +520,7 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector,
506 int page_in_segment = sector / sectors_per_page; 520 int page_in_segment = sector / sectors_per_page;
507 int sector_in_page = sector % sectors_per_page; 521 int sector_in_page = sector % sectors_per_page;
508 522
509 int chip = lpt_lookup[log_segment].chip; 523 int bank = lpt_lookup[log_segment].bank;
510 int phys_segment = lpt_lookup[log_segment].phys_segment; 524 int phys_segment = lpt_lookup[log_segment].phys_segment;
511 525
512 /* Check if any of the write caches refer to this segment/page. 526 /* Check if any of the write caches refer to this segment/page.
@@ -521,7 +535,7 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector,
521 && write_caches[cache_num].page_map[page_in_segment] != -1) 535 && write_caches[cache_num].page_map[page_in_segment] != -1)
522 { 536 {
523 found = true; 537 found = true;
524 chip = write_caches[cache_num].chip; 538 bank = write_caches[cache_num].bank;
525 phys_segment = write_caches[cache_num].phys_segment; 539 phys_segment = write_caches[cache_num].phys_segment;
526 page_in_segment = write_caches[cache_num].page_map[page_in_segment]; 540 page_in_segment = write_caches[cache_num].page_map[page_in_segment];
527 } 541 }
@@ -531,14 +545,19 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector,
531 } 545 }
532 } 546 }
533 547
534 return nand_read_sector_of_phys_segment(chip, phys_segment, 548 return nand_read_sector_of_phys_segment(bank, phys_segment,
535 page_in_segment, 549 page_in_segment,
536 sector_in_page, buf); 550 sector_in_page, buf);
537} 551}
538 552
539#if 0 // LPT table is work-in-progress
540 553
541static void read_lpt_block(int chip, int phys_segment) 554#ifdef USE_TCC_LPT
555
556/* Reading the LPT from NAND is not yet fully understood. This code is therefore
557 not enabled by default, as it gives much worse results than the bank-scanning
558 approach currently used. */
559
560static void read_lpt_block(int bank, int phys_segment)
542{ 561{
543 int page = 1; /* table starts at page 1 of segment */ 562 int page = 1; /* table starts at page 1 of segment */
544 bool cont = true; 563 bool cont = true;
@@ -548,8 +567,9 @@ static void read_lpt_block(int chip, int phys_segment)
548 while (cont && page < pages_per_block) 567 while (cont && page < pages_per_block)
549 { 568 {
550 int i = 0; 569 int i = 0;
570 unsigned int* int_buf = (int*)page_buf;
551 571
552 nand_read_sector_of_phys_segment(chip, phys_segment, 572 nand_read_sector_of_phys_segment(bank, phys_segment,
553 page, 0, /* only sector 0 is used */ 573 page, 0, /* only sector 0 is used */
554 page_buf); 574 page_buf);
555 575
@@ -557,12 +577,12 @@ static void read_lpt_block(int chip, int phys_segment)
557 Do this by reading the logical segment number of entry 0 */ 577 Do this by reading the logical segment number of entry 0 */
558 if (lpt_ptr == NULL) 578 if (lpt_ptr == NULL)
559 { 579 {
560 int first_chip = page_buf[0] / segments_per_bank; 580 int first_bank = int_buf[0] / segments_per_bank;
561 int first_phys_segment = page_buf[0] % segments_per_bank; 581 int first_phys_segment = int_buf[0] % segments_per_bank;
562 582
563 unsigned char spare_buf[16]; 583 unsigned char spare_buf[16];
564 584
565 nand_read_raw(first_chip, 585 nand_read_raw(first_bank,
566 phys_segment_to_page_addr(first_phys_segment, 0), 586 phys_segment_to_page_addr(first_phys_segment, 0),
567 SECTOR_SIZE, /* offset */ 587 SECTOR_SIZE, /* offset */
568 16, spare_buf); 588 16, spare_buf);
@@ -573,16 +593,16 @@ static void read_lpt_block(int chip, int phys_segment)
573 593
574#if defined(BOOTLOADER) && 1 594#if defined(BOOTLOADER) && 1
575 printf("lpt @ %lx:%lx (ls:%lx)", 595 printf("lpt @ %lx:%lx (ls:%lx)",
576 first_chip, first_phys_segment, first_log_segment); 596 first_bank, first_phys_segment, first_log_segment);
577#endif 597#endif
578 } 598 }
579 599
580 while (cont && (i < SECTOR_SIZE/4)) 600 while (cont && (i < SECTOR_SIZE/4))
581 { 601 {
582 if (page_buf[i] != 0xFFFFFFFF) 602 if (int_buf[i] != 0xFFFFFFFF)
583 { 603 {
584 lpt_ptr->chip = page_buf[i] / segments_per_bank; 604 lpt_ptr->bank = int_buf[i] / segments_per_bank;
585 lpt_ptr->phys_segment = page_buf[i] % segments_per_bank; 605 lpt_ptr->phys_segment = int_buf[i] % segments_per_bank;
586 606
587 lpt_ptr++; 607 lpt_ptr++;
588 i++; 608 i++;
@@ -593,10 +613,10 @@ static void read_lpt_block(int chip, int phys_segment)
593 } 613 }
594} 614}
595 615
596#endif 616#endif /* USE_TCC_LPT */
597 617
598 618
599static void read_write_cache_segment(int chip, int phys_segment) 619static void read_write_cache_segment(int bank, int phys_segment)
600{ 620{
601 int page; 621 int page;
602 unsigned char spare_buf[16]; 622 unsigned char spare_buf[16];
@@ -604,17 +624,17 @@ static void read_write_cache_segment(int chip, int phys_segment)
604 if (write_caches_in_use == MAX_WRITE_CACHES) 624 if (write_caches_in_use == MAX_WRITE_CACHES)
605 panicf("Max NAND write caches reached"); 625 panicf("Max NAND write caches reached");
606 626
607 write_caches[write_caches_in_use].chip = chip; 627 write_caches[write_caches_in_use].bank = bank;
608 write_caches[write_caches_in_use].phys_segment = phys_segment; 628 write_caches[write_caches_in_use].phys_segment = phys_segment;
609 629
610 /* Loop over each page in the phys segment (from page 1 onwards). 630 /* Loop over each page in the phys segment (from page 1 onwards).
611 Read spare for 1st sector, store location of page in array. */ 631 Read spare for 1st sector, store location of page in array. */
612 for (page = 1; page < pages_per_block * 4; page++) 632 for (page = 1; page < pages_per_block * BLOCKS_PER_SEGMENT; page++)
613 { 633 {
614 unsigned short cached_page; 634 unsigned short cached_page;
615 unsigned short log_segment; 635 unsigned short log_segment;
616 636
617 nand_read_raw(chip, phys_segment_to_page_addr(phys_segment, page), 637 nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, page),
618 SECTOR_SIZE, /* offset to first sector's spare */ 638 SECTOR_SIZE, /* offset to first sector's spare */
619 16, spare_buf); 639 16, spare_buf);
620 640
@@ -631,70 +651,6 @@ static void read_write_cache_segment(int chip, int phys_segment)
631} 651}
632 652
633 653
634/* TEMP testing functions */
635
636#ifdef BOOTLOADER
637
638#if 0
639static void display_page(int chip, int page)
640{
641 int i;
642 nand_read_raw(chip, page, 0, page_size+spare_size, page_buf);
643
644 for (i = 0; i < (page_size+spare_size)/4; i += 132)
645 {
646 int j,interesting = 0;
647 line = 1;
648 printf("c:%d p:%lx s:%d", chip, page, i/128);
649
650 for (j=i; j<(i+131); j++)
651 {
652 if (page_buf[j] != 0xffffffff) interesting = 1;
653 }
654
655 if (interesting)
656 {
657 for (j=i; j<(i+131); j+=8)
658 {
659 printf("%lx %lx %lx %lx %lx %lx %lx %lx",
660 page_buf[j],page_buf[j+1],page_buf[j+2],page_buf[j+3],
661 page_buf[j+4],page_buf[j+5],page_buf[j+6],page_buf[j+7]);
662 }
663 while (!button_read_device()) {};
664 while (button_read_device()) {};
665 reset_screen();
666 }
667 }
668}
669#endif
670
671static void nand_test(void)
672{
673 int segment = 0;
674
675 printf("%d banks", total_banks);
676 printf("* %d pages", pages_per_bank);
677 printf("* %d bytes per page", page_size);
678
679 while (lpt_lookup[segment].chip != -1
680 && segment < segments_per_bank * total_banks)
681 {
682 segment++;
683 }
684 printf("%d sequential segments found (%dMb)",
685 segment, (unsigned)(segment*bytes_per_segment)>>20);
686}
687#endif
688
689
690/* API Functions */
691#if 0 /* currently unused */
692static void ata_led(bool onoff)
693{
694 led(onoff);
695}
696#endif
697
698int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, 654int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
699 void* inbuf) 655 void* inbuf)
700{ 656{
@@ -730,7 +686,7 @@ int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
730 } 686 }
731 start += done; 687 start += done;
732 } 688 }
733 689
734 mutex_unlock(&ata_mtx); 690 mutex_unlock(&ata_mtx);
735 return 0; 691 return 0;
736} 692}
@@ -796,15 +752,14 @@ int ata_init(void)
796 unsigned char spare_buf[16]; 752 unsigned char spare_buf[16];
797 753
798 if (initialized) return 0; 754 if (initialized) return 0;
799 755
800 /* Get chip characteristics and number of banks */ 756 /* Get chip characteristics and number of banks */
801 nand_get_chip_info(); 757 nand_get_chip_info();
802 758
803 for (i = 0; i < MAX_SEGMENTS; i++) 759 for (i = 0; i < MAX_SEGMENTS; i++)
804 { 760 {
805 lpt_lookup[i].chip = -1; 761 lpt_lookup[i].bank = -1;
806 lpt_lookup[i].phys_segment = -1; 762 lpt_lookup[i].phys_segment = -1;
807 //lpt_lookup[i].segment_flag = -1;
808 } 763 }
809 764
810 write_caches_in_use = 0; 765 write_caches_in_use = 0;
@@ -814,7 +769,7 @@ int ata_init(void)
814 int page; 769 int page;
815 770
816 write_caches[i].log_segment = -1; 771 write_caches[i].log_segment = -1;
817 write_caches[i].chip = -1; 772 write_caches[i].bank = -1;
818 write_caches[i].phys_segment = -1; 773 write_caches[i].phys_segment = -1;
819 774
820 for (page = 0; page < MAX_PAGES_PER_BLOCK * 4; page++) 775 for (page = 0; page < MAX_PAGES_PER_BLOCK * 4; page++)
@@ -835,32 +790,27 @@ int ata_init(void)
835 790
836 switch (spare_buf[4]) /* block type */ 791 switch (spare_buf[4]) /* block type */
837 { 792 {
793#ifdef USE_TCC_LPT
838 case 0x12: 794 case 0x12:
839 { 795 {
840 /* Log->Phys Translation table (for Main data area) */ 796 /* Log->Phys Translation table (for Main data area) */
841 //read_lpt_block(bank, phys_segment); 797 read_lpt_block(bank, phys_segment);
842 break; 798 break;
843 } 799 }
844 800#else
845 case 0x13:
846 case 0x17: 801 case 0x17:
847 { 802 {
848 /* Main data area segment */ 803 /* Main data area segment */
849 int segment = (spare_buf[6] << 8) | spare_buf[7]; 804 unsigned short segment = (spare_buf[6] << 8) | spare_buf[7];
850 805
851 if (segment < MAX_SEGMENTS) 806 if (segment < MAX_SEGMENTS)
852 { 807 {
853 /* Store in LPT if not present or 0x17 overrides 0x13 */ 808 lpt_lookup[segment].bank = bank;
854 //if (lpt_lookup[segment].segment_flag == -1 || 809 lpt_lookup[segment].phys_segment = phys_segment;
855 // lpt_lookup[segment].segment_flag == 0x13)
856 {
857 lpt_lookup[segment].chip = bank;
858 lpt_lookup[segment].phys_segment = phys_segment;
859 //lpt_lookup[segment].segment_flag = spare_buf[4];
860 }
861 } 810 }
862 break; 811 break;
863 } 812 }
813#endif
864 814
865 case 0x15: 815 case 0x15:
866 { 816 {
@@ -872,12 +822,38 @@ int ata_init(void)
872 } 822 }
873 } 823 }
874 824
875 initialized = true; 825#ifndef USE_TCC_LPT
876 826 /* Scan banks a second time as 0x13 segments appear to override 0x17 */
877#ifdef BOOTLOADER 827 for (bank = 0; bank < total_banks; bank++)
878 /* TEMP - print out some diagnostics */ 828 {
879 nand_test(); 829 for (phys_segment = 0; phys_segment < segments_per_bank; phys_segment++)
830 {
831 /* Read spare bytes from first sector of each segment */
832 nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, 0),
833 SECTOR_SIZE, /* offset */
834 16, spare_buf);
835
836 switch (spare_buf[4]) /* block type */
837 {
838 case 0x13:
839 {
840 /* Main data area segment */
841 unsigned short segment = (spare_buf[6] << 8) | spare_buf[7];
842
843 if (segment < MAX_SEGMENTS)
844 {
845 /* 0x17 seems to override 0x13, so store in our LPT */
846 lpt_lookup[segment].bank = bank;
847 lpt_lookup[segment].phys_segment = phys_segment;
848 }
849 break;
850 }
851 }
852 }
853 }
880#endif 854#endif
855
856 initialized = true;
881 857
882 return 0; 858 return 0;
883} 859}