blob: c62886cf6c2abd94b6124f96a9cc698d4fbc6199 [file] [log] [blame]
Sheetal Tigadolib0156702020-01-05 14:59:04 +05301/*
2 * Copyright (c) 2016 - 2020, Broadcom
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stdlib.h>
8#include <stddef.h>
9
10#include "bcm_emmc.h"
11#include "emmc_chal_types.h"
12#include "emmc_chal_sd.h"
13#include "emmc_csl_sdprot.h"
14#include "emmc_csl_sdcmd.h"
15#include "emmc_csl_sd.h"
16#include "emmc_chal_sd.h"
17#include "emmc_pboot_hal_memory_drv.h"
18
19int sd_cmd0(struct sd_handle *handle)
20{
21 int res;
22 uint32_t argument = 0x0; /* Go to IDLE state. */
23
24 /* send cmd and parse result */
25 res = send_cmd(handle, SD_CMD_GO_IDLE_STATE, argument, 0, NULL);
26
27 if (res == SD_OK) {
28 /* Clear all other interrupts */
29 chal_sd_clear_irq((void *)handle->device, 0xffffffff);
30 }
31
32 return res;
33}
34
35int sd_cmd1(struct sd_handle *handle, uint32_t ocr, uint32_t *ocr_output)
36{
37 int res;
38 uint32_t options;
39 struct sd_resp resp;
40
41 options = SD_CMDR_RSP_TYPE_R3_4 << SD_CMDR_RSP_TYPE_S;
42
43 if (ocr_output == NULL) {
44 EMMC_TRACE("Invalid args\n");
45 return SD_FAIL;
46 }
47
48 /* send cmd and parse result */
49 res = send_cmd(handle, SD_CMD_SEND_OPCOND, ocr, options, &resp);
50
51 if (res == SD_OK)
52 *ocr_output = resp.data.r3.ocr;
53
54 return res;
55}
56
57int sd_cmd2(struct sd_handle *handle)
58{
59 uint32_t options;
60 struct sd_resp resp;
61
62 /* send cmd and parse result */
63 options = SD_CMDR_RSP_TYPE_R2 << SD_CMDR_RSP_TYPE_S;
64
65 return send_cmd(handle, SD_CMD_ALL_SEND_CID, 0, options, &resp);
66}
67
68int sd_cmd3(struct sd_handle *handle)
69{
70 int res;
71 uint32_t options = 0;
72 uint32_t argument;
73 struct sd_resp resp;
74
75 /* use non zero and non 0x1 value for rca */
76 handle->device->ctrl.rca = 0x5;
77 argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT;
78
79 options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
80 SD4_EMMC_TOP_CMD_CCHK_EN_MASK |
81 SD4_EMMC_TOP_CMD_CRC_EN_MASK;
82
83 /* send cmd and parse result */
84 res = send_cmd(handle, SD_CMD_MMC_SET_RCA, argument, options, &resp);
85
86 if (res != SD_OK)
87 handle->device->ctrl.rca = 0;
88
89 return res;
90}
91
92int sd_cmd7(struct sd_handle *handle, uint32_t rca)
93{
94 int res;
95 uint32_t argument, options;
96 struct sd_resp resp;
97
98 argument = (rca << SD_CMD7_ARG_RCA_SHIFT);
99
100 /*
101 * Response to CMD7 is:
102 * R1 while selectiing from Stand-By State to Transfer State
103 * R1b while selecting from Disconnected State to Programming State.
104 *
105 * In this driver, we only issue a CMD7 once, to go to transfer mode
106 * during init_mmc_card().
107 */
108 options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
109 SD4_EMMC_TOP_CMD_CCHK_EN_MASK |
110 SD4_EMMC_TOP_CMD_CRC_EN_MASK;
111
112 /* send cmd and parse result */
113 res = send_cmd(handle, SD_CMD_SELECT_DESELECT_CARD, argument, options,
114 &resp);
115
116 if (res == SD_OK)
117 /* Clear all other interrupts */
118 chal_sd_clear_irq((void *)handle->device, 0xffffffff);
119
120 return res;
121}
122
123
124/*
125 * CMD8 Get CSD_EXT
126 */
127int mmc_cmd8(struct sd_handle *handle, uint8_t *extCsdReg)
128{
129 uint32_t res, options;
130 struct sd_resp resp;
131
132 data_xfer_setup(handle, extCsdReg, CEATA_EXT_CSDBLOCK_SIZE,
133 SD_XFER_CARD_TO_HOST);
134
135 options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
136 SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK |
137 SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK;
138
139 /* send cmd and parse result */
140 res = send_cmd(handle, SD_CMD_READ_EXT_CSD, 0, options, &resp);
141
142 if (res == SD_OK)
143 res = process_data_xfer(handle, extCsdReg, 0,
144 CEATA_EXT_CSDBLOCK_SIZE,
145 SD_XFER_CARD_TO_HOST);
146
147 return res;
148}
149
150int sd_cmd9(struct sd_handle *handle, struct sd_card_data *card)
151{
152 int res;
153 uint32_t argument, options, iBlkNum, multiFactor = 1;
154 uint32_t maxReadBlockLen = 1, maxWriteBlockLen = 1;
155 struct sd_resp resp;
156
157 argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT;
158
159 options = SD_CMDR_RSP_TYPE_R2 << SD_CMDR_RSP_TYPE_S |
160 SD4_EMMC_TOP_CMD_CRC_EN_MASK;
161
162 /* send cmd and parse result */
163 res = send_cmd(handle, SD_CMD_SEND_CSD, argument, options, &resp);
164
165 if (res != SD_OK)
166 return res;
167
168 if (handle->card->type == SD_CARD_MMC) {
169 card->csd.mmc.structure = (resp.data.r2.rsp4 >> 22) & 0x3;
170 card->csd.mmc.csdSpecVer = (resp.data.r2.rsp4 >> 18) & 0x0f;
171 card->csd.mmc.taac = (resp.data.r2.rsp4 >> 8) & 0xff;
172 card->csd.mmc.nsac = resp.data.r2.rsp4 & 0xff;
173 card->csd.mmc.speed = resp.data.r2.rsp3 >> 24;
174 card->csd.mmc.classes = (resp.data.r2.rsp3 >> 12) & 0xfff;
175 card->csd.mmc.rdBlkLen = (resp.data.r2.rsp3 >> 8) & 0xf;
176 card->csd.mmc.rdBlkPartial = (resp.data.r2.rsp3 >> 7) & 0x01;
177 card->csd.mmc.wrBlkMisalign = (resp.data.r2.rsp3 >> 6) & 0x1;
178 card->csd.mmc.rdBlkMisalign = (resp.data.r2.rsp3 >> 5) & 0x1;
179 card->csd.mmc.dsr = (resp.data.r2.rsp2 >> 4) & 0x01;
180 card->csd.mmc.size =
181 ((resp.data.r2.rsp3 & 0x3) << 10) +
182 ((resp.data.r2.rsp2 >> 22) & 0x3ff);
183 card->csd.mmc.vddRdCurrMin = (resp.data.r2.rsp2 >> 19) & 0x7;
184 card->csd.mmc.vddRdCurrMax = (resp.data.r2.rsp2 >> 16) & 0x7;
185 card->csd.mmc.vddWrCurrMin = (resp.data.r2.rsp2 >> 13) & 0x7;
186 card->csd.mmc.vddWrCurrMax = (resp.data.r2.rsp2 >> 10) & 0x7;
187 card->csd.mmc.devSizeMulti = (resp.data.r2.rsp2 >> 7) & 0x7;
188 card->csd.mmc.eraseGrpSize = (resp.data.r2.rsp2 >> 2) & 0x1f;
189 card->csd.mmc.eraseGrpSizeMulti =
190 ((resp.data.r2.rsp2 & 0x3) << 3) +
191 ((resp.data.r2.rsp1 >> 29) & 0x7);
192 card->csd.mmc.wrProtGroupSize =
193 ((resp.data.r2.rsp1 >> 24) & 0x1f);
194 card->csd.mmc.wrProtGroupEnable =
195 (resp.data.r2.rsp1 >> 23) & 0x1;
196 card->csd.mmc.manuDefEcc = (resp.data.r2.rsp1 >> 21) & 0x3;
197 card->csd.mmc.wrSpeedFactor = (resp.data.r2.rsp1 >> 18) & 0x7;
198 card->csd.mmc.wrBlkLen = (resp.data.r2.rsp1 >> 14) & 0xf;
199 card->csd.mmc.wrBlkPartial = (resp.data.r2.rsp1 >> 13) & 0x1;
200 card->csd.mmc.protAppl = (resp.data.r2.rsp1 >> 8) & 0x1;
201 card->csd.mmc.copyFlag = (resp.data.r2.rsp1 >> 7) & 0x1;
202 card->csd.mmc.permWrProt = (resp.data.r2.rsp1 >> 6) & 0x1;
203 card->csd.mmc.tmpWrProt = (resp.data.r2.rsp1 >> 5) & 0x1;
204 card->csd.mmc.fileFormat = (resp.data.r2.rsp1 >> 4) & 0x03;
205 card->csd.mmc.eccCode = resp.data.r2.rsp1 & 0x03;
206 maxReadBlockLen <<= card->csd.mmc.rdBlkLen;
207 maxWriteBlockLen <<= card->csd.mmc.wrBlkLen;
208
209 iBlkNum = card->csd.mmc.size + 1;
210 multiFactor = (1 << (card->csd.mmc.devSizeMulti + 2));
211
212 handle->card->size =
213 iBlkNum * multiFactor * (1 << card->csd.mmc.rdBlkLen);
214 }
215
216 handle->card->maxRdBlkLen = maxReadBlockLen;
217 handle->card->maxWtBlkLen = maxWriteBlockLen;
218
219 if (handle->card->size < 0xA00000) {
220 /*
221 * 10MB Too small size mean, cmd9 response is wrong,
222 * Use default value 1G
223 */
224 handle->card->size = 0x40000000;
225 handle->card->maxRdBlkLen = 512;
226 handle->card->maxWtBlkLen = 512;
227 }
228
229 if ((handle->card->maxRdBlkLen > 512) ||
230 (handle->card->maxWtBlkLen > 512)) {
231 handle->card->maxRdBlkLen = 512;
232 handle->card->maxWtBlkLen = 512;
233 } else if ((handle->card->maxRdBlkLen == 0) ||
234 (handle->card->maxWtBlkLen == 0)) {
235 handle->card->maxRdBlkLen = 512;
236 handle->card->maxWtBlkLen = 512;
237 }
238
239 handle->device->cfg.blockSize = handle->card->maxRdBlkLen;
240
241 return res;
242}
243
244int sd_cmd13(struct sd_handle *handle, uint32_t *status)
245{
246 int res;
247 uint32_t argument, options;
248 struct sd_resp resp;
249
250 argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT;
251
252 options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
253 SD4_EMMC_TOP_CMD_CCHK_EN_MASK |
254 SD4_EMMC_TOP_CMD_CRC_EN_MASK;
255
256 /* send cmd and parse result */
257 res = send_cmd(handle, SD_CMD_SEND_STATUS, argument, options, &resp);
258
259 if (res == SD_OK) {
260 *status = resp.cardStatus;
261 }
262
263 return res;
264}
265
266int sd_cmd16(struct sd_handle *handle, uint32_t length)
267{
268 int res;
269 uint32_t argument, options, ntry;
270 struct sd_resp resp;
271
272 argument = length;
273
274 options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
275 SD4_EMMC_TOP_CMD_CRC_EN_MASK |
276 SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
277
278 ntry = 0;
279 do {
280 res = sd_cmd13(handle, &resp.cardStatus);
281 if (res != SD_OK) {
282 EMMC_TRACE(
283 "cmd13 failed before cmd16: rca 0x%0x, return %d, response 0x%0x\n",
284 handle->device->ctrl.rca, res, resp.cardStatus);
285 return res;
286 }
287
288 if (resp.cardStatus & 0x100)
289 break;
290
291 EMMC_TRACE("cmd13 rsp:0x%08x before cmd16\n", resp.cardStatus);
292
293 if (ntry > handle->device->cfg.retryLimit) {
294 EMMC_TRACE("cmd13 retry reach limit %d\n",
295 handle->device->cfg.retryLimit);
296 return SD_CMD_TIMEOUT;
297 }
298
299 ntry++;
300 EMMC_TRACE("cmd13 retry %d\n", ntry);
301
302 SD_US_DELAY(1000);
303
304 } while (1);
305
306 /* send cmd and parse result */
307 res = send_cmd(handle, SD_CMD_SET_BLOCKLEN, argument, options, &resp);
308
309 return res;
310}
311
312int sd_cmd17(struct sd_handle *handle,
313 uint32_t addr, uint32_t len, uint8_t *buffer)
314{
315 int res;
316 uint32_t argument, options, ntry;
317 struct sd_resp resp;
318
319 ntry = 0;
320 do {
321 res = sd_cmd13(handle, &resp.cardStatus);
322 if (res != SD_OK) {
323 EMMC_TRACE(
324 "cmd 13 failed before cmd17: rca 0x%0x, return %d, response 0x%0x\n",
325 handle->device->ctrl.rca, res, resp.cardStatus);
326 return res;
327 }
328
329 if (resp.cardStatus & 0x100)
330 break;
331
332 EMMC_TRACE("cmd13 rsp:0x%08x before cmd17\n", resp.cardStatus);
333
334 if (ntry > handle->device->cfg.retryLimit) {
335 EMMC_TRACE("cmd13 retry reach limit %d\n",
336 handle->device->cfg.retryLimit);
337 return SD_CMD_TIMEOUT;
338 }
339
340 ntry++;
341 EMMC_TRACE("cmd13 retry %d\n", ntry);
342
343 SD_US_DELAY(1000);
344
345 } while (1);
346
347 data_xfer_setup(handle, buffer, len, SD_XFER_CARD_TO_HOST);
348
349 /* send cmd and parse result */
350 argument = addr;
351 options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
352 SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK |
353 SD4_EMMC_TOP_CMD_CRC_EN_MASK | SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
354
355 res = send_cmd(handle, SD_CMD_READ_SINGLE_BLOCK, argument, options,
356 &resp);
357
358 if (res != SD_OK)
359 return res;
360
361 res = process_data_xfer(handle, buffer, addr, len, SD_XFER_CARD_TO_HOST);
362
363 return res;
364}
365
366int sd_cmd18(struct sd_handle *handle,
367 uint32_t addr, uint32_t len, uint8_t *buffer)
368{
369 int res;
370 uint32_t argument, options, ntry;
371 struct sd_resp resp;
372
373 ntry = 0;
374 do {
375 res = sd_cmd13(handle, &resp.cardStatus);
376 if (res != SD_OK) {
377 EMMC_TRACE(
378 "cmd 13 failed before cmd18: rca 0x%0x, return %d, response 0x%0x\n",
379 handle->device->ctrl.rca, res, resp.cardStatus);
380 return res;
381 }
382
383 if (resp.cardStatus & 0x100)
384 break;
385
386 EMMC_TRACE("cmd13 rsp:0x%08x before cmd18\n", resp.cardStatus);
387
388 if (ntry > handle->device->cfg.retryLimit) {
389 EMMC_TRACE("cmd13 retry reach limit %d\n",
390 handle->device->cfg.retryLimit);
391 return SD_CMD_TIMEOUT;
392 }
393
394 ntry++;
395 EMMC_TRACE("cmd13 retry %d\n", ntry);
396
397 SD_US_DELAY(1000);
398 } while (1);
399
400 data_xfer_setup(handle, buffer, len, SD_XFER_CARD_TO_HOST);
401
402 argument = addr;
403
404 options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
405 SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK |
406 SD4_EMMC_TOP_CMD_MSBS_MASK | SD4_EMMC_TOP_CMD_CCHK_EN_MASK |
407 SD4_EMMC_TOP_CMD_BCEN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK |
408 BIT(SD4_EMMC_TOP_CMD_ACMDEN_SHIFT);
409
410 /* send cmd and parse result */
411 res = send_cmd(handle, SD_CMD_READ_MULTIPLE_BLOCK, argument, options,
412 &resp);
413
414 if (res != SD_OK)
415 return res;
416
417 res = process_data_xfer(handle, buffer, addr, len, SD_XFER_CARD_TO_HOST);
418
419 return res;
420}
421
422#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE
423static int card_sts_resp(struct sd_handle *handle, uint32_t *status)
424{
425 int res;
426 uint32_t ntry = 0;
427
428 do {
429 res = sd_cmd13(handle, status);
430 if (res != SD_OK) {
431 EMMC_TRACE(
432 "cmd 13 failed before cmd35: rca 0x%0x, return %d\n",
433 handle->device->ctrl.rca, res);
434 return res;
435 }
436
437 if (*status & 0x100)
438 break;
439
440 EMMC_TRACE("cmd13 rsp:0x%08x before cmd35\n", resp.cardStatus);
441
442 if (ntry > handle->device->cfg.retryLimit) {
443 EMMC_TRACE("cmd13 retry reach limit %d\n",
444 handle->device->cfg.retryLimit);
445 return SD_CMD_TIMEOUT;
446 }
447
448 ntry++;
449 EMMC_TRACE("cmd13 retry %d\n", ntry);
450
451 SD_US_DELAY(1000);
452 } while (1);
453
454 return SD_OK;
455}
456
457int sd_cmd35(struct sd_handle *handle, uint32_t start)
458{
459 int res;
460 uint32_t argument, options;
461 struct sd_resp resp;
462
463 res = card_sts_resp(handle, &resp.cardStatus);
464 if (res != SD_OK)
465 return res;
466
467 argument = start;
468
469 options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
470 SD4_EMMC_TOP_CMD_CRC_EN_MASK |
471 SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
472
473 /* send cmd and parse result */
474 res = send_cmd(handle, SD_CMD_ERASE_GROUP_START,
475 argument, options, &resp);
476
477 if (res != SD_OK)
478 return res;
479
480 return res;
481}
482
483int sd_cmd36(struct sd_handle *handle, uint32_t end)
484{
485 int res;
486 uint32_t argument, options;
487 struct sd_resp resp;
488
489 res = card_sts_resp(handle, &resp.cardStatus);
490 if (res != SD_OK)
491 return res;
492
493 argument = end;
494
495 options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
496 SD4_EMMC_TOP_CMD_CRC_EN_MASK |
497 SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
498
499 /* send cmd and parse result */
500 res = send_cmd(handle, SD_CMD_ERASE_GROUP_END,
501 argument, options, &resp);
502
503 if (res != SD_OK)
504 return res;
505
506 return res;
507}
508
509int sd_cmd38(struct sd_handle *handle)
510{
511 int res;
512 uint32_t argument, options;
513 struct sd_resp resp;
514
515 res = card_sts_resp(handle, &resp.cardStatus);
516 if (res != SD_OK)
517 return res;
518
519 argument = 0;
520
521 options = (SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S) |
522 SD4_EMMC_TOP_CMD_CRC_EN_MASK |
523 SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
524
525 /* send cmd and parse result */
526 res = send_cmd(handle, SD_CMD_ERASE, argument, options, &resp);
527
528 if (res != SD_OK)
529 return res;
530
531 return res;
532}
533#endif
534
535#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
536
537int sd_cmd24(struct sd_handle *handle,
538 uint32_t addr, uint32_t len, uint8_t *buffer)
539{
540 int res;
541 uint32_t argument, options, ntry;
542 struct sd_resp resp;
543
544 ntry = 0;
545 do {
546 res = sd_cmd13(handle, &resp.cardStatus);
547 if (res != SD_OK) {
548 EMMC_TRACE(
549 "cmd 13 failed before cmd24: rca 0x%0x, return %d, response 0x%0x\n",
550 handle->device->ctrl.rca, res, &resp.cardStatus);
551 return res;
552 }
553
554 if (resp.cardStatus & 0x100)
555 break;
556
557 EMMC_TRACE("cmd13 rsp:0x%08x before cmd24\n", resp.cardStatus);
558
559 if (ntry > handle->device->cfg.retryLimit) {
560 EMMC_TRACE("cmd13 retry reach limit %d\n",
561 handle->device->cfg.retryLimit);
562 return SD_CMD_TIMEOUT;
563 }
564
565 ntry++;
566 EMMC_TRACE("cmd13 retry %d\n", ntry);
567
568 SD_US_DELAY(1000);
569
570 } while (1);
571
572 data_xfer_setup(handle, buffer, len, SD_XFER_HOST_TO_CARD);
573
574 argument = addr;
575
576 options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
577 SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK |
578 SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
579
580 /* send cmd and parse result */
581 res = send_cmd(handle, SD_CMD_WRITE_BLOCK, argument, options, &resp);
582
583 if (res != SD_OK)
584 return res;
585
586 res = process_data_xfer(handle, buffer, addr, len, SD_XFER_HOST_TO_CARD);
587
588 return res;
589}
590
591int sd_cmd25(struct sd_handle *handle,
592 uint32_t addr, uint32_t len, uint8_t *buffer)
593{
594 int res = SD_OK;
595 uint32_t argument, options, ntry;
596 struct sd_resp resp;
597
598 ntry = 0;
599 do {
600 res = sd_cmd13(handle, &resp.cardStatus);
601 if (res != SD_OK) {
602 EMMC_TRACE(
603 "cmd 13 failed before cmd25: rca 0x%0x, return %d, response 0x%0x\n",
604 handle->device->ctrl.rca, res, &resp.cardStatus);
605 return res;
606 }
607
608 if (resp.cardStatus & 0x100)
609 break;
610
611 EMMC_TRACE("cmd13 rsp:0x%08x before cmd25\n", resp.cardStatus);
612
613 if (ntry > handle->device->cfg.retryLimit) {
614 EMMC_TRACE("cmd13 retry reach limit %d\n",
615 handle->device->cfg.retryLimit);
616 return SD_CMD_TIMEOUT;
617 }
618
619 ntry++;
620 EMMC_TRACE("cmd13 retry %d\n", ntry);
621
622 SD_US_DELAY(1000);
623 } while (1);
624
625 data_xfer_setup(handle, buffer, len, SD_XFER_HOST_TO_CARD);
626
627 argument = addr;
628
629 options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
630 SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_MSBS_MASK |
631 SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_BCEN_MASK |
632 SD4_EMMC_TOP_CMD_CRC_EN_MASK |
633 BIT(SD4_EMMC_TOP_CMD_ACMDEN_SHIFT);
634
635 /* send cmd and parse result */
636 res = send_cmd(handle, SD_CMD_WRITE_MULTIPLE_BLOCK,
637 argument, options, &resp);
638
639 if (res != SD_OK)
640 return res;
641
642 res = process_data_xfer(handle, buffer, addr, len, SD_XFER_HOST_TO_CARD);
643
644 return res;
645}
646#endif /* INCLUDE_EMMC_DRIVER_WRITE_CODE */
647
648int mmc_cmd6(struct sd_handle *handle, uint32_t argument)
649{
650 int res;
651 uint32_t options;
652 struct sd_resp resp;
653
654 options = SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S |
655 SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK;
656
657 EMMC_TRACE("Sending CMD6 with argument 0x%X\n", argument);
658
659 /* send cmd and parse result */
660 res = send_cmd(handle, SD_ACMD_SET_BUS_WIDTH, argument, options, &resp);
661
662 /*
663 * For R1b type response:
664 * controller issues a COMMAND COMPLETE interrupt when the R1
665 * response is received,
666 * then controller monitors DAT0 for busy status,
667 * controller issues a TRANSFER COMPLETE interrupt when busy signal
668 * clears.
669 */
670 wait_for_event(handle,
671 SD4_EMMC_TOP_INTR_TXDONE_MASK | SD_ERR_INTERRUPTS,
672 handle->device->cfg.wfe_retry);
673
674 if (res == SD_OK) {
675 /* Check result of Cmd6 using Cmd13 to check card status */
676
677 /* Check status using Cmd13 */
678 res = sd_cmd13(handle, &resp.cardStatus);
679
680 if (res == SD_OK) {
681 /* Check bit 7 (SWITCH_ERROR) in card status */
682 if ((resp.cardStatus & 0x80) != 0) {
683 EMMC_TRACE("cmd6 failed: SWITCH_ERROR\n");
684 res = SD_FAIL;
685 }
686 } else {
687 EMMC_TRACE("cmd13 failed after cmd6: ");
688 EMMC_TRACE("rca 0x%0x, return %d, response 0x%0x\n",
689 handle->device->ctrl.rca, res, resp.cardStatus);
690 }
691 }
692
693 return res;
694}
695
696
697#define SD_BUSY_CHECK 0x00203000
698#define DAT0_LEVEL_MASK 0x100000 /* bit20 in PSTATE */
699#define DEV_BUSY_TIMEOUT 600000 /* 60 Sec : 600000 * 100us */
700
701int send_cmd(struct sd_handle *handle, uint32_t cmdIndex, uint32_t argument,
702 uint32_t options, struct sd_resp *resp)
703{
704 int status = SD_OK;
705 uint32_t event = 0, present, timeout = 0, retry = 0, mask = 3;
706 uint32_t temp_resp[4];
707
708 if (handle == NULL) {
709 EMMC_TRACE("Invalid handle for cmd%d\n", cmdIndex);
710 return SD_INVALID_HANDLE;
711 }
712
713 mask = (SD_BUSY_CHECK & options) ? 3 : 1;
714
715RETRY_WRITE_CMD:
716 do {
717 /* Make sure it is ok to send command */
718 present =
719 chal_sd_get_present_status((CHAL_HANDLE *) handle->device);
720 timeout++;
721
722 if (present & mask)
723 SD_US_DELAY(1000);
724 else
725 break;
726
727 } while (timeout < EMMC_BUSY_CMD_TIMEOUT_MS);
728
729 if (timeout >= EMMC_BUSY_CMD_TIMEOUT_MS) {
730 status = SD_CMD_MISSING;
731 EMMC_TRACE("cmd%d timedout %dms\n", cmdIndex, timeout);
732 }
733
734 /* Reset both DAT and CMD line if only of them are stuck */
735 if (present & mask)
736 check_error(handle, SD4_EMMC_TOP_INTR_CMDERROR_MASK);
737
738 handle->device->ctrl.argReg = argument;
739 chal_sd_send_cmd((CHAL_HANDLE *) handle->device, cmdIndex,
740 handle->device->ctrl.argReg, options);
741
742 handle->device->ctrl.cmdIndex = cmdIndex;
743
744 event = wait_for_event(handle,
745 (SD4_EMMC_TOP_INTR_CMDDONE_MASK |
746 SD_ERR_INTERRUPTS),
747 handle->device->cfg.wfe_retry);
748
749 if (handle->device->ctrl.cmdStatus == SD_CMD_MISSING) {
750 retry++;
751
752 if (retry >= handle->device->cfg.retryLimit) {
753 status = SD_CMD_MISSING;
754 EMMC_TRACE("cmd%d retry reaches the limit %d\n",
755 cmdIndex, retry);
756 } else {
757 /* reset both DAT & CMD line if one of them is stuck */
758 present = chal_sd_get_present_status((CHAL_HANDLE *)
759 handle->device);
760
761 if (present & mask)
762 check_error(handle,
763 SD4_EMMC_TOP_INTR_CMDERROR_MASK);
764
765 EMMC_TRACE("cmd%d retry %d PSTATE[0x%08x]\n",
766 cmdIndex, retry,
767 chal_sd_get_present_status((CHAL_HANDLE *)
768 handle->device));
769 goto RETRY_WRITE_CMD;
770 }
771 }
772
773 if (handle->device->ctrl.cmdStatus == SD_OK) {
774 if (resp != NULL) {
775 status =
776 chal_sd_get_response((CHAL_HANDLE *) handle->device,
777 temp_resp);
778 process_cmd_response(handle,
779 handle->device->ctrl.cmdIndex,
780 temp_resp[0], temp_resp[1],
781 temp_resp[2], temp_resp[3], resp);
782 }
783
784 /* Check Device busy after CMD */
785 if ((cmdIndex == 5) || (cmdIndex == 6) || (cmdIndex == 7) ||
786 (cmdIndex == 28) || (cmdIndex == 29) || (cmdIndex == 38)) {
787
788 timeout = 0;
789 do {
790 present =
791 chal_sd_get_present_status((CHAL_HANDLE *)
792 handle->device);
793
794 timeout++;
795
796 /* Dat[0]:bit20 low means device busy */
797 if ((present & DAT0_LEVEL_MASK) == 0) {
798 EMMC_TRACE("Device busy: ");
799 EMMC_TRACE(
800 "cmd%d arg:0x%08x: PSTATE[0x%08x]\n",
801 cmdIndex, argument, present);
802 SD_US_DELAY(100);
803 } else {
804 break;
805 }
806 } while (timeout < DEV_BUSY_TIMEOUT);
807 }
808 } else if (handle->device->ctrl.cmdStatus &&
809 handle->device->ctrl.cmdStatus != SD_CMD_MISSING) {
810 retry++;
811 status = check_error(handle, handle->device->ctrl.cmdStatus);
812
813 EMMC_TRACE(
814 "cmd%d error: cmdStatus:0x%08x error_status:0x%08x\n",
815 cmdIndex, handle->device->ctrl.cmdStatus, status);
816
817 if ((handle->device->ctrl.cmdIndex == 1) ||
818 (handle->device->ctrl.cmdIndex == 5)) {
819 status = event;
820 } else if ((handle->device->ctrl.cmdIndex == 7) ||
821 (handle->device->ctrl.cmdIndex == 41)) {
822 status = event;
823 } else if ((status == SD_ERROR_RECOVERABLE) &&
824 (retry < handle->device->cfg.retryLimit)) {
825 EMMC_TRACE("cmd%d recoverable error ", cmdIndex);
826 EMMC_TRACE("retry %d PSTATE[0x%08x].\n", retry,
827 chal_sd_get_present_status((CHAL_HANDLE *)
828 handle->device));
829 goto RETRY_WRITE_CMD;
830 } else {
831 EMMC_TRACE("cmd%d retry reaches the limit %d\n",
832 cmdIndex, retry);
833 status = event;
834 }
835 }
836
837 handle->device->ctrl.blkReg = 0;
838 /* clear error status for next command */
839 handle->device->ctrl.cmdStatus = 0;
840
841 return status;
842}