summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Malesinski <tomal@rockbox.org>2006-08-12 22:51:18 +0000
committerTomasz Malesinski <tomal@rockbox.org>2006-08-12 22:51:18 +0000
commitc1810b31f170e887668652ff4e3d76c392a5fb70 (patch)
treede7c62c7fe64e58e0da58cfc2d27adb86620909f
parent17972c9267eddccd6c6f5f41d004d7627bd0c773 (diff)
downloadrockbox-c1810b31f170e887668652ff4e3d76c392a5fb70.tar.gz
rockbox-c1810b31f170e887668652ff4e3d76c392a5fb70.zip
Added support for 512MB chips. Added support for multiple chips.
Fixed a bug in ata_read_sectors. Made some functions static and inline. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10555 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/ata_flash.c70
1 files changed, 47 insertions, 23 deletions
diff --git a/firmware/drivers/ata_flash.c b/firmware/drivers/ata_flash.c
index 17796e0d50..72520ac499 100644
--- a/firmware/drivers/ata_flash.c
+++ b/firmware/drivers/ata_flash.c
@@ -54,19 +54,22 @@ static unsigned char flash_ce[4] = {0x20, 0x02, 0x10, 0x08};
54#define FLASH_REG_ADDR (*((volatile unsigned char*)(FLASH_IO_BASE + 8))) 54#define FLASH_REG_ADDR (*((volatile unsigned char*)(FLASH_IO_BASE + 8)))
55 55
56#define SEGMENT_SIZE 1000 56#define SEGMENT_SIZE 1000
57#define MAX_N_SEGMENTS 2 57#define MAX_N_SEGMENTS 8
58 58
59#endif 59#endif
60 60
61#define FLASH_MODEL_NONE 0 61#define FLASH_MODEL_NONE 0
62#define FLASH_MODEL_256 1 62#define FLASH_MODEL_256 1
63#define FLASH_MODEL_512 2
63 64
64struct flash_disk 65struct flash_disk
65{ 66{
66 short model;
67 unsigned short block_map[MAX_N_SEGMENTS][SEGMENT_SIZE]; 67 unsigned short block_map[MAX_N_SEGMENTS][SEGMENT_SIZE];
68 short cur_block; 68 short cur_block;
69 int cur_phblock_start; 69 int cur_phblock_start;
70 int n_chips;
71 unsigned char chip_no[4];
72 unsigned char model;
70}; 73};
71 74
72static struct flash_disk flash_disk; 75static struct flash_disk flash_disk;
@@ -81,45 +84,53 @@ void flash_select_chip(int no, int sel)
81#endif 84#endif
82} 85}
83 86
84unsigned char flash_read_data(void) 87static inline unsigned char flash_read_data(void)
85{ 88{
86 return FLASH_REG_DATA; 89 return FLASH_REG_DATA;
87} 90}
88 91
89void flash_write_data(unsigned char data) 92static inline void flash_write_data(unsigned char data)
90{ 93{
91 FLASH_REG_DATA = data; 94 FLASH_REG_DATA = data;
92} 95}
93 96
94void flash_write_cmd(unsigned char cmd) 97/* TODO: these two doesn't work when inlined, probably some
98 delay is required */
99
100static void flash_write_cmd(unsigned char cmd)
95{ 101{
96 FLASH_REG_CMD = cmd; 102 FLASH_REG_CMD = cmd;
97} 103}
98 104
99void flash_write_addr(unsigned char addr) 105static void flash_write_addr(unsigned char addr)
100{ 106{
101 FLASH_REG_ADDR = addr; 107 FLASH_REG_ADDR = addr;
102} 108}
103 109
104void flash_wait_ready(void) 110static void flash_wait_ready(void)
105{ 111{
106 int i; 112 int i;
107 for (i = 0; i < 5; i++) 113 for (i = 0; i < 5; i++)
108 while ((GPIO6_READ & 8) == 0); 114 while ((GPIO6_READ & 8) == 0);
109} 115}
110 116
117static unsigned char model_n_sectors_order[] = {0, 19, 20};
118
111int flash_map_sector(int sector, int* chip, int* chip_sector) 119int flash_map_sector(int sector, int* chip, int* chip_sector)
112{ 120{
113 switch (flash_disk.model) 121 int ord, c;
114 { 122 if (flash_disk.model == FLASH_MODEL_NONE)
115 case FLASH_MODEL_NONE: 123 return -1;
116 default: 124
117 return -1; 125 ord = model_n_sectors_order[flash_disk.model];
118 case FLASH_MODEL_256: 126 c = sector >> ord;
119 *chip = 0; 127 *chip_sector = sector & ((1 << ord) - 1);
120 *chip_sector = sector; 128
121 return 0; 129 if (c >= flash_disk.n_chips)
122 } 130 return -1;
131
132 *chip = flash_disk.chip_no[c];
133 return 0;
123} 134}
124 135
125int flash_read_id(int no) { 136int flash_read_id(int no) {
@@ -199,19 +210,19 @@ int flash_read_sector_oob(int sector, unsigned char* oob)
199 return 0; 210 return 0;
200} 211}
201 212
202static unsigned char model_n_segments[] = {0, 2}; 213static unsigned char model_n_segments[] = {0, 2, 4};
203 214
204static int flash_get_n_segments(void) 215static inline int flash_get_n_segments(void)
205{ 216{
206 return model_n_segments[flash_disk.model]; 217 return model_n_segments[flash_disk.model] * flash_disk.n_chips;
207} 218}
208 219
209static int flash_get_n_phblocks(void) 220static inline int flash_get_n_phblocks(void)
210{ 221{
211 return 1024; 222 return 1024;
212} 223}
213 224
214static int model_n_sectors_in_block[] = {0, 256}; 225static int model_n_sectors_in_block[] = {0, 256, 256};
215 226
216static int flash_get_n_sectors_in_block(void) 227static int flash_get_n_sectors_in_block(void)
217{ 228{
@@ -362,6 +373,7 @@ int ata_read_sectors(IF_MV2(int drive,)
362 int done = flash_disk_read_sectors(start, incount, inbuf); 373 int done = flash_disk_read_sectors(start, incount, inbuf);
363 if (done < 0) 374 if (done < 0)
364 return -1; 375 return -1;
376 start += done;
365 incount -= done; 377 incount -= done;
366 inbuf += SECTOR_SIZE * done; 378 inbuf += SECTOR_SIZE * done;
367 } 379 }
@@ -434,7 +446,7 @@ unsigned short* ata_get_identify(void)
434 446
435int ata_init(void) 447int ata_init(void)
436{ 448{
437 int id; 449 int i, id, id2;
438 450
439 id = flash_read_id(0); 451 id = flash_read_id(0);
440 switch (id) 452 switch (id)
@@ -442,11 +454,23 @@ int ata_init(void)
442 case 0xda: 454 case 0xda:
443 flash_disk.model = FLASH_MODEL_256; 455 flash_disk.model = FLASH_MODEL_256;
444 break; 456 break;
457 case 0xdc:
458 flash_disk.model = FLASH_MODEL_512;
459 break;
445 default: 460 default:
446 flash_disk.model = FLASH_MODEL_NONE; 461 flash_disk.model = FLASH_MODEL_NONE;
447 return -1; 462 return -1;
448 } 463 }
449 464
465 flash_disk.n_chips = 1;
466 flash_disk.chip_no[0] = 0;
467 for (i = 1; i < 4; i++)
468 {
469 id2 = flash_read_id(i);
470 if (id2 == id)
471 flash_disk.chip_no[flash_disk.n_chips++] = i;
472 }
473
450 if (flash_disk_scan() < 0) 474 if (flash_disk_scan() < 0)
451 return -2; 475 return -2;
452 476