xref: /rk3399_ARM-atf/plat/intel/soc/common/drivers/sdmmc/sdmmc.c (revision e264b5573952c72805a14e69e438168c00163e9a)
1 /*
2  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
3  * Copyright (c) 2024, Altera Corporation. All rights reserved.
4  *
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"
23 #include "socfpga_mailbox.h"
24 
25 static const struct mmc_ops *ops;
26 static unsigned int mmc_ocr_value;
27 static struct mmc_csd_emmc mmc_csd;
28 static struct sd_switch_status sd_switch_func_status;
29 static unsigned char mmc_ext_csd[512] __aligned(16);
30 static unsigned int mmc_flags;
31 static struct mmc_device_info *mmc_dev_info;
32 static unsigned int rca;
33 static unsigned int scr[2]__aligned(16) = { 0 };
34 
35 extern const struct mmc_ops cdns_sdmmc_ops;
36 extern struct cdns_sdmmc_params cdns_params;
37 extern struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg;
38 extern struct cdns_sdmmc_sdhc sdmmc_sdhc_reg;
39 
40 static bool is_cmd23_enabled(void)
41 {
42 	return ((mmc_flags & MMC_FLAG_CMD23) != 0U);
43 }
44 
45 static 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 */
51 void 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 
67 static 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 
97 static 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 
128 static 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 
150 static 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 
213 static 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 
240 static 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 
350 static 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 
377 static 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 
419 static 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 
434 static 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 
465 static 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 
523 	memcpy_s(&mmc_csd, sizeof(mmc_csd) / MBOX_WORD_BYTE,
524 		&resp_data, sizeof(resp_data) / MBOX_WORD_BYTE);
525 
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 
580 size_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 
647 size_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 
714 int 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 
740 int 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 
764 	memcpy_s(&cdns_params, sizeof(struct cdns_sdmmc_params) / MBOX_WORD_BYTE,
765 		params, sizeof(struct cdns_sdmmc_params) / MBOX_WORD_BYTE);
766 	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 }
774