summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525/sd-as3525v2.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/as3525/sd-as3525v2.c')
-rw-r--r--firmware/target/arm/as3525/sd-as3525v2.c108
1 files changed, 33 insertions, 75 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c
index 27664ec52b..dec36a520d 100644
--- a/firmware/target/arm/as3525/sd-as3525v2.c
+++ b/firmware/target/arm/as3525/sd-as3525v2.c
@@ -483,6 +483,7 @@ static int sd_init_card(const int drive)
483 long init_timeout; 483 long init_timeout;
484 bool sd_v2 = false; 484 bool sd_v2 = false;
485 485
486 card_info[drive].initialized = 0;
486 card_info[drive].rca = 0; 487 card_info[drive].rca = 0;
487 488
488 /* assume 24 MHz clock / 60 = 400 kHz */ 489 /* assume 24 MHz clock / 60 = 400 kHz */
@@ -571,14 +572,6 @@ static int sd_init_card(const int drive)
571 572
572#endif /* ! BOOTLOADER */ 573#endif /* ! BOOTLOADER */
573 574
574 /* Set low power mode */
575#if defined(SANSA_FUZEV2) || defined(SANSA_CLIPPLUS) || defined(SANSA_CLIPZIP)
576 if (amsv2_variant == 1)
577 MCI_CLKENA |= 1<<(1 + 16);
578 else
579#endif
580 MCI_CLKENA |= 1<<(drive + 16);
581
582 card_info[drive].initialized = 1; 575 card_info[drive].initialized = 1;
583 576
584 return 0; 577 return 0;
@@ -709,14 +702,6 @@ int sd_init(void)
709 702
710 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE); 703 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
711 704
712 CGU_IDE = (1<<7) /* AHB interface enable */
713 | (AS3525_IDE_DIV << 2)
714 | 1; /* clock source = PLLA */
715
716 CGU_MEMSTICK = (1<<7) /* interface enable */
717 | (AS3525_MS_DIV << 2)
718 | 1; /* clock source = PLLA */
719
720 CGU_SDSLOT = (1<<7) /* interface enable */ 705 CGU_SDSLOT = (1<<7) /* interface enable */
721 | (AS3525_SDSLOT_DIV << 2) 706 | (AS3525_SDSLOT_DIV << 2)
722 | 1; /* clock source = PLLA */ 707 | 1; /* clock source = PLLA */
@@ -775,8 +760,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
775 const int drive = 0; 760 const int drive = 0;
776#endif 761#endif
777 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); 762 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1));
778 int const retry_all_max = 1; 763 int retry_all = 2;
779 int retry_all = 0;
780 int const retry_data_max = 3; 764 int const retry_data_max = 3;
781 int retry_data; 765 int retry_data;
782 unsigned int real_numblocks; 766 unsigned int real_numblocks;
@@ -787,26 +771,25 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
787 led(true); 771 led(true);
788#endif 772#endif
789 773
790 if(count < 0) /* XXX: why is it signed ? */ 774 if(count < 1) /* XXX: why is it signed ? */
791 { 775 {
776 panicf("SD count:%d write:%d drive:%d", count, write, drive);
777/*
792 ret = -18; 778 ret = -18;
793 goto sd_transfer_error_no_dma; 779 goto exit;
780*/
794 } 781 }
795 782
796 /* skip SanDisk OF */ 783 /* skip SanDisk OF */
797 if (drive == INTERNAL_AS3525) 784 if (drive == INTERNAL_AS3525)
798 start += AMS_OF_SIZE; 785 start += AMS_OF_SIZE;
799 786
800 /* no need for complete retry on main, just SD */ 787 while (!card_info[drive].initialized)
801 if (drive == SD_SLOT_AS3525)
802 retry_all = retry_all_max;
803
804sd_transfer_retry_with_reinit:
805 if (card_info[drive].initialized <= 0)
806 { 788 {
789retry_with_reinit:
790 if (--retry_all < 0)
791 goto exit;
807 ret = sd_init_card(drive); 792 ret = sd_init_card(drive);
808 if (!(card_info[drive].initialized))
809 goto sd_transfer_error_no_dma;
810 } 793 }
811 794
812 /* Check the real block size after the card has been initialized */ 795 /* Check the real block size after the card has been initialized */
@@ -818,14 +801,14 @@ sd_transfer_retry_with_reinit:
818 if ((start+count) > real_numblocks) 801 if ((start+count) > real_numblocks)
819 { 802 {
820 ret = -19; 803 ret = -19;
821 goto sd_transfer_error_no_dma; 804 goto retry_with_reinit;
822 } 805 }
823 806
824 /* CMD7 w/rca: Select card to put it in TRAN state */ 807 /* CMD7 w/rca: Select card to put it in TRAN state */
825 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_NO_RESP, NULL)) 808 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_NO_RESP, NULL))
826 { 809 {
827 ret = -20; 810 ret = -20;
828 goto sd_transfer_error_no_dma; 811 goto retry_with_reinit;
829 } 812 }
830 813
831 dma_retain(); 814 dma_retain();
@@ -841,7 +824,7 @@ sd_transfer_retry_with_reinit:
841 const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; 824 const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
842 retry_data = retry_data_max; 825 retry_data = retry_data_max;
843 826
844 while (1) 827 while (count > 0)
845 { 828 {
846 void *dma_buf; 829 void *dma_buf;
847 unsigned int transfer = count; 830 unsigned int transfer = count;
@@ -881,7 +864,7 @@ sd_transfer_retry_with_reinit:
881 if(!send_cmd(drive, cmd, arg, MCI_RESP, &response)) 864 if(!send_cmd(drive, cmd, arg, MCI_RESP, &response))
882 { 865 {
883 ret = -21; 866 ret = -21;
884 goto sd_transfer_error; 867 break;
885 } 868 }
886 869
887 semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK); 870 semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
@@ -897,14 +880,14 @@ sd_transfer_retry_with_reinit:
897 if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP, &response)) 880 if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP, &response))
898 { 881 {
899 ret = -22; 882 ret = -22;
900 goto sd_transfer_error; 883 break;
901 } 884 }
902 885
903 ret = sd_wait_for_tran_state(drive); 886 ret = sd_wait_for_tran_state(drive);
904 if (ret < 0) 887 if (ret < 0)
905 { 888 {
906 ret -= 25; 889 ret -= 25;
907 goto sd_transfer_error; 890 break;
908 } 891 }
909 892
910 /* According to datasheet DMA channel should be automatically disabled 893 /* According to datasheet DMA channel should be automatically disabled
@@ -912,62 +895,41 @@ sd_transfer_retry_with_reinit:
912 * Disable DMA channel manually to prevent problems with DMA. */ 895 * Disable DMA channel manually to prevent problems with DMA. */
913 dma_disable_channel(1); 896 dma_disable_channel(1);
914 897
915 if(!retry) 898 if (retry) /* reset controller if we had an error */
916 {
917 if(!write && !aligned)
918 memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE);
919 buf += transfer * SD_BLOCK_SIZE;
920 start += transfer;
921 count -= transfer;
922
923 if (count > 0)
924 continue;
925 }
926 else /* reset controller if we had an error */
927 { 899 {
928 MCI_CTRL |= (FIFO_RESET|DMA_RESET); 900 MCI_CTRL |= (FIFO_RESET|DMA_RESET);
929 while(MCI_CTRL & (FIFO_RESET|DMA_RESET)) 901 while (MCI_CTRL & (FIFO_RESET|DMA_RESET));
930 ;
931 if (--retry_data >= 0) 902 if (--retry_data >= 0)
932 continue; 903 continue;
933 904
934 ret -= 24; 905 ret -= 24;
935 goto sd_transfer_error; 906 break;
936 } 907 }
937 908
938 break; 909 if (!write && !aligned)
910 memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE);
911 buf += transfer * SD_BLOCK_SIZE;
912 start += transfer;
913 count -= transfer;
939 } 914 }
940 915
941 dma_release(); 916 dma_release();
942 917
918 if (ret != 0) /* if we have error */
919 goto retry_with_reinit;
920
943 /* CMD lines are separate, not common, so we need to actively deselect */ 921 /* CMD lines are separate, not common, so we need to actively deselect */
944 /* CMD7 w/rca =0 : deselects card & puts it in STBY state */ 922 /* CMD7 w/rca =0 : deselects card & puts it in STBY state */
945 if(!send_cmd(drive, SD_DESELECT_CARD, 0, MCI_NO_RESP, NULL)) 923 if(!send_cmd(drive, SD_DESELECT_CARD, 0, MCI_NO_RESP, NULL))
946 {
947 ret = -23; 924 ret = -23;
948 goto sd_transfer_error;
949 }
950 925
951 while (1) 926exit:
952 {
953#ifndef BOOTLOADER 927#ifndef BOOTLOADER
954 sd_enable(false); 928 sd_enable(false);
955 led(false); 929 led(false);
956#endif 930#endif
957 mutex_unlock(&sd_mtx); 931 mutex_unlock(&sd_mtx);
958 return ret; 932 return ret;
959
960sd_transfer_error:
961 dma_release();
962
963sd_transfer_error_no_dma:
964 card_info[drive].initialized = 0;
965
966 /* .initialized might have been >= 0 but now stale if the ata sd thread
967 * isn't handling an insert because of USB */
968 if (--retry_all >= 0)
969 goto sd_transfer_retry_with_reinit;
970 }
971} 933}
972 934
973int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, 935int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
@@ -993,15 +955,11 @@ void sd_enable(bool on)
993 if (on) 955 if (on)
994 { 956 {
995 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE); 957 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
996 CGU_IDE |= (1<<7); /* AHB interface enable */
997 CGU_MEMSTICK |= (1<<7); /* interface enable */
998 CGU_SDSLOT |= (1<<7); /* interface enable */ 958 CGU_SDSLOT |= (1<<7); /* interface enable */
999 } 959 }
1000 else 960 else
1001 { 961 {
1002 CGU_SDSLOT &= ~(1<<7); /* interface enable */ 962 CGU_SDSLOT &= ~(1<<7); /* interface enable */
1003 CGU_MEMSTICK &= ~(1<<7); /* interface enable */
1004 CGU_IDE &= ~(1<<7); /* AHB interface enable */
1005 bitclr32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE); 963 bitclr32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
1006 } 964 }
1007} 965}