xref: /rk3399_ARM-atf/drivers/brcm/emmc/emmc_csl_sdcard.c (revision bffde63de7a2c1a8534c1d969857d17fa17e30df)
1*bffde63dSSheetal Tigadoli /*
2*bffde63dSSheetal Tigadoli  * Copyright (c) 2016 - 2020, Broadcom
3*bffde63dSSheetal Tigadoli  *
4*bffde63dSSheetal Tigadoli  * SPDX-License-Identifier: BSD-3-Clause
5*bffde63dSSheetal Tigadoli  */
6*bffde63dSSheetal Tigadoli 
7*bffde63dSSheetal Tigadoli #include <stdlib.h>
8*bffde63dSSheetal Tigadoli #include <string.h>
9*bffde63dSSheetal Tigadoli #include <stddef.h>
10*bffde63dSSheetal Tigadoli 
11*bffde63dSSheetal Tigadoli #include <arch_helpers.h>
12*bffde63dSSheetal Tigadoli #include <lib/mmio.h>
13*bffde63dSSheetal Tigadoli 
14*bffde63dSSheetal Tigadoli #include "bcm_emmc.h"
15*bffde63dSSheetal Tigadoli #include "emmc_chal_types.h"
16*bffde63dSSheetal Tigadoli #include "emmc_csl_sdprot.h"
17*bffde63dSSheetal Tigadoli #include "emmc_chal_sd.h"
18*bffde63dSSheetal Tigadoli #include "emmc_csl_sdcmd.h"
19*bffde63dSSheetal Tigadoli #include "emmc_csl_sd.h"
20*bffde63dSSheetal Tigadoli #include "emmc_pboot_hal_memory_drv.h"
21*bffde63dSSheetal Tigadoli 
22*bffde63dSSheetal Tigadoli #define SD_CARD_BUSY                    0x80000000
23*bffde63dSSheetal Tigadoli #define SD_CARD_RETRY_LIMIT             1000
24*bffde63dSSheetal Tigadoli #define SD_CARD_HIGH_SPEED_PS           13
25*bffde63dSSheetal Tigadoli #define SD_CHK_HIGH_SPEED_MODE          0x00FFFFF1
26*bffde63dSSheetal Tigadoli #define SD_SET_HIGH_SPEED_MODE          0x80FFFFF1
27*bffde63dSSheetal Tigadoli #define SD_MMC_ENABLE_HIGH_SPEED        0x03b90100	//0x03b90103
28*bffde63dSSheetal Tigadoli #define SD_MMC_8BIT_MODE                0x03b70200
29*bffde63dSSheetal Tigadoli #define SD_MMC_4BIT_MODE                0x03b70100
30*bffde63dSSheetal Tigadoli #define SD_MMC_1BIT_MODE                0x03b70000
31*bffde63dSSheetal Tigadoli 
32*bffde63dSSheetal Tigadoli #define SD_MMC_BOOT_8BIT_MODE           0x03b10200
33*bffde63dSSheetal Tigadoli #define SD_MMC_BOOT_4BIT_MODE           0x03b10100
34*bffde63dSSheetal Tigadoli #define SD_MMC_BOOT_1BIT_MODE           0x03b10000
35*bffde63dSSheetal Tigadoli #define SDIO_HW_EMMC_EXT_CSD_BOOT_CNF   0X03B30000
36*bffde63dSSheetal Tigadoli 
37*bffde63dSSheetal Tigadoli #ifdef USE_EMMC_FIP_TOC_CACHE
38*bffde63dSSheetal Tigadoli /*
39*bffde63dSSheetal Tigadoli  * Cache size mirrors the size of the global eMMC temp buffer
40*bffde63dSSheetal Tigadoli  * which is used for non-image body reads such as headers, ToC etc.
41*bffde63dSSheetal Tigadoli  */
42*bffde63dSSheetal Tigadoli #define CACHE_SIZE           ((EMMC_BLOCK_SIZE) * 2)
43*bffde63dSSheetal Tigadoli #define PARTITION_BLOCK_ADDR ((PLAT_FIP_ATTEMPT_OFFSET)/(EMMC_BLOCK_SIZE))
44*bffde63dSSheetal Tigadoli 
45*bffde63dSSheetal Tigadoli static uint32_t cached_partition_block;
46*bffde63dSSheetal Tigadoli static uint8_t cached_block[CACHE_SIZE];
47*bffde63dSSheetal Tigadoli #endif
48*bffde63dSSheetal Tigadoli 
49*bffde63dSSheetal Tigadoli static int set_card_data_width(struct sd_handle *handle, int width);
50*bffde63dSSheetal Tigadoli static int abort_err(struct sd_handle *handle);
51*bffde63dSSheetal Tigadoli static int err_recovery(struct sd_handle *handle, uint32_t errors);
52*bffde63dSSheetal Tigadoli static int xfer_data(struct sd_handle *handle, uint32_t mode, uint32_t addr,
53*bffde63dSSheetal Tigadoli 		     uint32_t length, uint8_t *base);
54*bffde63dSSheetal Tigadoli 
55*bffde63dSSheetal Tigadoli int set_boot_config(struct sd_handle *handle, uint32_t config)
56*bffde63dSSheetal Tigadoli {
57*bffde63dSSheetal Tigadoli 	return mmc_cmd6(handle, SDIO_HW_EMMC_EXT_CSD_BOOT_CNF | config);
58*bffde63dSSheetal Tigadoli }
59*bffde63dSSheetal Tigadoli 
60*bffde63dSSheetal Tigadoli void process_csd_mmc_speed(struct sd_handle *handle, uint32_t csd_mmc_speed)
61*bffde63dSSheetal Tigadoli {
62*bffde63dSSheetal Tigadoli 	uint32_t div_ctrl_setting;
63*bffde63dSSheetal Tigadoli 
64*bffde63dSSheetal Tigadoli 	/* CSD field TRAN_SPEED:
65*bffde63dSSheetal Tigadoli 	 * Bits [2:0] 0 = 100 KHz
66*bffde63dSSheetal Tigadoli 	 *            1 = 1 MHz
67*bffde63dSSheetal Tigadoli 	 *            2 = 10 MHz
68*bffde63dSSheetal Tigadoli 	 *            3 = 100 MHz
69*bffde63dSSheetal Tigadoli 	 *            4...7 Reserved.
70*bffde63dSSheetal Tigadoli 	 * Bits [6:3] 0 = Reserved
71*bffde63dSSheetal Tigadoli 	 *            1 = 1.0
72*bffde63dSSheetal Tigadoli 	 *            2 = 1.2
73*bffde63dSSheetal Tigadoli 	 *            3 = 1.3
74*bffde63dSSheetal Tigadoli 	 *            4 = 1.5
75*bffde63dSSheetal Tigadoli 	 *            5 = 2.0
76*bffde63dSSheetal Tigadoli 	 *            6 = 2.6
77*bffde63dSSheetal Tigadoli 	 *            7 = 3.0
78*bffde63dSSheetal Tigadoli 	 *            8 = 3.5
79*bffde63dSSheetal Tigadoli 	 *            9 = 4.0
80*bffde63dSSheetal Tigadoli 	 *            A = 4.5
81*bffde63dSSheetal Tigadoli 	 *            B = 5.2
82*bffde63dSSheetal Tigadoli 	 *            C = 5.5
83*bffde63dSSheetal Tigadoli 	 *            D = 6.0
84*bffde63dSSheetal Tigadoli 	 *            E = 7.0
85*bffde63dSSheetal Tigadoli 	 *            F = 8.0
86*bffde63dSSheetal Tigadoli 	 * For cards supporting version 4.0, 4.1, and 4.2 of the standard,
87*bffde63dSSheetal Tigadoli 	 * the value shall be 20 MHz (0x2A).
88*bffde63dSSheetal Tigadoli 	 * For cards supporting version 4.3 , the value shall be 26 MHz (0x32)
89*bffde63dSSheetal Tigadoli 	 */
90*bffde63dSSheetal Tigadoli 
91*bffde63dSSheetal Tigadoli 	switch (csd_mmc_speed & 0x7F) {
92*bffde63dSSheetal Tigadoli 	case 0x2A:
93*bffde63dSSheetal Tigadoli 		EMMC_TRACE("Speeding up eMMC clock to 20MHz\n");
94*bffde63dSSheetal Tigadoli 		div_ctrl_setting =
95*bffde63dSSheetal Tigadoli 		    chal_sd_freq_2_div_ctrl_setting(20 * 1000 * 1000);
96*bffde63dSSheetal Tigadoli 		break;
97*bffde63dSSheetal Tigadoli 	case 0x32:
98*bffde63dSSheetal Tigadoli 		EMMC_TRACE("Speeding up eMMC clock to 26MHz\n");
99*bffde63dSSheetal Tigadoli 		div_ctrl_setting =
100*bffde63dSSheetal Tigadoli 		    chal_sd_freq_2_div_ctrl_setting(26 * 1000 * 1000);
101*bffde63dSSheetal Tigadoli 		break;
102*bffde63dSSheetal Tigadoli 	default:
103*bffde63dSSheetal Tigadoli 		/* Unknown */
104*bffde63dSSheetal Tigadoli 		return;
105*bffde63dSSheetal Tigadoli 	}
106*bffde63dSSheetal Tigadoli 
107*bffde63dSSheetal Tigadoli 	chal_sd_set_clock((CHAL_HANDLE *) handle->device, div_ctrl_setting, 0);
108*bffde63dSSheetal Tigadoli 
109*bffde63dSSheetal Tigadoli 	chal_sd_set_clock((CHAL_HANDLE *) handle->device, div_ctrl_setting, 1);
110*bffde63dSSheetal Tigadoli 
111*bffde63dSSheetal Tigadoli 	SD_US_DELAY(1000);
112*bffde63dSSheetal Tigadoli }
113*bffde63dSSheetal Tigadoli 
114*bffde63dSSheetal Tigadoli 
115*bffde63dSSheetal Tigadoli /*
116*bffde63dSSheetal Tigadoli  * The function changes SD/SDIO/MMC card data width if
117*bffde63dSSheetal Tigadoli  * the card support configurable data width. The host controller
118*bffde63dSSheetal Tigadoli  * and the card has to be in the same bus data width.
119*bffde63dSSheetal Tigadoli  */
120*bffde63dSSheetal Tigadoli int set_card_data_width(struct sd_handle *handle, int width)
121*bffde63dSSheetal Tigadoli {
122*bffde63dSSheetal Tigadoli 	uint32_t data_width = 0;
123*bffde63dSSheetal Tigadoli 	int is_valid_arg = 1;
124*bffde63dSSheetal Tigadoli 	int rc = SD_FAIL;
125*bffde63dSSheetal Tigadoli 	char *bitwidth_str = " ";
126*bffde63dSSheetal Tigadoli 	char *result_str = "failed";
127*bffde63dSSheetal Tigadoli 
128*bffde63dSSheetal Tigadoli 	switch (width) {
129*bffde63dSSheetal Tigadoli #ifdef DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT
130*bffde63dSSheetal Tigadoli 	case SD_BUS_DATA_WIDTH_8BIT:
131*bffde63dSSheetal Tigadoli 		data_width = SD_MMC_8BIT_MODE;
132*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
133*bffde63dSSheetal Tigadoli 		bitwidth_str = "8_BIT";
134*bffde63dSSheetal Tigadoli #endif
135*bffde63dSSheetal Tigadoli 		break;
136*bffde63dSSheetal Tigadoli #endif
137*bffde63dSSheetal Tigadoli 	case SD_BUS_DATA_WIDTH_4BIT:
138*bffde63dSSheetal Tigadoli 		data_width = SD_MMC_4BIT_MODE;
139*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
140*bffde63dSSheetal Tigadoli 		bitwidth_str = "4_BIT";
141*bffde63dSSheetal Tigadoli #endif
142*bffde63dSSheetal Tigadoli 		break;
143*bffde63dSSheetal Tigadoli 
144*bffde63dSSheetal Tigadoli 	case SD_BUS_DATA_WIDTH_1BIT:
145*bffde63dSSheetal Tigadoli 		data_width = SD_MMC_1BIT_MODE;
146*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
147*bffde63dSSheetal Tigadoli 		bitwidth_str = "1_BIT";
148*bffde63dSSheetal Tigadoli #endif
149*bffde63dSSheetal Tigadoli 		break;
150*bffde63dSSheetal Tigadoli 
151*bffde63dSSheetal Tigadoli 	default:
152*bffde63dSSheetal Tigadoli 		is_valid_arg = 0;
153*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
154*bffde63dSSheetal Tigadoli 		bitwidth_str = "unknown";
155*bffde63dSSheetal Tigadoli #endif
156*bffde63dSSheetal Tigadoli 		break;
157*bffde63dSSheetal Tigadoli 	}
158*bffde63dSSheetal Tigadoli 
159*bffde63dSSheetal Tigadoli 	if (is_valid_arg) {
160*bffde63dSSheetal Tigadoli 		rc = mmc_cmd6(handle, data_width);
161*bffde63dSSheetal Tigadoli 		if (rc == SD_OK) {
162*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
163*bffde63dSSheetal Tigadoli 			result_str = "succeeded";
164*bffde63dSSheetal Tigadoli #endif
165*bffde63dSSheetal Tigadoli 			chal_sd_config_bus_width((CHAL_HANDLE *) handle->device,
166*bffde63dSSheetal Tigadoli 						 width);
167*bffde63dSSheetal Tigadoli 		} else {
168*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
169*bffde63dSSheetal Tigadoli 			result_str = "failed";
170*bffde63dSSheetal Tigadoli #endif
171*bffde63dSSheetal Tigadoli 		}
172*bffde63dSSheetal Tigadoli 	} else {
173*bffde63dSSheetal Tigadoli 		rc = SD_FAIL;
174*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
175*bffde63dSSheetal Tigadoli 		result_str = "ignored";
176*bffde63dSSheetal Tigadoli #endif
177*bffde63dSSheetal Tigadoli 	}
178*bffde63dSSheetal Tigadoli 
179*bffde63dSSheetal Tigadoli 	VERBOSE("SDIO Data Width(%s) %s.\n", bitwidth_str, result_str);
180*bffde63dSSheetal Tigadoli 
181*bffde63dSSheetal Tigadoli 	return rc;
182*bffde63dSSheetal Tigadoli }
183*bffde63dSSheetal Tigadoli 
184*bffde63dSSheetal Tigadoli 
185*bffde63dSSheetal Tigadoli /*
186*bffde63dSSheetal Tigadoli  * Error handling routine. Does abort data
187*bffde63dSSheetal Tigadoli  * transmission if error is found.
188*bffde63dSSheetal Tigadoli  */
189*bffde63dSSheetal Tigadoli static int abort_err(struct sd_handle *handle)
190*bffde63dSSheetal Tigadoli {
191*bffde63dSSheetal Tigadoli 	uint32_t present, options, event, rel = 0;
192*bffde63dSSheetal Tigadoli 	struct sd_resp cmdRsp;
193*bffde63dSSheetal Tigadoli 
194*bffde63dSSheetal Tigadoli 	handle->device->ctrl.argReg = 0;
195*bffde63dSSheetal Tigadoli 	handle->device->ctrl.cmdIndex = SD_CMD_STOP_TRANSMISSION;
196*bffde63dSSheetal Tigadoli 
197*bffde63dSSheetal Tigadoli 	options = (SD_CMD_STOP_TRANSMISSION << 24) |
198*bffde63dSSheetal Tigadoli 		  (SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S) |
199*bffde63dSSheetal Tigadoli 		  SD4_EMMC_TOP_CMD_CRC_EN_MASK |
200*bffde63dSSheetal Tigadoli 		  SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
201*bffde63dSSheetal Tigadoli 
202*bffde63dSSheetal Tigadoli 	chal_sd_send_cmd((CHAL_HANDLE *) handle->device,
203*bffde63dSSheetal Tigadoli 			 handle->device->ctrl.cmdIndex,
204*bffde63dSSheetal Tigadoli 			 handle->device->ctrl.argReg, options);
205*bffde63dSSheetal Tigadoli 
206*bffde63dSSheetal Tigadoli 	event = wait_for_event(handle,
207*bffde63dSSheetal Tigadoli 			       SD4_EMMC_TOP_INTR_CMDDONE_MASK |
208*bffde63dSSheetal Tigadoli 			       SD_ERR_INTERRUPTS,
209*bffde63dSSheetal Tigadoli 			       handle->device->cfg.wfe_retry);
210*bffde63dSSheetal Tigadoli 
211*bffde63dSSheetal Tigadoli 	if (event & SD_CMD_ERROR_INT) {
212*bffde63dSSheetal Tigadoli 		rel = SD_ERROR_NON_RECOVERABLE;
213*bffde63dSSheetal Tigadoli 	} else {
214*bffde63dSSheetal Tigadoli 		if (event & SD_DAT_TIMEOUT) {
215*bffde63dSSheetal Tigadoli 			return SD_ERROR_NON_RECOVERABLE;
216*bffde63dSSheetal Tigadoli 		}
217*bffde63dSSheetal Tigadoli 
218*bffde63dSSheetal Tigadoli 		chal_sd_get_response((CHAL_HANDLE *) handle->device,
219*bffde63dSSheetal Tigadoli 				     (uint32_t *)&cmdRsp);
220*bffde63dSSheetal Tigadoli 
221*bffde63dSSheetal Tigadoli 		process_cmd_response(handle, handle->device->ctrl.cmdIndex,
222*bffde63dSSheetal Tigadoli 				     cmdRsp.data.r2.rsp1, cmdRsp.data.r2.rsp2,
223*bffde63dSSheetal Tigadoli 				     cmdRsp.data.r2.rsp3, cmdRsp.data.r2.rsp4,
224*bffde63dSSheetal Tigadoli 				     &cmdRsp);
225*bffde63dSSheetal Tigadoli 
226*bffde63dSSheetal Tigadoli 		SD_US_DELAY(2000);
227*bffde63dSSheetal Tigadoli 
228*bffde63dSSheetal Tigadoli 		present =
229*bffde63dSSheetal Tigadoli 		    chal_sd_get_present_status((CHAL_HANDLE *) handle->device);
230*bffde63dSSheetal Tigadoli 
231*bffde63dSSheetal Tigadoli 		if ((present & 0x00F00000) == 0x00F00000)
232*bffde63dSSheetal Tigadoli 			rel = SD_ERROR_RECOVERABLE;
233*bffde63dSSheetal Tigadoli 		else
234*bffde63dSSheetal Tigadoli 			rel = SD_ERROR_NON_RECOVERABLE;
235*bffde63dSSheetal Tigadoli 	}
236*bffde63dSSheetal Tigadoli 
237*bffde63dSSheetal Tigadoli 	return rel;
238*bffde63dSSheetal Tigadoli }
239*bffde63dSSheetal Tigadoli 
240*bffde63dSSheetal Tigadoli 
241*bffde63dSSheetal Tigadoli /*
242*bffde63dSSheetal Tigadoli  * The function handles real data transmission on both DMA and
243*bffde63dSSheetal Tigadoli  * none DMA mode, In None DMA mode the data transfer starts
244*bffde63dSSheetal Tigadoli  * when the command is sent to the card, data has to be written
245*bffde63dSSheetal Tigadoli  * into the host contollers buffer at this time one block
246*bffde63dSSheetal Tigadoli  * at a time.
247*bffde63dSSheetal Tigadoli  * In DMA mode, the real data transfer is done by the DMA engine
248*bffde63dSSheetal Tigadoli  * and this functions just waits for the data transfer to complete.
249*bffde63dSSheetal Tigadoli  *
250*bffde63dSSheetal Tigadoli  */
251*bffde63dSSheetal Tigadoli int process_data_xfer(struct sd_handle *handle, uint8_t *buffer, uint32_t addr,
252*bffde63dSSheetal Tigadoli 		      uint32_t length, int dir)
253*bffde63dSSheetal Tigadoli {
254*bffde63dSSheetal Tigadoli 	if (dir == SD_XFER_HOST_TO_CARD) {
255*bffde63dSSheetal Tigadoli #ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
256*bffde63dSSheetal Tigadoli 		if (handle->device->cfg.dma == SD_DMA_OFF) {
257*bffde63dSSheetal Tigadoli 			/*
258*bffde63dSSheetal Tigadoli 			 * In NON DMA mode, the real data xfer starts from here
259*bffde63dSSheetal Tigadoli 			 */
260*bffde63dSSheetal Tigadoli 			if (write_buffer(handle, length, buffer))
261*bffde63dSSheetal Tigadoli 				return SD_WRITE_ERROR;
262*bffde63dSSheetal Tigadoli 		} else {
263*bffde63dSSheetal Tigadoli 			wait_for_event(handle,
264*bffde63dSSheetal Tigadoli 				       SD4_EMMC_TOP_INTR_TXDONE_MASK |
265*bffde63dSSheetal Tigadoli 				       SD_ERR_INTERRUPTS,
266*bffde63dSSheetal Tigadoli 				       handle->device->cfg.wfe_retry);
267*bffde63dSSheetal Tigadoli 
268*bffde63dSSheetal Tigadoli 			if (handle->device->ctrl.cmdStatus == SD_OK)
269*bffde63dSSheetal Tigadoli 				return SD_OK;
270*bffde63dSSheetal Tigadoli 
271*bffde63dSSheetal Tigadoli 			check_error(handle, handle->device->ctrl.cmdStatus);
272*bffde63dSSheetal Tigadoli 			return SD_WRITE_ERROR;
273*bffde63dSSheetal Tigadoli 		}
274*bffde63dSSheetal Tigadoli #else
275*bffde63dSSheetal Tigadoli 		return SD_WRITE_ERROR;
276*bffde63dSSheetal Tigadoli #endif
277*bffde63dSSheetal Tigadoli 	} else {		/* SD_XFER_CARD_TO_HOST */
278*bffde63dSSheetal Tigadoli 
279*bffde63dSSheetal Tigadoli 		if (handle->device->cfg.dma == SD_DMA_OFF) {
280*bffde63dSSheetal Tigadoli 			/* In NON DMA mode, the real data
281*bffde63dSSheetal Tigadoli 			 * transfer starts from here
282*bffde63dSSheetal Tigadoli 			 */
283*bffde63dSSheetal Tigadoli 			if (read_buffer(handle, length, buffer))
284*bffde63dSSheetal Tigadoli 				return SD_READ_ERROR;
285*bffde63dSSheetal Tigadoli 
286*bffde63dSSheetal Tigadoli 		} else {	/* for DMA mode */
287*bffde63dSSheetal Tigadoli 
288*bffde63dSSheetal Tigadoli 			/*
289*bffde63dSSheetal Tigadoli 			 * once the data transmission is done
290*bffde63dSSheetal Tigadoli 			 * copy data to the host buffer.
291*bffde63dSSheetal Tigadoli 			 */
292*bffde63dSSheetal Tigadoli 			wait_for_event(handle,
293*bffde63dSSheetal Tigadoli 				       SD4_EMMC_TOP_INTR_TXDONE_MASK |
294*bffde63dSSheetal Tigadoli 				       SD_ERR_INTERRUPTS,
295*bffde63dSSheetal Tigadoli 				       handle->device->cfg.wfe_retry);
296*bffde63dSSheetal Tigadoli 
297*bffde63dSSheetal Tigadoli 			if (handle->device->ctrl.cmdStatus == SD_OK)
298*bffde63dSSheetal Tigadoli 				return SD_OK;
299*bffde63dSSheetal Tigadoli 
300*bffde63dSSheetal Tigadoli 			check_error(handle, handle->device->ctrl.cmdStatus);
301*bffde63dSSheetal Tigadoli 			return SD_READ_ERROR;
302*bffde63dSSheetal Tigadoli 		}
303*bffde63dSSheetal Tigadoli 	}
304*bffde63dSSheetal Tigadoli 	return SD_OK;
305*bffde63dSSheetal Tigadoli }
306*bffde63dSSheetal Tigadoli 
307*bffde63dSSheetal Tigadoli 
308*bffde63dSSheetal Tigadoli /*
309*bffde63dSSheetal Tigadoli  * The function sets block size for the next SD/SDIO/MMC
310*bffde63dSSheetal Tigadoli  * card read/write command.
311*bffde63dSSheetal Tigadoli  */
312*bffde63dSSheetal Tigadoli int select_blk_sz(struct sd_handle *handle, uint16_t size)
313*bffde63dSSheetal Tigadoli {
314*bffde63dSSheetal Tigadoli 	return sd_cmd16(handle, size);
315*bffde63dSSheetal Tigadoli }
316*bffde63dSSheetal Tigadoli 
317*bffde63dSSheetal Tigadoli 
318*bffde63dSSheetal Tigadoli /*
319*bffde63dSSheetal Tigadoli  * The function initalizes the SD/SDIO/MMC/CEATA and detects
320*bffde63dSSheetal Tigadoli  * the card according to the flag of detection.
321*bffde63dSSheetal Tigadoli  * Once this function is called, the card is put into ready state
322*bffde63dSSheetal Tigadoli  * so application can do data transfer to and from the card.
323*bffde63dSSheetal Tigadoli  */
324*bffde63dSSheetal Tigadoli int init_card(struct sd_handle *handle, int detection)
325*bffde63dSSheetal Tigadoli {
326*bffde63dSSheetal Tigadoli 	/*
327*bffde63dSSheetal Tigadoli 	 * After Reset, eMMC comes up in 1 Bit Data Width by default.
328*bffde63dSSheetal Tigadoli 	 * Set host side to match.
329*bffde63dSSheetal Tigadoli 	 */
330*bffde63dSSheetal Tigadoli 	chal_sd_config_bus_width((CHAL_HANDLE *) handle->device,
331*bffde63dSSheetal Tigadoli 				 SD_BUS_DATA_WIDTH_1BIT);
332*bffde63dSSheetal Tigadoli 
333*bffde63dSSheetal Tigadoli #ifdef USE_EMMC_FIP_TOC_CACHE
334*bffde63dSSheetal Tigadoli 	cached_partition_block = 0;
335*bffde63dSSheetal Tigadoli #endif
336*bffde63dSSheetal Tigadoli 	handle->device->ctrl.present = 0; /* init card present to be no card */
337*bffde63dSSheetal Tigadoli 
338*bffde63dSSheetal Tigadoli 	init_mmc_card(handle);
339*bffde63dSSheetal Tigadoli 
340*bffde63dSSheetal Tigadoli 	handle->device->ctrl.present = 1; /* card is detected */
341*bffde63dSSheetal Tigadoli 
342*bffde63dSSheetal Tigadoli 	/* switch the data width back */
343*bffde63dSSheetal Tigadoli 	if (handle->card->type != SD_CARD_MMC)
344*bffde63dSSheetal Tigadoli 		return SD_FAIL;
345*bffde63dSSheetal Tigadoli 
346*bffde63dSSheetal Tigadoli 	/*
347*bffde63dSSheetal Tigadoli 	 * Dynamically set Data Width to highest supported value.
348*bffde63dSSheetal Tigadoli 	 * Try different data width settings (highest to lowest).
349*bffde63dSSheetal Tigadoli 	 * Verify each setting by reading EXT_CSD and comparing
350*bffde63dSSheetal Tigadoli 	 * against the EXT_CSD contents previously read in call to
351*bffde63dSSheetal Tigadoli 	 * init_mmc_card() earlier. Stop at first verified data width
352*bffde63dSSheetal Tigadoli 	 * setting.
353*bffde63dSSheetal Tigadoli 	 */
354*bffde63dSSheetal Tigadoli 	{
355*bffde63dSSheetal Tigadoli #define EXT_CSD_PROPERTIES_SECTION_START_INDEX	192
356*bffde63dSSheetal Tigadoli #define EXT_CSD_PROPERTIES_SECTION_END_INDEX	511
357*bffde63dSSheetal Tigadoli 		uint8_t buffer[EXT_CSD_SIZE];
358*bffde63dSSheetal Tigadoli #ifdef DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT
359*bffde63dSSheetal Tigadoli 		/* Try 8 Bit Data Width */
360*bffde63dSSheetal Tigadoli 		chal_sd_config_bus_width((CHAL_HANDLE *) handle->device,
361*bffde63dSSheetal Tigadoli 					 SD_BUS_DATA_WIDTH_8BIT);
362*bffde63dSSheetal Tigadoli 		if ((!set_card_data_width(handle, SD_BUS_DATA_WIDTH_8BIT)) &&
363*bffde63dSSheetal Tigadoli 		    (!mmc_cmd8(handle, buffer)) &&
364*bffde63dSSheetal Tigadoli 		    (!memcmp(&buffer[EXT_CSD_PROPERTIES_SECTION_START_INDEX],
365*bffde63dSSheetal Tigadoli 			     &(emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_PROPERTIES_SECTION_START_INDEX]),
366*bffde63dSSheetal Tigadoli 			     EXT_CSD_PROPERTIES_SECTION_END_INDEX - EXT_CSD_PROPERTIES_SECTION_START_INDEX + 1)))
367*bffde63dSSheetal Tigadoli 
368*bffde63dSSheetal Tigadoli 			return SD_OK;
369*bffde63dSSheetal Tigadoli #endif
370*bffde63dSSheetal Tigadoli 		/* Fall back to 4 Bit Data Width */
371*bffde63dSSheetal Tigadoli 		chal_sd_config_bus_width((CHAL_HANDLE *) handle->device,
372*bffde63dSSheetal Tigadoli 					 SD_BUS_DATA_WIDTH_4BIT);
373*bffde63dSSheetal Tigadoli 		if ((!set_card_data_width(handle, SD_BUS_DATA_WIDTH_4BIT)) &&
374*bffde63dSSheetal Tigadoli 		    (!mmc_cmd8(handle, buffer)) &&
375*bffde63dSSheetal Tigadoli 		    (!memcmp(&buffer[EXT_CSD_PROPERTIES_SECTION_START_INDEX],
376*bffde63dSSheetal Tigadoli 			     &(emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_PROPERTIES_SECTION_START_INDEX]),
377*bffde63dSSheetal Tigadoli 			     EXT_CSD_PROPERTIES_SECTION_END_INDEX - EXT_CSD_PROPERTIES_SECTION_START_INDEX + 1)))
378*bffde63dSSheetal Tigadoli 
379*bffde63dSSheetal Tigadoli 			return SD_OK;
380*bffde63dSSheetal Tigadoli 
381*bffde63dSSheetal Tigadoli 		/* Fall back to 1 Bit Data Width */
382*bffde63dSSheetal Tigadoli 		chal_sd_config_bus_width((CHAL_HANDLE *) handle->device,
383*bffde63dSSheetal Tigadoli 					 SD_BUS_DATA_WIDTH_1BIT);
384*bffde63dSSheetal Tigadoli 		/* Just use 1 Bit Data Width then. */
385*bffde63dSSheetal Tigadoli 		if (!set_card_data_width(handle, SD_BUS_DATA_WIDTH_1BIT))
386*bffde63dSSheetal Tigadoli 			return SD_OK;
387*bffde63dSSheetal Tigadoli 
388*bffde63dSSheetal Tigadoli 	}
389*bffde63dSSheetal Tigadoli 	return SD_CARD_INIT_ERROR;
390*bffde63dSSheetal Tigadoli }
391*bffde63dSSheetal Tigadoli 
392*bffde63dSSheetal Tigadoli 
393*bffde63dSSheetal Tigadoli /*
394*bffde63dSSheetal Tigadoli  * The function handles MMC/CEATA card initalization.
395*bffde63dSSheetal Tigadoli  */
396*bffde63dSSheetal Tigadoli int init_mmc_card(struct sd_handle *handle)
397*bffde63dSSheetal Tigadoli {
398*bffde63dSSheetal Tigadoli 	uint32_t ocr = 0, newOcr, rc, limit = 0;
399*bffde63dSSheetal Tigadoli 	uint32_t cmd1_option = 0x40300000;
400*bffde63dSSheetal Tigadoli 	uint32_t sec_count;
401*bffde63dSSheetal Tigadoli 
402*bffde63dSSheetal Tigadoli 	handle->card->type = SD_CARD_MMC;
403*bffde63dSSheetal Tigadoli 
404*bffde63dSSheetal Tigadoli 	do {
405*bffde63dSSheetal Tigadoli 		SD_US_DELAY(1000);
406*bffde63dSSheetal Tigadoli 		newOcr = 0;
407*bffde63dSSheetal Tigadoli 		ocr = 0;
408*bffde63dSSheetal Tigadoli 		rc = sd_cmd1(handle, cmd1_option, &newOcr);
409*bffde63dSSheetal Tigadoli 		limit++;
410*bffde63dSSheetal Tigadoli 
411*bffde63dSSheetal Tigadoli 		if (rc == SD_OK)
412*bffde63dSSheetal Tigadoli 			ocr = newOcr;
413*bffde63dSSheetal Tigadoli 
414*bffde63dSSheetal Tigadoli 	} while (((ocr & SD_CARD_BUSY) == 0) && (limit < SD_CARD_RETRY_LIMIT));
415*bffde63dSSheetal Tigadoli 
416*bffde63dSSheetal Tigadoli 	if (limit >= SD_CARD_RETRY_LIMIT) {
417*bffde63dSSheetal Tigadoli 		handle->card->type = SD_CARD_UNKNOWN;
418*bffde63dSSheetal Tigadoli 		EMMC_TRACE("CMD1 Timeout: Device is not ready\n");
419*bffde63dSSheetal Tigadoli 		return SD_CARD_UNKNOWN;
420*bffde63dSSheetal Tigadoli 	}
421*bffde63dSSheetal Tigadoli 
422*bffde63dSSheetal Tigadoli 	/* Save the ocr register */
423*bffde63dSSheetal Tigadoli 	handle->device->ctrl.ocr = ocr;
424*bffde63dSSheetal Tigadoli 
425*bffde63dSSheetal Tigadoli 	/* Ready State */
426*bffde63dSSheetal Tigadoli 	rc = sd_cmd2(handle);
427*bffde63dSSheetal Tigadoli 	if (rc != SD_OK) {
428*bffde63dSSheetal Tigadoli 		handle->card->type = SD_CARD_UNKNOWN;
429*bffde63dSSheetal Tigadoli 		return SD_CARD_UNKNOWN;
430*bffde63dSSheetal Tigadoli 	}
431*bffde63dSSheetal Tigadoli 
432*bffde63dSSheetal Tigadoli 	rc = sd_cmd3(handle);
433*bffde63dSSheetal Tigadoli 	if (rc != SD_OK) {
434*bffde63dSSheetal Tigadoli 		handle->card->type = SD_CARD_UNKNOWN;
435*bffde63dSSheetal Tigadoli 		return SD_CARD_UNKNOWN;
436*bffde63dSSheetal Tigadoli 	}
437*bffde63dSSheetal Tigadoli 	/* read CSD */
438*bffde63dSSheetal Tigadoli 	rc = sd_cmd9(handle, &emmc_global_vars_ptr->cardData);
439*bffde63dSSheetal Tigadoli 	if (rc != SD_OK) {
440*bffde63dSSheetal Tigadoli 		handle->card->type = SD_CARD_UNKNOWN;
441*bffde63dSSheetal Tigadoli 		return SD_CARD_UNKNOWN;
442*bffde63dSSheetal Tigadoli 	}
443*bffde63dSSheetal Tigadoli 
444*bffde63dSSheetal Tigadoli 	/* Increase clock frequency according to what the card advertises */
445*bffde63dSSheetal Tigadoli 	EMMC_TRACE("From CSD...  cardData.csd.mmc.speed = 0x%X\n",
446*bffde63dSSheetal Tigadoli 		   emmc_global_vars_ptr->cardData.csd.mmc.speed);
447*bffde63dSSheetal Tigadoli 	process_csd_mmc_speed(handle,
448*bffde63dSSheetal Tigadoli 			      emmc_global_vars_ptr->cardData.csd.mmc.speed);
449*bffde63dSSheetal Tigadoli 
450*bffde63dSSheetal Tigadoli 	/* goto transfer mode */
451*bffde63dSSheetal Tigadoli 	rc = sd_cmd7(handle, handle->device->ctrl.rca);
452*bffde63dSSheetal Tigadoli 	if (rc != SD_OK) {
453*bffde63dSSheetal Tigadoli 		handle->card->type = SD_CARD_UNKNOWN;
454*bffde63dSSheetal Tigadoli 		return SD_CARD_UNKNOWN;
455*bffde63dSSheetal Tigadoli 	}
456*bffde63dSSheetal Tigadoli 
457*bffde63dSSheetal Tigadoli 	rc = mmc_cmd8(handle, emmc_global_buf_ptr->u.Ext_CSD_storage);
458*bffde63dSSheetal Tigadoli 	if (rc == SD_OK) {
459*bffde63dSSheetal Tigadoli 		/* calcul real capacity */
460*bffde63dSSheetal Tigadoli 		sec_count = emmc_global_buf_ptr->u.Ext_CSD_storage[212] |
461*bffde63dSSheetal Tigadoli 			    emmc_global_buf_ptr->u.Ext_CSD_storage[213] << 8 |
462*bffde63dSSheetal Tigadoli 			    emmc_global_buf_ptr->u.Ext_CSD_storage[214] << 16 |
463*bffde63dSSheetal Tigadoli 			    emmc_global_buf_ptr->u.Ext_CSD_storage[215] << 24;
464*bffde63dSSheetal Tigadoli 
465*bffde63dSSheetal Tigadoli 		EMMC_TRACE("Device density = %ldMBytes\n",
466*bffde63dSSheetal Tigadoli 			   handle->card->size / (1024 * 1024));
467*bffde63dSSheetal Tigadoli 
468*bffde63dSSheetal Tigadoli 		if (sec_count > 0) {
469*bffde63dSSheetal Tigadoli 			handle->card->size = (uint64_t)sec_count * 512;
470*bffde63dSSheetal Tigadoli 
471*bffde63dSSheetal Tigadoli 			EMMC_TRACE("Updated Device density = %ldMBytes\n",
472*bffde63dSSheetal Tigadoli 				   handle->card->size / (1024 * 1024));
473*bffde63dSSheetal Tigadoli 		}
474*bffde63dSSheetal Tigadoli 
475*bffde63dSSheetal Tigadoli 		if (sec_count > (2u * 1024 * 1024 * 1024) / 512) {
476*bffde63dSSheetal Tigadoli 			handle->device->ctrl.ocr |= SD_CARD_HIGH_CAPACITY;
477*bffde63dSSheetal Tigadoli 			handle->device->cfg.blockSize = 512;
478*bffde63dSSheetal Tigadoli 		}
479*bffde63dSSheetal Tigadoli 
480*bffde63dSSheetal Tigadoli 		if (handle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
481*bffde63dSSheetal Tigadoli 			EMMC_TRACE("Sector addressing\n");
482*bffde63dSSheetal Tigadoli 		else
483*bffde63dSSheetal Tigadoli 			EMMC_TRACE("Byte addressing\n");
484*bffde63dSSheetal Tigadoli 
485*bffde63dSSheetal Tigadoli 		EMMC_TRACE("Ext_CSD_storage[162]: 0x%02X  Ext_CSD_storage[179]: 0x%02X\n",
486*bffde63dSSheetal Tigadoli 			   emmc_global_buf_ptr->u.Ext_CSD_storage[162],
487*bffde63dSSheetal Tigadoli 			   emmc_global_buf_ptr->u.Ext_CSD_storage[179]);
488*bffde63dSSheetal Tigadoli 	}
489*bffde63dSSheetal Tigadoli 
490*bffde63dSSheetal Tigadoli 	return handle->card->type;
491*bffde63dSSheetal Tigadoli }
492*bffde63dSSheetal Tigadoli 
493*bffde63dSSheetal Tigadoli 
494*bffde63dSSheetal Tigadoli /*
495*bffde63dSSheetal Tigadoli  * The function send reset command to the card.
496*bffde63dSSheetal Tigadoli  * The card will be in ready status after the reset.
497*bffde63dSSheetal Tigadoli  */
498*bffde63dSSheetal Tigadoli int reset_card(struct sd_handle *handle)
499*bffde63dSSheetal Tigadoli {
500*bffde63dSSheetal Tigadoli 	int res = SD_OK;
501*bffde63dSSheetal Tigadoli 
502*bffde63dSSheetal Tigadoli 	/* on reset, card's RCA should return to 0 */
503*bffde63dSSheetal Tigadoli 	handle->device->ctrl.rca = 0;
504*bffde63dSSheetal Tigadoli 
505*bffde63dSSheetal Tigadoli 	res = sd_cmd0(handle);
506*bffde63dSSheetal Tigadoli 
507*bffde63dSSheetal Tigadoli 	if (res != SD_OK)
508*bffde63dSSheetal Tigadoli 		return SD_RESET_ERROR;
509*bffde63dSSheetal Tigadoli 
510*bffde63dSSheetal Tigadoli 	return res;
511*bffde63dSSheetal Tigadoli }
512*bffde63dSSheetal Tigadoli 
513*bffde63dSSheetal Tigadoli 
514*bffde63dSSheetal Tigadoli /*
515*bffde63dSSheetal Tigadoli  * The function sends command to the card and starts
516*bffde63dSSheetal Tigadoli  * data transmission.
517*bffde63dSSheetal Tigadoli  */
518*bffde63dSSheetal Tigadoli static int xfer_data(struct sd_handle *handle,
519*bffde63dSSheetal Tigadoli 		     uint32_t mode,
520*bffde63dSSheetal Tigadoli 		     uint32_t addr, uint32_t length, uint8_t *base)
521*bffde63dSSheetal Tigadoli {
522*bffde63dSSheetal Tigadoli 	int rc = SD_OK;
523*bffde63dSSheetal Tigadoli 
524*bffde63dSSheetal Tigadoli 	VERBOSE("XFER: dest: 0x%llx, addr: 0x%x, size: 0x%x bytes\n",
525*bffde63dSSheetal Tigadoli 		(uint64_t)base, addr, length);
526*bffde63dSSheetal Tigadoli 
527*bffde63dSSheetal Tigadoli 	if ((length / handle->device->cfg.blockSize) > 1) {
528*bffde63dSSheetal Tigadoli 		if (mode == SD_OP_READ) {
529*bffde63dSSheetal Tigadoli 			inv_dcache_range((uintptr_t)base, (uint64_t)length);
530*bffde63dSSheetal Tigadoli 			rc = sd_cmd18(handle, addr, length, base);
531*bffde63dSSheetal Tigadoli 		} else {
532*bffde63dSSheetal Tigadoli #ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
533*bffde63dSSheetal Tigadoli 			flush_dcache_range((uintptr_t)base, (uint64_t)length);
534*bffde63dSSheetal Tigadoli 			rc = sd_cmd25(handle, addr, length, base);
535*bffde63dSSheetal Tigadoli #else
536*bffde63dSSheetal Tigadoli 			rc = SD_DATA_XFER_ERROR;
537*bffde63dSSheetal Tigadoli #endif
538*bffde63dSSheetal Tigadoli 		}
539*bffde63dSSheetal Tigadoli 	} else {
540*bffde63dSSheetal Tigadoli 		if (mode == SD_OP_READ) {
541*bffde63dSSheetal Tigadoli 			inv_dcache_range((uintptr_t)base, (uint64_t)length);
542*bffde63dSSheetal Tigadoli 			rc = sd_cmd17(handle, addr,
543*bffde63dSSheetal Tigadoli 				      handle->device->cfg.blockSize, base);
544*bffde63dSSheetal Tigadoli 		} else {
545*bffde63dSSheetal Tigadoli #ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
546*bffde63dSSheetal Tigadoli 			flush_dcache_range((uintptr_t)base, (uint64_t)length);
547*bffde63dSSheetal Tigadoli 			rc = sd_cmd24(handle, addr,
548*bffde63dSSheetal Tigadoli 				      handle->device->cfg.blockSize, base);
549*bffde63dSSheetal Tigadoli #else
550*bffde63dSSheetal Tigadoli 			rc = SD_DATA_XFER_ERROR;
551*bffde63dSSheetal Tigadoli #endif
552*bffde63dSSheetal Tigadoli 		}
553*bffde63dSSheetal Tigadoli 	}
554*bffde63dSSheetal Tigadoli 
555*bffde63dSSheetal Tigadoli 	if (rc != SD_OK)
556*bffde63dSSheetal Tigadoli 		return SD_DATA_XFER_ERROR;
557*bffde63dSSheetal Tigadoli 
558*bffde63dSSheetal Tigadoli 	return SD_OK;
559*bffde63dSSheetal Tigadoli }
560*bffde63dSSheetal Tigadoli 
561*bffde63dSSheetal Tigadoli #ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE
562*bffde63dSSheetal Tigadoli int erase_card(struct sd_handle *handle, uint32_t addr, uint32_t blocks)
563*bffde63dSSheetal Tigadoli {
564*bffde63dSSheetal Tigadoli 	uint32_t end_addr;
565*bffde63dSSheetal Tigadoli 
566*bffde63dSSheetal Tigadoli 	INFO("ERASE: addr: 0x%x, num of sectors: 0x%x\n", addr, blocks);
567*bffde63dSSheetal Tigadoli 
568*bffde63dSSheetal Tigadoli 	if (sd_cmd35(handle, addr) != SD_OK)
569*bffde63dSSheetal Tigadoli 		return SD_FAIL;
570*bffde63dSSheetal Tigadoli 
571*bffde63dSSheetal Tigadoli 	end_addr = addr + blocks - 1;
572*bffde63dSSheetal Tigadoli 	if (sd_cmd36(handle, end_addr) != SD_OK)
573*bffde63dSSheetal Tigadoli 		return SD_FAIL;
574*bffde63dSSheetal Tigadoli 
575*bffde63dSSheetal Tigadoli 	if (sd_cmd38(handle) != SD_OK)
576*bffde63dSSheetal Tigadoli 		return SD_FAIL;
577*bffde63dSSheetal Tigadoli 
578*bffde63dSSheetal Tigadoli 	return SD_OK;
579*bffde63dSSheetal Tigadoli }
580*bffde63dSSheetal Tigadoli #endif
581*bffde63dSSheetal Tigadoli 
582*bffde63dSSheetal Tigadoli /*
583*bffde63dSSheetal Tigadoli  * The function reads block data from a card.
584*bffde63dSSheetal Tigadoli  */
585*bffde63dSSheetal Tigadoli #ifdef USE_EMMC_FIP_TOC_CACHE
586*bffde63dSSheetal Tigadoli int read_block(struct sd_handle *handle,
587*bffde63dSSheetal Tigadoli 	       uint8_t *dst, uint32_t addr, uint32_t len)
588*bffde63dSSheetal Tigadoli {
589*bffde63dSSheetal Tigadoli 	int rel = SD_OK;
590*bffde63dSSheetal Tigadoli 
591*bffde63dSSheetal Tigadoli 	/*
592*bffde63dSSheetal Tigadoli 	 * Avoid doing repeated reads of the partition block
593*bffde63dSSheetal Tigadoli 	 * by caching.
594*bffde63dSSheetal Tigadoli 	 */
595*bffde63dSSheetal Tigadoli 	if (cached_partition_block &&
596*bffde63dSSheetal Tigadoli 	    addr == PARTITION_BLOCK_ADDR &&
597*bffde63dSSheetal Tigadoli 	    len == CACHE_SIZE) {
598*bffde63dSSheetal Tigadoli 		memcpy(dst, cached_block, len);
599*bffde63dSSheetal Tigadoli 	} else {
600*bffde63dSSheetal Tigadoli 		rel = xfer_data(handle, SD_OP_READ, addr, len, dst);
601*bffde63dSSheetal Tigadoli 
602*bffde63dSSheetal Tigadoli 		if (len == CACHE_SIZE && addr == PARTITION_BLOCK_ADDR) {
603*bffde63dSSheetal Tigadoli 			cached_partition_block = 1;
604*bffde63dSSheetal Tigadoli 			memcpy(cached_block, dst, len);
605*bffde63dSSheetal Tigadoli 		}
606*bffde63dSSheetal Tigadoli 	}
607*bffde63dSSheetal Tigadoli 
608*bffde63dSSheetal Tigadoli 	return rel;
609*bffde63dSSheetal Tigadoli }
610*bffde63dSSheetal Tigadoli #else
611*bffde63dSSheetal Tigadoli int read_block(struct sd_handle *handle,
612*bffde63dSSheetal Tigadoli 	       uint8_t *dst, uint32_t addr, uint32_t len)
613*bffde63dSSheetal Tigadoli {
614*bffde63dSSheetal Tigadoli 	return xfer_data(handle, SD_OP_READ, addr, len, dst);
615*bffde63dSSheetal Tigadoli }
616*bffde63dSSheetal Tigadoli #endif
617*bffde63dSSheetal Tigadoli 
618*bffde63dSSheetal Tigadoli #ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
619*bffde63dSSheetal Tigadoli 
620*bffde63dSSheetal Tigadoli /*
621*bffde63dSSheetal Tigadoli  * The function writes block data to a card.
622*bffde63dSSheetal Tigadoli  */
623*bffde63dSSheetal Tigadoli int write_block(struct sd_handle *handle,
624*bffde63dSSheetal Tigadoli 		uint8_t *src, uint32_t addr, uint32_t len)
625*bffde63dSSheetal Tigadoli {
626*bffde63dSSheetal Tigadoli 	int rel = SD_OK;
627*bffde63dSSheetal Tigadoli 
628*bffde63dSSheetal Tigadoli 	/*
629*bffde63dSSheetal Tigadoli 	 * Current HC has problem to get response of cmd16 after cmd12,
630*bffde63dSSheetal Tigadoli 	 * the delay is necessary to sure the next cmd16 will not be timed out.
631*bffde63dSSheetal Tigadoli 	 * The delay has to be at least 4 ms.
632*bffde63dSSheetal Tigadoli 	 * The code removed cmd16 and use cmd13 to get card status before
633*bffde63dSSheetal Tigadoli 	 * sending cmd18 or cmd25 to make sure the card is ready and thus
634*bffde63dSSheetal Tigadoli 	 * no need to have delay here.
635*bffde63dSSheetal Tigadoli 	 */
636*bffde63dSSheetal Tigadoli 
637*bffde63dSSheetal Tigadoli 	rel = xfer_data(handle, SD_OP_WRITE, addr, len, src);
638*bffde63dSSheetal Tigadoli 
639*bffde63dSSheetal Tigadoli 	EMMC_TRACE("wr_blk addr:0x%08X src:0x%08X len:0x%08X result:%d\n",
640*bffde63dSSheetal Tigadoli 		   addr, src, len, rel);
641*bffde63dSSheetal Tigadoli 
642*bffde63dSSheetal Tigadoli 	return rel;
643*bffde63dSSheetal Tigadoli }
644*bffde63dSSheetal Tigadoli 
645*bffde63dSSheetal Tigadoli 
646*bffde63dSSheetal Tigadoli /*
647*bffde63dSSheetal Tigadoli  * The function is called to write one block data directly to
648*bffde63dSSheetal Tigadoli  * a card's data buffer.
649*bffde63dSSheetal Tigadoli  * it is used in Non-DMA mode for card data transmission.
650*bffde63dSSheetal Tigadoli  */
651*bffde63dSSheetal Tigadoli int write_buffer(struct sd_handle *handle, uint32_t length, uint8_t *data)
652*bffde63dSSheetal Tigadoli {
653*bffde63dSSheetal Tigadoli 	uint32_t rem, blockSize, event;
654*bffde63dSSheetal Tigadoli 	uint8_t *pData = data;
655*bffde63dSSheetal Tigadoli 
656*bffde63dSSheetal Tigadoli 	blockSize = handle->device->cfg.blockSize;
657*bffde63dSSheetal Tigadoli 	rem = length;
658*bffde63dSSheetal Tigadoli 
659*bffde63dSSheetal Tigadoli 	if (rem == 0)
660*bffde63dSSheetal Tigadoli 		return SD_OK;
661*bffde63dSSheetal Tigadoli 
662*bffde63dSSheetal Tigadoli 	while (rem > 0) {
663*bffde63dSSheetal Tigadoli 
664*bffde63dSSheetal Tigadoli 		event = wait_for_event(handle,
665*bffde63dSSheetal Tigadoli 				       SD4_EMMC_TOP_INTR_BWRDY_MASK |
666*bffde63dSSheetal Tigadoli 				       SD_ERR_INTERRUPTS,
667*bffde63dSSheetal Tigadoli 				       handle->device->cfg.wfe_retry);
668*bffde63dSSheetal Tigadoli 
669*bffde63dSSheetal Tigadoli 		if (handle->device->ctrl.cmdStatus) {
670*bffde63dSSheetal Tigadoli 			check_error(handle, handle->device->ctrl.cmdStatus);
671*bffde63dSSheetal Tigadoli 			return SD_WRITE_ERROR;
672*bffde63dSSheetal Tigadoli 		}
673*bffde63dSSheetal Tigadoli 
674*bffde63dSSheetal Tigadoli 		if (rem >= blockSize)
675*bffde63dSSheetal Tigadoli 			chal_sd_write_buffer((CHAL_HANDLE *) handle->device,
676*bffde63dSSheetal Tigadoli 					     blockSize, pData);
677*bffde63dSSheetal Tigadoli 		else
678*bffde63dSSheetal Tigadoli 			chal_sd_write_buffer((CHAL_HANDLE *) handle->device,
679*bffde63dSSheetal Tigadoli 					     rem, pData);
680*bffde63dSSheetal Tigadoli 
681*bffde63dSSheetal Tigadoli 		if (rem > blockSize) {
682*bffde63dSSheetal Tigadoli 			rem -= blockSize;
683*bffde63dSSheetal Tigadoli 			pData += blockSize;
684*bffde63dSSheetal Tigadoli 		} else {
685*bffde63dSSheetal Tigadoli 			pData += rem;
686*bffde63dSSheetal Tigadoli 			rem = 0;
687*bffde63dSSheetal Tigadoli 		}
688*bffde63dSSheetal Tigadoli 	}
689*bffde63dSSheetal Tigadoli 
690*bffde63dSSheetal Tigadoli 	if ((event & SD4_EMMC_TOP_INTR_TXDONE_MASK) !=
691*bffde63dSSheetal Tigadoli 	    SD4_EMMC_TOP_INTR_TXDONE_MASK) {
692*bffde63dSSheetal Tigadoli 		event = wait_for_event(handle,
693*bffde63dSSheetal Tigadoli 				       SD4_EMMC_TOP_INTR_TXDONE_MASK |
694*bffde63dSSheetal Tigadoli 				       SD_ERR_INTERRUPTS,
695*bffde63dSSheetal Tigadoli 				       handle->device->cfg.wfe_retry);
696*bffde63dSSheetal Tigadoli 
697*bffde63dSSheetal Tigadoli 		if (handle->device->ctrl.cmdStatus != SD_OK) {
698*bffde63dSSheetal Tigadoli 			check_error(handle, handle->device->ctrl.cmdStatus);
699*bffde63dSSheetal Tigadoli 			return SD_WRITE_ERROR;
700*bffde63dSSheetal Tigadoli 		}
701*bffde63dSSheetal Tigadoli 	} else {
702*bffde63dSSheetal Tigadoli 		handle->device->ctrl.eventList &= ~SD4_EMMC_TOP_INTR_TXDONE_MASK;
703*bffde63dSSheetal Tigadoli 	}
704*bffde63dSSheetal Tigadoli 
705*bffde63dSSheetal Tigadoli 	return SD_OK;
706*bffde63dSSheetal Tigadoli }
707*bffde63dSSheetal Tigadoli #endif /* INCLUDE_EMMC_DRIVER_WRITE_CODE */
708*bffde63dSSheetal Tigadoli 
709*bffde63dSSheetal Tigadoli 
710*bffde63dSSheetal Tigadoli /*
711*bffde63dSSheetal Tigadoli  * The function is called to read maximal one block data
712*bffde63dSSheetal Tigadoli  * directly from a card
713*bffde63dSSheetal Tigadoli  * It is used in Non-DMA mode for card data transmission.
714*bffde63dSSheetal Tigadoli  */
715*bffde63dSSheetal Tigadoli int read_buffer(struct sd_handle *handle, uint32_t length, uint8_t *data)
716*bffde63dSSheetal Tigadoli {
717*bffde63dSSheetal Tigadoli 	uint32_t rem, blockSize, event = 0;
718*bffde63dSSheetal Tigadoli 	uint8_t *pData = data;
719*bffde63dSSheetal Tigadoli 
720*bffde63dSSheetal Tigadoli 	blockSize = handle->device->cfg.blockSize;
721*bffde63dSSheetal Tigadoli 	rem = length;
722*bffde63dSSheetal Tigadoli 
723*bffde63dSSheetal Tigadoli 	if (rem == 0)
724*bffde63dSSheetal Tigadoli 		return SD_OK;
725*bffde63dSSheetal Tigadoli 
726*bffde63dSSheetal Tigadoli 	while (rem > 0) {
727*bffde63dSSheetal Tigadoli 		event = wait_for_event(handle,
728*bffde63dSSheetal Tigadoli 				       SD4_EMMC_TOP_INTR_BRRDY_MASK |
729*bffde63dSSheetal Tigadoli 				       SD_ERR_INTERRUPTS,
730*bffde63dSSheetal Tigadoli 				       handle->device->cfg.wfe_retry);
731*bffde63dSSheetal Tigadoli 
732*bffde63dSSheetal Tigadoli 		if (handle->device->ctrl.cmdStatus) {
733*bffde63dSSheetal Tigadoli 			check_error(handle, handle->device->ctrl.cmdStatus);
734*bffde63dSSheetal Tigadoli 			return SD_READ_ERROR;
735*bffde63dSSheetal Tigadoli 		}
736*bffde63dSSheetal Tigadoli 
737*bffde63dSSheetal Tigadoli 		if (rem >= blockSize)
738*bffde63dSSheetal Tigadoli 			chal_sd_read_buffer((CHAL_HANDLE *) handle->device,
739*bffde63dSSheetal Tigadoli 					    blockSize, pData);
740*bffde63dSSheetal Tigadoli 		else
741*bffde63dSSheetal Tigadoli 			chal_sd_read_buffer((CHAL_HANDLE *) handle->device, rem,
742*bffde63dSSheetal Tigadoli 					    pData);
743*bffde63dSSheetal Tigadoli 
744*bffde63dSSheetal Tigadoli 		if (rem > blockSize) {
745*bffde63dSSheetal Tigadoli 			rem -= blockSize;
746*bffde63dSSheetal Tigadoli 			pData += blockSize;
747*bffde63dSSheetal Tigadoli 		} else {
748*bffde63dSSheetal Tigadoli 			pData += rem;
749*bffde63dSSheetal Tigadoli 			rem = 0;
750*bffde63dSSheetal Tigadoli 		}
751*bffde63dSSheetal Tigadoli 	}
752*bffde63dSSheetal Tigadoli 
753*bffde63dSSheetal Tigadoli 	/* In case, there are extra data in the SD FIFO, just dump them. */
754*bffde63dSSheetal Tigadoli 	chal_sd_dump_fifo((CHAL_HANDLE *) handle->device);
755*bffde63dSSheetal Tigadoli 
756*bffde63dSSheetal Tigadoli 	if ((event & SD4_EMMC_TOP_INTR_TXDONE_MASK) !=
757*bffde63dSSheetal Tigadoli 	    SD4_EMMC_TOP_INTR_TXDONE_MASK) {
758*bffde63dSSheetal Tigadoli 		event = wait_for_event(handle, SD4_EMMC_TOP_INTR_TXDONE_MASK,
759*bffde63dSSheetal Tigadoli 				       handle->device->cfg.wfe_retry);
760*bffde63dSSheetal Tigadoli 
761*bffde63dSSheetal Tigadoli 		if (handle->device->ctrl.cmdStatus) {
762*bffde63dSSheetal Tigadoli 			check_error(handle, handle->device->ctrl.cmdStatus);
763*bffde63dSSheetal Tigadoli 			return SD_READ_ERROR;
764*bffde63dSSheetal Tigadoli 		}
765*bffde63dSSheetal Tigadoli 	} else {
766*bffde63dSSheetal Tigadoli 		handle->device->ctrl.eventList &= ~SD4_EMMC_TOP_INTR_TXDONE_MASK;
767*bffde63dSSheetal Tigadoli 	}
768*bffde63dSSheetal Tigadoli 
769*bffde63dSSheetal Tigadoli 	return SD_OK;
770*bffde63dSSheetal Tigadoli }
771*bffde63dSSheetal Tigadoli 
772*bffde63dSSheetal Tigadoli 
773*bffde63dSSheetal Tigadoli /*
774*bffde63dSSheetal Tigadoli  * Error handling routine.
775*bffde63dSSheetal Tigadoli  * The function just reset the DAT
776*bffde63dSSheetal Tigadoli  * and CMD line if an error occures during data transmission.
777*bffde63dSSheetal Tigadoli  */
778*bffde63dSSheetal Tigadoli int check_error(struct sd_handle *handle, uint32_t ints)
779*bffde63dSSheetal Tigadoli {
780*bffde63dSSheetal Tigadoli 	uint32_t rel;
781*bffde63dSSheetal Tigadoli 
782*bffde63dSSheetal Tigadoli 	chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device,
783*bffde63dSSheetal Tigadoli 			       SD_ERR_INTERRUPTS, 0);
784*bffde63dSSheetal Tigadoli 
785*bffde63dSSheetal Tigadoli 	if (ints & SD4_EMMC_TOP_INTR_CMDERROR_MASK) {
786*bffde63dSSheetal Tigadoli 
787*bffde63dSSheetal Tigadoli 		chal_sd_reset_line((CHAL_HANDLE *) handle->device,
788*bffde63dSSheetal Tigadoli 				   SD4_EMMC_TOP_CTRL1_CMDRST_MASK);
789*bffde63dSSheetal Tigadoli 		rel = abort_err(handle);
790*bffde63dSSheetal Tigadoli 
791*bffde63dSSheetal Tigadoli 		chal_sd_reset_line((CHAL_HANDLE *) handle->device,
792*bffde63dSSheetal Tigadoli 				   SD4_EMMC_TOP_CTRL1_DATRST_MASK);
793*bffde63dSSheetal Tigadoli 		chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device,
794*bffde63dSSheetal Tigadoli 				       SD_ERR_INTERRUPTS, 1);
795*bffde63dSSheetal Tigadoli 
796*bffde63dSSheetal Tigadoli 		return (rel == SD_ERROR_NON_RECOVERABLE) ?
797*bffde63dSSheetal Tigadoli 				SD_ERROR_NON_RECOVERABLE : SD_ERROR_RECOVERABLE;
798*bffde63dSSheetal Tigadoli 	} else {
799*bffde63dSSheetal Tigadoli 		rel = err_recovery(handle, ints);
800*bffde63dSSheetal Tigadoli 	}
801*bffde63dSSheetal Tigadoli 
802*bffde63dSSheetal Tigadoli 	chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device,
803*bffde63dSSheetal Tigadoli 			       SD_ERR_INTERRUPTS, 1);
804*bffde63dSSheetal Tigadoli 
805*bffde63dSSheetal Tigadoli 	return rel;
806*bffde63dSSheetal Tigadoli }
807*bffde63dSSheetal Tigadoli 
808*bffde63dSSheetal Tigadoli 
809*bffde63dSSheetal Tigadoli /*
810*bffde63dSSheetal Tigadoli  * Error recovery routine.
811*bffde63dSSheetal Tigadoli  * Try to recover from the error.
812*bffde63dSSheetal Tigadoli  */
813*bffde63dSSheetal Tigadoli static int err_recovery(struct sd_handle *handle, uint32_t errors)
814*bffde63dSSheetal Tigadoli {
815*bffde63dSSheetal Tigadoli 	uint32_t rel = 0;
816*bffde63dSSheetal Tigadoli 
817*bffde63dSSheetal Tigadoli 	/*
818*bffde63dSSheetal Tigadoli 	 * In case of timeout error, the cmd line and data line maybe
819*bffde63dSSheetal Tigadoli 	 * still active or stuck at atcitve so it is needed to reset
820*bffde63dSSheetal Tigadoli 	 * either data line or cmd line to make sure a new cmd can be sent.
821*bffde63dSSheetal Tigadoli 	 */
822*bffde63dSSheetal Tigadoli 
823*bffde63dSSheetal Tigadoli 	if (errors & SD_CMD_ERROR_INT)
824*bffde63dSSheetal Tigadoli 		chal_sd_reset_line((CHAL_HANDLE *) handle->device,
825*bffde63dSSheetal Tigadoli 				   SD4_EMMC_TOP_CTRL1_CMDRST_MASK);
826*bffde63dSSheetal Tigadoli 
827*bffde63dSSheetal Tigadoli 	if (errors & SD_DAT_ERROR_INT)
828*bffde63dSSheetal Tigadoli 		chal_sd_reset_line((CHAL_HANDLE *) handle->device,
829*bffde63dSSheetal Tigadoli 				   SD4_EMMC_TOP_CTRL1_DATRST_MASK);
830*bffde63dSSheetal Tigadoli 
831*bffde63dSSheetal Tigadoli 	/* Abort transaction by sending out stop command */
832*bffde63dSSheetal Tigadoli 	if ((handle->device->ctrl.cmdIndex == 18) ||
833*bffde63dSSheetal Tigadoli 	    (handle->device->ctrl.cmdIndex == 25))
834*bffde63dSSheetal Tigadoli 		rel = abort_err(handle);
835*bffde63dSSheetal Tigadoli 
836*bffde63dSSheetal Tigadoli 	return rel;
837*bffde63dSSheetal Tigadoli }
838*bffde63dSSheetal Tigadoli 
839*bffde63dSSheetal Tigadoli 
840*bffde63dSSheetal Tigadoli /*
841*bffde63dSSheetal Tigadoli  * The function is called to read one block data directly from a card.
842*bffde63dSSheetal Tigadoli  * It is used in Non-DMA mode for card data transmission.
843*bffde63dSSheetal Tigadoli  */
844*bffde63dSSheetal Tigadoli int process_cmd_response(struct sd_handle *handle,
845*bffde63dSSheetal Tigadoli 			 uint32_t cmdIndex,
846*bffde63dSSheetal Tigadoli 			 uint32_t rsp0,
847*bffde63dSSheetal Tigadoli 			 uint32_t rsp1,
848*bffde63dSSheetal Tigadoli 			 uint32_t rsp2, uint32_t rsp3, struct sd_resp *resp)
849*bffde63dSSheetal Tigadoli {
850*bffde63dSSheetal Tigadoli 	int result = SD_OK;
851*bffde63dSSheetal Tigadoli 
852*bffde63dSSheetal Tigadoli 	/* R6 */
853*bffde63dSSheetal Tigadoli 	uint32_t rca = (rsp0 >> 16) & 0xffff;
854*bffde63dSSheetal Tigadoli 	uint32_t cardStatus = rsp0;
855*bffde63dSSheetal Tigadoli 
856*bffde63dSSheetal Tigadoli 	/* R4 */
857*bffde63dSSheetal Tigadoli 	uint32_t cBit = (rsp0 >> 31) & 0x1;
858*bffde63dSSheetal Tigadoli 	uint32_t funcs = (rsp0 >> 28) & 0x7;
859*bffde63dSSheetal Tigadoli 	uint32_t memPresent = (rsp0 >> 27) & 0x1;
860*bffde63dSSheetal Tigadoli 
861*bffde63dSSheetal Tigadoli 	resp->r1 = 0x3f;
862*bffde63dSSheetal Tigadoli 	resp->cardStatus = cardStatus;
863*bffde63dSSheetal Tigadoli 
864*bffde63dSSheetal Tigadoli 	if (cmdIndex == SD_CMD_IO_SEND_OP_COND) {
865*bffde63dSSheetal Tigadoli 		resp->data.r4.cardReady = cBit;
866*bffde63dSSheetal Tigadoli 		resp->data.r4.funcs = funcs;
867*bffde63dSSheetal Tigadoli 		resp->data.r4.memPresent = memPresent;
868*bffde63dSSheetal Tigadoli 		resp->data.r4.ocr = cardStatus;
869*bffde63dSSheetal Tigadoli 	}
870*bffde63dSSheetal Tigadoli 
871*bffde63dSSheetal Tigadoli 	if (cmdIndex == SD_CMD_MMC_SET_RCA) {
872*bffde63dSSheetal Tigadoli 		resp->data.r6.rca = rca;
873*bffde63dSSheetal Tigadoli 		resp->data.r6.cardStatus = cardStatus & 0xFFFF;
874*bffde63dSSheetal Tigadoli 	}
875*bffde63dSSheetal Tigadoli 
876*bffde63dSSheetal Tigadoli 	if (cmdIndex == SD_CMD_SELECT_DESELECT_CARD) {
877*bffde63dSSheetal Tigadoli 		resp->data.r7.rca = rca;
878*bffde63dSSheetal Tigadoli 	}
879*bffde63dSSheetal Tigadoli 
880*bffde63dSSheetal Tigadoli 	if (cmdIndex == SD_CMD_IO_RW_DIRECT) {
881*bffde63dSSheetal Tigadoli 		if (((rsp0 >> 16) & 0xffff) != 0)
882*bffde63dSSheetal Tigadoli 			result = SD_CMD_ERR_INVALID_RESPONSE;
883*bffde63dSSheetal Tigadoli 
884*bffde63dSSheetal Tigadoli 		resp->data.r5.data = rsp0 & 0xff;
885*bffde63dSSheetal Tigadoli 	}
886*bffde63dSSheetal Tigadoli 
887*bffde63dSSheetal Tigadoli 	if (cmdIndex == SD_CMD_IO_RW_EXTENDED) {
888*bffde63dSSheetal Tigadoli 		if (((rsp0 >> 16) & 0xffff) != 0)
889*bffde63dSSheetal Tigadoli 			result = SD_CMD_ERR_INVALID_RESPONSE;
890*bffde63dSSheetal Tigadoli 
891*bffde63dSSheetal Tigadoli 		resp->data.r5.data = rsp0 & 0xff;
892*bffde63dSSheetal Tigadoli 	}
893*bffde63dSSheetal Tigadoli 
894*bffde63dSSheetal Tigadoli 	if (cmdIndex == SD_ACMD_SD_SEND_OP_COND ||
895*bffde63dSSheetal Tigadoli 	    cmdIndex == SD_CMD_SEND_OPCOND)
896*bffde63dSSheetal Tigadoli 		resp->data.r3.ocr = cardStatus;
897*bffde63dSSheetal Tigadoli 
898*bffde63dSSheetal Tigadoli 	if (cmdIndex == SD_CMD_SEND_CSD ||
899*bffde63dSSheetal Tigadoli 	    cmdIndex == SD_CMD_SEND_CID ||
900*bffde63dSSheetal Tigadoli 	    cmdIndex == SD_CMD_ALL_SEND_CID) {
901*bffde63dSSheetal Tigadoli 		resp->data.r2.rsp4 = rsp3;
902*bffde63dSSheetal Tigadoli 		resp->data.r2.rsp3 = rsp2;
903*bffde63dSSheetal Tigadoli 		resp->data.r2.rsp2 = rsp1;
904*bffde63dSSheetal Tigadoli 		resp->data.r2.rsp1 = rsp0;
905*bffde63dSSheetal Tigadoli 	}
906*bffde63dSSheetal Tigadoli 
907*bffde63dSSheetal Tigadoli 	if ((cmdIndex == SD_CMD_READ_EXT_CSD) &&
908*bffde63dSSheetal Tigadoli 	    (handle->card->type == SD_CARD_SD)) {
909*bffde63dSSheetal Tigadoli 		if ((resp->cardStatus & 0xAA) != 0xAA) {
910*bffde63dSSheetal Tigadoli 			result = SD_CMD_ERR_INVALID_RESPONSE;
911*bffde63dSSheetal Tigadoli 		}
912*bffde63dSSheetal Tigadoli 	}
913*bffde63dSSheetal Tigadoli 
914*bffde63dSSheetal Tigadoli 	return result;
915*bffde63dSSheetal Tigadoli }
916*bffde63dSSheetal Tigadoli 
917*bffde63dSSheetal Tigadoli 
918*bffde63dSSheetal Tigadoli /*
919*bffde63dSSheetal Tigadoli  * The function sets DMA buffer and data length, process
920*bffde63dSSheetal Tigadoli  * block size and the number of blocks to be transferred.
921*bffde63dSSheetal Tigadoli  * It returns the DMA buffer address.
922*bffde63dSSheetal Tigadoli  * It copies dma data from user buffer to the DMA buffer
923*bffde63dSSheetal Tigadoli  * if the operation is to write data to the SD card.
924*bffde63dSSheetal Tigadoli  */
925*bffde63dSSheetal Tigadoli void data_xfer_setup(struct sd_handle *handle, uint8_t *data, uint32_t length,
926*bffde63dSSheetal Tigadoli 		     int dir)
927*bffde63dSSheetal Tigadoli {
928*bffde63dSSheetal Tigadoli 	chal_sd_setup_xfer((CHAL_HANDLE *)handle->device, data, length, dir);
929*bffde63dSSheetal Tigadoli }
930*bffde63dSSheetal Tigadoli 
931*bffde63dSSheetal Tigadoli 
932*bffde63dSSheetal Tigadoli /*
933*bffde63dSSheetal Tigadoli  * The function does soft reset the host SD controller. After
934*bffde63dSSheetal Tigadoli  * the function call all host controller's register are reset
935*bffde63dSSheetal Tigadoli  * to default vallue;
936*bffde63dSSheetal Tigadoli  *
937*bffde63dSSheetal Tigadoli  * Note    This function only resets the host controller it does not
938*bffde63dSSheetal Tigadoli  *          reset the controller's handler.
939*bffde63dSSheetal Tigadoli  */
940*bffde63dSSheetal Tigadoli int reset_host_ctrl(struct sd_handle *handle)
941*bffde63dSSheetal Tigadoli {
942*bffde63dSSheetal Tigadoli 	chal_sd_stop();
943*bffde63dSSheetal Tigadoli 
944*bffde63dSSheetal Tigadoli 	return SD_OK;
945*bffde63dSSheetal Tigadoli }
946*bffde63dSSheetal Tigadoli 
947*bffde63dSSheetal Tigadoli static void pstate_log(struct sd_handle *handle)
948*bffde63dSSheetal Tigadoli {
949*bffde63dSSheetal Tigadoli 	ERROR("PSTATE: 0x%x\n", mmio_read_32
950*bffde63dSSheetal Tigadoli 		(handle->device->ctrl.sdRegBaseAddr +
951*bffde63dSSheetal Tigadoli 			SD4_EMMC_TOP_PSTATE_SD4_OFFSET));
952*bffde63dSSheetal Tigadoli 	ERROR("ERRSTAT: 0x%x\n", mmio_read_32
953*bffde63dSSheetal Tigadoli 		(handle->device->ctrl.sdRegBaseAddr +
954*bffde63dSSheetal Tigadoli 			SD4_EMMC_TOP_ERRSTAT_OFFSET));
955*bffde63dSSheetal Tigadoli }
956*bffde63dSSheetal Tigadoli 
957*bffde63dSSheetal Tigadoli /*
958*bffde63dSSheetal Tigadoli  * The function waits for one or a group of interrupts specified
959*bffde63dSSheetal Tigadoli  * by mask. The function returns if any one the interrupt status
960*bffde63dSSheetal Tigadoli  * is set. If interrupt mode is not enabled then it will poll
961*bffde63dSSheetal Tigadoli  * the interrupt status register until a interrupt status is set
962*bffde63dSSheetal Tigadoli  * an error interrupt happens. If interrupt mode is enabled then
963*bffde63dSSheetal Tigadoli  * this function should be called after the interrupt
964*bffde63dSSheetal Tigadoli  * is received by ISR routine.
965*bffde63dSSheetal Tigadoli  */
966*bffde63dSSheetal Tigadoli uint32_t wait_for_event(struct sd_handle *handle,
967*bffde63dSSheetal Tigadoli 			uint32_t mask, uint32_t retry)
968*bffde63dSSheetal Tigadoli {
969*bffde63dSSheetal Tigadoli 	uint32_t regval, cmd12, time = 0;
970*bffde63dSSheetal Tigadoli 
971*bffde63dSSheetal Tigadoli 	handle->device->ctrl.cmdStatus = 0;	/* no error */
972*bffde63dSSheetal Tigadoli 	EMMC_TRACE("%s %d mask:0x%x timeout:%d irq_status:0x%x\n",
973*bffde63dSSheetal Tigadoli 		   __func__, __LINE__, mask, retry,
974*bffde63dSSheetal Tigadoli 		   chal_sd_get_irq_status((CHAL_HANDLE *)handle->device));
975*bffde63dSSheetal Tigadoli 
976*bffde63dSSheetal Tigadoli 	/* Polling mode */
977*bffde63dSSheetal Tigadoli 	do {
978*bffde63dSSheetal Tigadoli 		regval = chal_sd_get_irq_status((CHAL_HANDLE *)handle->device);
979*bffde63dSSheetal Tigadoli 
980*bffde63dSSheetal Tigadoli 		if (regval & SD4_EMMC_TOP_INTR_DMAIRQ_MASK) {
981*bffde63dSSheetal Tigadoli 			chal_sd_set_dma_addr((CHAL_HANDLE *)handle->device,
982*bffde63dSSheetal Tigadoli 					(uintptr_t)
983*bffde63dSSheetal Tigadoli 				chal_sd_get_dma_addr((CHAL_HANDLE *)
984*bffde63dSSheetal Tigadoli 						handle->device));
985*bffde63dSSheetal Tigadoli 			chal_sd_clear_irq((CHAL_HANDLE *)handle->device,
986*bffde63dSSheetal Tigadoli 					  SD4_EMMC_TOP_INTR_DMAIRQ_MASK);
987*bffde63dSSheetal Tigadoli 		}
988*bffde63dSSheetal Tigadoli 
989*bffde63dSSheetal Tigadoli 		if (time++ > retry) {
990*bffde63dSSheetal Tigadoli 			ERROR("EMMC: No response (cmd%d) after %dus.\n",
991*bffde63dSSheetal Tigadoli 			      handle->device->ctrl.cmdIndex,
992*bffde63dSSheetal Tigadoli 			      time * EMMC_WFE_RETRY_DELAY_US);
993*bffde63dSSheetal Tigadoli 			handle->device->ctrl.cmdStatus = SD_CMD_MISSING;
994*bffde63dSSheetal Tigadoli 			pstate_log(handle);
995*bffde63dSSheetal Tigadoli 			ERROR("EMMC: INT[0x%x]\n", regval);
996*bffde63dSSheetal Tigadoli 			break;
997*bffde63dSSheetal Tigadoli 		}
998*bffde63dSSheetal Tigadoli 
999*bffde63dSSheetal Tigadoli 		if (regval & SD4_EMMC_TOP_INTR_CTOERR_MASK) {
1000*bffde63dSSheetal Tigadoli 			ERROR("EMMC: Cmd%d timeout INT[0x%x]\n",
1001*bffde63dSSheetal Tigadoli 			      handle->device->ctrl.cmdIndex, regval);
1002*bffde63dSSheetal Tigadoli 			handle->device->ctrl.cmdStatus =
1003*bffde63dSSheetal Tigadoli 			    SD4_EMMC_TOP_INTR_CTOERR_MASK;
1004*bffde63dSSheetal Tigadoli 			pstate_log(handle);
1005*bffde63dSSheetal Tigadoli 			break;
1006*bffde63dSSheetal Tigadoli 		}
1007*bffde63dSSheetal Tigadoli 		if (regval & SD_CMD_ERROR_FLAGS) {
1008*bffde63dSSheetal Tigadoli 			ERROR("EMMC: Cmd%d error INT[0x%x]\n",
1009*bffde63dSSheetal Tigadoli 			      handle->device->ctrl.cmdIndex, regval);
1010*bffde63dSSheetal Tigadoli 			handle->device->ctrl.cmdStatus = SD_CMD_ERROR_FLAGS;
1011*bffde63dSSheetal Tigadoli 			pstate_log(handle);
1012*bffde63dSSheetal Tigadoli 			break;
1013*bffde63dSSheetal Tigadoli 		}
1014*bffde63dSSheetal Tigadoli 
1015*bffde63dSSheetal Tigadoli 		cmd12 = chal_sd_get_atuo12_error((CHAL_HANDLE *)handle->device);
1016*bffde63dSSheetal Tigadoli 		if (cmd12) {
1017*bffde63dSSheetal Tigadoli 			ERROR("EMMC: Cmd%d auto cmd12 err:0x%x\n",
1018*bffde63dSSheetal Tigadoli 			      handle->device->ctrl.cmdIndex, cmd12);
1019*bffde63dSSheetal Tigadoli 			handle->device->ctrl.cmdStatus = cmd12;
1020*bffde63dSSheetal Tigadoli 			pstate_log(handle);
1021*bffde63dSSheetal Tigadoli 			break;
1022*bffde63dSSheetal Tigadoli 		}
1023*bffde63dSSheetal Tigadoli 
1024*bffde63dSSheetal Tigadoli 		if (SD_DATA_ERROR_FLAGS & regval) {
1025*bffde63dSSheetal Tigadoli 			ERROR("EMMC: Data for cmd%d error, INT[0x%x]\n",
1026*bffde63dSSheetal Tigadoli 			      handle->device->ctrl.cmdIndex, regval);
1027*bffde63dSSheetal Tigadoli 			handle->device->ctrl.cmdStatus =
1028*bffde63dSSheetal Tigadoli 			    (SD_DATA_ERROR_FLAGS & regval);
1029*bffde63dSSheetal Tigadoli 			pstate_log(handle);
1030*bffde63dSSheetal Tigadoli 			break;
1031*bffde63dSSheetal Tigadoli 		}
1032*bffde63dSSheetal Tigadoli 
1033*bffde63dSSheetal Tigadoli 		if ((regval & mask) == 0)
1034*bffde63dSSheetal Tigadoli 			udelay(EMMC_WFE_RETRY_DELAY_US);
1035*bffde63dSSheetal Tigadoli 
1036*bffde63dSSheetal Tigadoli 	} while ((regval & mask) == 0);
1037*bffde63dSSheetal Tigadoli 
1038*bffde63dSSheetal Tigadoli 	/* clear the interrupt since it is processed */
1039*bffde63dSSheetal Tigadoli 	chal_sd_clear_irq((CHAL_HANDLE *)handle->device, (regval & mask));
1040*bffde63dSSheetal Tigadoli 
1041*bffde63dSSheetal Tigadoli 	return (regval & mask);
1042*bffde63dSSheetal Tigadoli }
1043*bffde63dSSheetal Tigadoli 
1044*bffde63dSSheetal Tigadoli int32_t set_config(struct sd_handle *handle, uint32_t speed, uint32_t retry,
1045*bffde63dSSheetal Tigadoli 		    uint32_t dma, uint32_t dmaBound, uint32_t blkSize,
1046*bffde63dSSheetal Tigadoli 		    uint32_t wfe_retry)
1047*bffde63dSSheetal Tigadoli {
1048*bffde63dSSheetal Tigadoli 	int32_t rel = 0;
1049*bffde63dSSheetal Tigadoli 
1050*bffde63dSSheetal Tigadoli 	if (handle == NULL)
1051*bffde63dSSheetal Tigadoli 		return SD_FAIL;
1052*bffde63dSSheetal Tigadoli 
1053*bffde63dSSheetal Tigadoli 	handle->device->cfg.wfe_retry = wfe_retry;
1054*bffde63dSSheetal Tigadoli 
1055*bffde63dSSheetal Tigadoli 	rel = chal_sd_config((CHAL_HANDLE *)handle->device, speed, retry,
1056*bffde63dSSheetal Tigadoli 			     dmaBound, blkSize, dma);
1057*bffde63dSSheetal Tigadoli 	return rel;
1058*bffde63dSSheetal Tigadoli 
1059*bffde63dSSheetal Tigadoli }
1060*bffde63dSSheetal Tigadoli 
1061*bffde63dSSheetal Tigadoli int mmc_cmd1(struct sd_handle *handle)
1062*bffde63dSSheetal Tigadoli {
1063*bffde63dSSheetal Tigadoli 	uint32_t newOcr, res;
1064*bffde63dSSheetal Tigadoli 	uint32_t cmd1_option = MMC_OCR_OP_VOLT | MMC_OCR_SECTOR_ACCESS_MODE;
1065*bffde63dSSheetal Tigadoli 
1066*bffde63dSSheetal Tigadoli 	/*
1067*bffde63dSSheetal Tigadoli 	 * After Reset, eMMC comes up in 1 Bit Data Width by default.
1068*bffde63dSSheetal Tigadoli 	 * Set host side to match.
1069*bffde63dSSheetal Tigadoli 	 */
1070*bffde63dSSheetal Tigadoli 	chal_sd_config_bus_width((CHAL_HANDLE *) handle->device,
1071*bffde63dSSheetal Tigadoli 				 SD_BUS_DATA_WIDTH_1BIT);
1072*bffde63dSSheetal Tigadoli 
1073*bffde63dSSheetal Tigadoli #ifdef USE_EMMC_FIP_TOC_CACHE
1074*bffde63dSSheetal Tigadoli 	cached_partition_block = 0;
1075*bffde63dSSheetal Tigadoli #endif
1076*bffde63dSSheetal Tigadoli 	handle->device->ctrl.present = 0; /* init card present to be no card */
1077*bffde63dSSheetal Tigadoli 
1078*bffde63dSSheetal Tigadoli 	handle->card->type = SD_CARD_MMC;
1079*bffde63dSSheetal Tigadoli 
1080*bffde63dSSheetal Tigadoli 	res = sd_cmd1(handle, cmd1_option, &newOcr);
1081*bffde63dSSheetal Tigadoli 
1082*bffde63dSSheetal Tigadoli 	if (res != SD_OK) {
1083*bffde63dSSheetal Tigadoli 		EMMC_TRACE("CMD1 Timeout: Device is not ready\n");
1084*bffde63dSSheetal Tigadoli 		res = SD_CARD_UNKNOWN;
1085*bffde63dSSheetal Tigadoli 	}
1086*bffde63dSSheetal Tigadoli 	return res;
1087*bffde63dSSheetal Tigadoli }
1088