blob: 48f91eb067779fc280ddd41272b2f7a72c524408 [file] [log] [blame]
Jit Loon Lima7f54942023-05-17 12:26:11 +08001/*
2 * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
Sieu Mun Tangebca5152024-08-26 07:59:10 +08003 * Copyright (c) 2024, Altera Corporation. All rights reserved.
Jit Loon Lima7f54942023-05-17 12:26:11 +08004 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#include <assert.h>
9#include <errno.h>
10#include <stdbool.h>
11#include <string.h>
12
13#include <arch_helpers.h>
14#include <common/debug.h>
15#include <drivers/cadence/cdns_combo_phy.h>
16#include <drivers/cadence/cdns_sdmmc.h>
17#include <drivers/delay_timer.h>
18#include <lib/mmio.h>
19#include <lib/utils.h>
20
21#include "agilex5_pinmux.h"
22#include "sdmmc.h"
Sieu Mun Tangebca5152024-08-26 07:59:10 +080023#include "socfpga_mailbox.h"
Jit Loon Lima7f54942023-05-17 12:26:11 +080024
25static const struct mmc_ops *ops;
26static unsigned int mmc_ocr_value;
27static struct mmc_csd_emmc mmc_csd;
28static struct sd_switch_status sd_switch_func_status;
29static unsigned char mmc_ext_csd[512] __aligned(16);
30static unsigned int mmc_flags;
31static struct mmc_device_info *mmc_dev_info;
32static unsigned int rca;
33static unsigned int scr[2]__aligned(16) = { 0 };
34
35extern const struct mmc_ops cdns_sdmmc_ops;
36extern struct cdns_sdmmc_params cdns_params;
37extern struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg;
38extern struct cdns_sdmmc_sdhc sdmmc_sdhc_reg;
39
40static bool is_cmd23_enabled(void)
41{
42 return ((mmc_flags & MMC_FLAG_CMD23) != 0U);
43}
44
45static bool is_sd_cmd6_enabled(void)
46{
47 return ((mmc_flags & MMC_FLAG_SD_CMD6) != 0U);
48}
49
50/* TODO: Will romove once ATF driver is developed */
51void sdmmc_pin_config(void)
52{
53 /* temp use base + addr. Official must change to common method */
54 mmio_write_32(AGX5_PINMUX_PIN0SEL+0x00, 0x0);
55 mmio_write_32(AGX5_PINMUX_PIN0SEL+0x04, 0x0);
56 mmio_write_32(AGX5_PINMUX_PIN0SEL+0x08, 0x0);
57 mmio_write_32(AGX5_PINMUX_PIN0SEL+0x0C, 0x0);
58 mmio_write_32(AGX5_PINMUX_PIN0SEL+0x10, 0x0);
59 mmio_write_32(AGX5_PINMUX_PIN0SEL+0x14, 0x0);
60 mmio_write_32(AGX5_PINMUX_PIN0SEL+0x18, 0x0);
61 mmio_write_32(AGX5_PINMUX_PIN0SEL+0x1C, 0x0);
62 mmio_write_32(AGX5_PINMUX_PIN0SEL+0x20, 0x0);
63 mmio_write_32(AGX5_PINMUX_PIN0SEL+0x24, 0x0);
64 mmio_write_32(AGX5_PINMUX_PIN0SEL+0x28, 0x0);
65}
66
67static int sdmmc_send_cmd(unsigned int idx, unsigned int arg,
68 unsigned int r_type, unsigned int *r_data)
69{
70 struct mmc_cmd cmd;
71 int ret;
72
73 zeromem(&cmd, sizeof(struct mmc_cmd));
74
75 cmd.cmd_idx = idx;
76 cmd.cmd_arg = arg;
77 cmd.resp_type = r_type;
78
79 ret = ops->send_cmd(&cmd);
80
81 if ((ret == 0) && (r_data != NULL)) {
82 int i;
83
84 for (i = 0; i < 4; i++) {
85 *r_data = cmd.resp_data[i];
86 r_data++;
87 }
88 }
89
90 if (ret != 0) {
91 VERBOSE("Send command %u error: %d\n", idx, ret);
92 }
93
94 return ret;
95}
96
97static int sdmmc_device_state(void)
98{
99 int retries = DEFAULT_SDMMC_MAX_RETRIES;
100 unsigned int resp_data[4];
101
102 do {
103 int ret;
104
105 if (retries == 0) {
106 ERROR("CMD13 failed after %d retries\n",
107 DEFAULT_SDMMC_MAX_RETRIES);
108 return -EIO;
109 }
110
111 ret = sdmmc_send_cmd(MMC_CMD(13), rca << RCA_SHIFT_OFFSET,
112 MMC_RESPONSE_R1, &resp_data[0]);
113 if (ret != 0) {
114 retries--;
115 continue;
116 }
117
118 if ((resp_data[0] & STATUS_SWITCH_ERROR) != 0U) {
119 return -EIO;
120 }
121
122 retries--;
123 } while ((resp_data[0] & STATUS_READY_FOR_DATA) == 0U);
124
125 return MMC_GET_STATE(resp_data[0]);
126}
127
128static int sdmmc_set_ext_csd(unsigned int ext_cmd, unsigned int value)
129{
130 int ret;
131
132 ret = sdmmc_send_cmd(MMC_CMD(6),
133 EXTCSD_WRITE_BYTES | EXTCSD_CMD(ext_cmd) |
134 EXTCSD_VALUE(value) | EXTCSD_CMD_SET_NORMAL,
135 MMC_RESPONSE_R1B, NULL);
136 if (ret != 0) {
137 return ret;
138 }
139
140 do {
141 ret = sdmmc_device_state();
142 if (ret < 0) {
143 return ret;
144 }
145 } while (ret == MMC_STATE_PRG);
146
147 return 0;
148}
149
150static int sdmmc_mmc_sd_switch(unsigned int bus_width)
151{
152 int ret;
153 int retries = DEFAULT_SDMMC_MAX_RETRIES;
154 unsigned int bus_width_arg = 0;
155
156 /* CMD55: Application Specific Command */
157 ret = sdmmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
158 MMC_RESPONSE_R5, NULL);
159 if (ret != 0) {
160 return ret;
161 }
162
163 ret = ops->prepare(0, (uintptr_t)&scr, sizeof(scr));
164 if (ret != 0) {
165 return ret;
166 }
167
168 /* ACMD51: SEND_SCR */
169 do {
170 ret = sdmmc_send_cmd(MMC_ACMD(51), 0, MMC_RESPONSE_R1, NULL);
171 if ((ret != 0) && (retries == 0)) {
172 ERROR("ACMD51 failed after %d retries (ret=%d)\n",
173 DEFAULT_SDMMC_MAX_RETRIES, ret);
174 return ret;
175 }
176
177 retries--;
178 } while (ret != 0);
179
180 ret = ops->read(0, (uintptr_t)&scr, sizeof(scr));
181 if (ret != 0) {
182 return ret;
183 }
184
185 if (((scr[0] & SD_SCR_BUS_WIDTH_4) != 0U) &&
186 (bus_width == MMC_BUS_WIDTH_4)) {
187 bus_width_arg = 2;
188 }
189
190 /* CMD55: Application Specific Command */
191 ret = sdmmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
192 MMC_RESPONSE_R5, NULL);
193 if (ret != 0) {
194 return ret;
195 }
196
197 /* ACMD6: SET_BUS_WIDTH */
198 ret = sdmmc_send_cmd(MMC_ACMD(6), bus_width_arg, MMC_RESPONSE_R1, NULL);
199 if (ret != 0) {
200 return ret;
201 }
202
203 do {
204 ret = sdmmc_device_state();
205 if (ret < 0) {
206 return ret;
207 }
208 } while (ret == MMC_STATE_PRG);
209
210 return 0;
211}
212
213static int sdmmc_set_ios(unsigned int clk, unsigned int bus_width)
214{
215 int ret;
216 unsigned int width = bus_width;
217
218 if (mmc_dev_info->mmc_dev_type != MMC_IS_EMMC) {
219 if (width == MMC_BUS_WIDTH_8) {
220 WARN("Wrong bus config for SD-card, force to 4\n");
221 width = MMC_BUS_WIDTH_4;
222 }
223 ret = sdmmc_mmc_sd_switch(width);
224 if (ret != 0) {
225 return ret;
226 }
227 } else if (mmc_csd.spec_vers == 4U) {
228 ret = sdmmc_set_ext_csd(CMD_EXTCSD_BUS_WIDTH,
229 (unsigned int)width);
230 if (ret != 0) {
231 return ret;
232 }
233 } else {
234 VERBOSE("Wrong MMC type or spec version\n");
235 }
236
237 return ops->set_ios(clk, width);
238}
239
240static int sdmmc_fill_device_info(void)
241{
242 unsigned long long c_size;
243 unsigned int speed_idx;
244 unsigned int nb_blocks;
245 unsigned int freq_unit;
246 int ret = 0;
247 struct mmc_csd_sd_v2 *csd_sd_v2;
248
249 switch (mmc_dev_info->mmc_dev_type) {
250 case MMC_IS_EMMC:
251 mmc_dev_info->block_size = MMC_BLOCK_SIZE;
252
253 ret = ops->prepare(0, (uintptr_t)&mmc_ext_csd,
254 sizeof(mmc_ext_csd));
255 if (ret != 0) {
256 return ret;
257 }
258
259 /* MMC CMD8: SEND_EXT_CSD */
260 ret = sdmmc_send_cmd(MMC_CMD(8), 0, MMC_RESPONSE_R1, NULL);
261 if (ret != 0) {
262 return ret;
263 }
264
265 ret = ops->read(0, (uintptr_t)&mmc_ext_csd,
266 sizeof(mmc_ext_csd));
267 if (ret != 0) {
268 return ret;
269 }
270
271 do {
272 ret = sdmmc_device_state();
273 if (ret < 0) {
274 return ret;
275 }
276 } while (ret != MMC_STATE_TRAN);
277
278 nb_blocks = (mmc_ext_csd[CMD_EXTCSD_SEC_CNT] << 0) |
279 (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 1] << 8) |
280 (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 2] << 16) |
281 (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 3] << 24);
282
283 mmc_dev_info->device_size = (unsigned long long)nb_blocks *
284 mmc_dev_info->block_size;
285
286 break;
287
288 case MMC_IS_SD:
289 /*
290 * Use the same mmc_csd struct, as required fields here
291 * (READ_BL_LEN, C_SIZE, CSIZE_MULT) are common with eMMC.
292 */
293 mmc_dev_info->block_size = BIT_32(mmc_csd.read_bl_len);
294
295 c_size = ((unsigned long long)mmc_csd.c_size_high << 2U) |
296 (unsigned long long)mmc_csd.c_size_low;
297 assert(c_size != 0xFFFU);
298
299 mmc_dev_info->device_size = (c_size + 1U) *
300 BIT_64(mmc_csd.c_size_mult + 2U) *
301 mmc_dev_info->block_size;
302
303 break;
304
305 case MMC_IS_SD_HC:
306 assert(mmc_csd.csd_structure == 1U);
307
308 mmc_dev_info->block_size = MMC_BLOCK_SIZE;
309
310 /* Need to use mmc_csd_sd_v2 struct */
311 csd_sd_v2 = (struct mmc_csd_sd_v2 *)&mmc_csd;
312 c_size = ((unsigned long long)csd_sd_v2->c_size_high << 16) |
313 (unsigned long long)csd_sd_v2->c_size_low;
314
315 mmc_dev_info->device_size = (c_size + 1U) << SDMMC_MULT_BY_512K_SHIFT;
316
317 break;
318
319 default:
320 ret = -EINVAL;
321 break;
322 }
323
324 if (ret < 0) {
325 return ret;
326 }
327
328 speed_idx = (mmc_csd.tran_speed & CSD_TRAN_SPEED_MULT_MASK) >>
329 CSD_TRAN_SPEED_MULT_SHIFT;
330
331 assert(speed_idx > 0U);
332
333 if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
334 mmc_dev_info->max_bus_freq = tran_speed_base[speed_idx];
335 } else {
336 mmc_dev_info->max_bus_freq = sd_tran_speed_base[speed_idx];
337 }
338
339 freq_unit = mmc_csd.tran_speed & CSD_TRAN_SPEED_UNIT_MASK;
340 while (freq_unit != 0U) {
341 mmc_dev_info->max_bus_freq *= 10U;
342 --freq_unit;
343 }
344
345 mmc_dev_info->max_bus_freq *= 10000U;
346
347 return 0;
348}
349
350static int sdmmc_sd_switch(unsigned int mode, unsigned char group,
351 unsigned char func)
352{
353 unsigned int group_shift = (group - 1U) * 4U;
354 unsigned int group_mask = GENMASK(group_shift + 3U, group_shift);
355 unsigned int arg;
356 int ret;
357
358 ret = ops->prepare(0, (uintptr_t)&sd_switch_func_status,
359 sizeof(sd_switch_func_status));
360 if (ret != 0) {
361 return ret;
362 }
363
364 /* MMC CMD6: SWITCH_FUNC */
365 arg = mode | SD_SWITCH_ALL_GROUPS_MASK;
366 arg &= ~group_mask;
367 arg |= func << group_shift;
368 ret = sdmmc_send_cmd(MMC_CMD(6), arg, MMC_RESPONSE_R1, NULL);
369 if (ret != 0) {
370 return ret;
371 }
372
373 return ops->read(0, (uintptr_t)&sd_switch_func_status,
374 sizeof(sd_switch_func_status));
375}
376
377static int sdmmc_sd_send_op_cond(void)
378{
379 int n;
380 unsigned int resp_data[4];
381
382 for (n = 0; n < SEND_SDMMC_OP_COND_MAX_RETRIES; n++) {
383 int ret;
384
385 /* CMD55: Application Specific Command */
386 ret = sdmmc_send_cmd(MMC_CMD(55), 0, MMC_RESPONSE_R1, NULL);
387 if (ret != 0) {
388 return ret;
389 }
390
391 /* ACMD41: SD_SEND_OP_COND */
392 ret = sdmmc_send_cmd(MMC_ACMD(41), OCR_HCS |
393 mmc_dev_info->ocr_voltage, MMC_RESPONSE_R3,
394 &resp_data[0]);
395 if (ret != 0) {
396 return ret;
397 }
398
399 if ((resp_data[0] & OCR_POWERUP) != 0U) {
400 mmc_ocr_value = resp_data[0];
401
402 if ((mmc_ocr_value & OCR_HCS) != 0U) {
403 mmc_dev_info->mmc_dev_type = MMC_IS_SD_HC;
404 } else {
405 mmc_dev_info->mmc_dev_type = MMC_IS_SD;
406 }
407
408 return 0;
409 }
410
411 mdelay(10);
412 }
413
414 ERROR("ACMD41 failed after %d retries\n", SEND_SDMMC_OP_COND_MAX_RETRIES);
415
416 return -EIO;
417}
418
419static int sdmmc_reset_to_idle(void)
420{
421 int ret;
422
423 /* CMD0: reset to IDLE */
424 ret = sdmmc_send_cmd(MMC_CMD(0), 0, 0, NULL);
425 if (ret != 0) {
426 return ret;
427 }
428
429 mdelay(2);
430
431 return 0;
432}
433
434static int sdmmc_send_op_cond(void)
435{
436 int ret, n;
437 unsigned int resp_data[4];
438
439 ret = sdmmc_reset_to_idle();
440 if (ret != 0) {
441 return ret;
442 }
443
444 for (n = 0; n < SEND_SDMMC_OP_COND_MAX_RETRIES; n++) {
445 ret = sdmmc_send_cmd(MMC_CMD(1), OCR_SECTOR_MODE |
446 OCR_VDD_MIN_2V7 | OCR_VDD_MIN_1V7,
447 MMC_RESPONSE_R3, &resp_data[0]);
448 if (ret != 0) {
449 return ret;
450 }
451
452 if ((resp_data[0] & OCR_POWERUP) != 0U) {
453 mmc_ocr_value = resp_data[0];
454 return 0;
455 }
456
457 mdelay(10);
458 }
459
460 ERROR("CMD1 failed after %d retries\n", SEND_SDMMC_OP_COND_MAX_RETRIES);
461
462 return -EIO;
463}
464
465static int sdmmc_enumerate(unsigned int clk, unsigned int bus_width)
466{
467 int ret;
468 unsigned int resp_data[4];
469
470 ops->init();
471
472 ret = sdmmc_reset_to_idle();
473 if (ret != 0) {
474 return ret;
475 }
476
477 if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
478 ret = sdmmc_send_op_cond();
479 } else {
480 /* CMD8: Send Interface Condition Command */
481 ret = sdmmc_send_cmd(MMC_CMD(8), VHS_2_7_3_6_V | CMD8_CHECK_PATTERN,
482 MMC_RESPONSE_R5, &resp_data[0]);
483
484 if ((ret == 0) && ((resp_data[0] & 0xffU) == CMD8_CHECK_PATTERN)) {
485 ret = sdmmc_sd_send_op_cond();
486 }
487 }
488 if (ret != 0) {
489 return ret;
490 }
491
492 /* CMD2: Card Identification */
493 ret = sdmmc_send_cmd(MMC_CMD(2), 0, MMC_RESPONSE_R2, NULL);
494 if (ret != 0) {
495 return ret;
496 }
497
498 /* CMD3: Set Relative Address */
499 if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
500 rca = MMC_FIX_RCA;
501 ret = sdmmc_send_cmd(MMC_CMD(3), rca << RCA_SHIFT_OFFSET,
502 MMC_RESPONSE_R1, NULL);
503 if (ret != 0) {
504 return ret;
505 }
506 } else {
507 ret = sdmmc_send_cmd(MMC_CMD(3), 0,
508 MMC_RESPONSE_R6, &resp_data[0]);
509 if (ret != 0) {
510 return ret;
511 }
512
513 rca = (resp_data[0] & 0xFFFF0000U) >> 16;
514 }
515
516 /* CMD9: CSD Register */
517 ret = sdmmc_send_cmd(MMC_CMD(9), rca << RCA_SHIFT_OFFSET,
518 MMC_RESPONSE_R2, &resp_data[0]);
519 if (ret != 0) {
520 return ret;
521 }
522
Sieu Mun Tangebca5152024-08-26 07:59:10 +0800523 memcpy_s(&mmc_csd, sizeof(mmc_csd) / MBOX_WORD_BYTE,
524 &resp_data, sizeof(resp_data) / MBOX_WORD_BYTE);
Jit Loon Lima7f54942023-05-17 12:26:11 +0800525
526 /* CMD7: Select Card */
527 ret = sdmmc_send_cmd(MMC_CMD(7), rca << RCA_SHIFT_OFFSET,
528 MMC_RESPONSE_R1, NULL);
529 if (ret != 0) {
530 return ret;
531 }
532
533 do {
534 ret = sdmmc_device_state();
535 if (ret < 0) {
536 return ret;
537 }
538 } while (ret != MMC_STATE_TRAN);
539
540 ret = sdmmc_set_ios(clk, bus_width);
541 if (ret != 0) {
542 return ret;
543 }
544
545 ret = sdmmc_fill_device_info();
546 if (ret != 0) {
547 return ret;
548 }
549
550 if (is_sd_cmd6_enabled() &&
551 (mmc_dev_info->mmc_dev_type == MMC_IS_SD_HC)) {
552 /* Try to switch to High Speed Mode */
553 ret = sdmmc_sd_switch(SD_SWITCH_FUNC_CHECK, 1U, 1U);
554 if (ret != 0) {
555 return ret;
556 }
557
558 if ((sd_switch_func_status.support_g1 & BIT(9)) == 0U) {
559 /* High speed not supported, keep default speed */
560 return 0;
561 }
562
563 ret = sdmmc_sd_switch(SD_SWITCH_FUNC_SWITCH, 1U, 1U);
564 if (ret != 0) {
565 return ret;
566 }
567
568 if ((sd_switch_func_status.sel_g2_g1 & 0x1U) == 0U) {
569 /* Cannot switch to high speed, keep default speed */
570 return 0;
571 }
572
573 mmc_dev_info->max_bus_freq = 50000000U;
574 ret = ops->set_ios(clk, bus_width);
575 }
576
577 return ret;
578}
579
580size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size)
581{
582 int ret;
583 unsigned int cmd_idx, cmd_arg;
584
585 assert((ops != NULL) &&
586 (ops->read != NULL) &&
587 (size != 0U) &&
588 ((size & MMC_BLOCK_MASK) == 0U));
589
590 ret = ops->prepare(lba, buf, size);
591 if (ret != 0) {
592 return 0;
593 }
594
595 if (is_cmd23_enabled()) {
596 /* Set block count */
597 ret = sdmmc_send_cmd(MMC_CMD(23), size / MMC_BLOCK_SIZE,
598 MMC_RESPONSE_R1, NULL);
599 if (ret != 0) {
600 return 0;
601 }
602
603 cmd_idx = MMC_CMD(18);
604 } else {
605 if (size > MMC_BLOCK_SIZE) {
606 cmd_idx = MMC_CMD(18);
607 } else {
608 cmd_idx = MMC_CMD(17);
609 }
610 }
611
612 if (((mmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE) &&
613 (mmc_dev_info->mmc_dev_type != MMC_IS_SD_HC)) {
614 cmd_arg = lba * MMC_BLOCK_SIZE;
615 } else {
616 cmd_arg = lba;
617 }
618
619 ret = sdmmc_send_cmd(cmd_idx, cmd_arg, MMC_RESPONSE_R1, NULL);
620 if (ret != 0) {
621 return 0;
622 }
623
624 ret = ops->read(lba, buf, size);
625 if (ret != 0) {
626 return 0;
627 }
628
629 /* Wait buffer empty */
630 do {
631 ret = sdmmc_device_state();
632 if (ret < 0) {
633 return 0;
634 }
635 } while ((ret != MMC_STATE_TRAN) && (ret != MMC_STATE_DATA));
636
637 if (!is_cmd23_enabled() && (size > MMC_BLOCK_SIZE)) {
638 ret = sdmmc_send_cmd(MMC_CMD(12), 0, MMC_RESPONSE_R1B, NULL);
639 if (ret != 0) {
640 return 0;
641 }
642 }
643
644 return size;
645}
646
647size_t sdmmc_write_blocks(int lba, const uintptr_t buf, size_t size)
648{
649 int ret;
650 unsigned int cmd_idx, cmd_arg;
651
652 assert((ops != NULL) &&
653 (ops->write != NULL) &&
654 (size != 0U) &&
655 ((buf & MMC_BLOCK_MASK) == 0U) &&
656 ((size & MMC_BLOCK_MASK) == 0U));
657
658 ret = ops->prepare(lba, buf, size);
659 if (ret != 0) {
660 return 0;
661 }
662
663 if (is_cmd23_enabled()) {
664 /* Set block count */
665 ret = sdmmc_send_cmd(MMC_CMD(23), size / MMC_BLOCK_SIZE,
666 MMC_RESPONSE_R1, NULL);
667 if (ret != 0) {
668 return 0;
669 }
670
671 cmd_idx = MMC_CMD(25);
672 } else {
673 if (size > MMC_BLOCK_SIZE) {
674 cmd_idx = MMC_CMD(25);
675 } else {
676 cmd_idx = MMC_CMD(24);
677 }
678 }
679
680 if ((mmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE) {
681 cmd_arg = lba * MMC_BLOCK_SIZE;
682 } else {
683 cmd_arg = lba;
684 }
685
686 ret = sdmmc_send_cmd(cmd_idx, cmd_arg, MMC_RESPONSE_R1, NULL);
687 if (ret != 0) {
688 return 0;
689 }
690
691 ret = ops->write(lba, buf, size);
692 if (ret != 0) {
693 return 0;
694 }
695
696 /* Wait buffer empty */
697 do {
698 ret = sdmmc_device_state();
699 if (ret < 0) {
700 return 0;
701 }
702 } while ((ret != MMC_STATE_TRAN) && (ret != MMC_STATE_RCV));
703
704 if (!is_cmd23_enabled() && (size > MMC_BLOCK_SIZE)) {
705 ret = sdmmc_send_cmd(MMC_CMD(12), 0, MMC_RESPONSE_R1B, NULL);
706 if (ret != 0) {
707 return 0;
708 }
709 }
710
711 return size;
712}
713
714int sd_or_mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
715 unsigned int width, unsigned int flags,
716 struct mmc_device_info *device_info)
717{
718 assert((ops_ptr != NULL) &&
719 (ops_ptr->init != NULL) &&
720 (ops_ptr->send_cmd != NULL) &&
721 (ops_ptr->set_ios != NULL) &&
722 (ops_ptr->prepare != NULL) &&
723 (ops_ptr->read != NULL) &&
724 (ops_ptr->write != NULL) &&
725 (device_info != NULL) &&
726 (clk != 0) &&
727 ((width == MMC_BUS_WIDTH_1) ||
728 (width == MMC_BUS_WIDTH_4) ||
729 (width == MMC_BUS_WIDTH_8) ||
730 (width == MMC_BUS_WIDTH_DDR_4) ||
731 (width == MMC_BUS_WIDTH_DDR_8)));
732
733 ops = ops_ptr;
734 mmc_flags = flags;
735 mmc_dev_info = device_info;
736
737 return sdmmc_enumerate(clk, width);
738}
739
740int sdmmc_init(handoff *hoff_ptr, struct cdns_sdmmc_params *params, struct mmc_device_info *info)
741{
742 int result = 0;
743
744 /* SDMMC pin mux configuration */
745 sdmmc_pin_config();
746 cdns_set_sdmmc_var(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
747 result = cdns_sd_host_init(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
748 if (result < 0) {
749 return result;
750 }
751
752 assert((params != NULL) &&
753 ((params->reg_base & MMC_BLOCK_MASK) == 0) &&
754 ((params->desc_base & MMC_BLOCK_MASK) == 0) &&
755 ((params->desc_size & MMC_BLOCK_MASK) == 0) &&
756 ((params->reg_pinmux & MMC_BLOCK_MASK) == 0) &&
757 ((params->reg_phy & MMC_BLOCK_MASK) == 0) &&
758 (params->desc_size > 0) &&
759 (params->clk_rate > 0) &&
760 ((params->bus_width == MMC_BUS_WIDTH_1) ||
761 (params->bus_width == MMC_BUS_WIDTH_4) ||
762 (params->bus_width == MMC_BUS_WIDTH_8)));
763
Sieu Mun Tangebca5152024-08-26 07:59:10 +0800764 memcpy_s(&cdns_params, sizeof(struct cdns_sdmmc_params) / MBOX_WORD_BYTE,
765 params, sizeof(struct cdns_sdmmc_params) / MBOX_WORD_BYTE);
Jit Loon Lima7f54942023-05-17 12:26:11 +0800766 cdns_params.cdn_sdmmc_dev_type = info->mmc_dev_type;
767 cdns_params.cdn_sdmmc_dev_mode = SD_DS;
768
769 result = sd_or_mmc_init(&cdns_sdmmc_ops, params->clk_rate, params->bus_width,
770 params->flags, info);
771
772 return result;
773}