diff options
-rw-r--r-- | firmware/export/dm320.h | 17 | ||||
-rw-r--r-- | firmware/target/arm/tms320dm320/sdmmc-dm320.c | 49 |
2 files changed, 49 insertions, 17 deletions
diff --git a/firmware/export/dm320.h b/firmware/export/dm320.h index def8508b0b..01f206bfc9 100644 --- a/firmware/export/dm320.h +++ b/firmware/export/dm320.h | |||
@@ -930,11 +930,27 @@ extern unsigned long _ttbstart; | |||
930 | #define MMC_ST1_DXFULL (1 << 3) | 930 | #define MMC_ST1_DXFULL (1 << 3) |
931 | #define MMC_ST1_DAT3ST (1 << 4) | 931 | #define MMC_ST1_DAT3ST (1 << 4) |
932 | 932 | ||
933 | #define MMC_IE_EDATDNE (1 << 0) | ||
934 | #define MMC_IE_EBSYDNE (1 << 1) | ||
935 | #define MMC_IE_ERSPDNE (1 << 2) | ||
936 | #define MMC_IE_ETOUTRD (1 << 3) | ||
937 | #define MMC_IE_ETOUTRS (1 << 4) | ||
938 | #define MMC_IE_ECRCWR (1 << 5) | ||
939 | #define MMC_IE_ECRCRD (1 << 6) | ||
940 | #define MMC_IE_ECRCRS (1 << 7) | ||
941 | #define MMC_IE_EDXRDY (1 << 9) | ||
942 | #define MMC_IE_EDRRDY (1 << 10) | ||
943 | #define MMC_IE_EDATED (1 << 11) | ||
944 | |||
933 | #define MMC_DMAMODE_RD_WORDSWAP (1 << 10) | 945 | #define MMC_DMAMODE_RD_WORDSWAP (1 << 10) |
934 | #define MMC_DMAMODE_WR_WORDSWAP (1 << 11) | 946 | #define MMC_DMAMODE_WR_WORDSWAP (1 << 11) |
935 | #define MMC_DMAMODE_WRITE (1 << 12) | 947 | #define MMC_DMAMODE_WRITE (1 << 12) |
936 | #define MMC_DMAMODE_ENABLE (1 << 13) | 948 | #define MMC_DMAMODE_ENABLE (1 << 13) |
937 | #define MMC_DMAMODE_TIMEOUTIRQ_EN (1 << 14) | 949 | #define MMC_DMAMODE_TIMEOUTIRQ_EN (1 << 14) |
950 | |||
951 | #define MMC_DMASTAT1_RUNST (1 << 12) | ||
952 | #define MMC_DMASTAT1_TOUTDT (1 << 13) | ||
953 | |||
938 | /* | 954 | /* |
939 | * IO_EINTx bits | 955 | * IO_EINTx bits |
940 | */ | 956 | */ |
@@ -1001,6 +1017,7 @@ extern unsigned long _ttbstart; | |||
1001 | #define INTR_IRQ1_EXT0 INTR_EINT1_EXT0 | 1017 | #define INTR_IRQ1_EXT0 INTR_EINT1_EXT0 |
1002 | #define INTR_IRQ1_EXT2 INTR_EINT1_EXT2 | 1018 | #define INTR_IRQ1_EXT2 INTR_EINT1_EXT2 |
1003 | #define INTR_IRQ1_EXT7 INTR_EINT1_EXT7 | 1019 | #define INTR_IRQ1_EXT7 INTR_EINT1_EXT7 |
1020 | #define INTR_IRQ1_MMCSDMS0 INTR_EINT1_MMCSDMS0 | ||
1004 | #define INTR_IRQ1_MTC0 INTR_EINT1_MTC0 | 1021 | #define INTR_IRQ1_MTC0 INTR_EINT1_MTC0 |
1005 | 1022 | ||
1006 | /* | 1023 | /* |
diff --git a/firmware/target/arm/tms320dm320/sdmmc-dm320.c b/firmware/target/arm/tms320dm320/sdmmc-dm320.c index cc5c4a822e..33354a3146 100644 --- a/firmware/target/arm/tms320dm320/sdmmc-dm320.c +++ b/firmware/target/arm/tms320dm320/sdmmc-dm320.c | |||
@@ -120,6 +120,7 @@ static struct sd_card_status sd_status[NUM_CARDS] = | |||
120 | 120 | ||
121 | /* Shoot for around 75% usage */ | 121 | /* Shoot for around 75% usage */ |
122 | static struct mutex sd_mtx SHAREDBSS_ATTR; | 122 | static struct mutex sd_mtx SHAREDBSS_ATTR; |
123 | static struct semaphore data_done SHAREDBSS_ATTR; | ||
123 | static volatile unsigned int transfer_error[NUM_DRIVES]; | 124 | static volatile unsigned int transfer_error[NUM_DRIVES]; |
124 | /* align on cache line size */ | 125 | /* align on cache line size */ |
125 | static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] | 126 | static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] |
@@ -234,25 +235,20 @@ static int sd_poll_status(int st_reg_num, volatile unsigned int flag) | |||
234 | 235 | ||
235 | static int dma_wait_for_completion(void) | 236 | static int dma_wait_for_completion(void) |
236 | { | 237 | { |
237 | unsigned short dma_status; | 238 | uint16_t dma_status; |
238 | 239 | ||
239 | do | 240 | semaphore_wait(&data_done, TIMEOUT_BLOCK); |
240 | { | ||
241 | long time = current_tick; | ||
242 | 241 | ||
243 | if (TIME_AFTER(time, next_yield)) | 242 | dma_status = IO_MMC_SD_DMA_STATUS1; |
244 | { | 243 | if (dma_status & MMC_DMASTAT1_TOUTDT) |
245 | long ty = current_tick; | 244 | { |
246 | yield(); | 245 | return -EC_DATA_TIMEOUT; |
247 | next_yield = ty + MIN_YIELD_PERIOD; | 246 | } |
248 | } | ||
249 | 247 | ||
250 | dma_status = IO_MMC_SD_DMA_STATUS1; | 248 | if (dma_status & MMC_DMASTAT1_RUNST) |
251 | if (dma_status & (1 << 13)) | 249 | { |
252 | { | 250 | panicf("Semaphore released while DMA still running"); |
253 | return -EC_DATA_TIMEOUT; | 251 | } |
254 | } | ||
255 | } while (dma_status & (1 << 12)); | ||
256 | 252 | ||
257 | return EC_OK; | 253 | return EC_OK; |
258 | } | 254 | } |
@@ -794,6 +790,7 @@ int sd_init(void) | |||
794 | if (!initialized) | 790 | if (!initialized) |
795 | { | 791 | { |
796 | mutex_init(&sd_mtx); | 792 | mutex_init(&sd_mtx); |
793 | semaphore_init(&data_done, 1, 0); | ||
797 | initialized = true; | 794 | initialized = true; |
798 | } | 795 | } |
799 | 796 | ||
@@ -810,7 +807,7 @@ int sd_init(void) | |||
810 | 807 | ||
811 | /* mmc module clock: 75 Mhz (AHB) / 2 = ~37.5 Mhz | 808 | /* mmc module clock: 75 Mhz (AHB) / 2 = ~37.5 Mhz |
812 | * (Frequencies above are taken from Sansa Connect's OF source code) */ | 809 | * (Frequencies above are taken from Sansa Connect's OF source code) */ |
813 | IO_CLK_DIV3 = (IO_CLK_DIV3 & 0xFF00) | 0x02; /* OF uses 1 */ | 810 | IO_CLK_DIV3 = (IO_CLK_DIV3 & 0xFF00) | 0x01; |
814 | 811 | ||
815 | bitset16(&IO_CLK_MOD2, CLK_MOD2_MMC); | 812 | bitset16(&IO_CLK_MOD2, CLK_MOD2_MMC); |
816 | 813 | ||
@@ -847,6 +844,10 @@ int sd_init(void) | |||
847 | #endif | 844 | #endif |
848 | #endif | 845 | #endif |
849 | 846 | ||
847 | /* Enable data done interrupt */ | ||
848 | IO_MMC_INT_ENABLE |= MMC_IE_EDATDNE; | ||
849 | IO_INTC_EINT1 |= INTR_EINT1_MMCSDMS0; | ||
850 | |||
850 | /* Disable Memory Card CLK - it is enabled on demand by TMS320DM320 */ | 851 | /* Disable Memory Card CLK - it is enabled on demand by TMS320DM320 */ |
851 | bitclr16(&IO_MMC_MEM_CLK_CONTROL, (1 << 8)); | 852 | bitclr16(&IO_MMC_MEM_CLK_CONTROL, (1 << 8)); |
852 | mutex_unlock(&sd_mtx); | 853 | mutex_unlock(&sd_mtx); |
@@ -888,3 +889,17 @@ int sd_event(long id, intptr_t data) | |||
888 | 889 | ||
889 | return rc; | 890 | return rc; |
890 | } | 891 | } |
892 | |||
893 | void SD_MMC(void) __attribute__ ((section(".icode"))); | ||
894 | void SD_MMC(void) | ||
895 | { | ||
896 | uint16_t status = IO_MMC_STATUS0; | ||
897 | |||
898 | /* Clear interrupt */ | ||
899 | IO_INTC_IRQ1 = INTR_IRQ1_MMCSDMS0; | ||
900 | |||
901 | if (status & MMC_ST0_DATDNE) | ||
902 | { | ||
903 | semaphore_release(&data_done); | ||
904 | } | ||
905 | } | ||