diff options
Diffstat (limited to 'firmware/target/arm/sandisk/sansa-e200/ata-e200.c')
-rw-r--r-- | firmware/target/arm/sandisk/sansa-e200/ata-e200.c | 624 |
1 files changed, 557 insertions, 67 deletions
diff --git a/firmware/target/arm/sandisk/sansa-e200/ata-e200.c b/firmware/target/arm/sandisk/sansa-e200/ata-e200.c index 0c37753c53..98d71c26ce 100644 --- a/firmware/target/arm/sandisk/sansa-e200/ata-e200.c +++ b/firmware/target/arm/sandisk/sansa-e200/ata-e200.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2006 Daniel Stenberg | 10 | * Copyright (C) 2006 Daniel Ankers |
11 | * | 11 | * |
12 | * All files in this archive are subject to the GNU General Public License. | 12 | * All files in this archive are subject to the GNU General Public License. |
13 | * See the file COPYING in the source tree root for full license agreement. | 13 | * See the file COPYING in the source tree root for full license agreement. |
@@ -16,106 +16,461 @@ | |||
16 | * KIND, either express or implied. | 16 | * KIND, either express or implied. |
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | 19 | /* TODO: Add ATA Callback support */ | |
20 | #include "lcd.h" | ||
20 | #include "ata.h" | 21 | #include "ata.h" |
22 | #include "ata-target.h" | ||
23 | #include "cpu.h" | ||
24 | #include "system.h" | ||
25 | #include <stdio.h> | ||
21 | #include <stdbool.h> | 26 | #include <stdbool.h> |
22 | #include <string.h> | 27 | #include <string.h> |
28 | #include "kernel.h" | ||
29 | #include "thread.h" | ||
30 | |||
31 | #define NOINLINE_ATTR __attribute__((noinline)) /* don't inline the loops */ | ||
23 | 32 | ||
33 | #define BLOCK_SIZE (512) | ||
24 | #define SECTOR_SIZE (512) | 34 | #define SECTOR_SIZE (512) |
25 | 35 | ||
36 | #define STATUS_REG (*(volatile unsigned int *)(0x70008204)) | ||
37 | #define REG_1 (*(volatile unsigned int *)(0x70008208)) | ||
38 | #define UNKNOWN (*(volatile unsigned int *)(0x70008210)) | ||
39 | #define BLOCK_SIZE_REG (*(volatile unsigned int *)(0x7000821c)) | ||
40 | #define BLOCK_COUNT_REG (*(volatile unsigned int *)(0x70008220)) | ||
41 | #define REG_5 (*(volatile unsigned int *)(0x70008224)) | ||
42 | #define CMD_REG0 (*(volatile unsigned int *)(0x70008228)) | ||
43 | #define CMD_REG1 (*(volatile unsigned int *)(0x7000822c)) | ||
44 | #define CMD_REG2 (*(volatile unsigned int *)(0x70008230)) | ||
45 | #define RESPONSE_REG (*(volatile unsigned int *)(0x70008234)) | ||
46 | #define SD_STATE_REG (*(volatile unsigned int *)(0x70008238)) | ||
47 | #define REG_11 (*(volatile unsigned int *)(0x70008240)) | ||
48 | #define REG_12 (*(volatile unsigned int *)(0x70008244)) | ||
49 | #define DATA_REG (*(volatile unsigned int *)(0x70008280)) | ||
50 | |||
51 | #define DATA_DONE (1 << 12) | ||
52 | #define CMD_DONE (1 << 13) | ||
53 | #define ERROR_BITS (0x3f) | ||
54 | #define FIFO_FULL (1 << 7) | ||
55 | #define FIFO_EMPTY (1 << 6) | ||
56 | |||
57 | /* SD States */ | ||
58 | #define IDLE 0 | ||
59 | #define READY 1 | ||
60 | #define IDENT 2 | ||
61 | #define STBY 3 | ||
62 | #define TRAN 4 | ||
63 | #define DATA 5 | ||
64 | #define RCV 6 | ||
65 | #define PRG 7 | ||
66 | #define DIS 8 | ||
67 | |||
68 | #define FIFO_SIZE 16 /* FIFO is 16 words deep */ | ||
69 | |||
70 | /* SD Commands */ | ||
71 | #define GO_IDLE_STATE 0 | ||
72 | #define ALL_SEND_CID 2 | ||
73 | #define SEND_RELATIVE_ADDR 3 | ||
74 | #define SET_DSR 4 | ||
75 | #define SWITCH_FUNC 6 | ||
76 | #define SELECT_CARD 7 | ||
77 | #define DESELECT_CARD 7 | ||
78 | #define SEND_CSD 9 | ||
79 | #define SEND_CID 10 | ||
80 | #define STOP_TRANSMISSION 12 | ||
81 | #define SEND_STATUS 13 | ||
82 | #define GO_INACTIVE_STATE 15 | ||
83 | #define SET_BLOCKLEN 16 | ||
84 | #define READ_SINGLE_BLOCK 17 | ||
85 | #define READ_MULTIPLE_BLOCK 18 | ||
86 | #define WRITE_BLOCK 24 | ||
87 | #define WRITE_MULTIPLE_BLOCK 25 | ||
88 | #define ERASE_WR_BLK_START 32 | ||
89 | #define ERASE_WR_BLK_END 33 | ||
90 | #define ERASE 38 | ||
91 | |||
92 | /* Application Specific commands */ | ||
93 | #define SET_BUS_WIDTH 6 | ||
94 | #define SD_APP_OP_COND 41 | ||
95 | |||
96 | #define READ_TIMEOUT 5*HZ | ||
97 | #define WRITE_TIMEOUT 0.5*HZ | ||
98 | |||
26 | static unsigned short identify_info[SECTOR_SIZE]; | 99 | static unsigned short identify_info[SECTOR_SIZE]; |
27 | int ata_spinup_time = 0; | 100 | int ata_spinup_time = 0; |
28 | long last_disk_activity = -1; | 101 | long last_disk_activity = -1; |
102 | static bool delayed_write = false; | ||
29 | 103 | ||
30 | void flash_select_chip(int no, int sel) | 104 | static unsigned char current_bank = 0; /* The bank that we are working with */ |
31 | { | ||
32 | |||
33 | } | ||
34 | 105 | ||
35 | unsigned char flash_read_data(void) | 106 | static tSDCardInfo card_info[2]; |
36 | { | ||
37 | 107 | ||
38 | } | 108 | /* For multi volume support */ |
109 | static int current_card = 0; | ||
39 | 110 | ||
40 | void flash_write_data(unsigned char data) | 111 | static struct mutex ata_mtx; |
41 | { | ||
42 | 112 | ||
43 | } | 113 | /* Private Functions */ |
44 | 114 | ||
45 | void flash_write_cmd(unsigned char cmd) | 115 | bool sd_send_command(unsigned int cmd, unsigned long arg1, unsigned int arg2) |
46 | { | 116 | { |
47 | 117 | bool result = false; | |
118 | unsigned char cbuf[32]; | ||
119 | do | ||
120 | { | ||
121 | CMD_REG0 = cmd; | ||
122 | CMD_REG1 = (unsigned int)((arg1 & 0xffff0000) >> 16); | ||
123 | CMD_REG2 = (unsigned int)((arg1 & 0xffff)); | ||
124 | UNKNOWN = arg2; | ||
125 | while ((STATUS_REG & CMD_DONE) == 0) | ||
126 | { | ||
127 | /* Busy wait */ | ||
128 | } | ||
129 | if ((STATUS_REG & ERROR_BITS) == 0) | ||
130 | { | ||
131 | result = true; | ||
132 | } else { | ||
133 | snprintf(cbuf, sizeof(cbuf), "%x", (STATUS_REG & ERROR_BITS)); | ||
134 | lcd_puts(0,10,cbuf); | ||
135 | lcd_update(); | ||
136 | } | ||
137 | } while ((STATUS_REG & ERROR_BITS) != 0); | ||
138 | return result; | ||
48 | } | 139 | } |
49 | 140 | ||
50 | void flash_write_addr(unsigned char addr) | 141 | void sd_read_response(unsigned int *response, int type) |
51 | { | 142 | { |
52 | 143 | int i; | |
144 | int words; /* Number of 16 bit words to read from RESPONSE_REG */ | ||
145 | unsigned int response_from_card[9]; | ||
146 | if(type == 2) | ||
147 | { | ||
148 | words = 9; /* R2 types are 8.5 16-bit words long */ | ||
149 | } else { | ||
150 | words = 3; | ||
151 | } | ||
152 | |||
153 | for (i = 0; i < words; i++) /* RESPONSE_REG is read MSB first */ | ||
154 | { | ||
155 | response_from_card[i] = RESPONSE_REG; /* Read most significant 16-bit word */ | ||
156 | } | ||
157 | |||
158 | switch (type) | ||
159 | { | ||
160 | case 1: | ||
161 | /* Response type 1 has the following structure: | ||
162 | Start bit | ||
163 | Transmission bit | ||
164 | Command index (6 bits) | ||
165 | Card Status (32 bits) | ||
166 | CRC7 (7 bits) | ||
167 | Stop bit | ||
168 | */ | ||
169 | /* TODO: Sanity checks */ | ||
170 | response[0] = ((response_from_card[0] & 0xff) << 24) | ||
171 | + (response_from_card[1] << 8) | ||
172 | + ((response_from_card[2] & 0xff00) >> 8); | ||
173 | break; | ||
174 | case 2: | ||
175 | /* Response type 2 has the following structure: | ||
176 | Start bit | ||
177 | Transmission bit | ||
178 | Reserved (6 bits) | ||
179 | CSD/CID register (127 bits) | ||
180 | Stop bit | ||
181 | */ | ||
182 | response[3] = ((response_from_card[0]&0xff)<<24) + | ||
183 | (response_from_card[1]<<8) + | ||
184 | ((response_from_card[2]&0xff00)>>8); | ||
185 | response[2] = ((response_from_card[2]&0xff)<<24) + | ||
186 | (response_from_card[3]<<8) + | ||
187 | ((response_from_card[4]&0xff00)>>8); | ||
188 | response[1] = ((response_from_card[4]&0xff)<<24) + | ||
189 | (response_from_card[5]<<8) + | ||
190 | ((response_from_card[6]&0xff00)>>8); | ||
191 | response[0] = ((response_from_card[6]&0xff)<<24) + | ||
192 | (response_from_card[7]<<8) + | ||
193 | ((response_from_card[8]&0xff00)>>8); | ||
194 | break; | ||
195 | case 3: | ||
196 | /* Response type 3 has the following structure: | ||
197 | Start bit | ||
198 | Transmission bit | ||
199 | Reserved (6 bits) | ||
200 | OCR register (32 bits) | ||
201 | Reserved (7 bits) | ||
202 | Stop bit | ||
203 | */ | ||
204 | response[0] = ((response_from_card[0] & 0xff) << 24) | ||
205 | + (response_from_card[1] << 8) | ||
206 | + ((response_from_card[2] & 0xff00) >> 8); | ||
207 | /* Types 4-6 not supported yet */ | ||
208 | } | ||
53 | } | 209 | } |
54 | 210 | ||
55 | void flash_wait_ready(void) | 211 | bool sd_send_acommand(unsigned int cmd, unsigned long arg1, unsigned int arg2) |
56 | { | 212 | { |
57 | 213 | unsigned int returncode; | |
214 | if (sd_send_command(55, (card_info[current_card].rca)<<16, 1) == false) | ||
215 | return false; | ||
216 | sd_read_response(&returncode, 1); | ||
217 | if (sd_send_command(cmd, arg1, arg2) == false) | ||
218 | return false; | ||
219 | return true; | ||
58 | } | 220 | } |
59 | 221 | ||
60 | int flash_map_sector(int sector, int* chip, int* chip_sector) | 222 | void sd_wait_for_state(tSDCardInfo* card, unsigned int state) |
61 | { | 223 | { |
62 | 224 | unsigned int response = 0; | |
225 | while(((response >> 9) & 0xf) != state) | ||
226 | { | ||
227 | sd_send_command(SEND_STATUS, (card->rca) << 16, 1); | ||
228 | sd_read_response(&response, 1); | ||
229 | /* TODO: Add a timeout and error handling */ | ||
230 | } | ||
231 | SD_STATE_REG = state; | ||
63 | } | 232 | } |
64 | 233 | ||
65 | int flash_read_id(int no) | ||
66 | { | ||
67 | 234 | ||
68 | } | 235 | static void copy_read_sectors(unsigned char* buf, int wordcount) |
236 | NOINLINE_ATTR ICODE_ATTR; | ||
69 | 237 | ||
70 | int flash_read_sector(int sector, unsigned char* buf, | 238 | static void copy_read_sectors(unsigned char* buf, int wordcount) |
71 | unsigned char* oob) | ||
72 | { | 239 | { |
73 | 240 | unsigned int tmp = 0; | |
241 | |||
242 | if ( (unsigned long)buf & 1) | ||
243 | { /* not 16-bit aligned, copy byte by byte */ | ||
244 | unsigned char* bufend = buf + wordcount*2; | ||
245 | do | ||
246 | { | ||
247 | tmp = DATA_REG; | ||
248 | *buf++ = tmp & 0xff; | ||
249 | *buf++ = tmp >> 8; | ||
250 | } while (buf < bufend); /* tail loop is faster */ | ||
251 | } | ||
252 | else | ||
253 | { /* 16-bit aligned, can do faster copy */ | ||
254 | unsigned short* wbuf = (unsigned short*)buf; | ||
255 | unsigned short* wbufend = wbuf + wordcount; | ||
256 | do | ||
257 | { | ||
258 | *wbuf = DATA_REG; | ||
259 | } while (++wbuf < wbufend); /* tail loop is faster */ | ||
260 | } | ||
74 | } | 261 | } |
75 | 262 | ||
76 | int flash_read_sector_oob(int sector, unsigned char* oob) | 263 | static void copy_write_sectors(const unsigned char* buf, int wordcount) |
77 | { | 264 | NOINLINE_ATTR ICODE_ATTR; |
78 | |||
79 | } | ||
80 | |||
81 | static int flash_get_n_segments(void) | ||
82 | { | ||
83 | |||
84 | } | ||
85 | 265 | ||
86 | static int flash_get_n_phblocks(void) | 266 | static void copy_write_sectors(const unsigned char* buf, int wordcount) |
87 | { | 267 | { |
88 | 268 | if ( (unsigned long)buf & 1) | |
269 | { /* not 16-bit aligned, copy byte by byte */ | ||
270 | unsigned short tmp = 0; | ||
271 | const unsigned char* bufend = buf + wordcount*2; | ||
272 | do | ||
273 | { | ||
274 | tmp = (unsigned short) *buf++; | ||
275 | tmp |= (unsigned short) *buf++ << 8; | ||
276 | DATA_REG = tmp; | ||
277 | } while (buf < bufend); /* tail loop is faster */ | ||
278 | } | ||
279 | else | ||
280 | { /* 16-bit aligned, can do faster copy */ | ||
281 | unsigned short* wbuf = (unsigned short*)buf; | ||
282 | unsigned short* wbufend = wbuf + wordcount; | ||
283 | do | ||
284 | { | ||
285 | lcd_update(); | ||
286 | DATA_REG = *wbuf; | ||
287 | } while (++wbuf < wbufend); /* tail loop is faster */ | ||
288 | } | ||
89 | } | 289 | } |
90 | 290 | ||
91 | static int flash_get_n_sectors_in_block(void) | ||
92 | { | ||
93 | |||
94 | } | ||
95 | 291 | ||
96 | static int flash_phblock_to_sector(int segment, int block) | 292 | void sd_select_bank(unsigned char bank) |
97 | { | 293 | { |
98 | 294 | unsigned int response; | |
295 | unsigned char card_data[512]; | ||
296 | unsigned char* write_buf; | ||
297 | int i; | ||
298 | tSDCardInfo *card = &card_info[0]; /* Bank selection will only be done on | ||
299 | the onboard flash */ | ||
300 | if (current_bank != bank) | ||
301 | { | ||
302 | memset(card_data, 0, 512); | ||
303 | sd_wait_for_state(card, TRAN); | ||
304 | BLOCK_SIZE_REG = 512; | ||
305 | BLOCK_COUNT_REG = 1; | ||
306 | sd_send_command(35, 0, 0x1c0d); /* CMD35 is vendor specific */ | ||
307 | sd_read_response(&response, 1); | ||
308 | SD_STATE_REG = PRG; | ||
309 | |||
310 | card_data[0] = bank; | ||
311 | |||
312 | /* Write the card data */ | ||
313 | write_buf = card_data; | ||
314 | for (i = 0; i < BLOCK_SIZE / 2; i += FIFO_SIZE) | ||
315 | { | ||
316 | /* Wait for the FIFO to be empty */ | ||
317 | while((STATUS_REG & FIFO_EMPTY) == 0) {} /* Erm... is this right? */ | ||
318 | |||
319 | copy_write_sectors(write_buf, FIFO_SIZE); | ||
320 | |||
321 | write_buf += FIFO_SIZE*2; /* Advance one chunk of 16 words */ | ||
322 | } | ||
323 | |||
324 | while((STATUS_REG & DATA_DONE) == 0) {} | ||
325 | current_bank = bank; | ||
326 | } | ||
99 | } | 327 | } |
100 | 328 | ||
101 | static int flash_is_bad_block(unsigned char* oob) | 329 | void sd_init_device(void) |
102 | { | 330 | { |
103 | 331 | /* SD Protocol registers */ | |
332 | unsigned int dummy; | ||
333 | int i; | ||
334 | |||
335 | static unsigned int read_bl_len = 0; | ||
336 | static unsigned int c_size = 0; | ||
337 | static unsigned int c_size_mult = 0; | ||
338 | static unsigned long mult = 0; | ||
339 | |||
340 | unsigned char carddata[512]; | ||
341 | unsigned char *dataptr; | ||
342 | tSDCardInfo *card = &card_info[0]; /* Init onboard flash only */ | ||
343 | |||
344 | /* Initialise card data as blank */ | ||
345 | card->initialized = false; | ||
346 | card->ocr = 0; | ||
347 | card->csd[0] = 0; | ||
348 | card->csd[1] = 0; | ||
349 | card->csd[2] = 0; | ||
350 | card->cid[0] = 0; | ||
351 | card->cid[1] = 0; | ||
352 | card->cid[2] = 0; | ||
353 | card->rca = 0; | ||
354 | |||
355 | card->capacity = 0; | ||
356 | card->numblocks = 0; | ||
357 | card->block_size = 0; | ||
358 | card->block_exp = 0; | ||
359 | |||
360 | /* Enable and initialise controller */ | ||
361 | GPIOG_ENABLE |= (0x3 << 5); | ||
362 | GPIOG_OUTPUT_EN |= (0x3 << 5); | ||
363 | GPIOG_OUTPUT_VAL |= (0x3 << 5); | ||
364 | outl(inl(0x70000088) & ~(0x4), 0x70000088); | ||
365 | outl(inl(0x7000008c) & ~(0x4), 0x7000008c); | ||
366 | outl(inl(0x70000080) | 0x4, 0x70000080); | ||
367 | outl(inl(0x70000084) | 0x4, 0x70000084); | ||
368 | REG_1 = 6; | ||
369 | outl(inl(0x70000014) & ~(0x3ffff), 0x70000014); | ||
370 | outl((inl(0x70000014) & ~(0x3ffff)) | 0x255aa, 0x70000014); | ||
371 | outl(0x1010, 0x70000034); | ||
372 | |||
373 | GPIOA_ENABLE |= (1 << 7); | ||
374 | GPIOA_OUTPUT_EN &= ~(1 << 7); | ||
375 | GPIOD_ENABLE |= (0x1f); | ||
376 | GPIOD_OUTPUT_EN |= (0x1f); | ||
377 | GPIOD_OUTPUT_VAL |= (0x1f); | ||
378 | outl(inl(0x6000600c) | (1 << 14), 0x6000600c); | ||
379 | outl(inl(0x60006004) | (1 << 14), 0x60006004); | ||
380 | outl(inl(0x60006004) & ~(1 << 14), 0x60006004); /* Reset Controller? */ | ||
381 | outl(0, 0x6000b000); | ||
382 | outl(0, 0x6000a000); /* Init DMA controller? */ | ||
383 | |||
384 | /* Init NAND */ | ||
385 | REG_11 |= (1 << 15); | ||
386 | REG_12 |= (1 << 15); | ||
387 | REG_12 &= ~(3 << 12); | ||
388 | REG_12 |= (1 << 13); | ||
389 | REG_11 &= ~(3 << 12); | ||
390 | REG_11 |= (1 << 13); | ||
391 | |||
392 | SD_STATE_REG = TRAN; | ||
393 | REG_5 = 0xf; | ||
394 | |||
395 | sd_send_command(GO_IDLE_STATE, 0, 256); | ||
396 | while ((card->ocr & (1 << 31)) == 0) /* Loop until the card is powered up */ | ||
397 | { | ||
398 | sd_send_acommand(SD_APP_OP_COND, 0x100000, 3); | ||
399 | sd_read_response(&(card->ocr), 3); | ||
400 | |||
401 | if (card->ocr == 0) | ||
402 | { | ||
403 | /* TODO: Handle failure */ | ||
404 | while (1) {}; | ||
405 | } | ||
406 | } | ||
407 | |||
408 | sd_send_command(ALL_SEND_CID, 0, 2); | ||
409 | sd_read_response(card->cid, 2); | ||
410 | sd_send_command(SEND_RELATIVE_ADDR, 0, 1); | ||
411 | sd_read_response(&card->rca, 1); | ||
412 | card->rca >>= 16; /* The Relative Card Address is the top 16 bits of the | ||
413 | 32 bits returned. Whenever it is used, it gets | ||
414 | shifted left by 16 bits, so this step could possibly | ||
415 | be skipped. */ | ||
416 | |||
417 | sd_send_command(SEND_CSD, card->rca << 16, 2); | ||
418 | sd_read_response(card->csd, 2); | ||
419 | |||
420 | /* Parse disk geometry */ | ||
421 | /* These calculations come from the Sandisk SD card product manual */ | ||
422 | read_bl_len = ((card->csd[2] >> 16) & 0xf); | ||
423 | c_size = ((card->csd[2] & (0x3ff)) << 2) + | ||
424 | ((card->csd[1] & (0xc0000000)) >> 30); | ||
425 | c_size_mult = ((card->csd[1] >> 15) & 0x7); | ||
426 | mult = (1<<(c_size_mult + 2)); | ||
427 | card->max_read_bl_len = (1<<read_bl_len); | ||
428 | card->block_size = BLOCK_SIZE; /* Always use 512 byte blocks */ | ||
429 | card->numblocks = (c_size + 1) * mult * (card->max_read_bl_len / 512); | ||
430 | card->capacity = card->numblocks * card->block_size; | ||
431 | |||
432 | REG_1 = 0; | ||
433 | sd_send_command(SELECT_CARD, card->rca << 16, 129); | ||
434 | sd_read_response(&dummy, 1); /* I don't think we use the result from this */ | ||
435 | sd_send_acommand(SET_BUS_WIDTH, (card->rca << 16) | 2, 1); | ||
436 | sd_read_response(&dummy, 1); /* 4 bit wide bus */ | ||
437 | sd_send_command(SET_BLOCKLEN, card->block_size, 1); | ||
438 | sd_read_response(&dummy, 1); | ||
439 | BLOCK_SIZE_REG = card->block_size; | ||
440 | |||
441 | /* If this card is > 4Gb, then we need to enable bank switching */ | ||
442 | if(card->numblocks > 0x7a77ff) | ||
443 | { | ||
444 | SD_STATE_REG = TRAN; | ||
445 | BLOCK_COUNT_REG = 1; | ||
446 | sd_send_command(SWITCH_FUNC, 0x80ffffef, 0x1c05); | ||
447 | sd_read_response(&dummy, 1); | ||
448 | /* Read 512 bytes from the card. | ||
449 | The first 512 bits contain the status information | ||
450 | TODO: Do something useful with this! */ | ||
451 | dataptr = carddata; | ||
452 | for (i = 0; i < BLOCK_SIZE / 2; i += FIFO_SIZE) | ||
453 | { | ||
454 | /* Wait for the FIFO to be full */ | ||
455 | while((STATUS_REG & FIFO_FULL) == 0) {} | ||
456 | |||
457 | copy_read_sectors(dataptr, FIFO_SIZE); | ||
458 | |||
459 | dataptr += (FIFO_SIZE*2); /* Advance one chunk of 16 words */ | ||
460 | } | ||
461 | } | ||
462 | mutex_init(&ata_mtx); | ||
104 | } | 463 | } |
105 | 464 | ||
106 | int flash_disk_scan(void) | 465 | /* API Functions */ |
107 | { | ||
108 | |||
109 | } | ||
110 | 466 | ||
111 | int flash_disk_find_block(int block) | 467 | void ata_led(bool onoff) |
112 | { | 468 | { |
113 | 469 | (void)onoff; | |
114 | } | 470 | } |
115 | 471 | ||
116 | int flash_disk_read_sectors(unsigned long start, | 472 | /* write the delayed sector to volume 0 */ |
117 | int count, | 473 | extern void ata_flush(void) |
118 | void* buf) | ||
119 | { | 474 | { |
120 | 475 | ||
121 | } | 476 | } |
@@ -125,21 +480,161 @@ int ata_read_sectors(IF_MV2(int drive,) | |||
125 | int incount, | 480 | int incount, |
126 | void* inbuf) | 481 | void* inbuf) |
127 | { | 482 | { |
128 | 483 | int ret = 0; | |
484 | long timeout; | ||
485 | int count; | ||
486 | void* buf; | ||
487 | long spinup_start; | ||
488 | unsigned int dummy; | ||
489 | unsigned int response; | ||
490 | unsigned int i; | ||
491 | tSDCardInfo *card = &card_info[current_card]; | ||
492 | |||
493 | /* TODO: Add DMA support. */ | ||
494 | |||
495 | #ifdef HAVE_MULTIVOLUME | ||
496 | (void)drive; /* unused for now */ | ||
497 | #endif | ||
498 | mutex_lock(&ata_mtx); | ||
499 | |||
500 | last_disk_activity = current_tick; | ||
501 | spinup_start = current_tick; | ||
502 | |||
503 | ata_led(true); | ||
504 | |||
505 | timeout = current_tick + READ_TIMEOUT; | ||
506 | |||
507 | /* TODO: Select device */ | ||
508 | if(current_card == 0) | ||
509 | { | ||
510 | if(start > 0x7a77ff) | ||
511 | { | ||
512 | sd_select_bank(1); | ||
513 | start-=0x7a77ff; | ||
514 | } else { | ||
515 | sd_select_bank(0); | ||
516 | } | ||
517 | } | ||
518 | |||
519 | buf = inbuf; | ||
520 | count = incount; | ||
521 | while (TIME_BEFORE(current_tick, timeout)) { | ||
522 | ret = 0; | ||
523 | last_disk_activity = current_tick; | ||
524 | |||
525 | SD_STATE_REG = TRAN; | ||
526 | BLOCK_COUNT_REG = count; | ||
527 | sd_send_command(READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, 0x1c25); | ||
528 | sd_read_response(&dummy, 1); | ||
529 | /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */ | ||
530 | |||
531 | for (i = 0; i < count * card->block_size / 2; i += FIFO_SIZE) | ||
532 | { | ||
533 | /* Wait for the FIFO to be full */ | ||
534 | while((STATUS_REG & FIFO_FULL) == 0) {} | ||
535 | |||
536 | copy_read_sectors(buf, FIFO_SIZE); | ||
537 | |||
538 | buf += FIFO_SIZE*2; /* Advance one chunk of 16 words */ | ||
539 | |||
540 | /* TODO: Switch bank if necessary */ | ||
541 | |||
542 | last_disk_activity = current_tick; | ||
543 | } | ||
544 | udelay(75); | ||
545 | sd_send_command(STOP_TRANSMISSION, 0, 1); | ||
546 | sd_read_response(&dummy, 1); | ||
547 | |||
548 | response = 0; | ||
549 | sd_wait_for_state(card, TRAN); | ||
550 | break; | ||
551 | } | ||
552 | ata_led(false); | ||
553 | |||
554 | mutex_unlock(&ata_mtx); | ||
555 | |||
556 | /* only flush if reading went ok */ | ||
557 | if ( (ret == 0) && delayed_write ) | ||
558 | ata_flush(); | ||
559 | |||
560 | return ret; | ||
129 | } | 561 | } |
130 | 562 | ||
563 | |||
131 | int ata_write_sectors(IF_MV2(int drive,) | 564 | int ata_write_sectors(IF_MV2(int drive,) |
132 | unsigned long start, | 565 | unsigned long start, |
133 | int count, | 566 | int count, |
134 | const void* buf) | 567 | const void* buf) |
135 | { | 568 | { |
136 | (void)start; | 569 | /* Write support is not finished yet */ |
137 | (void)count; | 570 | /* TODO: The standard suggests using ACMD23 prior to writing multiple blocks |
138 | (void)buf; | 571 | to improve performance */ |
139 | return -1; | 572 | unsigned int response; |
573 | void const* write_buf; | ||
574 | int ret = 0; | ||
575 | unsigned int i; | ||
576 | long timeout; | ||
577 | tSDCardInfo *card = &card_info[current_card]; | ||
578 | |||
579 | mutex_lock(&ata_mtx); | ||
580 | ata_led(true); | ||
581 | if(current_card == 0) | ||
582 | { | ||
583 | if(start <= 0x7a77ff) | ||
584 | { | ||
585 | sd_select_bank(0); | ||
586 | } else { | ||
587 | sd_select_bank(1); | ||
588 | start -= 0x7a77ff; | ||
589 | } | ||
590 | } | ||
591 | |||
592 | retry: | ||
593 | sd_wait_for_state(card, TRAN); | ||
594 | BLOCK_COUNT_REG = count; | ||
595 | sd_send_command(WRITE_MULTIPLE_BLOCK, start * SECTOR_SIZE, 0x1c2d); | ||
596 | sd_read_response(&response, 1); | ||
597 | write_buf = buf; | ||
598 | for (i = 0; i < count * card->block_size / 2; i += FIFO_SIZE) | ||
599 | { | ||
600 | if(i >= (count * card->block_size / 2)-FIFO_SIZE) | ||
601 | { | ||
602 | /* Set SD_STATE_REG to PRG for the last buffer fill */ | ||
603 | SD_STATE_REG = PRG; | ||
604 | } | ||
605 | |||
606 | /* Wait for the FIFO to be empty */ | ||
607 | while((STATUS_REG & FIFO_EMPTY) == 0) {} | ||
608 | /* Perhaps we could use bit 8 of card status (READY_FOR_DATA)? */ | ||
609 | |||
610 | copy_write_sectors(write_buf, FIFO_SIZE); | ||
611 | |||
612 | write_buf += FIFO_SIZE*2; /* Advance one chunk of 16 words */ | ||
613 | /* TODO: Switch bank if necessary */ | ||
614 | |||
615 | last_disk_activity = current_tick; | ||
616 | } | ||
617 | |||
618 | timeout = current_tick + WRITE_TIMEOUT; | ||
619 | |||
620 | while((STATUS_REG & DATA_DONE) == 0) { | ||
621 | if(current_tick >= timeout) | ||
622 | { | ||
623 | sd_send_command(STOP_TRANSMISSION, 0, 1); | ||
624 | sd_read_response(&response, 1); | ||
625 | goto retry; | ||
626 | } | ||
627 | } | ||
628 | sd_send_command(STOP_TRANSMISSION, 0, 1); | ||
629 | sd_read_response(&response, 1); | ||
630 | |||
631 | sd_wait_for_state(card, TRAN); | ||
632 | mutex_unlock(&ata_mtx); | ||
633 | ata_led(false); | ||
634 | return ret; | ||
140 | } | 635 | } |
141 | 636 | ||
142 | /* schedule a single sector write, executed with the the next spinup | 637 | /* schedule a single sector write, executed with the the next spinup |
143 | (volume 0 only, used for config sector) */ | 638 | (volume 0 only, used for config sector) */ |
144 | extern void ata_delayed_write(unsigned long sector, const void* buf) | 639 | extern void ata_delayed_write(unsigned long sector, const void* buf) |
145 | { | 640 | { |
@@ -147,12 +642,6 @@ extern void ata_delayed_write(unsigned long sector, const void* buf) | |||
147 | (void)buf; | 642 | (void)buf; |
148 | } | 643 | } |
149 | 644 | ||
150 | /* write the delayed sector to volume 0 */ | ||
151 | extern void ata_flush(void) | ||
152 | { | ||
153 | |||
154 | } | ||
155 | |||
156 | void ata_spindown(int seconds) | 645 | void ata_spindown(int seconds) |
157 | { | 646 | { |
158 | (void)seconds; | 647 | (void)seconds; |
@@ -189,10 +678,11 @@ void ata_enable(bool on) | |||
189 | 678 | ||
190 | unsigned short* ata_get_identify(void) | 679 | unsigned short* ata_get_identify(void) |
191 | { | 680 | { |
192 | 681 | return identify_info; | |
193 | } | 682 | } |
194 | 683 | ||
195 | int ata_init(void) | 684 | int ata_init(void) |
196 | { | 685 | { |
686 | sd_init_device(); | ||
197 | return 0; | 687 | return 0; |
198 | } | 688 | } |