summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/ata_mmc.c102
1 files changed, 76 insertions, 26 deletions
diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c
index a7d7f1d40a..b4c2e844e0 100644
--- a/firmware/drivers/ata_mmc.c
+++ b/firmware/drivers/ata_mmc.c
@@ -137,6 +137,12 @@ static int initialize_card(int card_no);
137 137
138static int select_card(int card_no) 138static int select_card(int card_no)
139{ 139{
140 if (!card_info[card_no].initialized)
141 {
142 write_transfer(dummy, 10); /* allow the card to synchronize */
143 while (!(SSR1 & SCI_TEND));
144 }
145
140 if (card_no == 0) 146 if (card_no == 0)
141 { /* internal */ 147 { /* internal */
142 or_b(0x10, &PADRH); /* set clock gate PA12 CHECKME: mask? */ 148 or_b(0x10, &PADRH); /* set clock gate PA12 CHECKME: mask? */
@@ -161,7 +167,7 @@ static int select_card(int card_no)
161 167
162static void deselect_card(void) 168static void deselect_card(void)
163{ 169{
164 while (!(SSR1 & SCI_TEND)); /* wait until end of transfer */ 170 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
165 or_b(0x06, &PADRH); /* deassert CS (both cards) */ 171 or_b(0x06, &PADRH); /* deassert CS (both cards) */
166} 172}
167 173
@@ -169,7 +175,7 @@ static void setup_sci1(int bitrate_register)
169{ 175{
170 int i; 176 int i;
171 177
172 while (!(SSR1 & SCI_TEND)); /* wait until previous transfer ended */ 178 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
173 179
174 SCR1 = 0; /* disable serial port */ 180 SCR1 = 0; /* disable serial port */
175 SMR1 = SYNC_MODE; /* no prescale */ 181 SMR1 = SYNC_MODE; /* no prescale */
@@ -187,12 +193,10 @@ static void write_transfer(const unsigned char *buf, int len)
187 const unsigned char *buf_end = buf + len; 193 const unsigned char *buf_end = buf + len;
188 194
189 /* TODO: DMA */ 195 /* TODO: DMA */
190 196
191 while (!(SSR1 & SCI_TEND)); /* wait until previous transfer ended */
192
193 while (buf < buf_end) 197 while (buf < buf_end)
194 { 198 {
195 while (!(SSR1 & SCI_TDRE)); /* wait for Tx reg. free */ 199 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
196 TDR1 = fliptable[(signed char)(*buf++)]; /* write byte */ 200 TDR1 = fliptable[(signed char)(*buf++)]; /* write byte */
197 SSR1 = 0; /* start transmitting */ 201 SSR1 = 0; /* start transmitting */
198 } 202 }
@@ -204,7 +208,7 @@ static void read_transfer(unsigned char *buf, int len)
204 208
205 /* TODO: DMA */ 209 /* TODO: DMA */
206 210
207 while (!(SSR1 & SCI_TEND)); /* wait until previous transfer ended */ 211 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
208 TDR1 = 0xFF; /* send do-nothing data in parallel */ 212 TDR1 = 0xFF; /* send do-nothing data in parallel */
209 213
210 while (buf < buf_end) 214 while (buf < buf_end)
@@ -221,7 +225,7 @@ static unsigned char poll_byte(int timeout)
221 int i; 225 int i;
222 unsigned char data = 0; /* stop the compiler complaining */ 226 unsigned char data = 0; /* stop the compiler complaining */
223 227
224 while (!(SSR1 & SCI_TEND)); /* wait until previous transfer ended */ 228 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
225 TDR1 = 0xFF; /* send do-nothing data in parallel */ 229 TDR1 = 0xFF; /* send do-nothing data in parallel */
226 230
227 i = 0; 231 i = 0;
@@ -234,6 +238,24 @@ static unsigned char poll_byte(int timeout)
234 return fliptable[(signed char)data]; 238 return fliptable[(signed char)data];
235} 239}
236 240
241static unsigned char poll_busy(int timeout)
242{
243 int i;
244 unsigned char data;
245
246 while (!(SSR1 &SCI_TEND)); /* wait for end of transfer */
247 TDR1 = 0xFF; /* send do-nothing data in parallel */
248
249 i = 0;
250 do {
251 SSR1 = 0; /* start receiving */
252 while (!(SSR1 & SCI_RDRF)); /* wait for data */
253 data = RDR1; /* read byte */
254 } while ((data == 0x00) && (++i < timeout));
255
256 return fliptable[(signed char)data];
257}
258
237static int send_cmd(int cmd, unsigned long parameter, unsigned char *response) 259static int send_cmd(int cmd, unsigned long parameter, unsigned char *response)
238{ 260{
239 unsigned char command[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95 }; 261 unsigned char command[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95 };
@@ -250,7 +272,7 @@ static int send_cmd(int cmd, unsigned long parameter, unsigned char *response)
250 272
251 write_transfer(command, 6); 273 write_transfer(command, 6);
252 274
253 response[0] = poll_byte(50); 275 response[0] = poll_byte(20);
254 276
255 if (response[0] != 0x00) 277 if (response[0] != 0x00)
256 { 278 {
@@ -301,6 +323,23 @@ static int receive_data(unsigned char *buf, int len, int timeout)
301 return 0; 323 return 0;
302} 324}
303 325
326static int send_data(const unsigned char *buf, int len, int timeout)
327{
328 static const unsigned char start_data = 0xFE;
329 int ret = 0;
330
331 write_transfer(&start_data, 1);
332 write_transfer(buf, len);
333 write_transfer(dummy, 2); /* crc - dontcare */
334
335 if ((poll_busy(timeout) & 0x1F) != 0x05) /* something went wrong */
336 ret = -1;
337
338 write_transfer(dummy, 1);
339
340 return ret;
341}
342
304static int initialize_card(int card_no) 343static int initialize_card(int card_no)
305{ 344{
306 int i, temp; 345 int i, temp;
@@ -322,8 +361,7 @@ static int initialize_card(int card_no)
322 361
323 card->initialized = false; 362 card->initialized = false;
324 setup_sci1(7); /* Initial rate: 375 kBit/s (need <= 400 per mmc specs) */ 363 setup_sci1(7); /* Initial rate: 375 kBit/s (need <= 400 per mmc specs) */
325 write_transfer(dummy, 10); /* synchronize: 74+ clocks */ 364
326
327 /* switch to SPI mode */ 365 /* switch to SPI mode */
328 send_cmd(CMD_GO_IDLE_STATE, 0, &response); 366 send_cmd(CMD_GO_IDLE_STATE, 0, &response);
329 if (response != 0x01) 367 if (response != 0x01)
@@ -331,7 +369,7 @@ static int initialize_card(int card_no)
331 369
332 /* initialize card */ 370 /* initialize card */
333 i = 0; 371 i = 0;
334 while (send_cmd(CMD_SEND_OP_COND, 0, &response) && (++i < 100)); 372 while (send_cmd(CMD_SEND_OP_COND, 0, &response) && (++i < 200));
335 if (response != 0x00) 373 if (response != 0x00)
336 return -2; /* not ready */ 374 return -2; /* not ready */
337 375
@@ -409,7 +447,7 @@ int ata_read_sectors(unsigned long start,
409 unsigned long addr; 447 unsigned long addr;
410 unsigned char response; 448 unsigned char response;
411 tCardInfo *card = &card_info[current_card]; 449 tCardInfo *card = &card_info[current_card];
412 450
413 addr = start * SECTOR_SIZE; 451 addr = start * SECTOR_SIZE;
414 452
415 mutex_lock(&ata_mtx); 453 mutex_lock(&ata_mtx);
@@ -424,7 +462,7 @@ int ata_read_sectors(unsigned long start,
424 addr += SECTOR_SIZE; 462 addr += SECTOR_SIZE;
425 inbuf += SECTOR_SIZE; 463 inbuf += SECTOR_SIZE;
426 } 464 }
427 465
428 deselect_card(); 466 deselect_card();
429 mutex_unlock(&ata_mtx); 467 mutex_unlock(&ata_mtx);
430 468
@@ -437,17 +475,30 @@ int ata_write_sectors(unsigned long start,
437 const void* buf) 475 const void* buf)
438{ 476{
439 int ret = 0; 477 int ret = 0;
478 int i;
479 unsigned long addr;
480 unsigned char response;
481 tCardInfo *card = &card_info[current_card];
440 482
441 if (start == 0) 483 if (start == 0)
442 panicf("Writing on sector 0\n"); 484 panicf("Writing on sector 0\n");
443 485
486 addr = start * SECTOR_SIZE;
487
444 mutex_lock(&ata_mtx); 488 mutex_lock(&ata_mtx);
489 ret = select_card(current_card);
445 490
446 /* ToDo: action */ 491 for (i = 0; (i < count) && (ret == 0); i++)
447 (void)start; 492 {
448 (void)count; 493 if ((ret = send_cmd(CMD_WRITE_BLOCK, addr, &response)))
449 (void)buf; 494 break;
495 ret = send_data(buf, SECTOR_SIZE, card->write_timeout);
450 496
497 addr += SECTOR_SIZE;
498 buf += SECTOR_SIZE;
499 }
500
501 deselect_card();
451 mutex_unlock(&ata_mtx); 502 mutex_unlock(&ata_mtx);
452 503
453 return ret; 504 return ret;
@@ -532,16 +583,15 @@ void ata_enable(bool on)
532 PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIOs, if not modified below */ 583 PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIOs, if not modified below */
533 if (on) 584 if (on)
534 { 585 {
535 /* serial setup */
536 PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */ 586 PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */
587 IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */
537 } 588 }
538 else 589 and_b(~0x80, &PADRL); /* assert reset */
539 { 590 sleep(HZ/20);
540 and_b(~0x80, &PADRL); /* assert reset */ 591 or_b(0x80, &PADRL); /* de-assert reset */
541 sleep(5); 592 sleep(HZ/20);
542 or_b(0x80, &PADRL); /* de-assert reset */ 593 card_info[0].initialized = false;
543 sleep(5); 594 card_info[1].initialized = false;
544 }
545} 595}
546 596
547int ata_init(void) 597int ata_init(void)