diff options
Diffstat (limited to 'firmware/target/arm/tms320dm320/sdmmc-dm320.c')
-rw-r--r-- | firmware/target/arm/tms320dm320/sdmmc-dm320.c | 49 |
1 files changed, 32 insertions, 17 deletions
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 | } | ||