diff options
author | Tomasz Malesinski <tomal@rockbox.org> | 2006-08-12 22:51:18 +0000 |
---|---|---|
committer | Tomasz Malesinski <tomal@rockbox.org> | 2006-08-12 22:51:18 +0000 |
commit | c1810b31f170e887668652ff4e3d76c392a5fb70 (patch) | |
tree | de7c62c7fe64e58e0da58cfc2d27adb86620909f /firmware/drivers | |
parent | 17972c9267eddccd6c6f5f41d004d7627bd0c773 (diff) | |
download | rockbox-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
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/ata_flash.c | 70 |
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 | ||
64 | struct flash_disk | 65 | struct 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 | ||
72 | static struct flash_disk flash_disk; | 75 | static 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 | ||
84 | unsigned char flash_read_data(void) | 87 | static inline unsigned char flash_read_data(void) |
85 | { | 88 | { |
86 | return FLASH_REG_DATA; | 89 | return FLASH_REG_DATA; |
87 | } | 90 | } |
88 | 91 | ||
89 | void flash_write_data(unsigned char data) | 92 | static inline void flash_write_data(unsigned char data) |
90 | { | 93 | { |
91 | FLASH_REG_DATA = data; | 94 | FLASH_REG_DATA = data; |
92 | } | 95 | } |
93 | 96 | ||
94 | void flash_write_cmd(unsigned char cmd) | 97 | /* TODO: these two doesn't work when inlined, probably some |
98 | delay is required */ | ||
99 | |||
100 | static void flash_write_cmd(unsigned char cmd) | ||
95 | { | 101 | { |
96 | FLASH_REG_CMD = cmd; | 102 | FLASH_REG_CMD = cmd; |
97 | } | 103 | } |
98 | 104 | ||
99 | void flash_write_addr(unsigned char addr) | 105 | static void flash_write_addr(unsigned char addr) |
100 | { | 106 | { |
101 | FLASH_REG_ADDR = addr; | 107 | FLASH_REG_ADDR = addr; |
102 | } | 108 | } |
103 | 109 | ||
104 | void flash_wait_ready(void) | 110 | static 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 | ||
117 | static unsigned char model_n_sectors_order[] = {0, 19, 20}; | ||
118 | |||
111 | int flash_map_sector(int sector, int* chip, int* chip_sector) | 119 | int 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 | ||
125 | int flash_read_id(int no) { | 136 | int 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 | ||
202 | static unsigned char model_n_segments[] = {0, 2}; | 213 | static unsigned char model_n_segments[] = {0, 2, 4}; |
203 | 214 | ||
204 | static int flash_get_n_segments(void) | 215 | static 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 | ||
209 | static int flash_get_n_phblocks(void) | 220 | static inline int flash_get_n_phblocks(void) |
210 | { | 221 | { |
211 | return 1024; | 222 | return 1024; |
212 | } | 223 | } |
213 | 224 | ||
214 | static int model_n_sectors_in_block[] = {0, 256}; | 225 | static int model_n_sectors_in_block[] = {0, 256, 256}; |
215 | 226 | ||
216 | static int flash_get_n_sectors_in_block(void) | 227 | static 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 | ||
435 | int ata_init(void) | 447 | int 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 | ||