xref: /arm-trusted-firmware/drivers/renesas/common/emmc/emmc_read.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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