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 38 static bool is_cmd23_enabled(void) 39 { 40 return ((mmc_flags & MMC_FLAG_CMD23) != 0U); 41 } 42 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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