diff options
Diffstat (limited to 'firmware/target/arm/as3525/sd-as3525v2.c')
-rw-r--r-- | firmware/target/arm/as3525/sd-as3525v2.c | 108 |
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 | |||
804 | sd_transfer_retry_with_reinit: | ||
805 | if (card_info[drive].initialized <= 0) | ||
806 | { | 788 | { |
789 | retry_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) | 926 | exit: |
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 | |||
960 | sd_transfer_error: | ||
961 | dma_release(); | ||
962 | |||
963 | sd_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 | ||
973 | int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, | 935 | int 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 | } |