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