1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2007-2011 4 * Allwinner Technology Co., Ltd. <www.allwinnertech.com> 5 * Aaron <leafy.myeh@allwinnertech.com> 6 * 7 * MMC driver for allwinner sunxi platform. 8 */ 9 10 #include <common.h> 11 #include <dm.h> 12 #include <errno.h> 13 #include <malloc.h> 14 #include <mmc.h> 15 #include <asm/io.h> 16 #include <asm/arch/clock.h> 17 #include <asm/arch/cpu.h> 18 #include <asm/arch/gpio.h> 19 #include <asm/arch/mmc.h> 20 #include <asm-generic/gpio.h> 21 22 struct sunxi_mmc_plat { 23 struct mmc_config cfg; 24 struct mmc mmc; 25 }; 26 27 struct sunxi_mmc_priv { 28 unsigned mmc_no; 29 uint32_t *mclkreg; 30 unsigned fatal_err; 31 struct gpio_desc cd_gpio; /* Change Detect GPIO */ 32 int cd_inverted; /* Inverted Card Detect */ 33 struct sunxi_mmc *reg; 34 struct mmc_config cfg; 35 }; 36 37 #if !CONFIG_IS_ENABLED(DM_MMC) 38 /* support 4 mmc hosts */ 39 struct sunxi_mmc_priv mmc_host[4]; 40 41 static int sunxi_mmc_getcd_gpio(int sdc_no) 42 { 43 switch (sdc_no) { 44 case 0: return sunxi_name_to_gpio(CONFIG_MMC0_CD_PIN); 45 case 1: return sunxi_name_to_gpio(CONFIG_MMC1_CD_PIN); 46 case 2: return sunxi_name_to_gpio(CONFIG_MMC2_CD_PIN); 47 case 3: return sunxi_name_to_gpio(CONFIG_MMC3_CD_PIN); 48 } 49 return -EINVAL; 50 } 51 52 static int mmc_resource_init(int sdc_no) 53 { 54 struct sunxi_mmc_priv *priv = &mmc_host[sdc_no]; 55 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; 56 int cd_pin, ret = 0; 57 58 debug("init mmc %d resource\n", sdc_no); 59 60 switch (sdc_no) { 61 case 0: 62 priv->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE; 63 priv->mclkreg = &ccm->sd0_clk_cfg; 64 break; 65 case 1: 66 priv->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE; 67 priv->mclkreg = &ccm->sd1_clk_cfg; 68 break; 69 case 2: 70 priv->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE; 71 priv->mclkreg = &ccm->sd2_clk_cfg; 72 break; 73 #ifdef SUNXI_MMC3_BASE 74 case 3: 75 priv->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE; 76 priv->mclkreg = &ccm->sd3_clk_cfg; 77 break; 78 #endif 79 default: 80 printf("Wrong mmc number %d\n", sdc_no); 81 return -1; 82 } 83 priv->mmc_no = sdc_no; 84 85 cd_pin = sunxi_mmc_getcd_gpio(sdc_no); 86 if (cd_pin >= 0) { 87 ret = gpio_request(cd_pin, "mmc_cd"); 88 if (!ret) { 89 sunxi_gpio_set_pull(cd_pin, SUNXI_GPIO_PULL_UP); 90 ret = gpio_direction_input(cd_pin); 91 } 92 } 93 94 return ret; 95 } 96 #endif 97 98 static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) 99 { 100 unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly; 101 bool new_mode = true; 102 bool calibrate = false; 103 u32 val = 0; 104 105 if (!IS_ENABLED(CONFIG_MMC_SUNXI_HAS_NEW_MODE)) 106 new_mode = false; 107 108 /* A83T support new mode only on eMMC */ 109 if (IS_ENABLED(CONFIG_MACH_SUN8I_A83T) && priv->mmc_no != 2) 110 new_mode = false; 111 112 #if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H6) 113 calibrate = true; 114 #endif 115 116 if (hz <= 24000000) { 117 pll = CCM_MMC_CTRL_OSCM24; 118 pll_hz = 24000000; 119 } else { 120 #ifdef CONFIG_MACH_SUN9I 121 pll = CCM_MMC_CTRL_PLL_PERIPH0; 122 pll_hz = clock_get_pll4_periph0(); 123 #elif defined(CONFIG_MACH_SUN50I_H6) 124 pll = CCM_MMC_CTRL_PLL6X2; 125 pll_hz = clock_get_pll6() * 2; 126 #else 127 pll = CCM_MMC_CTRL_PLL6; 128 pll_hz = clock_get_pll6(); 129 #endif 130 } 131 132 div = pll_hz / hz; 133 if (pll_hz % hz) 134 div++; 135 136 n = 0; 137 while (div > 16) { 138 n++; 139 div = (div + 1) / 2; 140 } 141 142 if (n > 3) { 143 printf("mmc %u error cannot set clock to %u\n", priv->mmc_no, 144 hz); 145 return -1; 146 } 147 148 /* determine delays */ 149 if (hz <= 400000) { 150 oclk_dly = 0; 151 sclk_dly = 0; 152 } else if (hz <= 25000000) { 153 oclk_dly = 0; 154 sclk_dly = 5; 155 #ifdef CONFIG_MACH_SUN9I 156 } else if (hz <= 52000000) { 157 oclk_dly = 5; 158 sclk_dly = 4; 159 } else { 160 /* hz > 52000000 */ 161 oclk_dly = 2; 162 sclk_dly = 4; 163 #else 164 } else if (hz <= 52000000) { 165 oclk_dly = 3; 166 sclk_dly = 4; 167 } else { 168 /* hz > 52000000 */ 169 oclk_dly = 1; 170 sclk_dly = 4; 171 #endif 172 } 173 174 if (new_mode) { 175 #ifdef CONFIG_MMC_SUNXI_HAS_NEW_MODE 176 #ifdef CONFIG_MMC_SUNXI_HAS_MODE_SWITCH 177 val = CCM_MMC_CTRL_MODE_SEL_NEW; 178 #endif 179 setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW); 180 #endif 181 } else if (!calibrate) { 182 /* 183 * Use hardcoded delay values if controller doesn't support 184 * calibration 185 */ 186 val = CCM_MMC_CTRL_OCLK_DLY(oclk_dly) | 187 CCM_MMC_CTRL_SCLK_DLY(sclk_dly); 188 } 189 190 writel(CCM_MMC_CTRL_ENABLE| pll | CCM_MMC_CTRL_N(n) | 191 CCM_MMC_CTRL_M(div) | val, priv->mclkreg); 192 193 debug("mmc %u set mod-clk req %u parent %u n %u m %u rate %u\n", 194 priv->mmc_no, hz, pll_hz, 1u << n, div, pll_hz / (1u << n) / div); 195 196 return 0; 197 } 198 199 static int mmc_update_clk(struct sunxi_mmc_priv *priv) 200 { 201 unsigned int cmd; 202 unsigned timeout_msecs = 2000; 203 unsigned long start = get_timer(0); 204 205 cmd = SUNXI_MMC_CMD_START | 206 SUNXI_MMC_CMD_UPCLK_ONLY | 207 SUNXI_MMC_CMD_WAIT_PRE_OVER; 208 209 writel(cmd, &priv->reg->cmd); 210 while (readl(&priv->reg->cmd) & SUNXI_MMC_CMD_START) { 211 if (get_timer(start) > timeout_msecs) 212 return -1; 213 } 214 215 /* clock update sets various irq status bits, clear these */ 216 writel(readl(&priv->reg->rint), &priv->reg->rint); 217 218 return 0; 219 } 220 221 static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc) 222 { 223 unsigned rval = readl(&priv->reg->clkcr); 224 225 /* Disable Clock */ 226 rval &= ~SUNXI_MMC_CLK_ENABLE; 227 writel(rval, &priv->reg->clkcr); 228 if (mmc_update_clk(priv)) 229 return -1; 230 231 /* Set mod_clk to new rate */ 232 if (mmc_set_mod_clk(priv, mmc->clock)) 233 return -1; 234 235 /* Clear internal divider */ 236 rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK; 237 writel(rval, &priv->reg->clkcr); 238 239 #if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H6) 240 /* A64 supports calibration of delays on MMC controller and we 241 * have to set delay of zero before starting calibration. 242 * Allwinner BSP driver sets a delay only in the case of 243 * using HS400 which is not supported by mainline U-Boot or 244 * Linux at the moment 245 */ 246 writel(SUNXI_MMC_CAL_DL_SW_EN, &priv->reg->samp_dl); 247 #endif 248 249 /* Re-enable Clock */ 250 rval |= SUNXI_MMC_CLK_ENABLE; 251 writel(rval, &priv->reg->clkcr); 252 if (mmc_update_clk(priv)) 253 return -1; 254 255 return 0; 256 } 257 258 static int sunxi_mmc_set_ios_common(struct sunxi_mmc_priv *priv, 259 struct mmc *mmc) 260 { 261 debug("set ios: bus_width: %x, clock: %d\n", 262 mmc->bus_width, mmc->clock); 263 264 /* Change clock first */ 265 if (mmc->clock && mmc_config_clock(priv, mmc) != 0) { 266 priv->fatal_err = 1; 267 return -EINVAL; 268 } 269 270 /* Change bus width */ 271 if (mmc->bus_width == 8) 272 writel(0x2, &priv->reg->width); 273 else if (mmc->bus_width == 4) 274 writel(0x1, &priv->reg->width); 275 else 276 writel(0x0, &priv->reg->width); 277 278 return 0; 279 } 280 281 #if !CONFIG_IS_ENABLED(DM_MMC) 282 static int sunxi_mmc_core_init(struct mmc *mmc) 283 { 284 struct sunxi_mmc_priv *priv = mmc->priv; 285 286 /* Reset controller */ 287 writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl); 288 udelay(1000); 289 290 return 0; 291 } 292 #endif 293 294 static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc, 295 struct mmc_data *data) 296 { 297 const int reading = !!(data->flags & MMC_DATA_READ); 298 const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY : 299 SUNXI_MMC_STATUS_FIFO_FULL; 300 unsigned i; 301 unsigned *buff = (unsigned int *)(reading ? data->dest : data->src); 302 unsigned byte_cnt = data->blocksize * data->blocks; 303 unsigned timeout_msecs = byte_cnt >> 8; 304 unsigned long start; 305 306 if (timeout_msecs < 2000) 307 timeout_msecs = 2000; 308 309 /* Always read / write data through the CPU */ 310 setbits_le32(&priv->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB); 311 312 start = get_timer(0); 313 314 for (i = 0; i < (byte_cnt >> 2); i++) { 315 while (readl(&priv->reg->status) & status_bit) { 316 if (get_timer(start) > timeout_msecs) 317 return -1; 318 } 319 320 if (reading) 321 buff[i] = readl(&priv->reg->fifo); 322 else 323 writel(buff[i], &priv->reg->fifo); 324 } 325 326 return 0; 327 } 328 329 static int mmc_rint_wait(struct sunxi_mmc_priv *priv, struct mmc *mmc, 330 uint timeout_msecs, uint done_bit, const char *what) 331 { 332 unsigned int status; 333 unsigned long start = get_timer(0); 334 335 do { 336 status = readl(&priv->reg->rint); 337 if ((get_timer(start) > timeout_msecs) || 338 (status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT)) { 339 debug("%s timeout %x\n", what, 340 status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT); 341 return -ETIMEDOUT; 342 } 343 } while (!(status & done_bit)); 344 345 return 0; 346 } 347 348 static int sunxi_mmc_send_cmd_common(struct sunxi_mmc_priv *priv, 349 struct mmc *mmc, struct mmc_cmd *cmd, 350 struct mmc_data *data) 351 { 352 unsigned int cmdval = SUNXI_MMC_CMD_START; 353 unsigned int timeout_msecs; 354 int error = 0; 355 unsigned int status = 0; 356 unsigned int bytecnt = 0; 357 358 if (priv->fatal_err) 359 return -1; 360 if (cmd->resp_type & MMC_RSP_BUSY) 361 debug("mmc cmd %d check rsp busy\n", cmd->cmdidx); 362 if (cmd->cmdidx == 12) 363 return 0; 364 365 if (!cmd->cmdidx) 366 cmdval |= SUNXI_MMC_CMD_SEND_INIT_SEQ; 367 if (cmd->resp_type & MMC_RSP_PRESENT) 368 cmdval |= SUNXI_MMC_CMD_RESP_EXPIRE; 369 if (cmd->resp_type & MMC_RSP_136) 370 cmdval |= SUNXI_MMC_CMD_LONG_RESPONSE; 371 if (cmd->resp_type & MMC_RSP_CRC) 372 cmdval |= SUNXI_MMC_CMD_CHK_RESPONSE_CRC; 373 374 if (data) { 375 if ((u32)(long)data->dest & 0x3) { 376 error = -1; 377 goto out; 378 } 379 380 cmdval |= SUNXI_MMC_CMD_DATA_EXPIRE|SUNXI_MMC_CMD_WAIT_PRE_OVER; 381 if (data->flags & MMC_DATA_WRITE) 382 cmdval |= SUNXI_MMC_CMD_WRITE; 383 if (data->blocks > 1) 384 cmdval |= SUNXI_MMC_CMD_AUTO_STOP; 385 writel(data->blocksize, &priv->reg->blksz); 386 writel(data->blocks * data->blocksize, &priv->reg->bytecnt); 387 } 388 389 debug("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", priv->mmc_no, 390 cmd->cmdidx, cmdval | cmd->cmdidx, cmd->cmdarg); 391 writel(cmd->cmdarg, &priv->reg->arg); 392 393 if (!data) 394 writel(cmdval | cmd->cmdidx, &priv->reg->cmd); 395 396 /* 397 * transfer data and check status 398 * STATREG[2] : FIFO empty 399 * STATREG[3] : FIFO full 400 */ 401 if (data) { 402 int ret = 0; 403 404 bytecnt = data->blocksize * data->blocks; 405 debug("trans data %d bytes\n", bytecnt); 406 writel(cmdval | cmd->cmdidx, &priv->reg->cmd); 407 ret = mmc_trans_data_by_cpu(priv, mmc, data); 408 if (ret) { 409 error = readl(&priv->reg->rint) & 410 SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT; 411 error = -ETIMEDOUT; 412 goto out; 413 } 414 } 415 416 error = mmc_rint_wait(priv, mmc, 1000, SUNXI_MMC_RINT_COMMAND_DONE, 417 "cmd"); 418 if (error) 419 goto out; 420 421 if (data) { 422 timeout_msecs = 120; 423 debug("cacl timeout %x msec\n", timeout_msecs); 424 error = mmc_rint_wait(priv, mmc, timeout_msecs, 425 data->blocks > 1 ? 426 SUNXI_MMC_RINT_AUTO_COMMAND_DONE : 427 SUNXI_MMC_RINT_DATA_OVER, 428 "data"); 429 if (error) 430 goto out; 431 } 432 433 if (cmd->resp_type & MMC_RSP_BUSY) { 434 unsigned long start = get_timer(0); 435 timeout_msecs = 2000; 436 437 do { 438 status = readl(&priv->reg->status); 439 if (get_timer(start) > timeout_msecs) { 440 debug("busy timeout\n"); 441 error = -ETIMEDOUT; 442 goto out; 443 } 444 } while (status & SUNXI_MMC_STATUS_CARD_DATA_BUSY); 445 } 446 447 if (cmd->resp_type & MMC_RSP_136) { 448 cmd->response[0] = readl(&priv->reg->resp3); 449 cmd->response[1] = readl(&priv->reg->resp2); 450 cmd->response[2] = readl(&priv->reg->resp1); 451 cmd->response[3] = readl(&priv->reg->resp0); 452 debug("mmc resp 0x%08x 0x%08x 0x%08x 0x%08x\n", 453 cmd->response[3], cmd->response[2], 454 cmd->response[1], cmd->response[0]); 455 } else { 456 cmd->response[0] = readl(&priv->reg->resp0); 457 debug("mmc resp 0x%08x\n", cmd->response[0]); 458 } 459 out: 460 if (error < 0) { 461 writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl); 462 mmc_update_clk(priv); 463 } 464 writel(0xffffffff, &priv->reg->rint); 465 writel(readl(&priv->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET, 466 &priv->reg->gctrl); 467 468 return error; 469 } 470 471 #if !CONFIG_IS_ENABLED(DM_MMC) 472 static int sunxi_mmc_set_ios_legacy(struct mmc *mmc) 473 { 474 struct sunxi_mmc_priv *priv = mmc->priv; 475 476 return sunxi_mmc_set_ios_common(priv, mmc); 477 } 478 479 static int sunxi_mmc_send_cmd_legacy(struct mmc *mmc, struct mmc_cmd *cmd, 480 struct mmc_data *data) 481 { 482 struct sunxi_mmc_priv *priv = mmc->priv; 483 484 return sunxi_mmc_send_cmd_common(priv, mmc, cmd, data); 485 } 486 487 static int sunxi_mmc_getcd_legacy(struct mmc *mmc) 488 { 489 struct sunxi_mmc_priv *priv = mmc->priv; 490 int cd_pin; 491 492 cd_pin = sunxi_mmc_getcd_gpio(priv->mmc_no); 493 if (cd_pin < 0) 494 return 1; 495 496 return !gpio_get_value(cd_pin); 497 } 498 499 static const struct mmc_ops sunxi_mmc_ops = { 500 .send_cmd = sunxi_mmc_send_cmd_legacy, 501 .set_ios = sunxi_mmc_set_ios_legacy, 502 .init = sunxi_mmc_core_init, 503 .getcd = sunxi_mmc_getcd_legacy, 504 }; 505 506 struct mmc *sunxi_mmc_init(int sdc_no) 507 { 508 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; 509 struct sunxi_mmc_priv *priv = &mmc_host[sdc_no]; 510 struct mmc_config *cfg = &priv->cfg; 511 int ret; 512 513 memset(priv, '\0', sizeof(struct sunxi_mmc_priv)); 514 515 cfg->name = "SUNXI SD/MMC"; 516 cfg->ops = &sunxi_mmc_ops; 517 518 cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; 519 cfg->host_caps = MMC_MODE_4BIT; 520 #if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN50I_H6) 521 if (sdc_no == 2) 522 cfg->host_caps = MMC_MODE_8BIT; 523 #endif 524 cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; 525 cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; 526 527 cfg->f_min = 400000; 528 cfg->f_max = 52000000; 529 530 if (mmc_resource_init(sdc_no) != 0) 531 return NULL; 532 533 /* config ahb clock */ 534 debug("init mmc %d clock and io\n", sdc_no); 535 #if !defined(CONFIG_MACH_SUN50I_H6) 536 setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no)); 537 538 #ifdef CONFIG_SUNXI_GEN_SUN6I 539 /* unassert reset */ 540 setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no)); 541 #endif 542 #if defined(CONFIG_MACH_SUN9I) 543 /* sun9i has a mmc-common module, also set the gate and reset there */ 544 writel(SUNXI_MMC_COMMON_CLK_GATE | SUNXI_MMC_COMMON_RESET, 545 SUNXI_MMC_COMMON_BASE + 4 * sdc_no); 546 #endif 547 #else /* CONFIG_MACH_SUN50I_H6 */ 548 setbits_le32(&ccm->sd_gate_reset, 1 << sdc_no); 549 /* unassert reset */ 550 setbits_le32(&ccm->sd_gate_reset, 1 << (RESET_SHIFT + sdc_no)); 551 #endif 552 ret = mmc_set_mod_clk(priv, 24000000); 553 if (ret) 554 return NULL; 555 556 return mmc_create(cfg, priv); 557 } 558 #else 559 560 static int sunxi_mmc_set_ios(struct udevice *dev) 561 { 562 struct sunxi_mmc_plat *plat = dev_get_platdata(dev); 563 struct sunxi_mmc_priv *priv = dev_get_priv(dev); 564 565 return sunxi_mmc_set_ios_common(priv, &plat->mmc); 566 } 567 568 static int sunxi_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, 569 struct mmc_data *data) 570 { 571 struct sunxi_mmc_plat *plat = dev_get_platdata(dev); 572 struct sunxi_mmc_priv *priv = dev_get_priv(dev); 573 574 return sunxi_mmc_send_cmd_common(priv, &plat->mmc, cmd, data); 575 } 576 577 static int sunxi_mmc_getcd(struct udevice *dev) 578 { 579 struct sunxi_mmc_priv *priv = dev_get_priv(dev); 580 581 if (dm_gpio_is_valid(&priv->cd_gpio)) { 582 int cd_state = dm_gpio_get_value(&priv->cd_gpio); 583 584 return cd_state ^ priv->cd_inverted; 585 } 586 return 1; 587 } 588 589 static const struct dm_mmc_ops sunxi_mmc_ops = { 590 .send_cmd = sunxi_mmc_send_cmd, 591 .set_ios = sunxi_mmc_set_ios, 592 .get_cd = sunxi_mmc_getcd, 593 }; 594 595 static int sunxi_mmc_probe(struct udevice *dev) 596 { 597 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); 598 struct sunxi_mmc_plat *plat = dev_get_platdata(dev); 599 struct sunxi_mmc_priv *priv = dev_get_priv(dev); 600 struct mmc_config *cfg = &plat->cfg; 601 struct ofnode_phandle_args args; 602 u32 *gate_reg; 603 int bus_width, ret; 604 605 cfg->name = dev->name; 606 bus_width = dev_read_u32_default(dev, "bus-width", 1); 607 608 cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; 609 cfg->host_caps = 0; 610 if (bus_width == 8) 611 cfg->host_caps |= MMC_MODE_8BIT; 612 if (bus_width >= 4) 613 cfg->host_caps |= MMC_MODE_4BIT; 614 cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; 615 cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; 616 617 cfg->f_min = 400000; 618 cfg->f_max = 52000000; 619 620 priv->reg = (void *)dev_read_addr(dev); 621 622 /* We don't have a sunxi clock driver so find the clock address here */ 623 ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0, 624 1, &args); 625 if (ret) 626 return ret; 627 priv->mclkreg = (u32 *)ofnode_get_addr(args.node); 628 629 ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0, 630 0, &args); 631 if (ret) 632 return ret; 633 gate_reg = (u32 *)ofnode_get_addr(args.node); 634 setbits_le32(gate_reg, 1 << args.args[0]); 635 priv->mmc_no = args.args[0] - 8; 636 637 ret = mmc_set_mod_clk(priv, 24000000); 638 if (ret) 639 return ret; 640 641 /* This GPIO is optional */ 642 if (!gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, 643 GPIOD_IS_IN)) { 644 int cd_pin = gpio_get_number(&priv->cd_gpio); 645 646 sunxi_gpio_set_pull(cd_pin, SUNXI_GPIO_PULL_UP); 647 } 648 649 /* Check if card detect is inverted */ 650 priv->cd_inverted = dev_read_bool(dev, "cd-inverted"); 651 652 upriv->mmc = &plat->mmc; 653 654 /* Reset controller */ 655 writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl); 656 udelay(1000); 657 658 return 0; 659 } 660 661 static int sunxi_mmc_bind(struct udevice *dev) 662 { 663 struct sunxi_mmc_plat *plat = dev_get_platdata(dev); 664 665 return mmc_bind(dev, &plat->mmc, &plat->cfg); 666 } 667 668 static const struct udevice_id sunxi_mmc_ids[] = { 669 { .compatible = "allwinner,sun4i-a10-mmc" }, 670 { .compatible = "allwinner,sun5i-a13-mmc" }, 671 { .compatible = "allwinner,sun7i-a20-mmc" }, 672 { } 673 }; 674 675 U_BOOT_DRIVER(sunxi_mmc_drv) = { 676 .name = "sunxi_mmc", 677 .id = UCLASS_MMC, 678 .of_match = sunxi_mmc_ids, 679 .bind = sunxi_mmc_bind, 680 .probe = sunxi_mmc_probe, 681 .ops = &sunxi_mmc_ops, 682 .platdata_auto_alloc_size = sizeof(struct sunxi_mmc_plat), 683 .priv_auto_alloc_size = sizeof(struct sunxi_mmc_priv), 684 }; 685 #endif 686