summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/tms320dm320/sdmmc-dm320.c49
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 */
122static struct mutex sd_mtx SHAREDBSS_ATTR; 122static struct mutex sd_mtx SHAREDBSS_ATTR;
123static struct semaphore data_done SHAREDBSS_ATTR;
123static volatile unsigned int transfer_error[NUM_DRIVES]; 124static volatile unsigned int transfer_error[NUM_DRIVES];
124/* align on cache line size */ 125/* align on cache line size */
125static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] 126static 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
235static int dma_wait_for_completion(void) 236static 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
893void SD_MMC(void) __attribute__ ((section(".icode")));
894void 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}