blob: 48b27c1642eda0151501b6c127f3ccab9a240d1c [file] [log] [blame]
Pankaj Gupta7d2f40f2020-12-09 14:02:39 +05301/*
2 * Copyright 2021 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 *
7 */
8
9#include <endian.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#include <arch_helpers.h>
15#include <common/debug.h>
16#include <drivers/io/io_block.h>
17#include "nxp_timer.h"
18#include "sd_mmc.h"
19#include <utils.h>
20#include <utils_def.h>
21
22
23/* Private structure for MMC driver data */
24static struct mmc mmc_drv_data;
25
26#ifndef NXP_POLICY_OTA
27/*
28 * For NXP_POLICY_OTA, SD needs to do R/W on OCRAM. OCRAM is secure memory at
29 * default. SD can only do non-secure DMA. Configuring SD to work in PIO mode
30 * instead of DMA mode will make SD R/W on OCRAM available.
31 */
32/* To debug without dma comment this MACRO */
33#define NXP_SD_DMA_CAPABILITY
34#endif
35#define SD_TIMEOUT 1000 /* ms */
36#define SD_TIMEOUT_HIGH 20000 /* ms */
37#define SD_BLOCK_TIMEOUT 8 /* ms */
38
39#define ERROR_ESDHC_CARD_DETECT_FAIL -1
40#define ERROR_ESDHC_UNUSABLE_CARD -2
41#define ERROR_ESDHC_COMMUNICATION_ERROR -3
42#define ERROR_ESDHC_BLOCK_LENGTH -4
43#define ERROR_ESDHC_DMA_ERROR -5
44#define ERROR_ESDHC_BUSY -6
45
46/***************************************************************
47 * Function : set_speed
48 * Arguments : mmc - Pointer to mmc struct
49 * clock - Clock Value to be set
50 * Return : void
51 * Description : Calculates the value of SDCLKFS and DVS to be set
52 * for getting the required clock assuming the base_clk
53 * as a fixed value (MAX_PLATFORM_CLOCK)
54 *****************************************************************/
55static void set_speed(struct mmc *mmc, uint32_t clock)
56{
57 /* sdhc_clk = (base clock) / [(SDCLKFS × 2) × (DVS +1)] */
58
59 uint32_t dvs = 1U;
60 uint32_t sdclkfs = 2U;
61 /* TBD - Change this to actual platform clock by reading via RCW */
62 uint32_t base_clk = MAX_PLATFORM_CLOCK;
63
64 if (base_clk / 16 > clock) {
65 for (sdclkfs = 2U; sdclkfs < 256U; sdclkfs *= 2U) {
66 if ((base_clk / sdclkfs) <= (clock * 16)) {
67 break;
68 }
69 }
70 }
71
72 for (dvs = 1U; dvs <= 16U; dvs++) {
73 if ((base_clk / (dvs * sdclkfs)) <= clock) {
74 break;
75 }
76 }
77
78 sdclkfs >>= 1U;
79 dvs -= 1U;
80
81 esdhc_out32(&mmc->esdhc_regs->sysctl,
82 (ESDHC_SYSCTL_DTOCV(TIMEOUT_COUNTER_SDCLK_2_27) |
83 ESDHC_SYSCTL_SDCLKFS(sdclkfs) | ESDHC_SYSCTL_DVS(dvs) |
84 ESDHC_SYSCTL_SDCLKEN));
85}
86
87/***************************************************************************
88 * Function : esdhc_init
89 * Arguments : mmc - Pointer to mmc struct
90 * card_detect - flag to indicate if card insert needs
91 * to be detected or not. For SDHC2 controller, Card detect
92 * is not present, so this field will be false
93 * Return : SUCCESS or Error Code
94 * Description : 1. Set Initial Clock Speed
95 * 2. Card Detect if not eMMC
96 * 3. Enable Controller Clock
97 * 4. Send 80 ticks for card to power up
98 * 5. Set LE mode and Bus Width as 1 bit.
99 ***************************************************************************/
100static int esdhc_init(struct mmc *mmc, bool card_detect)
101{
102 uint32_t val;
103 uint64_t start_time;
104
105 /* Reset the entire host controller */
106 val = esdhc_in32(&mmc->esdhc_regs->sysctl) | ESDHC_SYSCTL_RSTA;
107 esdhc_out32(&mmc->esdhc_regs->sysctl, val);
108
109 /* Wait until the controller is available */
110 start_time = get_timer_val(0);
111 while (get_timer_val(start_time) < SD_TIMEOUT_HIGH) {
112 val = esdhc_in32(&mmc->esdhc_regs->sysctl) & ESDHC_SYSCTL_RSTA;
113 if (val == 0U) {
114 break;
115 }
116 }
117
118 val = esdhc_in32(&mmc->esdhc_regs->sysctl) &
119 (ESDHC_SYSCTL_RSTA);
120 if (val != 0U) {
121 ERROR("SD Reset failed\n");
122 return ERROR_ESDHC_BUSY;
123 }
124
125 /* Set initial clock speed */
126 set_speed(mmc, CARD_IDENTIFICATION_FREQ);
127
128 if (card_detect) {
129 /* Check CINS in prsstat register */
130 val = esdhc_in32(&mmc->esdhc_regs->prsstat) &
131 ESDHC_PRSSTAT_CINS;
132 if (val == 0) {
133 ERROR("CINS not set in prsstat\n");
134 return ERROR_ESDHC_CARD_DETECT_FAIL;
135 }
136 }
137
138 /* Enable controller clock */
139 val = esdhc_in32(&mmc->esdhc_regs->sysctl) | ESDHC_SYSCTL_SDCLKEN;
140 esdhc_out32(&mmc->esdhc_regs->sysctl, val);
141
142 /* Send 80 clock ticks for the card to power up */
143 val = esdhc_in32(&mmc->esdhc_regs->sysctl) | ESDHC_SYSCTL_INITA;
144 esdhc_out32(&mmc->esdhc_regs->sysctl, val);
145
146 start_time = get_timer_val(0);
147 while (get_timer_val(start_time) < SD_TIMEOUT) {
148 val = esdhc_in32(&mmc->esdhc_regs->sysctl) & ESDHC_SYSCTL_INITA;
149 if (val != 0U) {
150 break;
151 }
152 }
153
154 val = esdhc_in32(&mmc->esdhc_regs->sysctl) & ESDHC_SYSCTL_INITA;
155 if (val == 0U) {
156 ERROR("Failed to power up the card\n");
157 return ERROR_ESDHC_CARD_DETECT_FAIL;
158 }
159
160 INFO("Card detected successfully\n");
161
162 val = esdhc_in32(&mmc->esdhc_regs->proctl);
163 val = val | (ESDHC_PROCTL_EMODE_LE | ESDHC_PROCTL_DTW_1BIT);
164
165 /* Set little endian mode, set bus width as 1-bit */
166 esdhc_out32(&mmc->esdhc_regs->proctl, val);
167
168 /* Enable cache snooping for DMA transactions */
169 val = esdhc_in32(&mmc->esdhc_regs->ctl) | ESDHC_DCR_SNOOP;
170 esdhc_out32(&mmc->esdhc_regs->ctl, val);
171
172 return 0;
173}
174
175/***************************************************************************
176 * Function : esdhc_send_cmd
177 * Arguments : mmc - Pointer to mmc struct
178 * cmd - Command Number
179 * args - Command Args
180 * Return : SUCCESS is 0, or Error Code ( < 0)
181 * Description : Updates the eSDHC registers cmdargs and xfertype
182 ***************************************************************************/
183static int esdhc_send_cmd(struct mmc *mmc, uint32_t cmd, uint32_t args)
184{
185 uint32_t val;
186 uint64_t start_time;
187 uint32_t xfertyp = 0;
188
189 esdhc_out32(&mmc->esdhc_regs->irqstat, ESDHC_IRQSTAT_CLEAR_ALL);
190
191 /* Wait for the command line & data line to be free */
192 /* (poll the CIHB,CDIHB bit of the present state register) */
193 start_time = get_timer_val(0);
194 while (get_timer_val(start_time) < SD_TIMEOUT_HIGH) {
195 val = esdhc_in32(&mmc->esdhc_regs->prsstat) &
196 (ESDHC_PRSSTAT_CIHB | ESDHC_PRSSTAT_CDIHB);
197 if (val == 0U) {
198 break;
199 }
200 }
201
202 val = esdhc_in32(&mmc->esdhc_regs->prsstat) &
203 (ESDHC_PRSSTAT_CIHB | ESDHC_PRSSTAT_CDIHB);
204 if (val != 0U) {
205 ERROR("SD send cmd: Command Line or Data Line Busy cmd = %x\n",
206 cmd);
207 return ERROR_ESDHC_BUSY;
208 }
209
210 if (cmd == CMD2 || cmd == CMD9) {
211 xfertyp |= ESDHC_XFERTYP_RSPTYP_136;
212 } else if (cmd == CMD7 || (cmd == CMD6 && mmc->card.type == MMC_CARD)) {
213 xfertyp |= ESDHC_XFERTYP_RSPTYP_48_BUSY;
214 } else if (cmd != CMD0) {
215 xfertyp |= ESDHC_XFERTYP_RSPTYP_48;
216 }
217
218 if (cmd == CMD2 || cmd == CMD9) {
219 xfertyp |= ESDHC_XFERTYP_CCCEN; /* Command index check enable */
220 } else if ((cmd != CMD0) && (cmd != ACMD41) && (cmd != CMD1)) {
221 xfertyp = xfertyp | ESDHC_XFERTYP_CCCEN | ESDHC_XFERTYP_CICEN;
222 }
223
224 if ((cmd == CMD8 || cmd == CMD14 || cmd == CMD19) &&
225 mmc->card.type == MMC_CARD) {
226 xfertyp |= ESDHC_XFERTYP_DPSEL;
227 if (cmd != CMD19) {
228 xfertyp |= ESDHC_XFERTYP_DTDSEL;
229 }
230 }
231
232 if (cmd == CMD6 || cmd == CMD17 || cmd == CMD18 || cmd == CMD24 ||
233 cmd == ACMD51) {
234 if (!(mmc->card.type == MMC_CARD && cmd == CMD6)) {
235 if (cmd == CMD24) {
236 xfertyp |= ESDHC_XFERTYP_DPSEL;
237 } else {
238 xfertyp |= (ESDHC_XFERTYP_DPSEL |
239 ESDHC_XFERTYP_DTDSEL);
240 }
241 }
242
243 if (cmd == CMD18) {
244 xfertyp |= ESDHC_XFERTYP_BCEN;
245 if (mmc->dma_support != 0) {
246 /* Set BCEN of XFERTYP */
247 xfertyp |= ESDHC_XFERTYP_DMAEN;
248 }
249 }
250
251 if ((cmd == CMD17 || cmd == CMD24) && (mmc->dma_support != 0)) {
252 xfertyp |= ESDHC_XFERTYP_DMAEN;
253 }
254 }
255
256 xfertyp |= ((cmd & 0x3F) << 24);
257 esdhc_out32(&mmc->esdhc_regs->cmdarg, args);
258 esdhc_out32(&mmc->esdhc_regs->xfertyp, xfertyp);
259
260#ifdef NXP_SD_DEBUG
261 INFO("cmd = %d\n", cmd);
262 INFO("args = %x\n", args);
263 INFO("xfertyp: = %x\n", xfertyp);
264#endif
265 return 0;
266}
267
268/***************************************************************************
269 * Function : esdhc_wait_response
270 * Arguments : mmc - Pointer to mmc struct
271 * response - Value updated
272 * Return : SUCCESS - Response Received
273 * COMMUNICATION_ERROR - Command not Complete
274 * COMMAND_ERROR - CIE, CCE or CEBE error
275 * RESP_TIMEOUT - CTOE error
276 * Description : Checks for successful command completion.
277 * Clears the CC bit at the end.
278 ***************************************************************************/
279static int esdhc_wait_response(struct mmc *mmc, uint32_t *response)
280{
281 uint32_t val;
282 uint64_t start_time;
283 uint32_t status = 0U;
284
285 /* Wait for the command to complete */
286 start_time = get_timer_val(0);
287 while (get_timer_val(start_time) < SD_TIMEOUT_HIGH) {
288 val = esdhc_in32(&mmc->esdhc_regs->irqstat) & ESDHC_IRQSTAT_CC;
289 if (val != 0U) {
290 break;
291 }
292 }
293
294 val = esdhc_in32(&mmc->esdhc_regs->irqstat) & ESDHC_IRQSTAT_CC;
295 if (val == 0U) {
296 ERROR("%s:IRQSTAT Cmd not complete(CC not set)\n", __func__);
297 return ERROR_ESDHC_COMMUNICATION_ERROR;
298 }
299
300 status = esdhc_in32(&mmc->esdhc_regs->irqstat);
301
302 /* Check whether the interrupt is a CRC, CTOE or CIE error */
303 if ((status & (ESDHC_IRQSTAT_CIE | ESDHC_IRQSTAT_CEBE |
304 ESDHC_IRQSTAT_CCE)) != 0) {
305 ERROR("%s: IRQSTAT CRC, CEBE or CIE error = %x\n",
306 __func__, status);
307 return COMMAND_ERROR;
308 }
309
310 if ((status & ESDHC_IRQSTAT_CTOE) != 0) {
311 INFO("%s: IRQSTAT CTOE set = %x\n", __func__, status);
312 return RESP_TIMEOUT;
313 }
314
315 if ((status & ESDHC_IRQSTAT_DMAE) != 0) {
316 ERROR("%s: IRQSTAT DMAE set = %x\n", __func__, status);
317 return ERROR_ESDHC_DMA_ERROR;
318 }
319
320 if (response != NULL) {
321 /* Get response values from eSDHC CMDRSPx registers. */
322 response[0] = esdhc_in32(&mmc->esdhc_regs->cmdrsp[0]);
323 response[1] = esdhc_in32(&mmc->esdhc_regs->cmdrsp[1]);
324 response[2] = esdhc_in32(&mmc->esdhc_regs->cmdrsp[2]);
325 response[3] = esdhc_in32(&mmc->esdhc_regs->cmdrsp[3]);
326#ifdef NXP_SD_DEBUG
327 INFO("Resp R1 R2 R3 R4\n");
328 INFO("Resp R1 = %x\n", response[0]);
329 INFO("R2 = %x\n", response[1]);
330 INFO("R3 = %x\n", response[2]);
331 INFO("R4 = %x\n", response[3]);
332 INFO("\n");
333#endif
334 }
335
336 /* Clear the CC bit - w1c */
337 val = esdhc_in32(&mmc->esdhc_regs->irqstat) | ESDHC_IRQSTAT_CC;
338 esdhc_out32(&mmc->esdhc_regs->irqstat, val);
339
340 return 0;
341}
342
343/***************************************************************************
344 * Function : mmc_switch_to_high_frquency
345 * Arguments : mmc - Pointer to mmc struct
346 * Return : SUCCESS or Error Code
Elyes Haouas2be03c02023-02-13 09:14:48 +0100347 * Description : mmc card below ver 4.0 does not support high speed
Pankaj Gupta7d2f40f2020-12-09 14:02:39 +0530348 * freq = 20 MHz
349 * Send CMD6 (CMD_SWITCH_FUNC) With args 0x03B90100
350 * Send CMD13 (CMD_SEND_STATUS)
351 * if SWITCH Error, freq = 26 MHz
352 * if no error, freq = 52 MHz
353 ***************************************************************************/
354static int mmc_switch_to_high_frquency(struct mmc *mmc)
355{
356 int error;
357 uint32_t response[4];
358 uint64_t start_time;
359
360 mmc->card.bus_freq = MMC_SS_20MHZ;
Elyes Haouas2be03c02023-02-13 09:14:48 +0100361 /* mmc card below ver 4.0 does not support high speed */
Pankaj Gupta7d2f40f2020-12-09 14:02:39 +0530362 if (mmc->card.version < MMC_CARD_VERSION_4_X) {
363 return 0;
364 }
365
366 /* send switch cmd to change the card to High speed */
367 error = esdhc_send_cmd(mmc, CMD_SWITCH_FUNC, SET_EXT_CSD_HS_TIMING);
368 if (error != 0) {
369 return error;
370 }
371 error = esdhc_wait_response(mmc, response);
372 if (error != 0) {
373 return error;
374 }
375
376 start_time = get_timer_val(0);
377 do {
378 /* check the status for which error */
379 error = esdhc_send_cmd(mmc,
380 CMD_SEND_STATUS, mmc->card.rca << 16);
381 if (error != 0) {
382 return error;
383 }
384
385 error = esdhc_wait_response(mmc, response);
386 if (error != 0) {
387 return error;
388 }
389 } while (((response[0] & SWITCH_ERROR) != 0) &&
390 (get_timer_val(start_time) < SD_TIMEOUT));
391
392 /* Check for the present state of card */
393 if ((response[0] & SWITCH_ERROR) != 0) {
394 mmc->card.bus_freq = MMC_HS_26MHZ;
395 } else {
396 mmc->card.bus_freq = MMC_HS_52MHZ;
397 }
398
399 return 0;
400}
401
402/***************************************************************************
403 * Function : esdhc_set_data_attributes
404 * Arguments : mmc - Pointer to mmc struct
405 * blkcnt
406 * blklen
407 * Return : SUCCESS or Error Code
408 * Description : Set block attributes and watermark level register
409 ***************************************************************************/
410static int esdhc_set_data_attributes(struct mmc *mmc, uint32_t *dest_ptr,
411 uint32_t blkcnt, uint32_t blklen)
412{
413 uint32_t val;
414 uint64_t start_time;
415 uint32_t wml;
416 uint32_t wl;
417 uint32_t dst = (uint32_t)((uint64_t)(dest_ptr));
418
419 /* set blkattr when no transactions are executing */
420 start_time = get_timer_val(0);
421 while (get_timer_val(start_time) < SD_TIMEOUT_HIGH) {
422 val = esdhc_in32(&mmc->esdhc_regs->prsstat) & ESDHC_PRSSTAT_DLA;
423 if (val == 0U) {
424 break;
425 }
426 }
427
428 val = esdhc_in32(&mmc->esdhc_regs->prsstat) & ESDHC_PRSSTAT_DLA;
429 if (val != 0U) {
430 ERROR("%s: Data line active.Can't set attribute\n", __func__);
431 return ERROR_ESDHC_COMMUNICATION_ERROR;
432 }
433
434 wml = esdhc_in32(&mmc->esdhc_regs->wml);
435 wml &= ~(ESDHC_WML_WR_BRST_MASK | ESDHC_WML_RD_BRST_MASK |
436 ESDHC_WML_RD_WML_MASK | ESDHC_WML_WR_WML_MASK);
437
438 if ((mmc->dma_support != 0) && (dest_ptr != NULL)) {
439 /* Set burst length to 128 bytes */
440 esdhc_out32(&mmc->esdhc_regs->wml,
441 wml | ESDHC_WML_WR_BRST(BURST_128_BYTES));
442 esdhc_out32(&mmc->esdhc_regs->wml,
443 wml | ESDHC_WML_RD_BRST(BURST_128_BYTES));
444
445 /* Set DMA System Destination Address */
446 esdhc_out32(&mmc->esdhc_regs->dsaddr, dst);
447 } else {
448 wl = (blklen >= BLOCK_LEN_512) ?
449 WML_512_BYTES : ((blklen + 3) / 4);
450 /* Set 'Read Water Mark Level' register */
451 esdhc_out32(&mmc->esdhc_regs->wml, wml | ESDHC_WML_RD_WML(wl));
452 }
453
454 /* Configure block Attributes register */
455 esdhc_out32(&mmc->esdhc_regs->blkattr,
456 ESDHC_BLKATTR_BLKCNT(blkcnt) | ESDHC_BLKATTR_BLKSZE(blklen));
457
458 mmc->block_len = blklen;
459
460 return 0;
461}
462
463/***************************************************************************
464 * Function : esdhc_read_data_nodma
465 * Arguments : mmc - Pointer to mmc struct
Elyes Haouas2be03c02023-02-13 09:14:48 +0100466 * dest_ptr - Buffer where read data is to be copied
Pankaj Gupta7d2f40f2020-12-09 14:02:39 +0530467 * len - Length of Data to be read
468 * Return : SUCCESS or Error Code
469 * Description : Read data from the sdhc buffer without using DMA
470 * and using polling mode
471 ***************************************************************************/
472static int esdhc_read_data_nodma(struct mmc *mmc, void *dest_ptr, uint32_t len)
473{
474 uint32_t i = 0U;
475 uint32_t status;
476 uint32_t num_blocks;
477 uint32_t *dst = (uint32_t *)dest_ptr;
478 uint32_t val;
479 uint64_t start_time;
480
481 num_blocks = len / mmc->block_len;
482
483 while ((num_blocks--) != 0U) {
484
485 start_time = get_timer_val(0);
486 while (get_timer_val(start_time) < SD_TIMEOUT_HIGH) {
487 val = esdhc_in32(&mmc->esdhc_regs->prsstat) &
488 ESDHC_PRSSTAT_BREN;
489 if (val != 0U) {
490 break;
491 }
492 }
493
494 val = esdhc_in32(&mmc->esdhc_regs->prsstat)
495 & ESDHC_PRSSTAT_BREN;
496 if (val == 0U) {
497 return ERROR_ESDHC_COMMUNICATION_ERROR;
498 }
499
500 for (i = 0U, status = esdhc_in32(&mmc->esdhc_regs->irqstat);
501 i < mmc->block_len / 4; i++, dst++) {
502 /* get data from data port */
503 val = mmio_read_32(
504 (uintptr_t)&mmc->esdhc_regs->datport);
505 esdhc_out32(dst, val);
506 /* Increment destination pointer */
507 status = esdhc_in32(&mmc->esdhc_regs->irqstat);
508 }
509 /* Check whether the interrupt is an DTOE/DCE/DEBE */
510 if ((status & (ESDHC_IRQSTAT_DTOE | ESDHC_IRQSTAT_DCE |
511 ESDHC_IRQSTAT_DEBE)) != 0) {
512 ERROR("SD read error - DTOE, DCE, DEBE bit set = %x\n",
513 status);
514 return ERROR_ESDHC_COMMUNICATION_ERROR;
515 }
516 }
517
518 /* Wait for TC */
519
520 start_time = get_timer_val(0);
521 while (get_timer_val(start_time) < SD_TIMEOUT_HIGH) {
522 val = esdhc_in32(&mmc->esdhc_regs->irqstat) & ESDHC_IRQSTAT_TC;
523 if (val != 0U) {
524 break;
525 }
526 }
527
528 val = esdhc_in32(&mmc->esdhc_regs->irqstat) & ESDHC_IRQSTAT_TC;
529 if (val == 0U) {
530 ERROR("SD read timeout: Transfer bit not set in IRQSTAT\n");
531 return ERROR_ESDHC_COMMUNICATION_ERROR;
532 }
533
534 return 0;
535}
536
537/***************************************************************************
538 * Function : esdhc_write_data_nodma
539 * Arguments : mmc - Pointer to mmc struct
540 * src_ptr - Buffer where data is copied from
541 * len - Length of Data to be written
542 * Return : SUCCESS or Error Code
543 * Description : Write data to the sdhc buffer without using DMA
544 * and using polling mode
545 ***************************************************************************/
546static int esdhc_write_data_nodma(struct mmc *mmc, void *src_ptr, uint32_t len)
547{
548 uint32_t i = 0U;
549 uint32_t status;
550 uint32_t num_blocks;
551 uint32_t *src = (uint32_t *)src_ptr;
552 uint32_t val;
553 uint64_t start_time;
554
555 num_blocks = len / mmc->block_len;
556
557 while ((num_blocks--) != 0U) {
558 start_time = get_timer_val(0);
559 while (get_timer_val(start_time) < SD_TIMEOUT_HIGH) {
560 val = esdhc_in32(&mmc->esdhc_regs->prsstat) &
561 ESDHC_PRSSTAT_BWEN;
562 if (val != 0U) {
563 break;
564 }
565 }
566
567 val = esdhc_in32(&mmc->esdhc_regs->prsstat) &
568 ESDHC_PRSSTAT_BWEN;
569 if (val == 0U) {
570 return ERROR_ESDHC_COMMUNICATION_ERROR;
571 }
572
573 for (i = 0U, status = esdhc_in32(&mmc->esdhc_regs->irqstat);
574 i < mmc->block_len / 4; i++, src++) {
575 val = esdhc_in32(src);
576 /* put data to data port */
577 mmio_write_32((uintptr_t)&mmc->esdhc_regs->datport,
578 val);
579 /* Increment source pointer */
580 status = esdhc_in32(&mmc->esdhc_regs->irqstat);
581 }
582 /* Check whether the interrupt is an DTOE/DCE/DEBE */
583 if ((status & (ESDHC_IRQSTAT_DTOE | ESDHC_IRQSTAT_DCE |
584 ESDHC_IRQSTAT_DEBE)) != 0) {
585 ERROR("SD write error - DTOE, DCE, DEBE bit set = %x\n",
586 status);
587 return ERROR_ESDHC_COMMUNICATION_ERROR;
588 }
589 }
590
591 /* Wait for TC */
592 start_time = get_timer_val(0);
593 while (get_timer_val(start_time) < SD_TIMEOUT_HIGH) {
594 val = esdhc_in32(&mmc->esdhc_regs->irqstat) & ESDHC_IRQSTAT_TC;
595 if (val != 0U) {
596 break;
597 }
598 }
599
600 val = esdhc_in32(&mmc->esdhc_regs->irqstat) & ESDHC_IRQSTAT_TC;
601 if (val == 0U) {
602 ERROR("SD write timeout: Transfer bit not set in IRQSTAT\n");
603 return ERROR_ESDHC_COMMUNICATION_ERROR;
604 }
605
606 return 0;
607}
608
609/***************************************************************************
610 * Function : esdhc_read_data_dma
611 * Arguments : mmc - Pointer to mmc struct
612 * len - Length of Data to be read
613 * Return : SUCCESS or Error Code
614 * Description : Read data from the sd card using DMA.
615 ***************************************************************************/
616static int esdhc_read_data_dma(struct mmc *mmc, uint32_t len)
617{
618 uint32_t status;
619 uint32_t tblk;
620 uint64_t start_time;
621
622 tblk = SD_BLOCK_TIMEOUT * (len / mmc->block_len);
623
624 start_time = get_timer_val(0);
625
626 /* poll till TC is set */
627 do {
628 status = esdhc_in32(&mmc->esdhc_regs->irqstat);
629
630 if ((status & (ESDHC_IRQSTAT_DEBE | ESDHC_IRQSTAT_DCE
631 | ESDHC_IRQSTAT_DTOE)) != 0) {
632 ERROR("SD read error - DTOE, DCE, DEBE bit set = %x\n",
633 status);
634 return ERROR_ESDHC_COMMUNICATION_ERROR;
635 }
636
637 if ((status & ESDHC_IRQSTAT_DMAE) != 0) {
638 ERROR("SD read error - DMA error = %x\n", status);
639 return ERROR_ESDHC_DMA_ERROR;
640 }
641
642 } while (((status & ESDHC_IRQSTAT_TC) == 0) &&
643 ((esdhc_in32(&mmc->esdhc_regs->prsstat) & ESDHC_PRSSTAT_DLA) != 0) &&
644 (get_timer_val(start_time) < SD_TIMEOUT_HIGH + tblk));
645
646 if (get_timer_val(start_time) > SD_TIMEOUT_HIGH + tblk) {
647 ERROR("SD read DMA timeout\n");
648 return ERROR_ESDHC_COMMUNICATION_ERROR;
649 }
650
651 return 0;
652}
653
654/***************************************************************************
655 * Function : esdhc_write_data_dma
656 * Arguments : mmc - Pointer to mmc struct
657 * len - Length of Data to be written
658 * Return : SUCCESS or Error Code
659 * Description : Write data to the sd card using DMA.
660 ***************************************************************************/
661static int esdhc_write_data_dma(struct mmc *mmc, uint32_t len)
662{
663 uint32_t status;
664 uint32_t tblk;
665 uint64_t start_time;
666
667 tblk = SD_BLOCK_TIMEOUT * (len / mmc->block_len);
668
669 start_time = get_timer_val(0);
670
671 /* poll till TC is set */
672 do {
673 status = esdhc_in32(&mmc->esdhc_regs->irqstat);
674
675 if ((status & (ESDHC_IRQSTAT_DEBE | ESDHC_IRQSTAT_DCE
676 | ESDHC_IRQSTAT_DTOE)) != 0) {
677 ERROR("SD write error - DTOE, DCE, DEBE bit set = %x\n",
678 status);
679 return ERROR_ESDHC_COMMUNICATION_ERROR;
680 }
681
682 if ((status & ESDHC_IRQSTAT_DMAE) != 0) {
683 ERROR("SD write error - DMA error = %x\n", status);
684 return ERROR_ESDHC_DMA_ERROR;
685 }
686 } while (((status & ESDHC_IRQSTAT_TC) == 0) &&
687 ((esdhc_in32(&mmc->esdhc_regs->prsstat) & ESDHC_PRSSTAT_DLA) != 0) &&
688 (get_timer_val(start_time) < SD_TIMEOUT_HIGH + tblk));
689
690 if (get_timer_val(start_time) > SD_TIMEOUT_HIGH + tblk) {
691 ERROR("SD write DMA timeout\n");
692 return ERROR_ESDHC_COMMUNICATION_ERROR;
693 }
694
695 return 0;
696}
697
698/***************************************************************************
699 * Function : esdhc_read_data
700 * Arguments : mmc - Pointer to mmc struct
Elyes Haouas2be03c02023-02-13 09:14:48 +0100701 * dest_ptr - Buffer where read data is to be copied
Pankaj Gupta7d2f40f2020-12-09 14:02:39 +0530702 * len - Length of Data to be read
703 * Return : SUCCESS or Error Code
704 * Description : Calls esdhc_read_data_nodma and clear interrupt status
705 ***************************************************************************/
706int esdhc_read_data(struct mmc *mmc, void *dest_ptr, uint32_t len)
707{
708 int ret;
709
710 if (mmc->dma_support && len > 64) {
711 ret = esdhc_read_data_dma(mmc, len);
712 } else {
713 ret = esdhc_read_data_nodma(mmc, dest_ptr, len);
714 }
715
716 /* clear interrupt status */
717 esdhc_out32(&mmc->esdhc_regs->irqstat, ESDHC_IRQSTAT_CLEAR_ALL);
718
719 return ret;
720}
721
722/***************************************************************************
723 * Function : esdhc_write_data
724 * Arguments : mmc - Pointer to mmc struct
725 * src_ptr - Buffer where data is copied from
726 * len - Length of Data to be written
727 * Return : SUCCESS or Error Code
728 * Description : Calls esdhc_write_data_nodma and clear interrupt status
729 ***************************************************************************/
730int esdhc_write_data(struct mmc *mmc, void *src_ptr, uint32_t len)
731{
732 int ret;
733
734 if (mmc->dma_support && len > 64) {
735 ret = esdhc_write_data_dma(mmc, len);
736 } else {
737 ret = esdhc_write_data_nodma(mmc, src_ptr, len);
738 }
739
740 /* clear interrupt status */
741 esdhc_out32(&mmc->esdhc_regs->irqstat, ESDHC_IRQSTAT_CLEAR_ALL);
742
743 return ret;
744}
745
746/***************************************************************************
747 * Function : sd_switch_to_high_freq
748 * Arguments : mmc - Pointer to mmc struct
749 * Return : SUCCESS or Error Code
750 * Description : 1. Send ACMD51 (CMD_SEND_SCR)
751 * 2. Read the SCR to check if card supports higher freq
752 * 3. check version from SCR
753 * 4. If SD 1.0, return (no Switch) freq = 25 MHz.
754 * 5. Send CMD6 (CMD_SWITCH_FUNC) with args 0x00FFFFF1 to
755 * check the status of switch func
756 * 6. Send CMD6 (CMD_SWITCH_FUNC) With args 0x80FFFFF1 to
757 * switch to high frequency = 50 Mhz
758 ***************************************************************************/
759static int sd_switch_to_high_freq(struct mmc *mmc)
760{
761 int err;
762 uint8_t scr[8];
763 uint8_t status[64];
764 uint32_t response[4];
765 uint32_t version;
766 uint32_t count;
767 uint32_t sd_versions[] = {SD_CARD_VERSION_1_0, SD_CARD_VERSION_1_10,
768 SD_CARD_VERSION_2_0};
769
770 mmc->card.bus_freq = SD_SS_25MHZ;
771 /* Send Application command */
772 err = esdhc_send_cmd(mmc, CMD_APP_CMD, mmc->card.rca << 16);
773 if (err != 0) {
774 return err;
775 }
776
777 err = esdhc_wait_response(mmc, response);
778 if (err != 0) {
779 return err;
780 }
781
782 esdhc_set_data_attributes(mmc, NULL, 1, 8);
783 /* Read the SCR to find out if this card supports higher speeds */
784 err = esdhc_send_cmd(mmc, CMD_SEND_SCR, mmc->card.rca << 16);
785 if (err != 0) {
786 return err;
787 }
788 err = esdhc_wait_response(mmc, response);
789 if (err != 0) {
790 return err;
791 }
792
793 /* read 8 bytes of scr data */
794 err = esdhc_read_data(mmc, scr, 8U);
795 if (err != 0) {
796 return ERROR_ESDHC_COMMUNICATION_ERROR;
797 }
798
799 /* check version from SCR */
800 version = scr[0] & U(0xF);
801 if (version <= 2U) {
802 mmc->card.version = sd_versions[version];
803 } else {
804 mmc->card.version = SD_CARD_VERSION_2_0;
805 }
806
807 /* does not support switch func */
808 if (mmc->card.version == SD_CARD_VERSION_1_0) {
809 return 0;
810 }
811
812 /* read 64 bytes of status */
813 esdhc_set_data_attributes(mmc, NULL, 1U, 64U);
814
815 /* check the status of switch func */
816 for (count = 0U; count < 4U; count++) {
817 err = esdhc_send_cmd(mmc, CMD_SWITCH_FUNC,
818 SD_SWITCH_FUNC_CHECK_MODE);
819 if (err != 0) {
820 return err;
821 }
822 err = esdhc_wait_response(mmc, response);
823 if (err != 0) {
824 return err;
825 }
826 /* read 64 bytes of scr data */
827 err = esdhc_read_data(mmc, status, 64U);
828 if (err != 0) {
829 return ERROR_ESDHC_COMMUNICATION_ERROR;
830 }
831
832 if ((status[29] & SD_SWITCH_FUNC_HIGH_SPEED) == 0) {
833 break;
834 }
835 }
836
837 if ((status[13] & SD_SWITCH_FUNC_HIGH_SPEED) == 0) {
838 return 0;
839 }
840
841 /* SWITCH */
842 esdhc_set_data_attributes(mmc, NULL, 1, 64);
843 err = esdhc_send_cmd(mmc, CMD_SWITCH_FUNC, SD_SWITCH_FUNC_SWITCH_MODE);
844 if (err != 0) {
845 return err;
846 }
847 err = esdhc_wait_response(mmc, response);
848 if (err != 0) {
849 return err;
850 }
851
852 err = esdhc_read_data(mmc, status, 64U);
853 if (err != 0) {
854 return ERROR_ESDHC_COMMUNICATION_ERROR;
855 }
856
857 if ((status[16]) == U(0x01)) {
858 mmc->card.bus_freq = SD_HS_50MHZ;
859 }
860
861 return 0;
862}
863
864/***************************************************************************
865 * Function : change_state_to_transfer_state
866 * Arguments : mmc - Pointer to mmc struct
867 * Return : SUCCESS or Error Code
868 * Description : 1. Send CMD7 (CMD_SELECT_CARD) to toggles the card
869 * between stand-by and transfer state
870 * 2. Send CMD13 (CMD_SEND_STATUS) to check state as
871 * Transfer State
872 ***************************************************************************/
873static int change_state_to_transfer_state(struct mmc *mmc)
874{
875 int error = 0;
876 uint32_t response[4];
877 uint64_t start_time;
878
879 /* Command CMD_SELECT_CARD/CMD7 toggles the card between stand-by
880 * and transfer states
881 */
882 error = esdhc_send_cmd(mmc, CMD_SELECT_CARD, mmc->card.rca << 16);
883 if (error != 0) {
884 return error;
885 }
886 error = esdhc_wait_response(mmc, response);
887 if (error != 0) {
888 return error;
889 }
890
891 start_time = get_timer_val(0);
892 while (get_timer_val(start_time) < SD_TIMEOUT_HIGH) {
893 /* send CMD13 to check card status */
894 error = esdhc_send_cmd(mmc,
895 CMD_SEND_STATUS, mmc->card.rca << 16);
896 if (error != 0) {
897 return error;
898 }
899 error = esdhc_wait_response(mmc, response);
900 if ((error != 0) || ((response[0] & R1_ERROR) != 0)) {
901 return error;
902 }
903
904 /* Check for the present state of card */
905 if (((response[0] >> 9U) & U(0xF)) == STATE_TRAN) {
906 break;
907 }
908 }
909 if (((response[0] >> 9U) & U(0xF)) == STATE_TRAN) {
910 return 0;
911 } else {
912 return ERROR_ESDHC_COMMUNICATION_ERROR;
913 }
914}
915
916/***************************************************************************
917 * Function : get_cid_rca_csd
918 * Arguments : mmc - Pointer to mmc struct
919 * Return : SUCCESS or Error Code
920 * Description : 1. Send CMD2 (CMD_ALL_SEND_CID)
921 * 2. get RCA for SD cards, set rca for mmc cards
922 * Send CMD3 (CMD_SEND_RELATIVE_ADDR)
923 * 3. Send CMD9 (CMD_SEND_CSD)
924 * 4. Get MMC Version from CSD
925 ***************************************************************************/
926static int get_cid_rca_csd(struct mmc *mmc)
927{
928 int err;
929 uint32_t version;
930 uint32_t response[4];
931 uint32_t mmc_version[] = {MMC_CARD_VERSION_1_2, MMC_CARD_VERSION_1_4,
932 MMC_CARD_VERSION_2_X, MMC_CARD_VERSION_3_X,
933 MMC_CARD_VERSION_4_X};
934
935 err = esdhc_send_cmd(mmc, CMD_ALL_SEND_CID, 0);
936 if (err != 0) {
937 return err;
938 }
939 err = esdhc_wait_response(mmc, response);
940 if (err != 0) {
941 return err;
942 }
943
944 /* get RCA for SD cards, set rca for mmc cards */
945 mmc->card.rca = SD_MMC_CARD_RCA;
946
947 /* send RCA cmd */
948 err = esdhc_send_cmd(mmc, CMD_SEND_RELATIVE_ADDR, mmc->card.rca << 16);
949 if (err != 0) {
950 return err;
951 }
952 err = esdhc_wait_response(mmc, response);
953 if (err != 0) {
954 return err;
955 }
956
957 /* for SD, get the the RCA */
958 if (mmc->card.type == SD_CARD) {
959 mmc->card.rca = (response[0] >> 16) & 0xFFFF;
960 }
961
962 /* Get the CSD (card specific data) from card. */
963 err = esdhc_send_cmd(mmc, CMD_SEND_CSD, mmc->card.rca << 16);
964 if (err != 0) {
965 return err;
966 }
967 err = esdhc_wait_response(mmc, response);
968 if (err != 0) {
969 return err;
970 }
971
972 version = (response[3] >> 18U) & U(0xF);
973 if (mmc->card.type == MMC_CARD) {
974 if (version <= MMC_CARD_VERSION_4_X) {
975 mmc->card.version = mmc_version[version];
976 } else {
977 mmc->card.version = MMC_CARD_VERSION_4_X;
978 }
979 }
980
981 mmc->card.block_len = 1 << ((response[2] >> 8) & 0xF);
982
983 if (mmc->card.block_len > BLOCK_LEN_512) {
984 mmc->card.block_len = BLOCK_LEN_512;
985 }
986
987 return 0;
988}
989
990/***************************************************************************
991 * Function : identify_mmc_card
992 * Arguments : mmc - Pointer to mmc struct
993 * Return : SUCCESS or Error Code
994 * Description : 1. Send Reset Command
995 * 2. Send CMD1 with args to set voltage range and Sector
996 * Mode. (Voltage Args = 0xFF8)
997 * 3. Check the OCR Response
998 ***************************************************************************/
999static int identify_mmc_card(struct mmc *mmc)
1000{
1001 uint64_t start_time;
1002 uint32_t resp[4];
1003 int ret;
1004 uint32_t args;
1005
1006 /* card reset */
1007 ret = esdhc_send_cmd(mmc, CMD_GO_IDLE_STATE, 0U);
1008 if (ret != 0) {
1009 return ret;
1010 }
1011 ret = esdhc_wait_response(mmc, resp);
1012 if (ret != 0) {
1013 return ret;
1014 }
1015
1016 /* Send CMD1 to get the ocr value repeatedly till the card */
1017 /* busy is clear. timeout = 20sec */
1018
1019 start_time = get_timer_val(0);
1020 do {
1021 /* set the bits for the voltage ranges supported by host */
1022 args = mmc->voltages_caps | MMC_OCR_SECTOR_MODE;
1023 ret = esdhc_send_cmd(mmc, CMD_MMC_SEND_OP_COND, args);
1024 if (ret != 0) {
1025 return ret;
1026 }
1027 ret = esdhc_wait_response(mmc, resp);
1028 if (ret != 0) {
1029 return ERROR_ESDHC_UNUSABLE_CARD;
1030 }
1031 } while (((resp[0] & MMC_OCR_BUSY) == 0U) &&
1032 (get_timer_val(start_time) < SD_TIMEOUT_HIGH));
1033
1034 if (get_timer_val(start_time) > SD_TIMEOUT_HIGH) {
1035 return ERROR_ESDHC_UNUSABLE_CARD;
1036 }
1037
1038 if ((resp[0] & MMC_OCR_CCS) == MMC_OCR_CCS) {
1039 mmc->card.is_high_capacity = 1;
1040 }
1041
1042 return MMC_CARD;
1043}
1044
1045/***************************************************************************
1046 * Function : check_for_sd_card
1047 * Arguments : mmc - Pointer to mmc struct
1048 * Return : SUCCESS or Error Code
1049 * Description : 1. Send Reset Command
1050 * 2. Send CMD8 with pattern 0xAA (to check for SD 2.0)
1051 * 3. Send ACMD41 with args to set voltage range and HCS
1052 * HCS is set only for SD Card > 2.0
1053 * Voltage Caps = 0xFF8
1054 * 4. Check the OCR Response
1055 ***************************************************************************/
1056static int check_for_sd_card(struct mmc *mmc)
1057{
1058 uint64_t start_time;
1059 uint32_t args;
1060 int ret;
1061 uint32_t resp[4];
1062
1063 /* Send reset command */
1064 ret = esdhc_send_cmd(mmc, CMD_GO_IDLE_STATE, 0U);
1065 if (ret != 0) {
1066 return ret;
1067 }
1068 ret = esdhc_wait_response(mmc, resp);
1069 if (ret != 0) {
1070 return ret;
1071 }
1072
1073 /* send CMD8 with pattern 0xAA */
1074 args = MMC_VDD_HIGH_VOLTAGE | 0xAA;
1075 ret = esdhc_send_cmd(mmc, CMD_SEND_IF_COND, args);
1076 if (ret != 0) {
1077 return ret;
1078 }
1079 ret = esdhc_wait_response(mmc, resp);
1080 if (ret == RESP_TIMEOUT) { /* sd ver 1.x or not sd */
1081 mmc->card.is_high_capacity = 0;
1082 } else if ((resp[0] & U(0xFF)) == U(0xAA)) { /* ver 2.0 or later */
1083 mmc->card.version = SD_CARD_VERSION_2_0;
1084 } else {
1085 return NOT_SD_CARD;
1086 }
1087 /* Send Application command-55 to get the ocr value repeatedly till
1088 * the card busy is clear. timeout = 20sec
1089 */
1090
1091 start_time = get_timer_val(0);
1092 do {
1093 ret = esdhc_send_cmd(mmc, CMD_APP_CMD, 0U);
1094 if (ret != 0) {
1095 return ret;
1096 }
1097 ret = esdhc_wait_response(mmc, resp);
1098 if (ret == COMMAND_ERROR) {
1099 return ERROR_ESDHC_UNUSABLE_CARD;
1100 }
1101
1102 /* set the bits for the voltage ranges supported by host */
1103 args = mmc->voltages_caps;
1104 if (mmc->card.version == SD_CARD_VERSION_2_0) {
1105 args |= SD_OCR_HCS;
1106 }
1107
1108 /* Send ACMD41 to set voltage range */
1109 ret = esdhc_send_cmd(mmc, CMD_SD_SEND_OP_COND, args);
1110 if (ret != 0) {
1111 return ret;
1112 }
1113 ret = esdhc_wait_response(mmc, resp);
1114 if (ret == COMMAND_ERROR) {
1115 return ERROR_ESDHC_UNUSABLE_CARD;
1116 } else if (ret == RESP_TIMEOUT) {
1117 return NOT_SD_CARD;
1118 }
1119 } while (((resp[0] & MMC_OCR_BUSY) == 0U) &&
1120 (get_timer_val(start_time) < SD_TIMEOUT_HIGH));
1121
1122 if (get_timer_val(start_time) > SD_TIMEOUT_HIGH) {
1123 INFO("SD_TIMEOUT_HIGH\n");
1124 return ERROR_ESDHC_UNUSABLE_CARD;
1125 }
1126
1127 /* bit set in card capacity status */
1128 if ((resp[0] & MMC_OCR_CCS) == MMC_OCR_CCS) {
1129 mmc->card.is_high_capacity = 1;
1130 }
1131
1132 return SD_CARD;
1133}
1134
1135/***************************************************************************
1136 * Function : esdhc_emmc_init
1137 * Arguments : mmc - Pointer to mmc struct
1138 * src_emmc - Flag to Indicate SRC as emmc
1139 * Return : SUCCESS or Error Code (< 0)
1140 * Description : Base Function called from sd_mmc_init or emmc_init
1141 ***************************************************************************/
1142int esdhc_emmc_init(struct mmc *mmc, bool card_detect)
1143{
1144 int error = 0;
1145 int ret = 0;
1146
1147 error = esdhc_init(mmc, card_detect);
1148 if (error != 0) {
1149 return error;
1150 }
1151
1152 mmc->card.bus_freq = CARD_IDENTIFICATION_FREQ;
1153 mmc->card.rca = 0;
1154 mmc->card.is_high_capacity = 0;
1155 mmc->card.type = ERROR_ESDHC_UNUSABLE_CARD;
1156
1157 /* Set Voltage caps as FF8 i.e all supported */
1158 /* high voltage bits 2.7 - 3.6 */
1159 mmc->voltages_caps = MMC_OCR_VDD_FF8;
1160
1161#ifdef NXP_SD_DMA_CAPABILITY
1162 /* Getting host DMA capabilities. */
1163 mmc->dma_support = esdhc_in32(&mmc->esdhc_regs->hostcapblt) &
1164 ESDHC_HOSTCAPBLT_DMAS;
1165#else
1166 mmc->dma_support = 0;
1167#endif
1168
1169 ret = NOT_SD_CARD;
1170 /* If SRC is not EMMC, check for SD or MMC */
1171 ret = check_for_sd_card(mmc);
1172 switch (ret) {
1173 case SD_CARD:
1174 mmc->card.type = SD_CARD;
1175 break;
1176
1177 case NOT_SD_CARD:
1178 /* try for MMC card */
1179 if (identify_mmc_card(mmc) == MMC_CARD) {
1180 mmc->card.type = MMC_CARD;
1181 } else {
1182 return ERROR_ESDHC_UNUSABLE_CARD;
1183 }
1184 break;
1185
1186 default:
1187 return ERROR_ESDHC_UNUSABLE_CARD;
1188 }
1189
1190 /* get CID, RCA and CSD. For MMC, set the rca */
1191 error = get_cid_rca_csd(mmc);
1192 if (error != 0) {
1193 return ERROR_ESDHC_COMMUNICATION_ERROR;
1194 }
1195
1196 /* change state to Transfer mode */
1197 error = change_state_to_transfer_state(mmc);
1198 if (error != 0) {
1199 return ERROR_ESDHC_COMMUNICATION_ERROR;
1200 }
1201
1202 /* change to high frequency if supported */
1203 if (mmc->card.type == SD_CARD) {
1204 error = sd_switch_to_high_freq(mmc);
1205 } else {
1206 error = mmc_switch_to_high_frquency(mmc);
1207 }
1208 if (error != 0) {
1209 return ERROR_ESDHC_COMMUNICATION_ERROR;
1210 }
1211
1212 /* mmc: 20000000, 26000000, 52000000 */
1213 /* sd: 25000000, 50000000 */
1214 set_speed(mmc, mmc->card.bus_freq);
1215
1216 INFO("init done:\n");
1217 return 0;
1218}
1219
1220/***************************************************************************
1221 * Function : sd_mmc_init
1222 * Arguments : mmc - Pointer to mmc struct
1223 * Return : SUCCESS or Error Code
1224 * Description : Base Function called via hal_init for SD/MMC
1225 * initialization
1226 ***************************************************************************/
1227int sd_mmc_init(uintptr_t nxp_esdhc_addr, bool card_detect)
1228{
1229 struct mmc *mmc = NULL;
1230 int ret;
1231
1232 mmc = &mmc_drv_data;
1233 memset(mmc, 0, sizeof(struct mmc));
1234 mmc->esdhc_regs = (struct esdhc_regs *)nxp_esdhc_addr;
1235
1236 INFO("esdhc_emmc_init\n");
1237 ret = esdhc_emmc_init(mmc, card_detect);
1238 return ret;
1239}
1240
1241/***************************************************************************
1242 * Function : esdhc_read_block
1243 * Arguments : mmc - Pointer to mmc struct
1244 * dst - Destination Pointer
1245 * block - Block Number
1246 * Return : SUCCESS or Error Code
1247 * Description : Read a Single block to Destination Pointer
1248 * 1. Send CMD16 (CMD_SET_BLOCKLEN) with args as blocklen
1249 * 2. Send CMD17 (CMD_READ_SINGLE_BLOCK) with args offset
1250 ***************************************************************************/
1251static int esdhc_read_block(struct mmc *mmc, void *dst, uint32_t block)
1252{
1253 uint32_t offset;
1254 int err;
1255
1256 /* send cmd16 to set the block size. */
1257 err = esdhc_send_cmd(mmc, CMD_SET_BLOCKLEN, mmc->card.block_len);
1258 if (err != 0) {
1259 return err;
1260 }
1261 err = esdhc_wait_response(mmc, NULL);
1262 if (err != 0) {
1263 return ERROR_ESDHC_COMMUNICATION_ERROR;
1264 }
1265
1266 if (mmc->card.is_high_capacity != 0) {
1267 offset = block;
1268 } else {
1269 offset = block * mmc->card.block_len;
1270 }
1271
1272 esdhc_set_data_attributes(mmc, dst, 1, mmc->card.block_len);
1273 err = esdhc_send_cmd(mmc, CMD_READ_SINGLE_BLOCK, offset);
1274 if (err != 0) {
1275 return err;
1276 }
1277 err = esdhc_wait_response(mmc, NULL);
1278 if (err != 0) {
1279 return err;
1280 }
1281
1282 err = esdhc_read_data(mmc, dst, mmc->card.block_len);
1283
1284 return err;
1285}
1286
1287/***************************************************************************
1288 * Function : esdhc_write_block
1289 * Arguments : mmc - Pointer to mmc struct
1290 * src - Source Pointer
1291 * block - Block Number
1292 * Return : SUCCESS or Error Code
1293 * Description : Write a Single block from Source Pointer
1294 * 1. Send CMD16 (CMD_SET_BLOCKLEN) with args as blocklen
1295 * 2. Send CMD24 (CMD_WRITE_SINGLE_BLOCK) with args offset
1296 ***************************************************************************/
1297static int esdhc_write_block(struct mmc *mmc, void *src, uint32_t block)
1298{
1299 uint32_t offset;
1300 int err;
1301
1302 /* send cmd16 to set the block size. */
1303 err = esdhc_send_cmd(mmc, CMD_SET_BLOCKLEN, mmc->card.block_len);
1304 if (err != 0) {
1305 return err;
1306 }
1307 err = esdhc_wait_response(mmc, NULL);
1308 if (err != 0) {
1309 return ERROR_ESDHC_COMMUNICATION_ERROR;
1310 }
1311
1312 if (mmc->card.is_high_capacity != 0) {
1313 offset = block;
1314 } else {
1315 offset = block * mmc->card.block_len;
1316 }
1317
1318 esdhc_set_data_attributes(mmc, src, 1, mmc->card.block_len);
1319 err = esdhc_send_cmd(mmc, CMD_WRITE_SINGLE_BLOCK, offset);
1320 if (err != 0) {
1321 return err;
1322 }
1323 err = esdhc_wait_response(mmc, NULL);
1324 if (err != 0) {
1325 return err;
1326 }
1327
1328 err = esdhc_write_data(mmc, src, mmc->card.block_len);
1329
1330 return err;
1331}
1332
1333/***************************************************************************
1334 * Function : esdhc_read
1335 * Arguments : src_offset - offset on sd/mmc to read from. Should be block
1336 * size aligned
1337 * dst - Destination Pointer
1338 * size - Length of Data ( Multiple of block size)
1339 * Return : SUCCESS or Error Code
1340 * Description : Calls esdhc_read_block repeatedly for reading the
1341 * data.
1342 ***************************************************************************/
1343int esdhc_read(struct mmc *mmc, uint32_t src_offset, uintptr_t dst, size_t size)
1344{
1345 int error = 0;
1346 uint32_t blk, num_blocks;
1347 uint8_t *buff = (uint8_t *)dst;
1348
1349#ifdef NXP_SD_DEBUG
1350 INFO("sd mmc read\n");
1351 INFO("src = %x, dst = %lxsize = %lu\n", src_offset, dst, size);
1352#endif
1353
1354 /* check for size */
1355 if (size == 0) {
1356 return 0;
1357 }
1358
1359 if ((size % mmc->card.block_len) != 0) {
1360 ERROR("Size is not block aligned\n");
1361 return -1;
1362 }
1363
1364 if ((src_offset % mmc->card.block_len) != 0) {
1365 ERROR("Size is not block aligned\n");
1366 return -1;
1367 }
1368
1369 /* start block */
1370 blk = src_offset / mmc->card.block_len;
1371#ifdef NXP_SD_DEBUG
1372 INFO("blk = %x\n", blk);
1373#endif
1374
1375 /* Number of blocks to be read */
1376 num_blocks = size / mmc->card.block_len;
1377
1378 while (num_blocks) {
1379 error = esdhc_read_block(mmc, buff, blk);
1380 if (error != 0) {
1381 ERROR("Read error = %x\n", error);
1382 return error;
1383 }
1384
1385 buff = buff + mmc->card.block_len;
1386 blk++;
1387 num_blocks--;
1388 }
1389
1390 INFO("sd-mmc read done.\n");
1391 return error;
1392}
1393
1394/***************************************************************************
1395 * Function : esdhc_write
1396 * Arguments : src - Source Pointer
1397 * dst_offset - offset on sd/mmc to write to. Should be block
1398 * size aligned
1399 * size - Length of Data (Multiple of block size)
1400 * Return : SUCCESS or Error Code
1401 * Description : Calls esdhc_write_block repeatedly for writing the
1402 * data.
1403 ***************************************************************************/
1404int esdhc_write(struct mmc *mmc, uintptr_t src, uint32_t dst_offset,
1405 size_t size)
1406{
1407 int error = 0;
1408 uint32_t blk, num_blocks;
1409 uint8_t *buff = (uint8_t *)src;
1410
1411#ifdef NXP_SD_DEBUG
1412 INFO("sd mmc write\n");
1413 INFO("src = %x, dst = %lxsize = %lu\n", src, dst_offset, size);
1414#endif
1415
1416 /* check for size */
1417 if (size == 0) {
1418 return 0;
1419 }
1420
1421 if ((size % mmc->card.block_len) != 0) {
1422 ERROR("Size is not block aligned\n");
1423 return -1;
1424 }
1425
1426 if ((dst_offset % mmc->card.block_len) != 0) {
1427 ERROR("Size is not block aligned\n");
1428 return -1;
1429 }
1430
1431 /* start block */
1432 blk = dst_offset / mmc->card.block_len;
1433#ifdef NXP_SD_DEBUG
1434 INFO("blk = %x\n", blk);
1435#endif
1436
1437 /* Number of blocks to be written */
1438 num_blocks = size / mmc->card.block_len;
1439
1440 while (num_blocks != 0U) {
1441 error = esdhc_write_block(mmc, buff, blk);
1442 if (error != 0U) {
1443 ERROR("Write error = %x\n", error);
1444 return error;
1445 }
1446
1447 buff = buff + mmc->card.block_len;
1448 blk++;
1449 num_blocks--;
1450 }
1451
1452 INFO("sd-mmc write done.\n");
1453 return error;
1454}
1455
1456static size_t ls_sd_emmc_read(int lba, uintptr_t buf, size_t size)
1457{
1458 struct mmc *mmc = NULL;
1459 int ret;
1460
1461 mmc = &mmc_drv_data;
1462 lba *= BLOCK_LEN_512;
1463 ret = esdhc_read(mmc, lba, buf, size);
1464 return ret ? 0 : size;
1465}
1466
1467static struct io_block_dev_spec ls_emmc_dev_spec = {
1468 .buffer = {
1469 .offset = 0,
1470 .length = 0,
1471 },
1472 .ops = {
1473 .read = ls_sd_emmc_read,
1474 },
1475 .block_size = BLOCK_LEN_512,
1476};
1477
1478int sd_emmc_init(uintptr_t *block_dev_spec,
1479 uintptr_t nxp_esdhc_addr,
1480 size_t nxp_sd_block_offset,
1481 size_t nxp_sd_block_size,
1482 bool card_detect)
1483{
1484 int ret;
1485
1486 ret = sd_mmc_init(nxp_esdhc_addr, card_detect);
1487 if (ret != 0) {
1488 return ret;
1489 }
1490
1491 ls_emmc_dev_spec.buffer.offset = nxp_sd_block_offset;
1492 ls_emmc_dev_spec.buffer.length = nxp_sd_block_size;
1493 *block_dev_spec = (uintptr_t)&ls_emmc_dev_spec;
1494
1495 return 0;
1496}