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