summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_jz47xx
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2020-08-25 08:52:53 -0400
committerSolomon Peachy <pizza@shaftnet.org>2020-08-25 12:07:50 -0400
commit0aa2197d9325159830bac3c6c8fde922e2b86482 (patch)
tree1561df0f50d38350c30cf4bd9a759179759484f3 /firmware/target/mips/ingenic_jz47xx
parent1b31101fdd131545b1ba0560ff67a46c702d278e (diff)
downloadrockbox-0aa2197d9325159830bac3c6c8fde922e2b86482.tar.gz
rockbox-0aa2197d9325159830bac3c6c8fde922e2b86482.zip
jz4760: SD driver enhancements:
* Check to see if clock is [not] running prior to [en|dis]abling it * Stop clock _prior_ to resetting controller * Stop clock after transaction is completed, not before initiating it * Use controller's low power mode (disables clocks when idle) * Fix, and enable, interrupt-driven DMA transfers * Fixes for full interrupt-driven operation (WIP, still broken) Change-Id: I723ffa6450fc85f97898c8a8b3e538ae31c4858e
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c131
1 files changed, 90 insertions, 41 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c
index 0717f80b9d..881c83066e 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c
@@ -29,10 +29,12 @@
29#include "logf.h" 29#include "logf.h"
30#include "storage.h" 30#include "storage.h"
31#include "string.h" 31#include "string.h"
32#include "panic.h"
32 33
33#define SD_INTERRUPT 0 34#define SD_INTERRUPT 0 // COMPLETELY BROKEN!
34#define SD_DMA_ENABLE 1 35#define SD_DMA_ENABLE 1
35#define SD_DMA_INTERRUPT 0 36#define SD_DMA_INTERRUPT 1 // HANGS RANDOMLY!
37#define SD_AUTO_CLOCK 1
36 38
37#if NUM_DRIVES > 2 39#if NUM_DRIVES > 2
38#error "JZ4760 SD driver supports NUM_DRIVES <= 2 only" 40#error "JZ4760 SD driver supports NUM_DRIVES <= 2 only"
@@ -267,6 +269,14 @@ static inline int jz_sd_stop_clock(const int drive)
267 register int timeout = 1000; 269 register int timeout = 1000;
268 270
269 //DEBUG("stop MMC clock"); 271 //DEBUG("stop MMC clock");
272#if SD_AUTO_CLOCK
273 REG_MSC_LPM(drive) = 0; /* disable auto clock stop */
274#endif
275
276 /* only stop if necessary */
277 if (!(REG_MSC_STAT(MSC_CHN(drive)) & MSC_STAT_CLK_EN))
278 return SD_NO_ERROR;
279
270 REG_MSC_STRPCL(MSC_CHN(drive)) = MSC_STRPCL_CLOCK_CONTROL_STOP; 280 REG_MSC_STRPCL(MSC_CHN(drive)) = MSC_STRPCL_CLOCK_CONTROL_STOP;
271 281
272 while (timeout && (REG_MSC_STAT(MSC_CHN(drive)) & MSC_STAT_CLK_EN)) 282 while (timeout && (REG_MSC_STAT(MSC_CHN(drive)) & MSC_STAT_CLK_EN))
@@ -279,6 +289,7 @@ static inline int jz_sd_stop_clock(const int drive)
279 } 289 }
280 udelay(1); 290 udelay(1);
281 } 291 }
292
282 //DEBUG("clock off time is %d microsec", timeout); 293 //DEBUG("clock off time is %d microsec", timeout);
283 return SD_NO_ERROR; 294 return SD_NO_ERROR;
284} 295}
@@ -286,7 +297,11 @@ static inline int jz_sd_stop_clock(const int drive)
286/* Start the MMC clock and operation */ 297/* Start the MMC clock and operation */
287static inline int jz_sd_start_clock(const int drive) 298static inline int jz_sd_start_clock(const int drive)
288{ 299{
289 REG_MSC_STRPCL(MSC_CHN(drive)) = MSC_STRPCL_CLOCK_CONTROL_START | MSC_STRPCL_START_OP; 300 int reg = MSC_STRPCL_START_OP;
301#if !SD_AUTO_CLOCK
302 reg |= (REG_MSC_STAT(MSC_CHN(drive)) & MSC_STAT_CLK_EN) ? 0 : MSC_STRPCL_CLOCK_CONTROL_START;
303#endif
304 REG_MSC_STRPCL(MSC_CHN(drive)) = reg;
290 return SD_NO_ERROR; 305 return SD_NO_ERROR;
291} 306}
292 307
@@ -588,91 +603,88 @@ void DMA_CALLBACK(DMA_SD_RX_CHANNEL0)(void)
588{ 603{
589 if (REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_1)) & DMAC_DCCSR_AR) 604 if (REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_1)) & DMAC_DCCSR_AR)
590 { 605 {
591 logf("SD RX DMA address error");
592 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_1)) &= ~DMAC_DCCSR_AR; 606 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_1)) &= ~DMAC_DCCSR_AR;
607 panicf("SD RX DMA address error");
593 } 608 }
594 609
595 if (REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_1)) & DMAC_DCCSR_HLT) 610 if (REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_1)) & DMAC_DCCSR_HLT)
596 { 611 {
597 logf("SD RX DMA halt");
598 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_1)) &= ~DMAC_DCCSR_HLT; 612 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_1)) &= ~DMAC_DCCSR_HLT;
613 panicf("SD RX DMA halt");
599 } 614 }
600 615
601 if (REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_1)) & DMAC_DCCSR_TT) 616 if (REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_1)) & DMAC_DCCSR_TT)
602 { 617 {
603 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_1)) &= ~DMAC_DCCSR_TT; 618 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_1)) &= ~DMAC_DCCSR_TT;
604 //sd_rx_dma_callback(); 619 //sd_rx_dma_callback();
620 semaphore_release(&sd_wakeup[SD_SLOT_1]);
605 } 621 }
606
607 semaphore_release(&sd_wakeup[SD_SLOT_1]);
608} 622}
609 623
610void DMA_CALLBACK(DMA_SD_RX_CHANNEL1)(void) 624void DMA_CALLBACK(DMA_SD_RX_CHANNEL1)(void)
611{ 625{
612 if (REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_2)) & DMAC_DCCSR_AR) 626 if (REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_2)) & DMAC_DCCSR_AR)
613 { 627 {
614 logf("SD RX DMA address error");
615 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_2)) &= ~DMAC_DCCSR_AR; 628 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_2)) &= ~DMAC_DCCSR_AR;
629 panicf("SD RX DMA address error");
616 } 630 }
617 631
618 if (REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_2)) & DMAC_DCCSR_HLT) 632 if (REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_2)) & DMAC_DCCSR_HLT)
619 { 633 {
620 logf("SD RX DMA halt");
621 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_2)) &= ~DMAC_DCCSR_HLT; 634 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_2)) &= ~DMAC_DCCSR_HLT;
635 panicf("SD RX DMA halt");
622 } 636 }
623 637
624 if (REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_2)) & DMAC_DCCSR_TT) 638 if (REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_2)) & DMAC_DCCSR_TT)
625 { 639 {
626 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_2)) &= ~DMAC_DCCSR_TT; 640 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(SD_SLOT_2)) &= ~DMAC_DCCSR_TT;
627 //sd_rx_dma_callback(); 641 //sd_rx_dma_callback();
642 semaphore_release(&sd_wakeup[SD_SLOT_2]);
628 } 643 }
629
630 semaphore_release(&sd_wakeup[SD_SLOT_2]);
631} 644}
632 645
633void DMA_CALLBACK(DMA_SD_TX_CHANNEL0)(void) 646void DMA_CALLBACK(DMA_SD_TX_CHANNEL0)(void)
634{ 647{
635 if (REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_1)) & DMAC_DCCSR_AR) 648 if (REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_1)) & DMAC_DCCSR_AR)
636 { 649 {
637 logf("SD TX DMA address error: %x, %x, %x", var1, var2, var3);
638 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_1)) &= ~DMAC_DCCSR_AR; 650 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_1)) &= ~DMAC_DCCSR_AR;
651 panicf("SD TX DMA address error");
639 } 652 }
640 653
641 if (REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_1)) & DMAC_DCCSR_HLT) 654 if (REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_1)) & DMAC_DCCSR_HLT)
642 { 655 {
643 logf("SD TX DMA halt");
644 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_1)) &= ~DMAC_DCCSR_HLT; 656 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_1)) &= ~DMAC_DCCSR_HLT;
657 panicf("SD TX DMA halt");
645 } 658 }
646 659
647 if (REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_1)) & DMAC_DCCSR_TT) 660 if (REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_1)) & DMAC_DCCSR_TT)
648 { 661 {
649 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_1)) &= ~DMAC_DCCSR_TT; 662 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_1)) &= ~DMAC_DCCSR_TT;
650 //sd_tx_dma_callback(); 663 //sd_tx_dma_callback();
664 semaphore_release(&sd_wakeup[SD_SLOT_1]);
651 } 665 }
652
653 semaphore_release(&sd_wakeup[SD_SLOT_1]);
654} 666}
667
655void DMA_CALLBACK(DMA_SD_TX_CHANNEL1)(void) 668void DMA_CALLBACK(DMA_SD_TX_CHANNEL1)(void)
656{ 669{
657 if (REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_2)) & DMAC_DCCSR_AR) 670 if (REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_2)) & DMAC_DCCSR_AR)
658 { 671 {
659 logf("SD TX DMA address error: %x, %x, %x", var1, var2, var3);
660 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_2)) &= ~DMAC_DCCSR_AR; 672 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_2)) &= ~DMAC_DCCSR_AR;
673 panicf("SD TX DMA address error");
661 } 674 }
662 675
663 if (REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_2)) & DMAC_DCCSR_HLT) 676 if (REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_2)) & DMAC_DCCSR_HLT)
664 { 677 {
665 logf("SD TX DMA halt");
666 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_2)) &= ~DMAC_DCCSR_HLT; 678 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_2)) &= ~DMAC_DCCSR_HLT;
679 panicf("SD TX DMA halt");
667 } 680 }
668 681
669 if (REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_2)) & DMAC_DCCSR_TT) 682 if (REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_2)) & DMAC_DCCSR_TT)
670 { 683 {
671 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_2)) &= ~DMAC_DCCSR_TT; 684 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(SD_SLOT_2)) &= ~DMAC_DCCSR_TT;
672 //sd_tx_dma_callback(); 685 //sd_tx_dma_callback();
686 semaphore_release(&sd_wakeup[SD_SLOT_2]);
673 } 687 }
674
675 semaphore_release(&sd_wakeup[SD_SLOT_2]);
676} 688}
677#endif /* SD_DMA_INTERRUPT */ 689#endif /* SD_DMA_INTERRUPT */
678#endif /* SD_DMA_ENABLE */ 690#endif /* SD_DMA_ENABLE */
@@ -715,8 +727,6 @@ static void jz_sd_set_clock(const int drive, unsigned int rate)
715{ 727{
716 int clkrt; 728 int clkrt;
717 729
718 jz_sd_stop_clock(drive);
719
720 /* select clock source from CPM */ 730 /* select clock source from CPM */
721 cpm_select_msc_clk(); 731 cpm_select_msc_clk();
722 732
@@ -747,28 +757,27 @@ static int jz_sd_exec_cmd(const int drive, struct sd_request *request)
747 /* On reset, 1-bit bus width */ 757 /* On reset, 1-bit bus width */
748 use_4bit[drive] = 0; 758 use_4bit[drive] = 0;
749 759
760 /* On reset, stop SD clock */
761 jz_sd_stop_clock(drive);
762
750 /* Reset MMC/SD controller */ 763 /* Reset MMC/SD controller */
751 __msc_reset(MSC_CHN(drive)); 764 __msc_reset(MSC_CHN(drive));
752 765
753 /* On reset, drop SD clock down */ 766 /* Drop SD clock down to lowest speed */
754 jz_sd_set_clock(drive, MMC_CLOCK_SLOW); 767 jz_sd_set_clock(drive, MMC_CLOCK_SLOW);
755 768
756 /* On reset, stop SD clock */ 769#if SD_AUTO_CLOCK
757 jz_sd_stop_clock(drive); 770 /* Re-enable clocks */
771 REG_MSC_STRPCL(MSC_CHN(drive)) = MSC_STRPCL_CLOCK_CONTROL_START;
772 REG_MSC_LPM(drive) = MSC_SET_LPM;
773#endif
758 } 774 }
759 775
760 /* stop clock */
761 jz_sd_stop_clock(drive);
762
763 /* mask all interrupts and clear status */ 776 /* mask all interrupts and clear status */
764 SD_IRQ_MASK(MSC_CHN(drive)); 777 SD_IRQ_MASK(MSC_CHN(drive));
765 778
766 /* open interrupt */ 779 /* open interrupt */
767#if SD_INTERRUPT
768 REG_MSC_IMASK(MSC_CHN(drive)) = ~(MSC_IMASK_DATA_TRAN_DONE | MSC_IMASK_PRG_DONE);
769#else
770 REG_MSC_IMASK(MSC_CHN(drive)) = ~(MSC_IMASK_END_CMD_RES | MSC_IMASK_DATA_TRAN_DONE | MSC_IMASK_PRG_DONE); 780 REG_MSC_IMASK(MSC_CHN(drive)) = ~(MSC_IMASK_END_CMD_RES | MSC_IMASK_DATA_TRAN_DONE | MSC_IMASK_PRG_DONE);
771#endif
772 781
773 /* Set command type and events */ 782 /* Set command type and events */
774 switch (request->cmd) 783 switch (request->cmd)
@@ -926,8 +935,8 @@ static int jz_sd_exec_cmd(const int drive, struct sd_request *request)
926 return SD_ERROR_TIMEOUT; 935 return SD_ERROR_TIMEOUT;
927 yield(); 936 yield();
928 } 937 }
929#endif
930 REG_MSC_IREG(MSC_CHN(drive)) = MSC_IREG_END_CMD_RES; /* clear flag */ 938 REG_MSC_IREG(MSC_CHN(drive)) = MSC_IREG_END_CMD_RES; /* clear flag */
939#endif
931 940
932 /* Check for status */ 941 /* Check for status */
933 retval = jz_sd_check_status(drive, request); 942 retval = jz_sd_check_status(drive, request);
@@ -964,8 +973,8 @@ static int jz_sd_exec_cmd(const int drive, struct sd_request *request)
964 /* Wait for Data Done */ 973 /* Wait for Data Done */
965 while (!(REG_MSC_IREG(MSC_CHN(drive)) & MSC_IREG_DATA_TRAN_DONE)) 974 while (!(REG_MSC_IREG(MSC_CHN(drive)) & MSC_IREG_DATA_TRAN_DONE))
966 yield(); 975 yield();
967#endif
968 REG_MSC_IREG(MSC_CHN(drive)) = MSC_IREG_DATA_TRAN_DONE; /* clear status */ 976 REG_MSC_IREG(MSC_CHN(drive)) = MSC_IREG_DATA_TRAN_DONE; /* clear status */
977#endif
969 } 978 }
970 979
971 /* Wait for Prog Done event */ 980 /* Wait for Prog Done event */
@@ -976,11 +985,14 @@ static int jz_sd_exec_cmd(const int drive, struct sd_request *request)
976#else 985#else
977 while (!(REG_MSC_IREG(MSC_CHN(drive)) & MSC_IREG_PRG_DONE)) 986 while (!(REG_MSC_IREG(MSC_CHN(drive)) & MSC_IREG_PRG_DONE))
978 yield(); 987 yield();
979#endif
980 REG_MSC_IREG(MSC_CHN(drive)) = MSC_IREG_PRG_DONE; /* clear status */ 988 REG_MSC_IREG(MSC_CHN(drive)) = MSC_IREG_PRG_DONE; /* clear status */
989#endif
981 } 990 }
982 991
983 /* Command completed */ 992 /* Command completed */
993#if !SD_AUTO_CLOCK
994 jz_sd_stop_clock(drive); /* stop SD clock */
995#endif
984 996
985 return SD_NO_ERROR; /* return successfully */ 997 return SD_NO_ERROR; /* return successfully */
986} 998}
@@ -996,17 +1008,44 @@ static int jz_sd_chkcard(const int drive)
996 return (__gpio_get_pin((drive == SD_SLOT_1) ? PIN_SD1_CD : PIN_SD2_CD) == 0 ? 1 : 0); 1008 return (__gpio_get_pin((drive == SD_SLOT_1) ? PIN_SD1_CD : PIN_SD2_CD) == 0 ? 1 : 0);
997} 1009}
998 1010
999/* MSC interrupt handler */ 1011/* MSC interrupt handlers */
1000void MSC(void)
1001{
1002#if SD_INTERRUPT 1012#if SD_INTERRUPT
1003 if (REG_MSC_IREG(MSC_CHN(SD_SLOT_1)) & MSC_IREG_DATA_TRAN_DONE) 1013void MSC2(void) /* SD_SLOT_1 */
1014{
1015 logf("MSC2 interrupt");
1016
1017 if (REG_MSC_IREG(MSC_CHN(SD_SLOT_1)) & MSC_IREG_END_CMD_RES) {
1018 REG_MSC_IREG(MSC_CHN(SD_SLOT_1)) = MSC_IREG_END_CMD_RES; /* clear flag */
1004 semaphore_release(&sd_wakeup[SD_SLOT_1]); 1019 semaphore_release(&sd_wakeup[SD_SLOT_1]);
1005 else if (REG_MSC_IREG(MSC_CHN(SD_SLOT_2)) & MSC_IREG_DATA_TRAN_DONE) 1020 }
1021 if (REG_MSC_IREG(MSC_CHN(SD_SLOT_1)) & MSC_IREG_PRG_DONE) {
1022 REG_MSC_IREG(MSC_CHN(SD_SLOT_1)) = MSC_IREG_PRG_DONE; /* clear flag */
1023 semaphore_release(&sd_wakeup[SD_SLOT_1]);
1024 }
1025 if (REG_MSC_IREG(MSC_CHN(SD_SLOT_1)) & MSC_IREG_DATA_TRAN_DONE) {
1026 REG_MSC_IREG(MSC_CHN(SD_SLOT_1)) = MSC_IREG_DATA_TRAN_DONE; /* clear flag */
1027 semaphore_release(&sd_wakeup[SD_SLOT_1]);
1028 }
1029}
1030
1031/* MSC interrupt handlers */
1032void MSC1(void) /* SD_SLOT_2 */
1033{
1034 logf("MSC1 interrupt");
1035 if (REG_MSC_IREG(MSC_CHN(SD_SLOT_2)) & MSC_IREG_END_CMD_RES) {
1036 REG_MSC_IREG(MSC_CHN(SD_SLOT_2)) = MSC_IREG_END_CMD_RES; /* clear flag */
1006 semaphore_release(&sd_wakeup[SD_SLOT_2]); 1037 semaphore_release(&sd_wakeup[SD_SLOT_2]);
1007#endif 1038 }
1008 logf("MSC interrupt"); 1039 if (REG_MSC_IREG(MSC_CHN(SD_SLOT_2)) & MSC_IREG_PRG_DONE) {
1040 REG_MSC_IREG(MSC_CHN(SD_SLOT_2)) = MSC_IREG_PRG_DONE; /* clear flag */
1041 semaphore_release(&sd_wakeup[SD_SLOT_2]);
1042 }
1043 if (REG_MSC_IREG(MSC_CHN(SD_SLOT_2)) & MSC_IREG_DATA_TRAN_DONE) {
1044 REG_MSC_IREG(MSC_CHN(SD_SLOT_2)) = MSC_IREG_DATA_TRAN_DONE; /* clear flag */
1045 semaphore_release(&sd_wakeup[SD_SLOT_2]);
1046 }
1009} 1047}
1048#endif
1010 1049
1011#ifdef HAVE_HOTSWAP 1050#ifdef HAVE_HOTSWAP
1012static void sd_gpio_setup_irq(const int drive, bool inserted) 1051static void sd_gpio_setup_irq(const int drive, bool inserted)
@@ -1038,7 +1077,12 @@ static void jz_sd_hardware_init(const int drive)
1038#endif 1077#endif
1039 __msc_reset(MSC_CHN(drive)); /* reset mmc/sd controller */ 1078 __msc_reset(MSC_CHN(drive)); /* reset mmc/sd controller */
1040 SD_IRQ_MASK(MSC_CHN(drive)); /* mask all IRQs */ 1079 SD_IRQ_MASK(MSC_CHN(drive)); /* mask all IRQs */
1080#if SD_AUTO_CLOCK
1081 REG_MSC_STRPCL(MSC_CHN(drive)) = MSC_STRPCL_CLOCK_CONTROL_START; /* Enable clocks */
1082 REG_MSC_LPM(drive) = MSC_SET_LPM; /* enable auto clock stop */
1083#else
1041 jz_sd_stop_clock(drive); /* stop SD clock */ 1084 jz_sd_stop_clock(drive); /* stop SD clock */
1085#endif
1042} 1086}
1043 1087
1044static void sd_send_cmd(const int drive, struct sd_request *request, int cmd, unsigned int arg, 1088static void sd_send_cmd(const int drive, struct sd_request *request, int cmd, unsigned int arg,
@@ -1315,6 +1359,11 @@ int sd_init(void)
1315 mutex_init(&sd_mtx[SD_SLOT_1]); 1359 mutex_init(&sd_mtx[SD_SLOT_1]);
1316 mutex_init(&sd_mtx[SD_SLOT_2]); 1360 mutex_init(&sd_mtx[SD_SLOT_2]);
1317 1361
1362#if SD_INTERRUPT
1363 system_enable_irq(IRQ_MSC2);
1364 system_enable_irq(IRQ_MSC1);
1365#endif
1366
1318#if SD_DMA_ENABLE && SD_DMA_INTERRUPT 1367#if SD_DMA_ENABLE && SD_DMA_INTERRUPT
1319 system_enable_irq(DMA_IRQ(DMA_SD_RX_CHANNEL(SD_SLOT_1))); 1368 system_enable_irq(DMA_IRQ(DMA_SD_RX_CHANNEL(SD_SLOT_1)));
1320 system_enable_irq(DMA_IRQ(DMA_SD_RX_CHANNEL(SD_SLOT_2))); 1369 system_enable_irq(DMA_IRQ(DMA_SD_RX_CHANNEL(SD_SLOT_2)));