blob: e04afd4cf0537283683c801077af5ddf090b0b62 [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#include <lib/mmio.h>
9
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +020010#include "emmc_config.h"
Biju Das08d33082020-12-13 19:41:27 +000011#include "emmc_def.h"
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +020012#include "emmc_hal.h"
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +020013#include "emmc_registers.h"
Biju Das08d33082020-12-13 19:41:27 +000014#include "emmc_std.h"
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +020015#include "micro_delay.h"
16#include "rcar_def.h"
17
18static EMMC_ERROR_CODE emmc_clock_ctrl(uint8_t mode);
19static EMMC_ERROR_CODE emmc_card_init(void);
20static EMMC_ERROR_CODE emmc_high_speed(void);
21static EMMC_ERROR_CODE emmc_bus_width(uint32_t width);
22static uint32_t emmc_set_timeout_register_value(uint32_t freq);
23static void set_sd_clk(uint32_t clkDiv);
24static uint32_t emmc_calc_tran_speed(uint32_t *freq);
25static void emmc_get_partition_access(void);
26static void emmc_set_bootpartition(void);
27
28static void emmc_set_bootpartition(void)
29{
30 uint32_t reg;
31
Marek Vasut9cadc782019-08-06 19:13:22 +020032 reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK);
33 if (reg == PRR_PRODUCT_M3_CUT10) {
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +020034 mmc_drv_obj.boot_partition_en =
35 (EMMC_PARTITION_ID) ((mmc_drv_obj.ext_csd_data[179] &
36 EMMC_BOOT_PARTITION_EN_MASK) >>
37 EMMC_BOOT_PARTITION_EN_SHIFT);
Marek Vasut9cadc782019-08-06 19:13:22 +020038 } else if ((reg == PRR_PRODUCT_H3_CUT20)
39 || (reg == PRR_PRODUCT_M3_CUT11)) {
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +020040 mmc_drv_obj.boot_partition_en = mmc_drv_obj.partition_access;
41 } else {
42 if ((mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION) !=
43 0U) {
44 mmc_drv_obj.boot_partition_en = PARTITION_ID_BOOT_2;
45 } else {
46 mmc_drv_obj.boot_partition_en = PARTITION_ID_BOOT_1;
47 }
48 }
49}
50
51static EMMC_ERROR_CODE emmc_card_init(void)
52{
53 int32_t retry;
54 uint32_t freq = MMC_400KHZ; /* 390KHz */
55 EMMC_ERROR_CODE result;
Biju Das08d33082020-12-13 19:41:27 +000056 uint32_t result_calc;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +020057
58 /* state check */
59 if ((mmc_drv_obj.initialize != TRUE)
60 || (mmc_drv_obj.card_power_enable != TRUE)
61 || ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0)
62 ) {
63 emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR_STATE);
64 return EMMC_ERR_STATE;
65 }
66
67 /* clock on (force change) */
68 mmc_drv_obj.current_freq = 0;
69 mmc_drv_obj.max_freq = MMC_20MHZ;
70 result = emmc_set_request_mmc_clock(&freq);
71 if (result != EMMC_SUCCESS) {
72 emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
73 return EMMC_ERR;
74 }
75
76 rcar_micro_delay(1000U); /* wait 1ms */
77
78 /* Get current access partition */
79 emmc_get_partition_access();
80
81 /* CMD0, arg=0x00000000 */
82 result = emmc_send_idle_cmd(0x00000000);
83 if (result != EMMC_SUCCESS) {
84 emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
85 return result;
86 }
87
88 rcar_micro_delay(200U); /* wait 74clock 390kHz(189.74us) */
89
90 /* CMD1 */
91 emmc_make_nontrans_cmd(CMD1_SEND_OP_COND, EMMC_HOST_OCR_VALUE);
92 for (retry = 300; retry > 0; retry--) {
93 result =
94 emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
95 if (result != EMMC_SUCCESS) {
96 emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
97 return result;
98 }
99
100 if ((mmc_drv_obj.r3_ocr & EMMC_OCR_STATUS_BIT) != 0) {
101 break; /* card is ready. exit loop */
102 }
103 rcar_micro_delay(1000U); /* wait 1ms */
104 }
105
106 if (retry == 0) {
107 emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR_TIMEOUT);
108 return EMMC_ERR_TIMEOUT;
109 }
110
111 switch (mmc_drv_obj.r3_ocr & EMMC_OCR_ACCESS_MODE_MASK) {
112 case EMMC_OCR_ACCESS_MODE_SECT:
113 mmc_drv_obj.access_mode = TRUE; /* sector mode */
114 break;
115 default:
116 /* unknown value */
117 emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR);
118 return EMMC_ERR;
119 }
120
121 /* CMD2 */
122 emmc_make_nontrans_cmd(CMD2_ALL_SEND_CID_MMC, 0x00000000);
123 mmc_drv_obj.response = (uint32_t *) (&mmc_drv_obj.cid_data[0]); /* use CID special buffer */
124 result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
125 if (result != EMMC_SUCCESS) {
126 emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
127 return result;
128 }
129
130 /* CMD3 */
131 emmc_make_nontrans_cmd(CMD3_SET_RELATIVE_ADDR, EMMC_RCA << 16);
132 result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
133 if (result != EMMC_SUCCESS) {
134 emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
135 return result;
136 }
137
138 /* CMD9 (CSD) */
139 emmc_make_nontrans_cmd(CMD9_SEND_CSD, EMMC_RCA << 16);
140 mmc_drv_obj.response = (uint32_t *) (&mmc_drv_obj.csd_data[0]); /* use CSD special buffer */
141 result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
142 if (result != EMMC_SUCCESS) {
143 emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
144 return result;
145 }
146
147 /* card version check */
148 if (EMMC_CSD_SPEC_VARS() < 4) {
149 emmc_write_error_info(EMMC_FUNCNO_CARD_INIT,
150 EMMC_ERR_ILLEGAL_CARD);
151 return EMMC_ERR_ILLEGAL_CARD;
152 }
153
154 /* CMD7 (select card) */
155 emmc_make_nontrans_cmd(CMD7_SELECT_CARD, EMMC_RCA << 16);
156 result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
157 if (result != EMMC_SUCCESS) {
158 emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
159 return result;
160 }
161
162 mmc_drv_obj.selected = TRUE;
163
Biju Das08d33082020-12-13 19:41:27 +0000164 /*
165 * card speed check
166 * Card spec is calculated from TRAN_SPEED(CSD)
167 */
168 result_calc = emmc_calc_tran_speed(&freq);
169 if (result_calc == 0) {
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200170 emmc_write_error_info(EMMC_FUNCNO_CARD_INIT,
171 EMMC_ERR_ILLEGAL_CARD);
172 return EMMC_ERR_ILLEGAL_CARD;
173 }
174 mmc_drv_obj.max_freq = freq; /* max frequency (card spec) */
175
176 result = emmc_set_request_mmc_clock(&freq);
177 if (result != EMMC_SUCCESS) {
178 emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
179 return EMMC_ERR;
180 }
181
182 /* set read/write timeout */
183 mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq);
184 SETR_32(SD_OPTION,
185 ((GETR_32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) |
186 mmc_drv_obj.data_timeout));
187
188 /* SET_BLOCKLEN(512byte) */
189 /* CMD16 */
190 emmc_make_nontrans_cmd(CMD16_SET_BLOCKLEN, EMMC_BLOCK_LENGTH);
191 result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
192 if (result != EMMC_SUCCESS) {
193 emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
194 return result;
195 }
196
197 /* Transfer Data Length */
198 SETR_32(SD_SIZE, EMMC_BLOCK_LENGTH);
199
200 /* CMD8 (EXT_CSD) */
201 emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000,
202 (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]),
203 EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ,
204 HAL_MEMCARD_NOT_DMA);
205 result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
206 if (result != EMMC_SUCCESS) {
Biju Das08d33082020-12-13 19:41:27 +0000207 /*
208 * CMD12 is not send.
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200209 * If BUS initialization is failed, user must be execute Bus initialization again.
210 * Bus initialization is start CMD0(soft reset command).
211 */
212 emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
213 return result;
214 }
215
216 /* Set boot partition */
217 emmc_set_bootpartition();
218
219 return EMMC_SUCCESS;
220}
221
222static EMMC_ERROR_CODE emmc_high_speed(void)
223{
Biju Das08d33082020-12-13 19:41:27 +0000224 uint32_t freq; /* High speed mode clock frequency */
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200225 EMMC_ERROR_CODE result;
226 uint8_t cardType;
227
228 /* state check */
229 if (mmc_drv_obj.selected != TRUE) {
230 emmc_write_error_info(EMMC_FUNCNO_HIGH_SPEED, EMMC_ERR_STATE);
231 return EMMC_ERR_STATE;
232 }
233
234 /* max frequency */
235 cardType = (uint8_t) mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_CARD_TYPE];
236 if ((cardType & EMMC_EXT_CSD_CARD_TYPE_52MHZ) != 0)
237 freq = MMC_52MHZ;
238 else if ((cardType & EMMC_EXT_CSD_CARD_TYPE_26MHZ) != 0)
239 freq = MMC_26MHZ;
240 else
241 freq = MMC_20MHZ;
242
Biju Das08d33082020-12-13 19:41:27 +0000243 /* Hi-Speed-mode selection */
244 if ((freq == MMC_52MHZ) || (freq == MMC_26MHZ)) {
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200245 /* CMD6 */
246 emmc_make_nontrans_cmd(CMD6_SWITCH, EMMC_SWITCH_HS_TIMING);
247 result =
248 emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
249 if (result != EMMC_SUCCESS) {
250 emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED);
251 return result;
252 }
253
254 mmc_drv_obj.hs_timing = TIMING_HIGH_SPEED; /* High-Speed */
255 }
256
257 /* set mmc clock */
258 mmc_drv_obj.max_freq = freq;
259 result = emmc_set_request_mmc_clock(&freq);
260 if (result != EMMC_SUCCESS) {
261 emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED);
262 return EMMC_ERR;
263 }
264
265 /* set read/write timeout */
266 mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq);
267 SETR_32(SD_OPTION,
268 ((GETR_32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) |
269 mmc_drv_obj.data_timeout));
270
271 /* CMD13 */
272 emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16);
273 result =
274 emmc_exec_cmd(EMMC_R1_ERROR_MASK_WITHOUT_CRC, mmc_drv_obj.response);
275 if (result != EMMC_SUCCESS) {
276 emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED);
277 return result;
278 }
279
280 return EMMC_SUCCESS;
281}
282
283static EMMC_ERROR_CODE emmc_clock_ctrl(uint8_t mode)
284{
285 uint32_t value;
286
287 /* busy check */
288 if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) {
289 emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK,
290 EMMC_ERR_CARD_BUSY);
291 return EMMC_ERR;
292 }
293
294 if (mode == TRUE) {
295 /* clock ON */
296 value =
297 ((GETR_32(SD_CLK_CTRL) | MMC_SD_CLK_START) &
298 SD_CLK_WRITE_MASK);
299 SETR_32(SD_CLK_CTRL, value); /* on */
300 mmc_drv_obj.clock_enable = TRUE;
301 } else {
302 /* clock OFF */
303 value =
304 ((GETR_32(SD_CLK_CTRL) & MMC_SD_CLK_STOP) &
305 SD_CLK_WRITE_MASK);
306 SETR_32(SD_CLK_CTRL, value); /* off */
307 mmc_drv_obj.clock_enable = FALSE;
308 }
309
310 return EMMC_SUCCESS;
311}
312
313static EMMC_ERROR_CODE emmc_bus_width(uint32_t width)
314{
315 EMMC_ERROR_CODE result = EMMC_ERR;
316
317 /* parameter check */
318 if ((width != 8) && (width != 4) && (width != 1)) {
319 emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, EMMC_ERR_PARAM);
320 return EMMC_ERR_PARAM;
321 }
322
323 /* state check */
324 if (mmc_drv_obj.selected != TRUE) {
325 emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, EMMC_ERR_STATE);
326 return EMMC_ERR_STATE;
327 }
328
Biju Das08d33082020-12-13 19:41:27 +0000329 /* 2 = 8bit, 1 = 4bit, 0 =1bit */
330 mmc_drv_obj.bus_width = (HAL_MEMCARD_DATA_WIDTH) (width >> 2);
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200331
332 /* CMD6 */
333 emmc_make_nontrans_cmd(CMD6_SWITCH,
334 (EMMC_SWITCH_BUS_WIDTH_1 |
335 (mmc_drv_obj.bus_width << 8)));
336 result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
337 if (result != EMMC_SUCCESS) {
338 /* occurred error */
339 mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT;
340 goto EXIT;
341 }
342
343 switch (mmc_drv_obj.bus_width) {
344 case HAL_MEMCARD_DATA_WIDTH_1_BIT:
345 SETR_32(SD_OPTION,
346 ((GETR_32(SD_OPTION) & ~(BIT15 | BIT13)) | BIT15));
347 break;
348 case HAL_MEMCARD_DATA_WIDTH_4_BIT:
349 SETR_32(SD_OPTION, (GETR_32(SD_OPTION) & ~(BIT15 | BIT13)));
350 break;
351 case HAL_MEMCARD_DATA_WIDTH_8_BIT:
352 SETR_32(SD_OPTION,
353 ((GETR_32(SD_OPTION) & ~(BIT15 | BIT13)) | BIT13));
354 break;
355 default:
356 goto EXIT;
357 }
358
359 /* CMD13 */
360 emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16);
361 result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
362 if (result != EMMC_SUCCESS) {
363 goto EXIT;
364 }
365
366 /* CMD8 (EXT_CSD) */
367 emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000,
368 (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]),
369 EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ,
370 HAL_MEMCARD_NOT_DMA);
371 result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
372 if (result != EMMC_SUCCESS) {
373 goto EXIT;
374 }
375
376 return EMMC_SUCCESS;
377
378EXIT:
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200379 emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, result);
380 ERROR("BL2: emmc bus_width error end\n");
381 return result;
382}
383
384EMMC_ERROR_CODE emmc_select_partition(EMMC_PARTITION_ID id)
385{
386 EMMC_ERROR_CODE result;
387 uint32_t arg;
388 uint32_t partition_config;
389
390 /* state check */
391 if (mmc_drv_obj.mount != TRUE) {
392 emmc_write_error_info(EMMC_FUNCNO_NONE, EMMC_ERR_STATE);
393 return EMMC_ERR_STATE;
394 }
395
396 /* id = PARTITION_ACCESS(Bit[2:0]) */
397 if ((id & ~PARTITION_ID_MASK) != 0) {
398 emmc_write_error_info(EMMC_FUNCNO_NONE, EMMC_ERR_PARAM);
399 return EMMC_ERR_PARAM;
400 }
401
402 /* EXT_CSD[179] value */
403 partition_config =
404 (uint32_t) mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_PARTITION_CONFIG];
405 if ((partition_config & PARTITION_ID_MASK) == id) {
406 result = EMMC_SUCCESS;
407 } else {
408
409 partition_config =
410 (uint32_t) ((partition_config & ~PARTITION_ID_MASK) | id);
411 arg = EMMC_SWITCH_PARTITION_CONFIG | (partition_config << 8);
412
413 result = emmc_set_ext_csd(arg);
414 }
415
416 return result;
417}
418
419static void set_sd_clk(uint32_t clkDiv)
420{
421 uint32_t dataL;
422
423 dataL = (GETR_32(SD_CLK_CTRL) & (~SD_CLK_CTRL_CLKDIV_MASK));
424
425 switch (clkDiv) {
426 case 1:
427 dataL |= 0x000000FFU;
428 break; /* 1/1 */
429 case 2:
430 dataL |= 0x00000000U;
431 break; /* 1/2 */
432 case 4:
433 dataL |= 0x00000001U;
434 break; /* 1/4 */
435 case 8:
436 dataL |= 0x00000002U;
437 break; /* 1/8 */
438 case 16:
439 dataL |= 0x00000004U;
440 break; /* 1/16 */
441 case 32:
442 dataL |= 0x00000008U;
443 break; /* 1/32 */
444 case 64:
445 dataL |= 0x00000010U;
446 break; /* 1/64 */
447 case 128:
448 dataL |= 0x00000020U;
449 break; /* 1/128 */
450 case 256:
451 dataL |= 0x00000040U;
452 break; /* 1/256 */
453 case 512:
454 dataL |= 0x00000080U;
455 break; /* 1/512 */
456 }
457
458 SETR_32(SD_CLK_CTRL, dataL);
459 mmc_drv_obj.current_freq = (uint32_t) clkDiv;
460}
461
462static void emmc_get_partition_access(void)
463{
464 uint32_t reg;
465 EMMC_ERROR_CODE result;
466
Marek Vasut9cadc782019-08-06 19:13:22 +0200467 reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK);
468 if ((reg == PRR_PRODUCT_H3_CUT20) || (reg == PRR_PRODUCT_M3_CUT11)) {
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200469 SETR_32(SD_OPTION, 0x000060EEU); /* 8 bits width */
470 /* CMD8 (EXT_CSD) */
471 emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000U,
472 (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]),
473 EMMC_MAX_EXT_CSD_LENGTH,
474 HAL_MEMCARD_READ, HAL_MEMCARD_NOT_DMA);
475 mmc_drv_obj.get_partition_access_flag = TRUE;
476 result =
477 emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
478 mmc_drv_obj.get_partition_access_flag = FALSE;
479 if (result == EMMC_SUCCESS) {
480 mmc_drv_obj.partition_access =
481 (EMMC_PARTITION_ID) (mmc_drv_obj.ext_csd_data[179]
482 & PARTITION_ID_MASK);
483 } else if (result == EMMC_ERR_CMD_TIMEOUT) {
484 mmc_drv_obj.partition_access = PARTITION_ID_BOOT_1;
485 } else {
486 emmc_write_error_info(EMMC_FUNCNO_GET_PERTITION_ACCESS,
487 result);
488 panic();
489 }
490 SETR_32(SD_OPTION, 0x0000C0EEU); /* Initialize */
491 }
492}
493
494static uint32_t emmc_calc_tran_speed(uint32_t *freq)
495{
Biju Das08d33082020-12-13 19:41:27 +0000496 const uint32_t unit[8] = { 10000U, 100000U, 1000000U, 10000000U,
497 0U, 0U, 0U, 0U }; /* frequency unit (1/10) */
498 const uint32_t mult[16] = { 0U, 10U, 12U, 13U, 15U, 20U, 26U, 30U, 35U,
499 40U, 45U, 52U, 55U, 60U, 70U, 80U };
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200500 uint32_t tran_speed = EMMC_CSD_TRAN_SPEED();
Biju Das08d33082020-12-13 19:41:27 +0000501 uint32_t max_freq;
502 uint32_t result;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200503
Biju Das08d33082020-12-13 19:41:27 +0000504 /*
505 * tran_speed = 0x32
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200506 * unit[tran_speed&0x7] = uint[0x2] = 1000000
507 * mult[(tran_speed&0x78)>>3] = mult[0x30>>3] = mult[6] = 26
508 * 1000000 * 26 = 26000000 (26MHz)
509 */
510
511 result = 1;
Biju Das08d33082020-12-13 19:41:27 +0000512 max_freq =
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200513 unit[tran_speed & EMMC_TRANSPEED_FREQ_UNIT_MASK] *
514 mult[(tran_speed & EMMC_TRANSPEED_MULT_MASK) >>
515 EMMC_TRANSPEED_MULT_SHIFT];
516
Biju Das08d33082020-12-13 19:41:27 +0000517 if (max_freq == 0) {
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200518 result = 0;
Biju Das08d33082020-12-13 19:41:27 +0000519 } else if (max_freq >= MMC_FREQ_52MHZ) {
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200520 *freq = MMC_52MHZ;
Biju Das08d33082020-12-13 19:41:27 +0000521 } else if (max_freq >= MMC_FREQ_26MHZ) {
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200522 *freq = MMC_26MHZ;
Biju Das08d33082020-12-13 19:41:27 +0000523 } else if (max_freq >= MMC_FREQ_20MHZ) {
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200524 *freq = MMC_20MHZ;
Biju Das08d33082020-12-13 19:41:27 +0000525 } else {
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200526 *freq = MMC_400KHZ;
Biju Das08d33082020-12-13 19:41:27 +0000527 }
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200528
529 return result;
530}
531
532static uint32_t emmc_set_timeout_register_value(uint32_t freq)
533{
Biju Das08d33082020-12-13 19:41:27 +0000534 uint32_t timeout_cnt; /* SD_OPTION - Timeout Counter */
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200535
536 switch (freq) {
537 case 1U:
Biju Das08d33082020-12-13 19:41:27 +0000538 timeout_cnt = 0xE0U;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200539 break; /* SDCLK * 2^27 */
540 case 2U:
Biju Das08d33082020-12-13 19:41:27 +0000541 timeout_cnt = 0xE0U;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200542 break; /* SDCLK * 2^27 */
543 case 4U:
Biju Das08d33082020-12-13 19:41:27 +0000544 timeout_cnt = 0xD0U;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200545 break; /* SDCLK * 2^26 */
546 case 8U:
Biju Das08d33082020-12-13 19:41:27 +0000547 timeout_cnt = 0xC0U;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200548 break; /* SDCLK * 2^25 */
549 case 16U:
Biju Das08d33082020-12-13 19:41:27 +0000550 timeout_cnt = 0xB0U;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200551 break; /* SDCLK * 2^24 */
552 case 32U:
Biju Das08d33082020-12-13 19:41:27 +0000553 timeout_cnt = 0xA0U;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200554 break; /* SDCLK * 2^23 */
555 case 64U:
Biju Das08d33082020-12-13 19:41:27 +0000556 timeout_cnt = 0x90U;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200557 break; /* SDCLK * 2^22 */
558 case 128U:
Biju Das08d33082020-12-13 19:41:27 +0000559 timeout_cnt = 0x80U;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200560 break; /* SDCLK * 2^21 */
561 case 256U:
Biju Das08d33082020-12-13 19:41:27 +0000562 timeout_cnt = 0x70U;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200563 break; /* SDCLK * 2^20 */
564 case 512U:
Biju Das08d33082020-12-13 19:41:27 +0000565 timeout_cnt = 0x70U;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200566 break; /* SDCLK * 2^20 */
567 default:
Biju Das08d33082020-12-13 19:41:27 +0000568 timeout_cnt = 0xE0U;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200569 break; /* SDCLK * 2^27 */
570 }
571
Biju Das08d33082020-12-13 19:41:27 +0000572 return timeout_cnt;
Jorge Ramirez-Ortiz766263c2018-09-23 09:39:56 +0200573}
574
575EMMC_ERROR_CODE emmc_set_ext_csd(uint32_t arg)
576{
577 EMMC_ERROR_CODE result;
578
579 /* CMD6 */
580 emmc_make_nontrans_cmd(CMD6_SWITCH, arg);
581 result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
582 if (result != EMMC_SUCCESS) {
583 return result;
584 }
585
586 /* CMD13 */
587 emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16);
588 result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
589 if (result != EMMC_SUCCESS) {
590 return result;
591 }
592
593 /* CMD8 (EXT_CSD) */
594 emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000,
595 (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]),
596 EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ,
597 HAL_MEMCARD_NOT_DMA);
598 result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
599 if (result != EMMC_SUCCESS) {
600 return result;
601 }
602 return EMMC_SUCCESS;
603}
604
605EMMC_ERROR_CODE emmc_set_request_mmc_clock(uint32_t *freq)
606{
607 /* parameter check */
608 if (freq == NULL) {
609 emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, EMMC_ERR_PARAM);
610 return EMMC_ERR_PARAM;
611 }
612
613 /* state check */
614 if ((mmc_drv_obj.initialize != TRUE)
615 || (mmc_drv_obj.card_power_enable != TRUE)) {
616 emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, EMMC_ERR_STATE);
617 return EMMC_ERR_STATE;
618 }
619
620 /* clock is already running in the desired frequency. */
621 if ((mmc_drv_obj.clock_enable == TRUE)
622 && (mmc_drv_obj.current_freq == *freq)) {
623 return EMMC_SUCCESS;
624 }
625
626 /* busy check */
627 if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) {
628 emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK,
629 EMMC_ERR_CARD_BUSY);
630 return EMMC_ERR;
631 }
632
633 set_sd_clk(*freq);
634 mmc_drv_obj.clock_enable = FALSE;
635
636 return emmc_clock_ctrl(TRUE); /* clock on */
637}
638
639EMMC_ERROR_CODE rcar_emmc_mount(void)
640{
641 EMMC_ERROR_CODE result;
642
643 /* state check */
644 if ((mmc_drv_obj.initialize != TRUE)
645 || (mmc_drv_obj.card_power_enable != TRUE)
646 || ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0)
647 ) {
648 emmc_write_error_info(EMMC_FUNCNO_MOUNT, EMMC_ERR_STATE);
649 return EMMC_ERR_STATE;
650 }
651
652 /* initialize card (IDLE state --> Transfer state) */
653 result = emmc_card_init();
654 if (result != EMMC_SUCCESS) {
655 emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
656 if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) {
657 /* nothing to do. */
658 }
659 return result;
660 }
661
662 /* Switching high speed mode */
663 result = emmc_high_speed();
664 if (result != EMMC_SUCCESS) {
665 emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED);
666 if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) {
667 /* nothing to do. */
668 }
669 return result;
670 }
671
672 /* Changing the data bus width */
673 result = emmc_bus_width(8);
674 if (result != EMMC_SUCCESS) {
675 emmc_write_error_info_func_no(EMMC_FUNCNO_BUS_WIDTH);
676 if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) {
677 /* nothing to do. */
678 }
679 return result;
680 }
681
682 /* mount complete */
683 mmc_drv_obj.mount = TRUE;
684
685 return EMMC_SUCCESS;
686}