@@ -456,7 +456,8 @@ int mmc_read(uint32_t cmd_index, uint32_t block_addr, uint32_t* dst,
456456 uint32_t sz )
457457{
458458 int status ;
459- uint32_t reg ;
459+ uint32_t block_count ;
460+ uint32_t reg , cmd_reg ;
460461
461462 /* wait for idle */
462463 status = mmc_wait_busy (0 );
@@ -468,46 +469,66 @@ int mmc_read(uint32_t cmd_index, uint32_t block_addr, uint32_t* dst,
468469 /* wait for command and data line busy to clear */
469470 while ((EMMC_SD_SRS09 & (EMMC_SD_SRS09_CICMD | EMMC_SD_SRS09_CIDAT )) != 0 );
470471
472+ /* get block count (round up) */
473+ block_count = (sz + (EMMC_SD_BLOCK_SIZE - 1 )) / EMMC_SD_BLOCK_SIZE ;
471474 /* set transfer block count */
472- EMMC_SD_SRS01 = (1 << EMMC_SD_SRS01_BCCT_SHIFT ) | sz ;
475+ EMMC_SD_SRS01 = (block_count << EMMC_SD_SRS01_BCCT_SHIFT ) | sz ;
476+
477+ cmd_reg = ((cmd_index << EMMC_SD_SRS03_CIDX_SHIFT ) |
478+ EMMC_SD_SRS03_DPS | EMMC_SD_SRS03_DTDS |
479+ EMMC_SD_SRS03_BCE | EMMC_SD_SRS03_RECE | EMMC_SD_SRS03_RID |
480+ EMMC_SD_SRS03_RESP_48 | EMMC_SD_SRS03_CRCCE | EMMC_SD_SRS03_CICE );
473481
474482 if (cmd_index == SD_ACMD51_SEND_SCR ) {
475- status = mmc_send_cmd (SD_CMD_16 , sz , EMMC_SD_RESP_R1 );
483+ status = mmc_send_cmd (SD_CMD16 , sz , EMMC_SD_RESP_R1 );
476484 if (status == 0 ) {
477485 status = mmc_send_cmd (SD_CMD55_APP_CMD , (g_rca << SD_RCA_SHIFT ),
478486 EMMC_SD_RESP_R1 );
479487 }
480488 status = 0 ; /* ignore error */
481489 }
490+ else if (cmd_index == MMC_CMD18_READ_MULTIPLE ) {
491+ cmd_reg |= EMMC_SD_SRS03_MSBS ; /* enable multi-block select */
492+ EMMC_SD_SRS01 = (block_count << EMMC_SD_SRS01_BCCT_SHIFT ) |
493+ EMMC_SD_BLOCK_SIZE ;
494+ }
482495
483496#ifdef DEBUG_MMC
484- wolfBoot_printf ("mmc_read: cmd_index: %d, block_addr: %08X, dst %p, sz: %d\n" ,
485- cmd_index , block_addr , dst , sz );
497+ wolfBoot_printf ("mmc_read: cmd_index: %d, block_addr: %08X, dst %p, sz: %d (%d blocks) \n" ,
498+ cmd_index , block_addr , dst , sz , block_count );
486499#endif
487500
488501 EMMC_SD_SRS02 = block_addr ; /* cmd argument */
489- /* execute command */
490- EMMC_SD_SRS03 = ((cmd_index << EMMC_SD_SRS03_CIDX_SHIFT ) |
491- EMMC_SD_SRS03_DPS | EMMC_SD_SRS03_DTDS |
492- EMMC_SD_SRS03_BCE | EMMC_SD_SRS03_RECE | EMMC_SD_SRS03_RID |
493- EMMC_SD_SRS03_RESP_48 | EMMC_SD_SRS03_CRCCE | EMMC_SD_SRS03_CICE );
494-
495- /* wait for buffer read ready */
496- while (((reg = EMMC_SD_SRS12 ) & (EMMC_SD_SRS12_BRR | EMMC_SD_SRS12_EINT )) == 0 );
497-
498- /* read in buffer - read 4 bytes at a time */
499- if (reg & EMMC_SD_SRS12_BRR ) {
500- uint32_t i ;
501- for (i = 0 ; i < sz ; i += 4 ) {
502- * dst = EMMC_SD_SRS08 ;
503- dst ++ ;
502+ EMMC_SD_SRS03 = cmd_reg ; /* execute command */
503+ while (sz > 0 ) {
504+ /* wait for buffer read ready */
505+ while (((reg = EMMC_SD_SRS12 ) &
506+ (EMMC_SD_SRS12_BRR | EMMC_SD_SRS12_EINT )) == 0 );
507+
508+ /* read in buffer - read 4 bytes at a time */
509+ if (reg & EMMC_SD_SRS12_BRR ) {
510+ uint32_t i , read_sz = sz ;
511+ if (read_sz > EMMC_SD_BLOCK_SIZE ) {
512+ read_sz = EMMC_SD_BLOCK_SIZE ;
513+ }
514+ for (i = 0 ; i < read_sz ; i += 4 ) {
515+ * dst = EMMC_SD_SRS08 ;
516+ dst ++ ;
517+ }
518+ sz -= read_sz ;
504519 }
505520 }
506521
522+ if (cmd_index == MMC_CMD18_READ_MULTIPLE ) {
523+ /* send CMD12 to stop transfer - ignore response */
524+ (void )mmc_send_cmd (MMC_CMD12_STOP_TRANS , (g_rca << SD_RCA_SHIFT ),
525+ EMMC_SD_RESP_R1 );
526+ }
527+
507528 /* check for any errors and wait for idle */
508529 reg = EMMC_SD_SRS12 ;
509530 if ((reg & EMMC_SD_SRS12_ERR_STAT ) == 0 ) {
510- mmc_delay (0xFF );
531+ mmc_delay (0xFFF );
511532 status = mmc_wait_busy (0 );
512533 }
513534 else {
@@ -585,7 +606,7 @@ int mmc_send_switch_function(uint32_t mode, uint32_t function_number,
585606 cmd_arg = (function_number << ((group_number - 1 ) * 4 ));
586607 do {
587608 /* first run check to see if function is supported */
588- status = mmc_read (SD_CMD_6_SWITCH_FUNC ,
609+ status = mmc_read (SD_CMD6_SWITCH_FUNC ,
589610 (mode | cmd_arg ),
590611 func_status , sizeof (func_status ));
591612 if (status == 0 ) {
@@ -904,7 +925,7 @@ int disk_read(int drv, uint64_t start, uint32_t count, uint8_t *buf)
904925 }
905926 if (read_sz < EMMC_SD_BLOCK_SIZE || /* last partial */
906927 start_offset != 0 || /* start not block aligned */
907- ((uintptr_t )buf % 4 ) != 0 ) /* buf not 4-byte aligned */
928+ ((uintptr_t )buf % 4 ) != 0 ) /* buf not 4-byte aligned */
908929 {
909930 /* block read to temporary buffer */
910931 status = mmc_read (MMC_CMD17_READ_SINGLE , block_addr ,
@@ -916,9 +937,13 @@ int disk_read(int drv, uint64_t start, uint32_t count, uint8_t *buf)
916937 }
917938 }
918939 else {
919- /* direct full block read */
920- status = mmc_read (MMC_CMD17_READ_SINGLE , block_addr ,
921- (uint32_t * )buf , read_sz );
940+ /* direct full block(s) read */
941+ uint32_t blocks = (count / EMMC_SD_BLOCK_SIZE );
942+ read_sz = (blocks * EMMC_SD_BLOCK_SIZE );
943+ status = mmc_read (blocks > 1 ?
944+ MMC_CMD18_READ_MULTIPLE :
945+ MMC_CMD17_READ_SINGLE ,
946+ block_addr , (uint32_t * )buf , read_sz );
922947 }
923948 if (status != 0 ) {
924949 break ;
0 commit comments