Lines Matching +full:pwr +full:- +full:reg
1 // SPDX-License-Identifier: GPL-2.0+
6 * Portions Copyright 2011-2016 NVIDIA Corporation
16 #include <asm/arch-tegra/tegra_mmc.h>
24 struct tegra_mmc *reg; member
37 u8 pwr = 0; in tegra_mmc_set_power() local
40 if (power != (unsigned short)-1) { in tegra_mmc_set_power()
43 pwr = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8; in tegra_mmc_set_power()
47 pwr = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_0; in tegra_mmc_set_power()
51 pwr = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3; in tegra_mmc_set_power()
55 debug("%s: pwr = %X\n", __func__, pwr); in tegra_mmc_set_power()
58 writeb(pwr, &priv->reg->pwrcon); in tegra_mmc_set_power()
59 if (pwr == 0) in tegra_mmc_set_power()
63 pwr |= TEGRA_MMC_PWRCTL_SD_BUS_POWER; in tegra_mmc_set_power()
64 writeb(pwr, &priv->reg->pwrcon); in tegra_mmc_set_power()
74 debug("buf: %p (%p), data->blocks: %u, data->blocksize: %u\n", in tegra_mmc_prepare_data()
75 bbstate->bounce_buffer, bbstate->user_buffer, data->blocks, in tegra_mmc_prepare_data()
76 data->blocksize); in tegra_mmc_prepare_data()
78 writel((u32)(unsigned long)bbstate->bounce_buffer, &priv->reg->sysad); in tegra_mmc_prepare_data()
83 * 10 = Selects 32-bit Address ADMA2 in tegra_mmc_prepare_data()
84 * 11 = Selects 64-bit Address ADMA2 in tegra_mmc_prepare_data()
86 ctrl = readb(&priv->reg->hostctl); in tegra_mmc_prepare_data()
89 writeb(ctrl, &priv->reg->hostctl); in tegra_mmc_prepare_data()
92 writew((7 << 12) | (data->blocksize & 0xFFF), &priv->reg->blksize); in tegra_mmc_prepare_data()
93 writew(data->blocks, &priv->reg->blkcnt); in tegra_mmc_prepare_data()
114 if (data->blocks > 1) in tegra_mmc_set_transfer_mode()
117 if (data->flags & MMC_DATA_READ) in tegra_mmc_set_transfer_mode()
120 writew(mode, &priv->reg->trnmod); in tegra_mmc_set_transfer_mode()
139 if ((data == NULL) && (cmd->resp_type & MMC_RSP_BUSY)) in tegra_mmc_wait_inhibit()
142 while (readl(&priv->reg->prnsts) & mask) { in tegra_mmc_wait_inhibit()
145 return -1; in tegra_mmc_wait_inhibit()
147 timeout--; in tegra_mmc_wait_inhibit()
173 debug("cmd->arg: %08x\n", cmd->cmdarg); in tegra_mmc_send_cmd_bounced()
174 writel(cmd->cmdarg, &priv->reg->argument); in tegra_mmc_send_cmd_bounced()
179 if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY)) in tegra_mmc_send_cmd_bounced()
180 return -1; in tegra_mmc_send_cmd_bounced()
194 if (!(cmd->resp_type & MMC_RSP_PRESENT)) in tegra_mmc_send_cmd_bounced()
196 else if (cmd->resp_type & MMC_RSP_136) in tegra_mmc_send_cmd_bounced()
198 else if (cmd->resp_type & MMC_RSP_BUSY) in tegra_mmc_send_cmd_bounced()
203 if (cmd->resp_type & MMC_RSP_CRC) in tegra_mmc_send_cmd_bounced()
205 if (cmd->resp_type & MMC_RSP_OPCODE) in tegra_mmc_send_cmd_bounced()
210 debug("cmd: %d\n", cmd->cmdidx); in tegra_mmc_send_cmd_bounced()
212 writew((cmd->cmdidx << 8) | flags, &priv->reg->cmdreg); in tegra_mmc_send_cmd_bounced()
215 mask = readl(&priv->reg->norintsts); in tegra_mmc_send_cmd_bounced()
219 writel(mask, &priv->reg->norintsts); in tegra_mmc_send_cmd_bounced()
226 writel(mask, &priv->reg->norintsts); in tegra_mmc_send_cmd_bounced()
227 return -ETIMEDOUT; in tegra_mmc_send_cmd_bounced()
232 debug("timeout: %08x cmd %d\n", mask, cmd->cmdidx); in tegra_mmc_send_cmd_bounced()
233 writel(mask, &priv->reg->norintsts); in tegra_mmc_send_cmd_bounced()
234 return -ETIMEDOUT; in tegra_mmc_send_cmd_bounced()
237 debug("error: %08x cmd %d\n", mask, cmd->cmdidx); in tegra_mmc_send_cmd_bounced()
238 writel(mask, &priv->reg->norintsts); in tegra_mmc_send_cmd_bounced()
239 return -1; in tegra_mmc_send_cmd_bounced()
242 if (cmd->resp_type & MMC_RSP_PRESENT) { in tegra_mmc_send_cmd_bounced()
243 if (cmd->resp_type & MMC_RSP_136) { in tegra_mmc_send_cmd_bounced()
247 (&priv->reg->rspreg3 - i); in tegra_mmc_send_cmd_bounced()
248 cmd->response[i] = readl(offset) << 8; in tegra_mmc_send_cmd_bounced()
251 cmd->response[i] |= in tegra_mmc_send_cmd_bounced()
252 readb(offset - 1); in tegra_mmc_send_cmd_bounced()
254 debug("cmd->resp[%d]: %08x\n", in tegra_mmc_send_cmd_bounced()
255 i, cmd->response[i]); in tegra_mmc_send_cmd_bounced()
257 } else if (cmd->resp_type & MMC_RSP_BUSY) { in tegra_mmc_send_cmd_bounced()
260 if (readl(&priv->reg->prnsts) in tegra_mmc_send_cmd_bounced()
267 writel(mask, &priv->reg->norintsts); in tegra_mmc_send_cmd_bounced()
268 return -ETIMEDOUT; in tegra_mmc_send_cmd_bounced()
271 cmd->response[0] = readl(&priv->reg->rspreg0); in tegra_mmc_send_cmd_bounced()
272 debug("cmd->resp[0]: %08x\n", cmd->response[0]); in tegra_mmc_send_cmd_bounced()
274 cmd->response[0] = readl(&priv->reg->rspreg0); in tegra_mmc_send_cmd_bounced()
275 debug("cmd->resp[0]: %08x\n", cmd->response[0]); in tegra_mmc_send_cmd_bounced()
283 mask = readl(&priv->reg->norintsts); in tegra_mmc_send_cmd_bounced()
287 writel(mask, &priv->reg->norintsts); in tegra_mmc_send_cmd_bounced()
290 return -1; in tegra_mmc_send_cmd_bounced()
296 unsigned int address = readl(&priv->reg->sysad); in tegra_mmc_send_cmd_bounced()
300 &priv->reg->norintsts); in tegra_mmc_send_cmd_bounced()
301 writel(address, &priv->reg->sysad); in tegra_mmc_send_cmd_bounced()
307 writel(mask, &priv->reg->norintsts); in tegra_mmc_send_cmd_bounced()
314 readl(&priv->reg->norintstsen), in tegra_mmc_send_cmd_bounced()
315 readl(&priv->reg->norintsigen), in tegra_mmc_send_cmd_bounced()
316 readl(&priv->reg->prnsts)); in tegra_mmc_send_cmd_bounced()
317 return -1; in tegra_mmc_send_cmd_bounced()
320 writel(mask, &priv->reg->norintsts); in tegra_mmc_send_cmd_bounced()
337 if (data->flags & MMC_DATA_READ) { in tegra_mmc_send_cmd()
338 buf = data->dest; in tegra_mmc_send_cmd()
341 buf = (void *)data->src; in tegra_mmc_send_cmd()
344 len = data->blocks * data->blocksize; in tegra_mmc_send_cmd()
372 rate = clk_set_rate(&priv->clk, clock); in tegra_mmc_change_clock()
373 div = (rate + clock - 1) / clock; in tegra_mmc_change_clock()
376 writew(0, &priv->reg->clkcon); in tegra_mmc_change_clock()
388 writew(clk, &priv->reg->clkcon); in tegra_mmc_change_clock()
392 while (!(readw(&priv->reg->clkcon) & in tegra_mmc_change_clock()
398 timeout--; in tegra_mmc_change_clock()
403 writew(clk, &priv->reg->clkcon); in tegra_mmc_change_clock()
408 priv->clock = clock; in tegra_mmc_change_clock()
418 debug("bus_width: %x, clock: %d\n", mmc->bus_width, mmc->clock); in tegra_mmc_set_ios()
421 tegra_mmc_change_clock(priv, mmc->clock); in tegra_mmc_set_ios()
423 ctrl = readb(&priv->reg->hostctl); in tegra_mmc_set_ios()
428 * 1 = 8-bit mode in tegra_mmc_set_ios()
430 * 1 = 4-bit mode in tegra_mmc_set_ios()
431 * 0 = 1-bit mode in tegra_mmc_set_ios()
433 if (mmc->bus_width == 8) in tegra_mmc_set_ios()
435 else if (mmc->bus_width == 4) in tegra_mmc_set_ios()
440 writeb(ctrl, &priv->reg->hostctl); in tegra_mmc_set_ios()
451 debug("%s: sdmmc address = %08x\n", __func__, (unsigned int)priv->reg); in tegra_mmc_pad_init()
454 if (priv->reg != (void *)0x78000000 && in tegra_mmc_pad_init()
455 priv->reg != (void *)0x78000400) { in tegra_mmc_pad_init()
461 val = readl(&priv->reg->sdmemcmppadctl); in tegra_mmc_pad_init()
464 writel(val, &priv->reg->sdmemcmppadctl); in tegra_mmc_pad_init()
466 val = readl(&priv->reg->autocalcfg); in tegra_mmc_pad_init()
469 writel(val, &priv->reg->autocalcfg); in tegra_mmc_pad_init()
483 writeb(TEGRA_MMC_SWRST_SW_RESET_FOR_ALL, &priv->reg->swrst); in tegra_mmc_reset()
485 priv->clock = 0; in tegra_mmc_reset()
491 while (readb(&priv->reg->swrst) & TEGRA_MMC_SWRST_SW_RESET_FOR_ALL) { in tegra_mmc_reset()
496 timeout--; in tegra_mmc_reset()
501 tegra_mmc_set_power(priv, fls(mmc->cfg->voltages) - 1); in tegra_mmc_reset()
503 readb(&priv->reg->pwrcon), readb(&priv->reg->hostctl)); in tegra_mmc_reset()
527 if (priv->reg == (void *)0x700b0400) { in tegra_mmc_init()
528 mask = readl(&priv->reg->venmiscctl); in tegra_mmc_init()
530 writel(mask, &priv->reg->venmiscctl); in tegra_mmc_init()
534 priv->version = readw(&priv->reg->hcver); in tegra_mmc_init()
535 debug("host version = %x\n", priv->version); in tegra_mmc_init()
538 writel(0xffffffff, &priv->reg->norintstsen); in tegra_mmc_init()
539 writel(0xffffffff, &priv->reg->norintsigen); in tegra_mmc_init()
541 writeb(0xe, &priv->reg->timeoutcon); /* TMCLK * 2^27 */ in tegra_mmc_init()
550 mask = readl(&priv->reg->norintstsen); in tegra_mmc_init()
557 writel(mask, &priv->reg->norintstsen); in tegra_mmc_init()
563 mask = readl(&priv->reg->norintsigen); in tegra_mmc_init()
566 writel(mask, &priv->reg->norintsigen); in tegra_mmc_init()
577 if (dm_gpio_is_valid(&priv->cd_gpio)) in tegra_mmc_getcd()
578 return dm_gpio_get_value(&priv->cd_gpio); in tegra_mmc_getcd()
594 struct mmc_config *cfg = &plat->cfg; in tegra_mmc_probe()
597 cfg->name = dev->name; in tegra_mmc_probe()
599 bus_width = dev_read_u32_default(dev, "bus-width", 1); in tegra_mmc_probe()
601 cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; in tegra_mmc_probe()
602 cfg->host_caps = 0; in tegra_mmc_probe()
604 cfg->host_caps |= MMC_MODE_8BIT; in tegra_mmc_probe()
606 cfg->host_caps |= MMC_MODE_4BIT; in tegra_mmc_probe()
607 cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; in tegra_mmc_probe()
611 * low-speed SDIO card frequency (actually 400KHz) in tegra_mmc_probe()
615 cfg->f_min = 375000; in tegra_mmc_probe()
616 cfg->f_max = 48000000; in tegra_mmc_probe()
618 cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; in tegra_mmc_probe()
620 priv->reg = (void *)dev_read_addr(dev); in tegra_mmc_probe()
622 ret = reset_get_by_name(dev, "sdhci", &priv->reset_ctl); in tegra_mmc_probe()
627 ret = clk_get_by_index(dev, 0, &priv->clk); in tegra_mmc_probe()
633 ret = reset_assert(&priv->reset_ctl); in tegra_mmc_probe()
636 ret = clk_enable(&priv->clk); in tegra_mmc_probe()
639 ret = clk_set_rate(&priv->clk, 20000000); in tegra_mmc_probe()
642 ret = reset_deassert(&priv->reset_ctl); in tegra_mmc_probe()
647 gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); in tegra_mmc_probe()
648 gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN); in tegra_mmc_probe()
649 gpio_request_by_name(dev, "power-gpios", 0, &priv->pwr_gpio, in tegra_mmc_probe()
651 if (dm_gpio_is_valid(&priv->pwr_gpio)) in tegra_mmc_probe()
652 dm_gpio_set_value(&priv->pwr_gpio, 1); in tegra_mmc_probe()
654 upriv->mmc = &plat->mmc; in tegra_mmc_probe()
663 return mmc_bind(dev, &plat->mmc, &plat->cfg); in tegra_mmc_bind()
667 { .compatible = "nvidia,tegra20-sdhci" },
668 { .compatible = "nvidia,tegra30-sdhci" },
669 { .compatible = "nvidia,tegra114-sdhci" },
670 { .compatible = "nvidia,tegra124-sdhci" },
671 { .compatible = "nvidia,tegra210-sdhci" },
672 { .compatible = "nvidia,tegra186-sdhci" },