diff options
author | Tomasz Moń <desowin@gmail.com> | 2021-06-14 21:15:04 +0200 |
---|---|---|
committer | Tomasz Moń <desowin@gmail.com> | 2021-06-15 07:31:29 +0000 |
commit | f6c7407cc3304f569ff58d4719e431a9f65e3840 (patch) | |
tree | 5b0987c4869fe4c14a4358c1ad7d65efb7fe2fb4 /firmware/target/arm/tms320dm320/sdmmc-dm320.c | |
parent | 95408f2117fdcac26662a2f020664d39c774e2c9 (diff) | |
download | rockbox-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
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 | } | ||