diff options
author | Jens Arnold <amiconn@rockbox.org> | 2004-09-28 06:23:57 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2004-09-28 06:23:57 +0000 |
commit | 90cbd3b06dae57464e0562edfa48106d19dd98db (patch) | |
tree | 725985248587d5a7e91cf1c2ecb363b021e847fb /firmware | |
parent | a82fd17d82b79f0ebbd18af4d4162ffa7313d539 (diff) | |
download | rockbox-90cbd3b06dae57464e0562edfa48106d19dd98db.tar.gz rockbox-90cbd3b06dae57464e0562edfa48106d19dd98db.zip |
First working MMC driver (very preliminary, and read-only), and some adaptions of the debug menu
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5123 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/ata_mmc.c | 516 |
1 files changed, 397 insertions, 119 deletions
diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c index e1439594e5..a7d7f1d40a 100644 --- a/firmware/drivers/ata_mmc.c +++ b/firmware/drivers/ata_mmc.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2002 by Alan Korr | 10 | * Copyright (C) 2004 by Jens Arnold |
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. |
@@ -31,67 +31,407 @@ | |||
31 | #include "hwcompat.h" | 31 | #include "hwcompat.h" |
32 | #include "adc.h" | 32 | #include "adc.h" |
33 | 33 | ||
34 | #include "bitswap.h" | ||
35 | |||
34 | /* use file for an MMC-based system, FIXME in makefile */ | 36 | /* use file for an MMC-based system, FIXME in makefile */ |
35 | #ifdef HAVE_MMC | 37 | #ifdef HAVE_MMC |
36 | 38 | ||
37 | #define SECTOR_SIZE 512 | 39 | #define SECTOR_SIZE 512 |
38 | #define Q_SLEEP 0 | 40 | |
41 | /* Command definitions */ | ||
42 | #define CMD_GO_IDLE_STATE 0x40 /* R1 */ | ||
43 | #define CMD_SEND_OP_COND 0x41 /* R1 */ | ||
44 | #define CMD_SEND_CSD 0x49 /* R1 */ | ||
45 | #define CMD_SEND_CID 0x4A /* R1 */ | ||
46 | #define CMD_STOP_TRANSMISSION 0x4C /* R1 */ | ||
47 | #define CMD_SEND_STATUS 0x4D /* R2 */ | ||
48 | #define CMD_SET_BLOCKLEN 0x50 /* R1 */ | ||
49 | #define CMD_READ_SINGLE_BLOCK 0x51 /* R1 */ | ||
50 | #define CMD_READ_MULTIPLE_BLOCK 0x52 /* R1 */ | ||
51 | #define CMD_SET_BLOCK_COUNT 0x57 /* R1 */ | ||
52 | #define CMD_WRITE_BLOCK 0x58 /* R1b */ | ||
53 | #define CMD_WRITE_MULTIPLE_BLOCK 0x59 /* R1b */ | ||
54 | #define CMD_READ_OCR 0x7A /* R3 */ | ||
55 | |||
56 | /* Response formats: | ||
57 | R1 = single byte, msb=0, various error flags | ||
58 | R1b = R1 + busy token(s) | ||
59 | R2 = 2 bytes (1st byte identical to R1), additional flags | ||
60 | R3 = 5 bytes (R1 + OCR register) | ||
61 | */ | ||
62 | |||
63 | #define R1_PARAMETER_ERR 0x40 | ||
64 | #define R1_ADDRESS_ERR 0x20 | ||
65 | #define R1_ERASE_SEQ_ERR 0x10 | ||
66 | #define R1_COM_CRC_ERR 0x08 | ||
67 | #define R1_ILLEGAL_CMD 0x04 | ||
68 | #define R1_ERASE_RESET 0x02 | ||
69 | #define R1_IN_IDLE_STATE 0x01 | ||
70 | |||
71 | #define R2_OUT_OF_RANGE 0x80 | ||
72 | #define R2_ERASE_PARAM 0x40 | ||
73 | #define R2_WP_VIOLATION 0x20 | ||
74 | #define R2_CARD_ECC_FAIL 0x10 | ||
75 | #define R2_CC_ERROR 0x08 | ||
76 | #define R2_ERROR 0x04 | ||
77 | #define R2_ERASE_SKIP 0x02 | ||
78 | #define R2_CARD_LOCKED 0x01 | ||
79 | |||
80 | // DEBUG | ||
81 | #include "../../apps/screens.h" | ||
39 | 82 | ||
40 | /* for compatibility */ | 83 | /* for compatibility */ |
41 | bool old_recorder = false; /* FIXME: get rid of this cross-dependency */ | 84 | bool old_recorder = false; /* FIXME: get rid of this cross-dependency */ |
42 | int ata_spinup_time = 0; | 85 | int ata_spinup_time = 0; |
43 | static int sleep_timeout = 5*HZ; | ||
44 | char ata_device = 0; /* device 0 (master) or 1 (slave) */ | 86 | char ata_device = 0; /* device 0 (master) or 1 (slave) */ |
45 | int ata_io_address = 0; /* 0x300 or 0x200, only valid on recorder */ | 87 | int ata_io_address = 0; /* 0x300 or 0x200, only valid on recorder */ |
46 | static unsigned short identify_info[SECTOR_SIZE]; | 88 | long last_disk_activity = -1; |
47 | 89 | ||
48 | static struct mutex ata_mtx; | 90 | /* private variables */ |
49 | 91 | ||
50 | static bool sleeping = true; | 92 | static struct mutex ata_mtx; |
51 | 93 | ||
52 | static char ata_stack[DEFAULT_STACK_SIZE]; | 94 | static char mmc_stack[DEFAULT_STACK_SIZE]; |
53 | static const char ata_thread_name[] = "ata"; | 95 | static const char mmc_thread_name[] = "mmc"; |
54 | static struct event_queue ata_queue; | 96 | static struct event_queue mmc_queue; |
55 | static bool initialized = false; | 97 | static bool initialized = false; |
56 | static bool delayed_write = false; | 98 | static int current_card = 0; |
57 | static unsigned char delayed_sector[SECTOR_SIZE]; | 99 | |
58 | static int delayed_sector_num; | 100 | static const unsigned char dummy[] = { |
101 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF | ||
102 | }; | ||
103 | |||
104 | typedef struct | ||
105 | { | ||
106 | bool initialized; | ||
107 | unsigned char bitrate_register; | ||
108 | unsigned char rev; | ||
109 | unsigned char rev_fract; | ||
110 | unsigned int speed; /* bps */ | ||
111 | unsigned int read_timeout; /* n * 8 clock cycles */ | ||
112 | unsigned int write_timeout; /* n * 8 clock cycles */ | ||
113 | unsigned int size; /* in bytes */ | ||
114 | unsigned int manuf_month; | ||
115 | unsigned int manuf_year; | ||
116 | unsigned long serial_number; | ||
117 | unsigned char name[7]; | ||
118 | } tCardInfo; | ||
119 | |||
120 | static tCardInfo card_info[2]; | ||
121 | |||
122 | /* private function declarations */ | ||
123 | |||
124 | static int select_card(int card_no); | ||
125 | static void deselect_card(void); | ||
126 | static void setup_sci1(int bitrate_register); | ||
127 | static void write_transfer(const unsigned char *buf, int len) | ||
128 | __attribute__ ((section(".icode"))); | ||
129 | static void read_transfer(unsigned char *buf, int len) | ||
130 | __attribute__ ((section(".icode"))); | ||
131 | static unsigned char poll_byte(int timeout); | ||
132 | static int send_cmd(int cmd, unsigned long parameter, unsigned char *response); | ||
133 | static int receive_data(unsigned char *buf, int len, int timeout); | ||
134 | static int initialize_card(int card_no); | ||
135 | |||
136 | /* implementation */ | ||
137 | |||
138 | static int select_card(int card_no) | ||
139 | { | ||
140 | if (card_no == 0) | ||
141 | { /* internal */ | ||
142 | or_b(0x10, &PADRH); /* set clock gate PA12 CHECKME: mask? */ | ||
143 | and_b(~0x04, &PADRH); /* assert CS */ | ||
144 | } | ||
145 | else | ||
146 | { /* external */ | ||
147 | and_b(~0x10, &PADRH); /* clear clock gate PA12 CHECKME: mask?*/ | ||
148 | and_b(~0x02, &PADRH); /* assert CS */ | ||
149 | } | ||
59 | 150 | ||
60 | static long last_user_activity = -1; | 151 | if (card_info[card_no].initialized) |
61 | long last_disk_activity = -1; | 152 | { |
153 | setup_sci1(card_info[card_no].bitrate_register); | ||
154 | return 0; | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | return initialize_card(card_no); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | static void deselect_card(void) | ||
163 | { | ||
164 | while (!(SSR1 & SCI_TEND)); /* wait until end of transfer */ | ||
165 | or_b(0x06, &PADRH); /* deassert CS (both cards) */ | ||
166 | } | ||
167 | |||
168 | static void setup_sci1(int bitrate_register) | ||
169 | { | ||
170 | int i; | ||
171 | |||
172 | while (!(SSR1 & SCI_TEND)); /* wait until previous transfer ended */ | ||
173 | |||
174 | SCR1 = 0; /* disable serial port */ | ||
175 | SMR1 = SYNC_MODE; /* no prescale */ | ||
176 | BRR1 = bitrate_register; | ||
177 | SCR1 = SCI_CKE0; | ||
178 | SSR1 = 0; | ||
179 | |||
180 | for (i = 0; i <= bitrate_register; i++); /* wait at least one bit time */ | ||
181 | |||
182 | or_b((SCI_TE|SCI_RE), &SCR1); /* enable transmitter & receiver */ | ||
183 | } | ||
184 | |||
185 | static void write_transfer(const unsigned char *buf, int len) | ||
186 | { | ||
187 | const unsigned char *buf_end = buf + len; | ||
188 | |||
189 | /* TODO: DMA */ | ||
190 | |||
191 | while (!(SSR1 & SCI_TEND)); /* wait until previous transfer ended */ | ||
192 | |||
193 | while (buf < buf_end) | ||
194 | { | ||
195 | while (!(SSR1 & SCI_TDRE)); /* wait for Tx reg. free */ | ||
196 | TDR1 = fliptable[(signed char)(*buf++)]; /* write byte */ | ||
197 | SSR1 = 0; /* start transmitting */ | ||
198 | } | ||
199 | } | ||
200 | |||
201 | static void read_transfer(unsigned char *buf, int len) | ||
202 | { | ||
203 | unsigned char *buf_end = buf + len; | ||
204 | |||
205 | /* TODO: DMA */ | ||
206 | |||
207 | while (!(SSR1 & SCI_TEND)); /* wait until previous transfer ended */ | ||
208 | TDR1 = 0xFF; /* send do-nothing data in parallel */ | ||
209 | |||
210 | while (buf < buf_end) | ||
211 | { | ||
212 | SSR1 = 0; /* start receiving */ | ||
213 | while (!(SSR1 & SCI_RDRF)); /* wait for data */ | ||
214 | *buf++ = fliptable[(signed char)(RDR1)]; /* read byte */ | ||
215 | } | ||
216 | } | ||
217 | |||
218 | /* timeout is in bytes */ | ||
219 | static unsigned char poll_byte(int timeout) | ||
220 | { | ||
221 | int i; | ||
222 | unsigned char data = 0; /* stop the compiler complaining */ | ||
223 | |||
224 | while (!(SSR1 & SCI_TEND)); /* wait until previous transfer ended */ | ||
225 | TDR1 = 0xFF; /* send do-nothing data in parallel */ | ||
226 | |||
227 | i = 0; | ||
228 | do { | ||
229 | SSR1 = 0; /* start receiving */ | ||
230 | while (!(SSR1 & SCI_RDRF)); /* wait for data */ | ||
231 | data = RDR1; /* read byte */ | ||
232 | } while ((data == 0xFF) && (++i < timeout)); | ||
233 | |||
234 | return fliptable[(signed char)data]; | ||
235 | } | ||
62 | 236 | ||
237 | static int send_cmd(int cmd, unsigned long parameter, unsigned char *response) | ||
238 | { | ||
239 | unsigned char command[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95 }; | ||
240 | |||
241 | command[0] = cmd; | ||
242 | |||
243 | if (parameter != 0) | ||
244 | { | ||
245 | command[1] = (parameter >> 24) & 0xFF; | ||
246 | command[2] = (parameter >> 16) & 0xFF; | ||
247 | command[3] = (parameter >> 8) & 0xFF; | ||
248 | command[4] = parameter & 0xFF; | ||
249 | } | ||
250 | |||
251 | write_transfer(command, 6); | ||
252 | |||
253 | response[0] = poll_byte(50); | ||
254 | |||
255 | if (response[0] != 0x00) | ||
256 | { | ||
257 | write_transfer(dummy, 1); | ||
258 | return -1; | ||
259 | } | ||
260 | |||
261 | switch (cmd) | ||
262 | { | ||
263 | case CMD_SEND_CSD: /* R1 response, leave open */ | ||
264 | case CMD_SEND_CID: | ||
265 | case CMD_READ_SINGLE_BLOCK: | ||
266 | // case READ_MULTIPLE_BLOCK: | ||
267 | break; | ||
268 | |||
269 | case CMD_SEND_STATUS: /* R2 response, close with dummy */ | ||
270 | read_transfer(response + 1, 1); | ||
271 | write_transfer(dummy, 1); | ||
272 | break; | ||
273 | |||
274 | case CMD_READ_OCR: /* R3 response, close with dummy */ | ||
275 | read_transfer(response + 1, 4); | ||
276 | write_transfer(dummy, 1); | ||
277 | break; | ||
278 | |||
279 | default: /* R1 response, close with dummy */ | ||
280 | write_transfer(dummy, 1); | ||
281 | break; /* also catches block writes */ | ||
282 | } | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static int receive_data(unsigned char *buf, int len, int timeout) | ||
288 | { | ||
289 | unsigned char crc[2]; /* unused */ | ||
290 | |||
291 | if (poll_byte(timeout) != 0xFE) | ||
292 | { | ||
293 | write_transfer(dummy, 1); | ||
294 | return -1; /* not start of data */ | ||
295 | } | ||
296 | |||
297 | read_transfer(buf, len); | ||
298 | read_transfer(crc, 2); /* throw away */ | ||
299 | write_transfer(dummy, 1); | ||
300 | |||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static int initialize_card(int card_no) | ||
305 | { | ||
306 | int i, temp; | ||
307 | unsigned char response; | ||
308 | unsigned char cxd[16]; | ||
309 | tCardInfo *card = &card_info[card_no]; | ||
310 | |||
311 | static const char mantissa[] = { /* *10 */ | ||
312 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
313 | 35, 40, 45, 50, 55, 60, 70, 80 | ||
314 | }; | ||
315 | static const int speed_exponent[] = { /* /10 */ | ||
316 | 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 | ||
317 | }; | ||
318 | |||
319 | static const int time_exponent[] = { /* reciprocal */ | ||
320 | 1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100 | ||
321 | }; | ||
322 | |||
323 | card->initialized = false; | ||
324 | setup_sci1(7); /* Initial rate: 375 kBit/s (need <= 400 per mmc specs) */ | ||
325 | write_transfer(dummy, 10); /* synchronize: 74+ clocks */ | ||
326 | |||
327 | /* switch to SPI mode */ | ||
328 | send_cmd(CMD_GO_IDLE_STATE, 0, &response); | ||
329 | if (response != 0x01) | ||
330 | return -1; /* error response */ | ||
331 | |||
332 | /* initialize card */ | ||
333 | i = 0; | ||
334 | while (send_cmd(CMD_SEND_OP_COND, 0, &response) && (++i < 100)); | ||
335 | if (response != 0x00) | ||
336 | return -2; /* not ready */ | ||
337 | |||
338 | /* get CSD register */ | ||
339 | if (send_cmd(CMD_SEND_CSD, 0, &response)) | ||
340 | return -3; | ||
341 | if (receive_data(cxd, 16, 50)) | ||
342 | return -4; | ||
343 | |||
344 | /* check block size */ | ||
345 | if (1 << (cxd[5] & 0x0F) != SECTOR_SIZE) | ||
346 | return -5; | ||
347 | |||
348 | /* max transmission speed the card is capable of */ | ||
349 | card->speed = mantissa[(cxd[3] & 0x78) >> 3] | ||
350 | * speed_exponent[(cxd[3] & 0x07)]; | ||
351 | |||
352 | /* calculate the clock divider */ | ||
353 | card->bitrate_register = (FREQ/4-1) / card->speed; | ||
354 | |||
355 | /* calculate read timeout in clock cycles from TSAC, NSAC and the actual | ||
356 | * clock frequency */ | ||
357 | temp = (FREQ/4) / (card->bitrate_register + 1); /* actual frequency */ | ||
358 | card->read_timeout = | ||
359 | (temp * mantissa[(cxd[1] & 0x78) >> 3] + (1000 * cxd[2])) | ||
360 | / (time_exponent[cxd[1] & 0x07] * 8); | ||
361 | |||
362 | /* calculate write timeout */ | ||
363 | temp = (cxd[12] & 0x1C) >> 2; | ||
364 | if (temp > 5) | ||
365 | temp = 5; | ||
366 | card->write_timeout = card->read_timeout * (1 << temp); | ||
367 | |||
368 | /* calculate size */ | ||
369 | card->size = ((unsigned int)(cxd[6] & 0x03) << 10) | ||
370 | + ((unsigned int)cxd[7] << 2) | ||
371 | + ((unsigned int)(cxd[8] & 0xC0) >> 6); | ||
372 | temp = ((cxd[9] & 0x03) << 1) + ((cxd[10] & 0x80) >> 7) + 2; | ||
373 | card->size *= (SECTOR_SIZE << temp); | ||
374 | |||
375 | /* switch to full speed */ | ||
376 | setup_sci1(card->bitrate_register); | ||
377 | |||
378 | /* get CID register */ | ||
379 | if (send_cmd(CMD_SEND_CID, 0, &response)) | ||
380 | return -6; | ||
381 | if (receive_data(cxd, 16, 50)) | ||
382 | return -7; | ||
383 | |||
384 | /* get data from CID */ | ||
385 | strncpy(card->name, &cxd[3], 6); | ||
386 | card->name[6] = '\0'; | ||
387 | |||
388 | card->rev = (cxd[9] & 0xF0) >> 4; | ||
389 | card->rev_fract = cxd[9] & 0x0F; | ||
390 | |||
391 | card->manuf_month = (cxd[14] & 0xF0) >> 4; | ||
392 | card->manuf_year = (cxd[14] & 0x0F) + 1997; | ||
393 | |||
394 | card->serial_number = ((unsigned long)cxd[10] << 24) | ||
395 | + ((unsigned long)cxd[11] << 16) | ||
396 | + ((unsigned long)cxd[12] << 8) | ||
397 | + (unsigned long)cxd[13]; | ||
398 | |||
399 | card->initialized = true; | ||
400 | return 0; | ||
401 | } | ||
63 | 402 | ||
64 | int ata_read_sectors(unsigned long start, | 403 | int ata_read_sectors(unsigned long start, |
65 | int incount, | 404 | int incount, |
66 | void* inbuf) | 405 | void* inbuf) |
67 | { | 406 | { |
68 | int ret = 0; | 407 | int ret = 0; |
408 | int i; | ||
409 | unsigned long addr; | ||
410 | unsigned char response; | ||
411 | tCardInfo *card = &card_info[current_card]; | ||
69 | 412 | ||
413 | addr = start * SECTOR_SIZE; | ||
414 | |||
70 | mutex_lock(&ata_mtx); | 415 | mutex_lock(&ata_mtx); |
416 | ret = select_card(current_card); | ||
71 | 417 | ||
72 | last_disk_activity = current_tick; | 418 | for (i = 0; (i < incount) && (ret == 0); i++) |
73 | 419 | { | |
74 | led(true); | 420 | if ((ret = send_cmd(CMD_READ_SINGLE_BLOCK, addr, &response))) |
75 | sleeping = false; | 421 | break; |
76 | 422 | ret = receive_data(inbuf, SECTOR_SIZE, card->read_timeout); | |
77 | /* ToDo: action */ | ||
78 | (void)start; | ||
79 | (void)incount; | ||
80 | (void)inbuf; | ||
81 | 423 | ||
82 | led(false); | 424 | addr += SECTOR_SIZE; |
425 | inbuf += SECTOR_SIZE; | ||
426 | } | ||
83 | 427 | ||
428 | deselect_card(); | ||
84 | mutex_unlock(&ata_mtx); | 429 | mutex_unlock(&ata_mtx); |
85 | 430 | ||
86 | /* only flush if reading went ok */ | ||
87 | if ( (ret == 0) && delayed_write ) | ||
88 | ata_flush(); | ||
89 | |||
90 | return ret; | 431 | return ret; |
91 | } | 432 | } |
92 | 433 | ||
93 | 434 | ||
94 | |||
95 | int ata_write_sectors(unsigned long start, | 435 | int ata_write_sectors(unsigned long start, |
96 | int count, | 436 | int count, |
97 | const void* buf) | 437 | const void* buf) |
@@ -102,65 +442,35 @@ int ata_write_sectors(unsigned long start, | |||
102 | panicf("Writing on sector 0\n"); | 442 | panicf("Writing on sector 0\n"); |
103 | 443 | ||
104 | mutex_lock(&ata_mtx); | 444 | mutex_lock(&ata_mtx); |
105 | sleeping = false; | ||
106 | |||
107 | last_disk_activity = current_tick; | ||
108 | |||
109 | led(true); | ||
110 | 445 | ||
111 | /* ToDo: action */ | 446 | /* ToDo: action */ |
112 | (void)start; | 447 | (void)start; |
113 | (void)count; | 448 | (void)count; |
114 | (void)buf; | 449 | (void)buf; |
115 | 450 | ||
116 | led(false); | ||
117 | |||
118 | mutex_unlock(&ata_mtx); | 451 | mutex_unlock(&ata_mtx); |
119 | 452 | ||
120 | /* only flush if writing went ok */ | ||
121 | if ( (ret == 0) && delayed_write ) | ||
122 | ata_flush(); | ||
123 | |||
124 | return ret; | 453 | return ret; |
125 | } | 454 | } |
126 | 455 | ||
456 | /* no need to delay with flash memory. There is no spinup :) */ | ||
127 | extern void ata_delayed_write(unsigned long sector, const void* buf) | 457 | extern void ata_delayed_write(unsigned long sector, const void* buf) |
128 | { | 458 | { |
129 | memcpy(delayed_sector, buf, SECTOR_SIZE); | 459 | ata_write_sectors(sector, 1, buf); |
130 | delayed_sector_num = sector; | ||
131 | delayed_write = true; | ||
132 | } | 460 | } |
133 | 461 | ||
134 | extern void ata_flush(void) | 462 | extern void ata_flush(void) |
135 | { | 463 | { |
136 | if ( delayed_write ) { | ||
137 | DEBUGF("ata_flush()\n"); | ||
138 | delayed_write = false; | ||
139 | ata_write_sectors(delayed_sector_num, 1, delayed_sector); | ||
140 | } | ||
141 | } | 464 | } |
142 | 465 | ||
143 | void ata_spindown(int seconds) | 466 | void ata_spindown(int seconds) |
144 | { | 467 | { |
145 | sleep_timeout = seconds * HZ; | 468 | (void)seconds; |
146 | } | 469 | } |
147 | 470 | ||
148 | bool ata_disk_is_active(void) | 471 | bool ata_disk_is_active(void) |
149 | { | 472 | { |
150 | return !sleeping; | 473 | return true; |
151 | } | ||
152 | |||
153 | static int ata_perform_sleep(void) | ||
154 | { | ||
155 | int ret = 0; | ||
156 | |||
157 | mutex_lock(&ata_mtx); | ||
158 | |||
159 | /* ToDo: is there an equivalent? */ | ||
160 | |||
161 | sleeping = true; | ||
162 | mutex_unlock(&ata_mtx); | ||
163 | return ret; | ||
164 | } | 474 | } |
165 | 475 | ||
166 | int ata_standby(int time) | 476 | int ata_standby(int time) |
@@ -178,61 +488,38 @@ int ata_standby(int time) | |||
178 | 488 | ||
179 | int ata_sleep(void) | 489 | int ata_sleep(void) |
180 | { | 490 | { |
181 | queue_post(&ata_queue, Q_SLEEP, NULL); | ||
182 | return 0; | 491 | return 0; |
183 | } | 492 | } |
184 | 493 | ||
185 | void ata_spin(void) | 494 | void ata_spin(void) |
186 | { | 495 | { |
187 | last_user_activity = current_tick; | ||
188 | } | 496 | } |
189 | 497 | ||
190 | static void ata_thread(void) | 498 | static void mmc_thread(void) |
191 | { | 499 | { |
192 | static long last_sleep = 0; | ||
193 | struct event ev; | 500 | struct event ev; |
194 | 501 | ||
195 | while (1) { | 502 | while (1) { |
196 | while ( queue_empty( &ata_queue ) ) { | 503 | while ( queue_empty( &mmc_queue ) ) { |
197 | if ( sleep_timeout && !sleeping && | ||
198 | TIME_AFTER( current_tick, | ||
199 | last_user_activity + sleep_timeout ) && | ||
200 | TIME_AFTER( current_tick, | ||
201 | last_disk_activity + sleep_timeout ) ) | ||
202 | { | ||
203 | ata_perform_sleep(); | ||
204 | last_sleep = current_tick; | ||
205 | } | ||
206 | 504 | ||
207 | sleep(HZ/4); | 505 | sleep(HZ/4); |
208 | } | 506 | } |
209 | queue_wait(&ata_queue, &ev); | 507 | queue_wait(&mmc_queue, &ev); |
210 | switch ( ev.id ) { | 508 | switch ( ev.id ) { |
211 | #ifndef USB_NONE | 509 | #ifndef USB_NONE |
212 | case SYS_USB_CONNECTED: | 510 | case SYS_USB_CONNECTED: |
213 | /* Tell the USB thread that we are safe */ | 511 | /* Tell the USB thread that we are safe */ |
214 | DEBUGF("ata_thread got SYS_USB_CONNECTED\n"); | 512 | DEBUGF("mmc_thread got SYS_USB_CONNECTED\n"); |
215 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | 513 | usb_acknowledge(SYS_USB_CONNECTED_ACK); |
216 | 514 | ||
217 | /* Wait until the USB cable is extracted again */ | 515 | /* Wait until the USB cable is extracted again */ |
218 | usb_wait_for_disconnect(&ata_queue); | 516 | usb_wait_for_disconnect(&mmc_queue); |
219 | break; | 517 | break; |
220 | #endif | 518 | #endif |
221 | case Q_SLEEP: | ||
222 | last_disk_activity = current_tick - sleep_timeout + (HZ/2); | ||
223 | break; | ||
224 | } | 519 | } |
225 | } | 520 | } |
226 | } | 521 | } |
227 | 522 | ||
228 | /* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */ | ||
229 | int ata_hard_reset(void) | ||
230 | { | ||
231 | int ret = 0; | ||
232 | |||
233 | return ret; | ||
234 | } | ||
235 | |||
236 | int ata_soft_reset(void) | 523 | int ata_soft_reset(void) |
237 | { | 524 | { |
238 | int ret = 0; | 525 | int ret = 0; |
@@ -242,30 +529,21 @@ int ata_soft_reset(void) | |||
242 | 529 | ||
243 | void ata_enable(bool on) | 530 | void ata_enable(bool on) |
244 | { | 531 | { |
245 | PBCR1 &= ~0x0CC0; /* PB13 and TxD1 become GPIOs, if not modified below */ | 532 | PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIOs, if not modified below */ |
246 | if (on) | 533 | if (on) |
247 | { | 534 | { |
248 | /* serial setup */ | 535 | /* serial setup */ |
249 | PBCR1 |= 0x0880; /* as SCK1, TxD1 */ | 536 | PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */ |
250 | } | 537 | } |
251 | else | 538 | else |
252 | { | 539 | { |
253 | PBDR |= 0x2000; /* drive PB13 high */ | 540 | and_b(~0x80, &PADRL); /* assert reset */ |
254 | PBIOR |= 0x2000; /* output PB13 */ | 541 | sleep(5); |
255 | PBIOR &= ~0x0800; /* high impedance for TxD1 GPIO */ | 542 | or_b(0x80, &PADRL); /* de-assert reset */ |
256 | PADR |= 0x0680; /* set all the selects+reset high (=inactive) */ | 543 | sleep(5); |
257 | |||
258 | PADR &= ~0x0080; /* assert reset */ | ||
259 | sleep(1); | ||
260 | PADR |= 0x0080; /* de-assert reset */ | ||
261 | } | 544 | } |
262 | } | 545 | } |
263 | 546 | ||
264 | unsigned short* ata_get_identify(void) | ||
265 | { | ||
266 | return identify_info; | ||
267 | } | ||
268 | |||
269 | int ata_init(void) | 547 | int ata_init(void) |
270 | { | 548 | { |
271 | int rc = 0; | 549 | int rc = 0; |
@@ -275,30 +553,30 @@ int ata_init(void) | |||
275 | led(false); | 553 | led(false); |
276 | 554 | ||
277 | /* Port setup */ | 555 | /* Port setup */ |
278 | PADR |= 0x0680; /* set all the selects + reset high (=inactive) */ | 556 | PADR |= 0x0680; /* set all the selects + reset high (=inactive) */ |
279 | PAIOR |= 0x1680; /* make outputs for them and the PA12 clock gate */ | 557 | PAIOR |= 0x1680; /* make outputs for them and the PA12 clock gate */ |
558 | |||
559 | PBDR |= 0x2C00; /* SCK1, TxD1 and RxD1 high when GPIO CHECKME: mask */ | ||
560 | PBIOR |= 0x2000; /* SCK1 output */ | ||
561 | PBIOR &= ~0x0C00; /* TxD1, RxD1 input */ | ||
280 | 562 | ||
281 | if(adc_read(ADC_MMC_SWITCH) < 0x200) | 563 | if(adc_read(ADC_MMC_SWITCH) < 0x200) |
282 | { /* MMC inserted */ | 564 | { /* MMC inserted */ |
283 | PADR &= ~0x1000; /* clear PA12 */ | 565 | current_card = 1; |
284 | PADR &= ~0x0200; /* chip select external flash */ | ||
285 | } | 566 | } |
286 | else | 567 | else |
287 | { /* no MMC, use internal memory */ | 568 | { /* no MMC, use internal memory */ |
288 | PADR |= 0x1000; /* set PA12 */ | 569 | current_card = 0; |
289 | PADR &= ~0x0400; /* chip select internal flash */ | ||
290 | } | 570 | } |
291 | 571 | ||
292 | sleeping = false; | ||
293 | ata_enable(true); | 572 | ata_enable(true); |
294 | 573 | ||
295 | if ( !initialized ) { | 574 | if ( !initialized ) { |
296 | 575 | ||
297 | queue_init(&ata_queue); | 576 | queue_init(&mmc_queue); |
298 | 577 | ||
299 | last_disk_activity = current_tick; | 578 | create_thread(mmc_thread, mmc_stack, |
300 | create_thread(ata_thread, ata_stack, | 579 | sizeof(mmc_stack), mmc_thread_name); |
301 | sizeof(ata_stack), ata_thread_name); | ||
302 | initialized = true; | 580 | initialized = true; |
303 | } | 581 | } |
304 | 582 | ||