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