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