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