1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <arch_helpers.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include "emmc_config.h" 10*91f16700Schasinglulu #include "emmc_def.h" 11*91f16700Schasinglulu #include "emmc_hal.h" 12*91f16700Schasinglulu #include "emmc_registers.h" 13*91f16700Schasinglulu #include "emmc_std.h" 14*91f16700Schasinglulu 15*91f16700Schasinglulu #define MIN_EMMC(a, b) (((a) < (b)) ? (a) : (b)) 16*91f16700Schasinglulu #define EMMC_RW_SECTOR_COUNT_MAX 0x0000ffffU 17*91f16700Schasinglulu 18*91f16700Schasinglulu static EMMC_ERROR_CODE emmc_multiple_block_read(uint32_t *buff_address_virtual, 19*91f16700Schasinglulu uint32_t sector_number, uint32_t count, 20*91f16700Schasinglulu HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode) 21*91f16700Schasinglulu { 22*91f16700Schasinglulu EMMC_ERROR_CODE result; 23*91f16700Schasinglulu 24*91f16700Schasinglulu /* parameter check */ 25*91f16700Schasinglulu if ((count > EMMC_RW_SECTOR_COUNT_MAX) 26*91f16700Schasinglulu || (count == 0) 27*91f16700Schasinglulu || ((transfer_mode != HAL_MEMCARD_DMA) 28*91f16700Schasinglulu && (transfer_mode != HAL_MEMCARD_NOT_DMA)) 29*91f16700Schasinglulu ) { 30*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_PARAM); 31*91f16700Schasinglulu return EMMC_ERR_PARAM; 32*91f16700Schasinglulu } 33*91f16700Schasinglulu 34*91f16700Schasinglulu /* CMD23 */ 35*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD23_SET_BLOCK_COUNT, count); 36*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 37*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 38*91f16700Schasinglulu return result; 39*91f16700Schasinglulu } 40*91f16700Schasinglulu SETR_32(SD_SECCNT, count); 41*91f16700Schasinglulu SETR_32(SD_STOP, 0x00000100); 42*91f16700Schasinglulu /* SD_BUF Read/Write DMA Transfer enable */ 43*91f16700Schasinglulu SETR_32(CC_EXT_MODE, (CC_EXT_MODE_CLEAR | CC_EXT_MODE_DMASDRW_ENABLE)); 44*91f16700Schasinglulu 45*91f16700Schasinglulu /* CMD18 */ 46*91f16700Schasinglulu emmc_make_trans_cmd(CMD18_READ_MULTIPLE_BLOCK, sector_number, 47*91f16700Schasinglulu buff_address_virtual, 48*91f16700Schasinglulu count << EMMC_SECTOR_SIZE_SHIFT, HAL_MEMCARD_READ, 49*91f16700Schasinglulu transfer_mode); 50*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 51*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 52*91f16700Schasinglulu return result; /* CMD18 error code */ 53*91f16700Schasinglulu } 54*91f16700Schasinglulu 55*91f16700Schasinglulu /* CMD13 */ 56*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16); 57*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 58*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 59*91f16700Schasinglulu return result; 60*91f16700Schasinglulu } 61*91f16700Schasinglulu #if RCAR_BL2_DCACHE == 1 62*91f16700Schasinglulu if (transfer_mode == HAL_MEMCARD_NOT_DMA) { 63*91f16700Schasinglulu flush_dcache_range((uint64_t) buff_address_virtual, 64*91f16700Schasinglulu ((size_t) count << EMMC_SECTOR_SIZE_SHIFT)); 65*91f16700Schasinglulu } 66*91f16700Schasinglulu #endif /* RCAR_BL2_DCACHE == 1 */ 67*91f16700Schasinglulu 68*91f16700Schasinglulu /* ready status check */ 69*91f16700Schasinglulu if ((mmc_drv_obj.r1_card_status & EMMC_R1_READY) == 0) { 70*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, 71*91f16700Schasinglulu EMMC_ERR_CARD_BUSY); 72*91f16700Schasinglulu return EMMC_ERR_CARD_BUSY; 73*91f16700Schasinglulu } 74*91f16700Schasinglulu 75*91f16700Schasinglulu /* state check */ 76*91f16700Schasinglulu if (mmc_drv_obj.current_state != EMMC_R1_STATE_TRAN) { 77*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, 78*91f16700Schasinglulu EMMC_ERR_CARD_STATE); 79*91f16700Schasinglulu return EMMC_ERR_CARD_STATE; 80*91f16700Schasinglulu } 81*91f16700Schasinglulu 82*91f16700Schasinglulu return EMMC_SUCCESS; 83*91f16700Schasinglulu } 84*91f16700Schasinglulu 85*91f16700Schasinglulu EMMC_ERROR_CODE emmc_read_sector(uint32_t *buff_address_virtual, 86*91f16700Schasinglulu uint32_t sector_number, 87*91f16700Schasinglulu uint32_t count, uint32_t feature_flags) 88*91f16700Schasinglulu { 89*91f16700Schasinglulu uint32_t trans_count; 90*91f16700Schasinglulu uint32_t remain; 91*91f16700Schasinglulu EMMC_ERROR_CODE result; 92*91f16700Schasinglulu HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode; 93*91f16700Schasinglulu 94*91f16700Schasinglulu /* parameter check */ 95*91f16700Schasinglulu if (count == 0) { 96*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_PARAM); 97*91f16700Schasinglulu return EMMC_ERR_PARAM; 98*91f16700Schasinglulu } 99*91f16700Schasinglulu 100*91f16700Schasinglulu /* state check */ 101*91f16700Schasinglulu if (mmc_drv_obj.mount != TRUE) { 102*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_STATE); 103*91f16700Schasinglulu return EMMC_ERR_STATE; 104*91f16700Schasinglulu } 105*91f16700Schasinglulu 106*91f16700Schasinglulu /* DMA? */ 107*91f16700Schasinglulu if ((feature_flags & LOADIMAGE_FLAGS_DMA_ENABLE) != 0) { 108*91f16700Schasinglulu transfer_mode = HAL_MEMCARD_DMA; 109*91f16700Schasinglulu } else { 110*91f16700Schasinglulu transfer_mode = HAL_MEMCARD_NOT_DMA; 111*91f16700Schasinglulu } 112*91f16700Schasinglulu 113*91f16700Schasinglulu remain = count; 114*91f16700Schasinglulu while (remain != 0) { 115*91f16700Schasinglulu trans_count = MIN_EMMC(remain, EMMC_RW_SECTOR_COUNT_MAX); 116*91f16700Schasinglulu result = 117*91f16700Schasinglulu emmc_multiple_block_read(buff_address_virtual, 118*91f16700Schasinglulu sector_number, trans_count, 119*91f16700Schasinglulu transfer_mode); 120*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 121*91f16700Schasinglulu return result; 122*91f16700Schasinglulu } 123*91f16700Schasinglulu 124*91f16700Schasinglulu buff_address_virtual += (EMMC_BLOCK_LENGTH_DW * trans_count); 125*91f16700Schasinglulu sector_number += trans_count; 126*91f16700Schasinglulu remain -= trans_count; 127*91f16700Schasinglulu } 128*91f16700Schasinglulu 129*91f16700Schasinglulu return EMMC_SUCCESS; 130*91f16700Schasinglulu } 131