Lines Matching +full:clkdiv +full:- +full:-
1 // SPDX-License-Identifier: GPL-2.0+
3 * ARM PrimeCell MultiMedia Card Interface - PL180
5 * Copyright (C) ST-Ericsson SA 2010
21 #include <asm-generic/gpio.h>
39 struct pl180_mmc_host *host = dev->priv; in wait_for_command_end()
42 if ((cmd->resp_type & MMC_RSP_PRESENT)) in wait_for_command_end()
48 hoststatus = readl(&host->base->status) & statusmask; in wait_for_command_end()
51 writel(statusmask, &host->base->status_clear); in wait_for_command_end()
53 debug("CMD%d time out\n", cmd->cmdidx); in wait_for_command_end()
54 return -ETIMEDOUT; in wait_for_command_end()
56 (cmd->resp_type & MMC_RSP_CRC)) { in wait_for_command_end()
57 printf("CMD%d CRC error\n", cmd->cmdidx); in wait_for_command_end()
58 return -EILSEQ; in wait_for_command_end()
61 if (cmd->resp_type & MMC_RSP_PRESENT) { in wait_for_command_end()
62 cmd->response[0] = readl(&host->base->response0); in wait_for_command_end()
63 cmd->response[1] = readl(&host->base->response1); in wait_for_command_end()
64 cmd->response[2] = readl(&host->base->response2); in wait_for_command_end()
65 cmd->response[3] = readl(&host->base->response3); in wait_for_command_end()
68 cmd->cmdidx, cmd->response[0], cmd->response[1], in wait_for_command_end()
69 cmd->response[2], cmd->response[3]); in wait_for_command_end()
80 struct pl180_mmc_host *host = dev->priv; in do_command()
82 sdi_cmd = ((cmd->cmdidx & SDI_CMD_CMDINDEX_MASK) | SDI_CMD_CPSMEN); in do_command()
84 if (cmd->resp_type) { in do_command()
86 if (cmd->resp_type & MMC_RSP_136) in do_command()
90 writel((u32)cmd->cmdarg, &host->base->argument); in do_command()
92 writel(sdi_cmd, &host->base->command); in do_command()
96 if ((result == 0) && (cmd->cmdidx == MMC_CMD_ALL_SEND_CID)) in do_command()
97 dev->rca = 10; in do_command()
100 if ((result == 0) && (cmd->cmdidx == MMC_CMD_SET_RELATIVE_ADDR)) { in do_command()
101 u32 sdi_pwr = readl(&host->base->power) & ~SDI_PWR_OPD; in do_command()
102 writel(sdi_pwr, &host->base->power); in do_command()
112 struct pl180_mmc_host *host = dev->priv; in read_bytes()
117 status = readl(&host->base->status); in read_bytes()
122 *(tempbuff) = readl(&host->base->fifo); in read_bytes()
124 xfercount -= sizeof(u32); in read_bytes()
126 status = readl(&host->base->status); in read_bytes()
135 status = readl(&host->base->status); in read_bytes()
144 return -ETIMEDOUT; in read_bytes()
147 return -EILSEQ; in read_bytes()
150 return -EIO; in read_bytes()
153 writel(SDI_ICR_MASK, &host->base->status_clear); in read_bytes()
157 return -ENOBUFS; in read_bytes()
168 struct pl180_mmc_host *host = dev->priv; in write_bytes()
173 status = readl(&host->base->status); in write_bytes()
180 &host->base->fifo); in write_bytes()
182 xfercount -= SDI_FIFO_BURST_SIZE * sizeof(u32); in write_bytes()
185 writel(*(tempbuff), &host->base->fifo); in write_bytes()
187 xfercount -= sizeof(u32); in write_bytes()
191 status = readl(&host->base->status); in write_bytes()
198 status = readl(&host->base->status); in write_bytes()
206 return -ETIMEDOUT; in write_bytes()
209 return -EILSEQ; in write_bytes()
212 writel(SDI_ICR_MASK, &host->base->status_clear); in write_bytes()
216 return -ENOBUFS; in write_bytes()
226 int error = -ETIMEDOUT; in do_data_transfer()
227 struct pl180_mmc_host *host = dev->priv; in do_data_transfer()
230 u32 data_len = (u32) (data->blocks * data->blocksize); in do_data_transfer()
232 if (!host->version2) { in do_data_transfer()
233 blksz = (ffs(data->blocksize) - 1); in do_data_transfer()
236 blksz = data->blocksize; in do_data_transfer()
241 writel(SDI_DTIMER_DEFAULT, &host->base->datatimer); in do_data_transfer()
242 writel(data_len, &host->base->datalength); in do_data_transfer()
245 if (data->flags & MMC_DATA_READ) { in do_data_transfer()
247 writel(data_ctrl, &host->base->datactrl); in do_data_transfer()
253 error = read_bytes(dev, (u32 *)data->dest, (u32)data->blocks, in do_data_transfer()
254 (u32)data->blocksize); in do_data_transfer()
255 } else if (data->flags & MMC_DATA_WRITE) { in do_data_transfer()
260 writel(data_ctrl, &host->base->datactrl); in do_data_transfer()
261 error = write_bytes(dev, (u32 *)data->src, (u32)data->blocks, in do_data_transfer()
262 (u32)data->blocksize); in do_data_transfer()
284 struct pl180_mmc_host *host = dev->priv; in host_set_ios()
287 sdi_clkcr = readl(&host->base->clock); in host_set_ios()
290 if (dev->clock) { in host_set_ios()
291 u32 clkdiv = 0; in host_set_ios() local
294 if (dev->clock >= dev->cfg->f_max) { in host_set_ios()
295 clkdiv = 0; in host_set_ios()
296 dev->clock = dev->cfg->f_max; in host_set_ios()
298 clkdiv = (host->clock_in / dev->clock) - 2; in host_set_ios()
301 tmp_clock = host->clock_in / (clkdiv + 2); in host_set_ios()
302 while (tmp_clock > dev->clock) { in host_set_ios()
303 clkdiv++; in host_set_ios()
304 tmp_clock = host->clock_in / (clkdiv + 2); in host_set_ios()
307 if (clkdiv > SDI_CLKCR_CLKDIV_MASK) in host_set_ios()
308 clkdiv = SDI_CLKCR_CLKDIV_MASK; in host_set_ios()
310 tmp_clock = host->clock_in / (clkdiv + 2); in host_set_ios()
311 dev->clock = tmp_clock; in host_set_ios()
313 sdi_clkcr |= clkdiv; in host_set_ios()
317 if (dev->bus_width) { in host_set_ios()
320 switch (dev->bus_width) { in host_set_ios()
331 printf("Invalid bus width: %d\n", dev->bus_width); in host_set_ios()
338 writel(sdi_clkcr, &host->base->clock); in host_set_ios()
348 struct pl180_mmc_host *host = dev->priv; in mmc_host_reset()
350 writel(host->pwr_init, &host->base->power); in mmc_host_reset()
362 * mmc_host_init - initialize the mmc controller.
371 writel(host->pwr_init, &host->base->power); in arm_pl180_mmci_init()
372 writel(host->clkdiv_init, &host->base->clock); in arm_pl180_mmci_init()
376 sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK; in arm_pl180_mmci_init()
377 writel(sdi_u32, &host->base->mask0); in arm_pl180_mmci_init()
379 host->cfg.name = host->name; in arm_pl180_mmci_init()
380 host->cfg.ops = &arm_pl180_mmci_ops; in arm_pl180_mmci_init()
383 host->cfg.host_caps = host->caps; in arm_pl180_mmci_init()
384 host->cfg.voltages = host->voltages; in arm_pl180_mmci_init()
385 host->cfg.f_min = host->clock_min; in arm_pl180_mmci_init()
386 host->cfg.f_max = host->clock_max; in arm_pl180_mmci_init()
387 if (host->b_max != 0) in arm_pl180_mmci_init()
388 host->cfg.b_max = host->b_max; in arm_pl180_mmci_init()
390 host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; in arm_pl180_mmci_init()
392 *mmc = mmc_create(&host->cfg, host); in arm_pl180_mmci_init()
394 return -1; in arm_pl180_mmci_init()
396 (*mmc)->block_dev.devnum); in arm_pl180_mmci_init()
407 writel(host->pwr_init, &host->base->power); in arm_pl180_mmc_init()
408 writel(host->clkdiv_init, &host->base->clock); in arm_pl180_mmc_init()
412 sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK; in arm_pl180_mmc_init()
413 writel(sdi_u32, &host->base->mask0); in arm_pl180_mmc_init()
420 struct mmc *mmc = &pdata->mmc; in arm_pl180_mmc_probe()
421 struct pl180_mmc_host *host = dev->priv; in arm_pl180_mmc_probe()
422 struct mmc_config *cfg = &pdata->cfg; in arm_pl180_mmc_probe()
438 host->pwr_init = INIT_PWR; in arm_pl180_mmc_probe()
439 host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V1 | SDI_CLKCR_CLKEN | in arm_pl180_mmc_probe()
441 host->clock_in = clk_get_rate(&clk); in arm_pl180_mmc_probe()
442 host->version2 = dev_get_driver_data(dev); in arm_pl180_mmc_probe()
444 cfg->name = dev->name; in arm_pl180_mmc_probe()
445 cfg->voltages = VOLTAGE_WINDOW_SD; in arm_pl180_mmc_probe()
446 cfg->host_caps = 0; in arm_pl180_mmc_probe()
447 cfg->f_min = host->clock_in / (2 * (SDI_CLKCR_CLKDIV_INIT_V1 + 1)); in arm_pl180_mmc_probe()
448 cfg->f_max = dev_read_u32_default(dev, "max-frequency", MMC_CLOCK_MAX); in arm_pl180_mmc_probe()
449 cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; in arm_pl180_mmc_probe()
451 gpio_request_by_name(dev, "cd-gpios", 0, &host->cd_gpio, GPIOD_IS_IN); in arm_pl180_mmc_probe()
453 bus_width = dev_read_u32_default(dev, "bus-width", 1); in arm_pl180_mmc_probe()
456 cfg->host_caps |= MMC_MODE_8BIT; in arm_pl180_mmc_probe()
457 /* Hosts capable of 8-bit transfers can also do 4 bits */ in arm_pl180_mmc_probe()
459 cfg->host_caps |= MMC_MODE_4BIT; in arm_pl180_mmc_probe()
464 dev_err(dev, "Invalid bus-width value %u\n", bus_width); in arm_pl180_mmc_probe()
468 mmc->priv = host; in arm_pl180_mmc_probe()
469 mmc->dev = dev; in arm_pl180_mmc_probe()
470 upriv->mmc = mmc; in arm_pl180_mmc_probe()
479 return mmc_bind(dev, &plat->mmc, &plat->cfg); in arm_pl180_mmc_bind()
499 struct pl180_mmc_host *host = dev->priv; in dm_mmc_getcd()
502 if (dm_gpio_is_valid(&host->cd_gpio)) in dm_mmc_getcd()
503 value = dm_gpio_get_value(&host->cd_gpio); in dm_mmc_getcd()
516 struct pl180_mmc_host *host = dev->priv; in arm_pl180_mmc_ofdata_to_platdata()
521 return -EINVAL; in arm_pl180_mmc_ofdata_to_platdata()
523 host->base = (void *)addr; in arm_pl180_mmc_ofdata_to_platdata()
529 { .compatible = "st,stm32f4xx-sdio", .data = VERSION1 },