blob: d255bffc9fc56c7dae67edca483ff10c116377d3 [file] [log] [blame]
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +02001/*
Biju Das08d33082020-12-13 19:41:27 +00002 * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00007#include <common/debug.h>
8
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +02009#include "emmc_config.h"
Biju Das08d33082020-12-13 19:41:27 +000010#include "emmc_def.h"
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +020011#include "emmc_hal.h"
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +020012#include "emmc_registers.h"
Biju Das08d33082020-12-13 19:41:27 +000013#include "emmc_std.h"
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +020014#include "micro_delay.h"
15
16static void emmc_little_to_big(uint8_t *p, uint32_t value)
17{
18 if (p == NULL)
19 return;
20
21 p[0] = (uint8_t) (value >> 24);
22 p[1] = (uint8_t) (value >> 16);
23 p[2] = (uint8_t) (value >> 8);
24 p[3] = (uint8_t) value;
Biju Das08d33082020-12-13 19:41:27 +000025
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +020026}
27
28static void emmc_softreset(void)
29{
30 int32_t loop = 10000;
31 int32_t retry = 1000;
32
33 /* flag clear */
34 mmc_drv_obj.during_cmd_processing = FALSE;
35 mmc_drv_obj.during_transfer = FALSE;
36 mmc_drv_obj.during_dma_transfer = FALSE;
37 mmc_drv_obj.state_machine_blocking = FALSE;
38 mmc_drv_obj.force_terminate = FALSE;
39 mmc_drv_obj.dma_error_flag = FALSE;
40
41 /* during operation ? */
42 if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) == 0)
43 goto reset;
44
45 /* wait CMDSEQ = 0 */
46 while (loop > 0) {
47 if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) == 0)
48 break; /* ready */
49
50 loop--;
51 if ((loop == 0) && (retry > 0)) {
52 rcar_micro_delay(1000U); /* wait 1ms */
53 loop = 10000;
54 retry--;
55 }
56 }
57
58reset:
59 /* reset */
60 SETR_32(SOFT_RST, (GETR_32(SOFT_RST) & (~SOFT_RST_SDRST)));
61 SETR_32(SOFT_RST, (GETR_32(SOFT_RST) | SOFT_RST_SDRST));
62
63 /* initialize */
64 SETR_32(SD_INFO1, 0x00000000U);
65 SETR_32(SD_INFO2, SD_INFO2_CLEAR);
66 SETR_32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */
67 SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +020068}
69
70static void emmc_read_response(uint32_t *response)
71{
72 uint8_t *p;
73
74 if (response == NULL)
75 return;
76
77 /* read response */
78 if (mmc_drv_obj.response_length != EMMC_MAX_RESPONSE_LENGTH) {
79 *response = GETR_32(SD_RSP10); /* [39:8] */
80 return;
81 }
82
83 /* CSD or CID */
84 p = (uint8_t *) (response);
85 emmc_little_to_big(p, ((GETR_32(SD_RSP76) << 8)
86 | (GETR_32(SD_RSP54) >> 24))); /* [127:96] */
87 emmc_little_to_big(p + 4, ((GETR_32(SD_RSP54) << 8)
88 | (GETR_32(SD_RSP32) >> 24))); /* [95:64] */
89 emmc_little_to_big(p + 8, ((GETR_32(SD_RSP32) << 8)
90 | (GETR_32(SD_RSP10) >> 24))); /* [63:32] */
91 emmc_little_to_big(p + 12, (GETR_32(SD_RSP10) << 8));
92}
93
94static EMMC_ERROR_CODE emmc_response_check(uint32_t *response,
95 uint32_t error_mask)
96{
97
98 HAL_MEMCARD_RESPONSE_TYPE response_type =
Biju Das08d33082020-12-13 19:41:27 +000099 ((HAL_MEMCARD_RESPONSE_TYPE)mmc_drv_obj.cmd_info.cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK);
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200100
101 if (response == NULL)
102 return EMMC_ERR_PARAM;
103
104 if (response_type == HAL_MEMCARD_RESPONSE_NONE)
105 return EMMC_SUCCESS;
106
107
108 if (response_type <= HAL_MEMCARD_RESPONSE_R1b) {
109 /* R1 or R1b */
110 mmc_drv_obj.current_state =
111 (EMMC_R1_STATE) ((*response & EMMC_R1_STATE_MASK) >>
112 EMMC_R1_STATE_SHIFT);
113 if ((*response & error_mask) != 0) {
114 if ((0x80 & *response) != 0) {
115 ERROR("BL2: emmc SWITCH_ERROR\n");
116 }
117 return EMMC_ERR_CARD_STATUS_BIT;
118 }
Biju Das08d33082020-12-13 19:41:27 +0000119 return EMMC_SUCCESS;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200120 }
121
122 if (response_type == HAL_MEMCARD_RESPONSE_R4) {
123 if ((*response & EMMC_R4_STATUS) != 0)
124 return EMMC_ERR_CARD_STATUS_BIT;
125 }
126
127 return EMMC_SUCCESS;
128}
129
130static void emmc_WaitCmd2Cmd_8Cycle(void)
131{
132 uint32_t dataL, wait = 0;
133
134 dataL = GETR_32(SD_CLK_CTRL);
135 dataL &= 0x000000FF;
136
137 switch (dataL) {
138 case 0xFF:
139 case 0x00:
140 case 0x01:
141 case 0x02:
142 case 0x04:
143 case 0x08:
144 case 0x10:
145 case 0x20:
146 wait = 10U;
147 break;
148 case 0x40:
149 wait = 20U;
150 break;
151 case 0x80:
152 wait = 30U;
153 break;
154 }
155
156 rcar_micro_delay(wait);
157}
158
159static void cmdErrSdInfo2Log(void)
160{
161 ERROR("BL2: emmc ERR SD_INFO2 = 0x%x\n", mmc_drv_obj.error_info.info2);
162}
163
164static void emmc_data_transfer_dma(void)
165{
166 mmc_drv_obj.during_dma_transfer = TRUE;
167 mmc_drv_obj.dma_error_flag = FALSE;
168
169 SETR_32(SD_INFO1_MASK, 0x00000000U);
170 SETR_32(SD_INFO2_MASK, (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));
171
172 /* DMAC setting */
173 if (mmc_drv_obj.cmd_info.dir == HAL_MEMCARD_WRITE) {
174 /* transfer complete interrupt enable */
175 SETR_32(DM_CM_INFO1_MASK,
176 (DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH0_ENABLE));
177 SETR_32(DM_CM_INFO2_MASK,
178 (DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH0_ENABLE));
179 /* BUFF --> FIFO */
180 SETR_32(DM_CM_DTRAN_MODE, (DM_CM_DTRAN_MODE_CH0 |
181 DM_CM_DTRAN_MODE_BIT_WIDTH));
182 } else {
183 /* transfer complete interrupt enable */
184 SETR_32(DM_CM_INFO1_MASK,
185 (DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH1_ENABLE));
186 SETR_32(DM_CM_INFO2_MASK,
187 (DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH1_ENABLE));
188 /* FIFO --> BUFF */
189 SETR_32(DM_CM_DTRAN_MODE, (DM_CM_DTRAN_MODE_CH1
190 | DM_CM_DTRAN_MODE_BIT_WIDTH));
191 }
192 SETR_32(DM_DTRAN_ADDR, (((uintptr_t) mmc_drv_obj.buff_address_virtual &
193 DM_DTRAN_ADDR_WRITE_MASK)));
194
195 SETR_32(DM_CM_DTRAN_CTRL, DM_CM_DTRAN_CTRL_START);
196}
197
198EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response)
199{
200 EMMC_ERROR_CODE rtn_code = EMMC_SUCCESS;
201 HAL_MEMCARD_RESPONSE_TYPE response_type;
202 HAL_MEMCARD_COMMAND_TYPE cmd_type;
203 EMMC_INT_STATE state;
204 uint32_t err_not_care_flag = FALSE;
205
206 /* parameter check */
207 if (response == NULL) {
208 emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR_PARAM);
209 return EMMC_ERR_PARAM;
210 }
211
212 /* state check */
213 if (mmc_drv_obj.clock_enable != TRUE) {
214 emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR_STATE);
215 return EMMC_ERR_STATE;
216 }
217
218 if (mmc_drv_obj.state_machine_blocking == TRUE) {
219 emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR);
220 return EMMC_ERR;
221 }
222
223 state = ESTATE_BEGIN;
224 response_type =
Biju Das08d33082020-12-13 19:41:27 +0000225 ((HAL_MEMCARD_RESPONSE_TYPE)mmc_drv_obj.cmd_info.cmd &
226 HAL_MEMCARD_RESPONSE_TYPE_MASK);
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200227 cmd_type =
Biju Das08d33082020-12-13 19:41:27 +0000228 ((HAL_MEMCARD_COMMAND_TYPE) mmc_drv_obj.cmd_info.cmd &
229 HAL_MEMCARD_COMMAND_TYPE_MASK);
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200230
231 /* state machine */
232 while ((mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END)) {
233 /* The interrupt factor flag is observed. */
234 emmc_interrupt();
235
236 /* wait interrupt */
237 if (mmc_drv_obj.state_machine_blocking == TRUE)
238 continue;
239
240 switch (state) {
241 case ESTATE_BEGIN:
242 /* Busy check */
243 if ((mmc_drv_obj.error_info.info2 & SD_INFO2_CBSY) != 0) {
244 emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD,
245 EMMC_ERR_CARD_BUSY);
246 return EMMC_ERR_CARD_BUSY;
247 }
248
249 /* clear register */
250 SETR_32(SD_INFO1, 0x00000000U);
251 SETR_32(SD_INFO2, SD_INFO2_CLEAR);
252 SETR_32(SD_INFO1_MASK, SD_INFO1_INFO0);
253 SETR_32(SD_INFO2_MASK,
254 (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));
255
256 state = ESTATE_ISSUE_CMD;
257 /* through */
258
259 case ESTATE_ISSUE_CMD:
260 /* ARG */
261 SETR_32(SD_ARG, mmc_drv_obj.cmd_info.arg);
262 /* issue cmd */
263 SETR_32(SD_CMD, mmc_drv_obj.cmd_info.hw);
264 /* Set driver flag */
265 mmc_drv_obj.during_cmd_processing = TRUE;
266 mmc_drv_obj.state_machine_blocking = TRUE;
267
268 if (response_type == HAL_MEMCARD_RESPONSE_NONE) {
269 state = ESTATE_NON_RESP_CMD;
270 } else {
271 state = ESTATE_RCV_RESP;
272 }
273
274 break;
275
276 case ESTATE_NON_RESP_CMD:
277 /* interrupt disable */
278 SETR_32(SD_INFO1_MASK, 0x00000000U);
279 SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR);
280
281 /* check interrupt */
282 if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) {
283 /* error interrupt */
284 cmdErrSdInfo2Log();
285 rtn_code = EMMC_ERR_INFO2;
286 state = ESTATE_ERROR;
287 } else if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO0) ==
288 0) {
289 /* not receive expected interrupt */
290 rtn_code = EMMC_ERR_RESPONSE;
291 state = ESTATE_ERROR;
292 } else {
293 emmc_WaitCmd2Cmd_8Cycle();
294 state = ESTATE_END;
295 }
296 break;
297
298 case ESTATE_RCV_RESP:
299 /* interrupt disable */
300 SETR_32(SD_INFO1_MASK, 0x00000000U);
301 SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR);
302
303 /* check interrupt */
304 if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) {
305 if ((mmc_drv_obj.get_partition_access_flag ==
306 TRUE)
307 && ((mmc_drv_obj.int_event2 & SD_INFO2_ERR6)
308 != 0U)) {
309 err_not_care_flag = TRUE;
310 rtn_code = EMMC_ERR_CMD_TIMEOUT;
311 } else {
312 /* error interrupt */
313 cmdErrSdInfo2Log();
314 rtn_code = EMMC_ERR_INFO2;
315 }
316 state = ESTATE_ERROR;
317 break;
318 } else if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO0) ==
319 0) {
320 /* not receive expected interrupt */
321 rtn_code = EMMC_ERR_RESPONSE;
322 state = ESTATE_ERROR;
323 break;
324 }
325
326 /* read response */
327 emmc_read_response(response);
328
329 /* check response */
330 rtn_code = emmc_response_check(response, error_mask);
331 if (rtn_code != EMMC_SUCCESS) {
332 state = ESTATE_ERROR;
333 break;
334 }
335
336 if (response_type == HAL_MEMCARD_RESPONSE_R1b) {
337 /* R1b */
338 SETR_32(SD_INFO2_MASK,
339 (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));
340 state = ESTATE_RCV_RESPONSE_BUSY;
341 } else {
342 state = ESTATE_CHECK_RESPONSE_COMPLETE;
343 }
344 break;
345
346 case ESTATE_RCV_RESPONSE_BUSY:
347 /* check interrupt */
348 if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) {
349 /* error interrupt */
350 cmdErrSdInfo2Log();
351 rtn_code = EMMC_ERR_INFO2;
352 state = ESTATE_ERROR;
353 break;
354 }
355 /* DAT0 not Busy */
356 if ((SD_INFO2_DAT0 & mmc_drv_obj.error_info.info2) != 0) {
357 state = ESTATE_CHECK_RESPONSE_COMPLETE;
358 break;
359 }
360 break;
361
362 case ESTATE_CHECK_RESPONSE_COMPLETE:
363 if (cmd_type >= HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE) {
364 state = ESTATE_DATA_TRANSFER;
365 } else {
366 emmc_WaitCmd2Cmd_8Cycle();
367 state = ESTATE_END;
368 }
369 break;
370
371 case ESTATE_DATA_TRANSFER:
372 /* ADTC command */
373 mmc_drv_obj.during_transfer = TRUE;
374 mmc_drv_obj.state_machine_blocking = TRUE;
375
376 if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) {
377 /* DMA */
378 emmc_data_transfer_dma();
379 } else {
380 /* PIO */
381 /* interrupt enable (FIFO read/write enable) */
382 if (mmc_drv_obj.cmd_info.dir ==
383 HAL_MEMCARD_WRITE) {
384 SETR_32(SD_INFO2_MASK,
385 (SD_INFO2_BWE | SD_INFO2_ALL_ERR
386 | SD_INFO2_CLEAR));
387 } else {
388 SETR_32(SD_INFO2_MASK,
389 (SD_INFO2_BRE | SD_INFO2_ALL_ERR
390 | SD_INFO2_CLEAR));
391 }
392 }
393 state = ESTATE_DATA_TRANSFER_COMPLETE;
394 break;
395
396 case ESTATE_DATA_TRANSFER_COMPLETE:
397 /* check interrupt */
398 if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) {
399 /* error interrupt */
400 cmdErrSdInfo2Log();
401 rtn_code = EMMC_ERR_INFO2;
402 state = ESTATE_TRANSFER_ERROR;
403 break;
404 }
405
406 /* DMAC error ? */
407 if (mmc_drv_obj.dma_error_flag == TRUE) {
408 /* Error occurred in DMAC driver. */
409 rtn_code = EMMC_ERR_FROM_DMAC_TRANSFER;
410 state = ESTATE_TRANSFER_ERROR;
411 } else if (mmc_drv_obj.during_dma_transfer == TRUE) {
412 /* DMAC not finished. unknown error */
413 rtn_code = EMMC_ERR;
414 state = ESTATE_TRANSFER_ERROR;
415 } else {
416 SETR_32(SD_INFO1_MASK, SD_INFO1_INFO2);
417 SETR_32(SD_INFO2_MASK,
418 (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));
419
420 mmc_drv_obj.state_machine_blocking = TRUE;
421
422 state = ESTATE_ACCESS_END;
423 }
424 break;
425
426 case ESTATE_ACCESS_END:
427
428 /* clear flag */
Biju Das08d33082020-12-13 19:41:27 +0000429 if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) {
430 /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */
431 SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR);
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200432 SETR_32(SD_STOP, 0x00000000U);
433 mmc_drv_obj.during_dma_transfer = FALSE;
434 }
435
436 SETR_32(SD_INFO1_MASK, 0x00000000U);
437 SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR);
438 SETR_32(SD_INFO1, 0x00000000U);
439 SETR_32(SD_INFO2, SD_INFO2_CLEAR);
440
441 if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO2) != 0) {
442 emmc_WaitCmd2Cmd_8Cycle();
443 state = ESTATE_END;
444 } else {
445 state = ESTATE_ERROR;
446 }
447 break;
448
449 case ESTATE_TRANSFER_ERROR:
450 /* The error occurred in the Data transfer. */
Biju Das08d33082020-12-13 19:41:27 +0000451 if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) {
452 /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */
453 SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR);
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200454 SETR_32(SD_STOP, 0x00000000U);
455 mmc_drv_obj.during_dma_transfer = FALSE;
456 }
457 /* through */
458
459 case ESTATE_ERROR:
460 if (err_not_care_flag == TRUE) {
461 mmc_drv_obj.during_cmd_processing = FALSE;
462 } else {
463 emmc_softreset();
464 emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD,
465 rtn_code);
466 }
467 return rtn_code;
468
469 default:
470 state = ESTATE_END;
471 break;
Biju Das08d33082020-12-13 19:41:27 +0000472 } /* switch (state) */
473 } /* while ( (mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END) ) */
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200474
475 /* force terminate */
476 if (mmc_drv_obj.force_terminate == TRUE) {
477 /* timeout timer is expired. Or, PIO data transfer error. */
478 /* Timeout occurred in the DMA transfer. */
479 if (mmc_drv_obj.during_dma_transfer == TRUE) {
480 mmc_drv_obj.during_dma_transfer = FALSE;
481 }
482 ERROR("BL2: emmc exec_cmd:EMMC_ERR_FORCE_TERMINATE\n");
483 emmc_softreset();
484
Biju Das08d33082020-12-13 19:41:27 +0000485 return EMMC_ERR_FORCE_TERMINATE; /* error information has already been written. */
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200486 }
487
488 /* success */
489 mmc_drv_obj.during_cmd_processing = FALSE;
490 mmc_drv_obj.during_transfer = FALSE;
491
492 return EMMC_SUCCESS;
493}