summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2011-08-08 20:09:27 +0000
committerMarcin Bukat <marcin.bukat@gmail.com>2011-08-08 20:09:27 +0000
commit1d2fae446699fbb7697b070fba9352cd4a3af53f (patch)
tree7fd70af355460a97ec97290866aca85bb92d4b54
parentc23f576a1cadc88d305ad04be039a2438eb85e14 (diff)
downloadrockbox-1d2fae446699fbb7697b070fba9352cd4a3af53f.tar.gz
rockbox-1d2fae446699fbb7697b070fba9352cd4a3af53f.zip
rk27xx sd driver fixes
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30269 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/rk27xx/sd-rk27xx.c125
1 files changed, 76 insertions, 49 deletions
diff --git a/firmware/target/arm/rk27xx/sd-rk27xx.c b/firmware/target/arm/rk27xx/sd-rk27xx.c
index c5a23ad00d..dab6c3e1f3 100644
--- a/firmware/target/arm/rk27xx/sd-rk27xx.c
+++ b/firmware/target/arm/rk27xx/sd-rk27xx.c
@@ -457,73 +457,90 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
457 457
458 ret = 0; 458 ret = 0;
459 retry = false; /* reset retry flag */ 459 retry = false; /* reset retry flag */
460 mmu_buff_reset(); /* reset recive buff state */ 460
461 mmu_buff_reset();
462
463 if (cnt == 1)
464 {
465 /* last block to tranfer */
466 SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
467 DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
468 DATA_XFER_SINGLE;
469 }
470 else
471 {
472 /* more than one block to transfer */
473 SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
474 DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
475 DATA_XFER_MULTI;
476 }
461 477
462 /* issue read command to the card */ 478 /* issue read command to the card */
463 if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response)) 479 if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response))
464 { 480 {
465 ret = -4; 481 ret = -2;
466 continue; 482 continue;
467 } 483 }
468 484
469 while (cnt > 0) 485 while (cnt > 0)
470 { 486 {
471 if (cnt == 1)
472 {
473 /* last block to tranfer */
474 SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
475 DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
476 DATA_XFER_SINGLE;
477 }
478 else
479 {
480 /* more than one block to transfer */
481 SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
482 DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
483 DATA_XFER_MULTI;
484 }
485
486 /* wait for transfer completion */ 487 /* wait for transfer completion */
487 semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK); 488 semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
488 489
489 if (retry) 490 if (retry)
490 { 491 {
491 /* data transfer error */ 492 /* data transfer error */
492 ret = -5; 493 ret = -3;
493 break; 494 break;
494 } 495 }
495 496
496 /* exchange buffers */ 497 /* exchange buffers */
497 mmu_switch_buff(); 498 mmu_switch_buff();
498 499
499 last_disk_activity = current_tick;
500
501 /* transfer data from receive buffer to the dest
502 * for (i=0; i<(512/4); i++)
503 * *dst++ = MMU_DATA;
504 *
505 * below is DMA version in software mode.
506 * SD module provides DMAreq signals and all this
507 * can be done in hardware in theory but I can't
508 * figure this out. OF doesn't use DMA at all.
509 */
510 A2A_IDST0 = (unsigned long)dst; 500 A2A_IDST0 = (unsigned long)dst;
511 A2A_CON0 = (3<<9) | (1<<6) | (1<<3) | (2<<1) | (1<<0); 501 A2A_CON0 = (3<<9) | /* burst 16 */
502 (1<<6) | /* fixed src */
503 (1<<3) | /* DMA start */
504 (2<<1) | /* word transfer size */
505 (1<<0); /* software mode */
512 506
513 /* wait for DMA engine to finish transfer */ 507 /* wait for DMA engine to finish transfer */
514 while (A2A_DMA_STS & 1); 508 while (A2A_DMA_STS & 1);
515 509
516 dst += 512; 510 dst += 512;
517 cnt--; 511 cnt--;
518 } /* while (cnt > 0) */
519 512
520 if (!send_cmd(SD_STOP_TRANSMISSION, 0, RES_R1b, &response)) 513 if (cnt == 0)
521 ret = -6; 514 {
515 if (!send_cmd(SD_STOP_TRANSMISSION, 0, RES_R1b, &response))
516 ret = -4;
517
518 break;
519 }
520 else if (cnt == 1)
521 {
522 /* last block to tranfer */
523 SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
524 DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
525 DATA_XFER_SINGLE;
526 }
527 else
528 {
529 /* more than one block to transfer */
530 SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
531 DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
532 DATA_XFER_MULTI;
533 }
534
535 last_disk_activity = current_tick;
536
537 } /* while (cnt > 0) */
522 538
523 /* transfer successfull - leave retry loop */ 539 /* transfer successfull - leave retry loop */
524 if (ret == 0) 540 if (ret == 0)
525 break; 541 break;
526 } 542
543 } /* while (retry_cnt++ < 20) */
527 544
528 sd_enable(false); 545 sd_enable(false);
529 mutex_unlock(&sd_mtx); 546 mutex_unlock(&sd_mtx);
@@ -548,7 +565,7 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
548 unsigned int retry_cnt = 0; 565 unsigned int retry_cnt = 0;
549 int cnt, ret = 0; 566 int cnt, ret = 0;
550 unsigned char *src; 567 unsigned char *src;
551 bool card_selected = false; 568 /* bool card_selected = false; */
552 569
553 mutex_lock(&sd_mtx); 570 mutex_lock(&sd_mtx);
554 sd_enable(true); 571 sd_enable(true);
@@ -574,6 +591,18 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
574 retry = false; /* reset retry flag */ 591 retry = false; /* reset retry flag */
575 mmu_buff_reset(); /* reset recive buff state */ 592 mmu_buff_reset(); /* reset recive buff state */
576 593
594 /* transfer data from receive buffer to the dest
595 * for (i=0; i<(512/4); i++)
596 * MMU_DATA = *src++;
597 *
598 * Below is DMA version in software mode.
599 */
600
601 A2A_ISRC0 = (unsigned long)src;
602 A2A_CON0 = (3<<9) | (1<<5) | (1<<3) | (2<<1) | (1<<0);
603
604 while (A2A_DMA_STS & 1);
605
577 if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response)) 606 if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response))
578 { 607 {
579 ret = -3; 608 ret = -3;
@@ -582,20 +611,6 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
582 611
583 while (cnt > 0) 612 while (cnt > 0)
584 { 613 {
585 /* transfer data from receive buffer to the dest
586 * for (i=0; i<(512/4); i++)
587 * MMU_DATA = *src++;
588 *
589 * Below is DMA version in software mode.
590 */
591
592 A2A_ISRC0 = (unsigned long)src;
593 A2A_CON0 = (3<<9) | (1<<5) | (1<<3) | (2<<1) | (1<<0);
594
595 while (A2A_DMA_STS & 1);
596
597 src += 512;
598
599 /* exchange buffers */ 614 /* exchange buffers */
600 mmu_switch_buff(); 615 mmu_switch_buff();
601 616
@@ -614,6 +629,18 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
614 DATA_BUS_1LINE | DATA_XFER_DMA_DIS | 629 DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
615 DATA_XFER_MULTI; 630 DATA_XFER_MULTI;
616 631
632 /* transfer data from receive buffer to the dest
633 * for (i=0; i<(512/4); i++)
634 * MMU_DATA = *src++;
635 *
636 * Below is DMA version in software mode.
637 */
638 src += 512;
639
640 A2A_ISRC0 = (unsigned long)src;
641 A2A_CON0 = (3<<9) | (1<<5) | (1<<3) | (2<<1) | (1<<0);
642
643 while (A2A_DMA_STS & 1);
617 } 644 }
618 645
619 /* wait for transfer completion */ 646 /* wait for transfer completion */