summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Moń <desowin@gmail.com>2021-06-14 21:15:04 +0200
committerTomasz Moń <desowin@gmail.com>2021-06-15 07:31:29 +0000
commitf6c7407cc3304f569ff58d4719e431a9f65e3840 (patch)
tree5b0987c4869fe4c14a4358c1ad7d65efb7fe2fb4
parent95408f2117fdcac26662a2f020664d39c774e2c9 (diff)
downloadrockbox-f6c7407cc3304f569ff58d4719e431a9f65e3840.tar.gz
rockbox-f6c7407cc3304f569ff58d4719e431a9f65e3840.zip
DM320: Use SD/MMC data done interrupt
Wait on semaphore until DMA finishes instead of busy waiting. This allows the CPU to be used by other tasks during transfers. Increase peripheral clock frequency, divide AHB by 2 instead of 3. Function clock frequency is AHB divided by MMC divider + 1. Change-Id: Ic890634da7e3541962ea3501eae8fa2ca2db606a
-rw-r--r--firmware/export/dm320.h17
-rw-r--r--firmware/target/arm/tms320dm320/sdmmc-dm320.c49
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 */
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}