@@ -310,6 +310,14 @@ void mmc_irq_handler(void)
310310
311311 /* Check for DMA interrupt */
312312 if (status & EMMC_SD_SRS12_DMAINT ) {
313+ /* Read updated DMA address - engine will increment block */
314+ uint32_t * addr = (uint32_t * )(uintptr_t )((((uint64_t )EMMC_SD_SRS23 ) << 32 ) |
315+ EMMC_SD_SRS22 );
316+ /* Set new DMA address for next boundary */
317+ EMMC_SD_SRS22 = (uint32_t )(uintptr_t )addr ;
318+ EMMC_SD_SRS23 = (uint32_t )(((uint64_t )(uintptr_t )addr ) >> 32 );
319+ /* triggers next DMA block on write of top bit */
320+
313321 g_mmc_irq_status |= MMC_IRQ_FLAG_DMAINT ;
314322 EMMC_SD_SRS12 = EMMC_SD_SRS12_DMAINT ; /* Clear interrupt */
315323 }
@@ -390,7 +398,6 @@ static int mmc_wait_irq(uint32_t expected_flags, uint32_t timeout)
390398 return 0 ;
391399 }
392400 }
393- /* Brief delay while waiting */
394401 asm volatile ("nop" );
395402 }
396403 return -1 ; /* Timeout */
@@ -591,6 +598,7 @@ static uint32_t mmc_get_response_type(uint8_t resp_type)
591598 return cmd_reg ;
592599}
593600
601+ #define DEVICE_BUSY 1
594602static int mmc_send_cmd_internal (uint32_t cmd_type ,
595603 uint32_t cmd_index , uint32_t cmd_arg , uint8_t resp_type )
596604{
@@ -619,24 +627,18 @@ static int mmc_send_cmd_internal(uint32_t cmd_type,
619627 while ((EMMC_SD_SRS12 & (EMMC_SD_SRS12_CC | EMMC_SD_SRS12_TC |
620628 EMMC_SD_SRS12_EINT )) == 0 && -- timeout > 0 );
621629
622- if (timeout == 0 || (EMMC_SD_SRS12 & EMMC_SD_SRS12_EINT )) {
623- wolfBoot_printf ("mmc_send_cmd:%s error SRS12: 0x%08X\n" ,
624- (timeout == 0 ) ? " timeout" : "" , EMMC_SD_SRS12 );
630+ if (timeout == 0 ) {
631+ wolfBoot_printf ("mmc_send_cmd: timeout waiting for command complete\n" );
632+ status = -1 ; /* error */
633+ }
634+ else if (EMMC_SD_SRS12 & EMMC_SD_SRS12_EINT ) {
635+ wolfBoot_printf ("mmc_send_cmd: error SRS12: 0x%08X\n" , EMMC_SD_SRS12 );
625636 status = -1 ; /* error */
626637 }
627638
628639 EMMC_SD_SRS12 = EMMC_SD_SRS12_CC ; /* clear command complete */
629640 while ((EMMC_SD_SRS09 & EMMC_SD_SRS09_CICMD ) != 0 );
630641
631- return status ;
632- }
633-
634- #define DEVICE_BUSY 1
635- int mmc_send_cmd (uint32_t cmd_index , uint32_t cmd_arg , uint8_t resp_type )
636- {
637- /* send command */
638- int status = mmc_send_cmd_internal (EMMC_SD_SRS03_CMD_NORMAL , cmd_index ,
639- cmd_arg , resp_type );
640642 if (status == 0 ) {
641643 /* check for device busy */
642644 if (resp_type == EMMC_SD_RESP_R1 || resp_type == EMMC_SD_RESP_R1B ) {
@@ -648,8 +650,17 @@ int mmc_send_cmd(uint32_t cmd_index, uint32_t cmd_arg, uint8_t resp_type)
648650 }
649651 }
650652
653+ return status ;
654+ }
655+
656+ int mmc_send_cmd (uint32_t cmd_index , uint32_t cmd_arg , uint8_t resp_type )
657+ {
658+ /* send command */
659+ int status = mmc_send_cmd_internal (EMMC_SD_SRS03_CMD_NORMAL , cmd_index ,
660+ cmd_arg , resp_type );
661+
651662 /* clear all status interrupts
652- * (except current limit, card interrupt/removal/insert) */
663+ * (except current limit, card interrupt/removal/insert) */
653664 EMMC_SD_SRS12 = ~(EMMC_SD_SRS12_ECL |
654665 EMMC_SD_SRS12_CINT |
655666 EMMC_SD_SRS12_CR |
@@ -737,7 +748,7 @@ int mmc_read(uint32_t cmd_index, uint32_t block_addr, uint32_t* dst,
737748 /* wait for command and data line busy to clear */
738749 while ((EMMC_SD_SRS09 & (EMMC_SD_SRS09_CICMD | EMMC_SD_SRS09_CIDAT )) != 0 );
739750
740- /* set transfer block count */
751+ /* set transfer block count and block size */
741752 EMMC_SD_SRS01 = (block_count << EMMC_SD_SRS01_BCCT_SHIFT ) | sz ;
742753
743754 cmd_reg = ((cmd_index << EMMC_SD_SRS03_CIDX_SHIFT ) |
@@ -762,27 +773,28 @@ int mmc_read(uint32_t cmd_index, uint32_t block_addr, uint32_t* dst,
762773 EMMC_SD_SRS01 = (block_count << EMMC_SD_SRS01_BCCT_SHIFT ) |
763774 EMMC_SD_SRS01_DMA_BUFF_512KB | EMMC_SD_BLOCK_SIZE ;
764775
765- /* SDMA mode (for 32-bit transfers) */
776+ /* SDMA mode */
766777 EMMC_SD_SRS10 |= EMMC_SD_SRS10_DMA_SDMA ;
767- EMMC_SD_SRS15 |= EMMC_SD_SRS15_HV4E ;
768- EMMC_SD_SRS16 &= ~EMMC_SD_SRS16_A64S ;
769778 /* set SDMA destination address */
770779 EMMC_SD_SRS22 = (uint32_t )(uintptr_t )dst ;
771780 EMMC_SD_SRS23 = (uint32_t )(((uint64_t )(uintptr_t )dst ) >> 32 );
772781
773782 /* Enable SDMA interrupts */
774783 mmc_enable_sdma_interrupts ();
775784 }
785+ else {
786+ EMMC_SD_SRS01 = (block_count << EMMC_SD_SRS01_BCCT_SHIFT ) |
787+ EMMC_SD_BLOCK_SIZE ;
788+ }
776789 }
777790
778791 EMMC_SD_SRS02 = block_addr ; /* cmd argument */
779792 EMMC_SD_SRS03 = cmd_reg ; /* execute command */
780793
781794 if (cmd_reg & EMMC_SD_SRS03_DMAE ) {
782795 while (1 ) { /* DMA mode with interrupt support */
783- /* Wait for DMA interrupt, transfer complete, or error */
784- status = mmc_wait_irq (MMC_IRQ_FLAG_DMAINT | MMC_IRQ_FLAG_TC ,
785- 0x00FFFFFF );
796+ /* Wait for transfer complete or error */
797+ status = mmc_wait_irq (MMC_IRQ_FLAG_TC , 0x00FFFFFF );
786798 if (status != 0 ) {
787799 /* Timeout or error */
788800 wolfBoot_printf ("mmc_read: SDMA interrupt timeout/error\n" );
@@ -795,17 +807,6 @@ int mmc_read(uint32_t cmd_index, uint32_t block_addr, uint32_t* dst,
795807 g_mmc_irq_status &= ~MMC_IRQ_FLAG_TC ;
796808 break ; /* Transfer complete */
797809 }
798-
799- /* Check for DMA boundary interrupt - need to update address */
800- if (g_mmc_irq_status & MMC_IRQ_FLAG_DMAINT ) {
801- g_mmc_irq_status &= ~MMC_IRQ_FLAG_DMAINT ;
802- /* Read updated DMA address - engine will have incremented */
803- dst = (uint32_t * )(uintptr_t )((((uint64_t )EMMC_SD_SRS23 ) << 32 ) |
804- EMMC_SD_SRS22 );
805- /* Set new DMA address for next boundary */
806- EMMC_SD_SRS22 = (uint32_t )(uintptr_t )dst ;
807- EMMC_SD_SRS23 = (uint32_t )(((uint64_t )(uintptr_t )dst ) >> 32 );
808- }
809810 }
810811
811812 /* Disable SDMA interrupts after transfer */
@@ -829,6 +830,10 @@ int mmc_read(uint32_t cmd_index, uint32_t block_addr, uint32_t* dst,
829830 }
830831 sz -= read_sz ;
831832 }
833+
834+ if (reg & EMMC_SD_SRS12_EINT ) {
835+ break ; /* error */
836+ }
832837 }
833838 }
834839
@@ -839,7 +844,7 @@ int mmc_read(uint32_t cmd_index, uint32_t block_addr, uint32_t* dst,
839844 if (cmd_index == MMC_CMD18_READ_MULTIPLE ) {
840845 (void )mmc_send_cmd_internal (EMMC_SD_SRS03_CMD_ABORT ,
841846 MMC_CMD12_STOP_TRANS , (g_rca << SD_RCA_SHIFT ),
842- EMMC_SD_RESP_R1 ); /* use R1B for write */
847+ EMMC_SD_RESP_R1 );
843848 }
844849
845850 /* wait for idle */
@@ -895,20 +900,15 @@ int mmc_write(uint32_t cmd_index, uint32_t block_addr, const uint32_t* src,
895900 /* wait for command and data line busy to clear */
896901 while ((EMMC_SD_SRS09 & (EMMC_SD_SRS09_CICMD | EMMC_SD_SRS09_CIDAT )) != 0 );
897902
898- /* set transfer block count */
903+ /* set transfer block count and block size */
899904 EMMC_SD_SRS01 = (block_count << EMMC_SD_SRS01_BCCT_SHIFT ) | sz ;
900905
901- /* Build command register for write:
902- * - DTDS=0 for write direction (DTDS=1 is read)
903- * - DPS=1 data present
904- * - BCE=1 block count enable
905- * - RECE=1 response error check enable
906- * - RID=1 response interrupt disable
907- */
906+ /* Build command register for write */
908907 cmd_reg = ((cmd_index << EMMC_SD_SRS03_CIDX_SHIFT ) |
909908 EMMC_SD_SRS03_DPS | /* Data present, no DTDS = write direction */
910909 EMMC_SD_SRS03_BCE | EMMC_SD_SRS03_RECE | EMMC_SD_SRS03_RID |
911- EMMC_SD_SRS03_RESP_48 | EMMC_SD_SRS03_CRCCE | EMMC_SD_SRS03_CICE );
910+ EMMC_SD_SRS03_RESP_48 | EMMC_SD_SRS03_CRCCE | EMMC_SD_SRS03_CICE
911+ );
912912
913913 if (cmd_index == MMC_CMD25_WRITE_MULTIPLE ) {
914914 cmd_reg |= EMMC_SD_SRS03_MSBS ; /* enable multi-block select */
@@ -930,20 +930,20 @@ int mmc_write(uint32_t cmd_index, uint32_t block_addr, const uint32_t* src,
930930 /* Enable SDMA interrupts */
931931 mmc_enable_sdma_interrupts ();
932932 }
933+ else {
934+ /* set transfer block count and block size */
935+ EMMC_SD_SRS01 = (block_count << EMMC_SD_SRS01_BCCT_SHIFT ) |
936+ EMMC_SD_BLOCK_SIZE ;
937+ }
933938 }
934939
935- /* wait for cmd/data line not busy */
936- while ((EMMC_SD_SRS09 &
937- (EMMC_SD_SRS09_CICMD | EMMC_SD_SRS09_CIDAT )) != 0 );
938-
939940 EMMC_SD_SRS02 = block_addr ; /* cmd argument */
940941 EMMC_SD_SRS03 = cmd_reg ; /* execute command */
941942
942943 if (cmd_reg & EMMC_SD_SRS03_DMAE ) {
943944 while (1 ) { /* DMA mode with interrupt support */
944- /* Wait for DMA interrupt, transfer complete, or error */
945- status = mmc_wait_irq (MMC_IRQ_FLAG_DMAINT | MMC_IRQ_FLAG_TC ,
946- 0x00FFFFFF );
945+ /* Wait for transfer complete or error */
946+ status = mmc_wait_irq (MMC_IRQ_FLAG_TC , 0x00FFFFFF );
947947 if (status != 0 ) {
948948 /* Timeout or error */
949949 wolfBoot_printf ("mmc_write: SDMA interrupt timeout/error\n" );
@@ -956,17 +956,6 @@ int mmc_write(uint32_t cmd_index, uint32_t block_addr, const uint32_t* src,
956956 g_mmc_irq_status &= ~MMC_IRQ_FLAG_TC ;
957957 break ; /* Transfer complete */
958958 }
959-
960- /* Check for DMA boundary interrupt - need to update address */
961- if (g_mmc_irq_status & MMC_IRQ_FLAG_DMAINT ) {
962- g_mmc_irq_status &= ~MMC_IRQ_FLAG_DMAINT ;
963- /* Read updated DMA address - engine will have incremented */
964- src = (const uint32_t * )(uintptr_t )((((uint64_t )EMMC_SD_SRS23 ) << 32 ) |
965- EMMC_SD_SRS22 );
966- /* Set new DMA address for next boundary */
967- EMMC_SD_SRS22 = (uint32_t )(uintptr_t )src ;
968- EMMC_SD_SRS23 = (uint32_t )(((uint64_t )(uintptr_t )src ) >> 32 );
969- }
970959 }
971960
972961 /* Disable SDMA interrupts after transfer */
@@ -990,30 +979,32 @@ int mmc_write(uint32_t cmd_index, uint32_t block_addr, const uint32_t* src,
990979 }
991980 sz -= write_sz ;
992981 }
993-
994- /* wait for trasnfer complete (or error) */
995- while (((reg = EMMC_SD_SRS12 ) &
996- (EMMC_SD_SRS12_TC | EMMC_SD_SRS12_EINT )) == 0 );
982+ if (reg & EMMC_SD_SRS12_EINT ) {
983+ break ; /* error */
984+ }
997985 }
986+
987+ /* wait for transfer complete (or error) BEFORE checking status */
988+ while (((reg = EMMC_SD_SRS12 ) &
989+ (EMMC_SD_SRS12_TC | EMMC_SD_SRS12_EINT )) == 0 );
998990 }
999991
1000992 /* check for any errors */
1001993 reg = EMMC_SD_SRS12 ;
1002994 if ((reg & EMMC_SD_SRS12_ERR_STAT ) == 0 ) { /* no errors */
1003995 /* if multi-block write, send CMD12 to stop transfer */
1004996 if (cmd_index == MMC_CMD25_WRITE_MULTIPLE ) {
997+ /* CMD12 requires CMD_ABORT type per SD spec */
1005998 status = mmc_send_cmd_internal (EMMC_SD_SRS03_CMD_ABORT ,
1006999 MMC_CMD12_STOP_TRANS , (g_rca << SD_RCA_SHIFT ),
1007- EMMC_SD_RESP_R1B ); /* R1B for write with busy */
1000+ EMMC_SD_RESP_R1B );
10081001 if (status != 0 ) {
10091002 wolfBoot_printf ("mmc_write: CMD12 stop transfer error\n" );
10101003 }
10111004 }
10121005
1013- /* wait for card to finish programming (DAT0 goes high when ready) */
1014- if (status == 0 ) {
1015- status = mmc_wait_busy (1 );
1016- }
1006+ /* wait for idle */
1007+ status = mmc_wait_busy (0 );
10171008 }
10181009 else {
10191010 wolfBoot_printf ("mmc_write: error SRS12: 0x%08X\n" , reg );
@@ -1393,7 +1384,7 @@ int mmc_init(void)
13931384 plic_init_mmc ();
13941385
13951386 /* Set initial timeout to 500ms */
1396- status = mmc_set_timeout (EMMC_SD_DATA_TIMEOUT_US );
1387+ status = mmc_set_timeout (EMMC_SD_INIT_TIMEOUT_US );
13971388 if (status != 0 ) {
13981389 return status ;
13991390 }
@@ -1548,9 +1539,9 @@ int mmc_init(void)
15481539 status = mmc_wait_busy (1 );
15491540 }
15501541 }
1542+ irq_restore = EMMC_SD_SRS13 ;
15511543 if (status == 0 ) {
15521544 /* disable card insert interrupt while changing bus width to avoid false triggers */
1553- irq_restore = EMMC_SD_SRS13 ;
15541545 EMMC_SD_SRS13 = (irq_restore & ~EMMC_SD_SRS13_CINT_SE );
15551546
15561547 status = mmc_set_bus_width (4 );
@@ -1595,8 +1586,11 @@ int mmc_init(void)
15951586 status = 0 ; /* Don't fail init on tuning failure */
15961587 }
15971588#endif
1598-
1599- EMMC_SD_SRS13 = irq_restore ; /* re-enable interrupt */
1589+ }
1590+ EMMC_SD_SRS13 = irq_restore ; /* re-enable interrupt */
1591+ if (status == 0 ) {
1592+ /* Set data timeout to 3000ms */
1593+ status = mmc_set_timeout (EMMC_SD_DATA_TIMEOUT_US );
16001594 }
16011595 return status ;
16021596}
@@ -1675,8 +1669,8 @@ int disk_write(int drv, uint64_t start, uint32_t count, const uint8_t *buf)
16751669 write_sz = EMMC_SD_BLOCK_SIZE ;
16761670 }
16771671 if (write_sz < EMMC_SD_BLOCK_SIZE || /* partial block */
1678- start_offset != 0 || /* start not block aligned */
1679- ((uintptr_t )buf % 4 ) != 0 ) /* buf not 4-byte aligned */
1672+ start_offset != 0 || /* start not block aligned */
1673+ ((uintptr_t )buf % 4 ) != 0 ) /* buf not 4-byte aligned */
16801674 {
16811675 /* read-modify-write for partial block */
16821676 status = mmc_read (MMC_CMD17_READ_SINGLE , block_addr ,
0 commit comments