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