Lines Matching +full:ast2500 +full:- +full:sdhci
1 // SPDX-License-Identifier: GPL-2.0-or-later
18 #include "sdhci-pltfm.h"
85 * -----|-------------|----------|------------
108 writel(cap_val, sdc->regs + mirror_reg_offset); in aspeed_sdc_set_slot_capability()
112 struct aspeed_sdhci *sdhci, in aspeed_sdc_configure_8bit_mode() argument
118 spin_lock(&sdc->lock); in aspeed_sdc_configure_8bit_mode()
119 info = readl(sdc->regs + ASPEED_SDC_INFO); in aspeed_sdc_configure_8bit_mode()
121 info |= sdhci->width_mask; in aspeed_sdc_configure_8bit_mode()
123 info &= ~sdhci->width_mask; in aspeed_sdc_configure_8bit_mode()
124 writel(info, sdc->regs + ASPEED_SDC_INFO); in aspeed_sdc_configure_8bit_mode()
125 spin_unlock(&sdc->lock); in aspeed_sdc_configure_8bit_mode()
132 reg &= ~(desc->enable_mask | desc->tap_mask); in aspeed_sdc_set_phase_tap()
134 reg |= tap << __ffs(desc->tap_mask); in aspeed_sdc_set_phase_tap()
135 reg |= desc->enable_value << __ffs(desc->enable_mask); in aspeed_sdc_set_phase_tap()
148 spin_lock(&sdc->lock); in aspeed_sdc_set_phase_taps()
149 reg = readl(sdc->regs + ASPEED_SDC_PHASE); in aspeed_sdc_set_phase_taps()
151 reg = aspeed_sdc_set_phase_tap(&desc->in, taps->in, taps->valid, reg); in aspeed_sdc_set_phase_taps()
152 reg = aspeed_sdc_set_phase_tap(&desc->out, taps->out, taps->valid, reg); in aspeed_sdc_set_phase_taps()
154 writel(reg, sdc->regs + ASPEED_SDC_PHASE); in aspeed_sdc_set_phase_taps()
155 spin_unlock(&sdc->lock); in aspeed_sdc_set_phase_taps()
175 phase_deg -= 180; in aspeed_sdhci_phase_to_tap()
203 taps->valid = phases->valid; in aspeed_sdhci_phases_to_taps()
205 if (!phases->valid) in aspeed_sdhci_phases_to_taps()
208 taps->in = aspeed_sdhci_phase_to_tap(dev, rate, phases->in_deg); in aspeed_sdhci_phases_to_taps()
209 taps->out = aspeed_sdhci_phase_to_tap(dev, rate, phases->out_deg); in aspeed_sdhci_phases_to_taps()
217 struct aspeed_sdhci *sdhci; in aspeed_sdhci_configure_phase() local
220 dev = mmc_dev(host->mmc); in aspeed_sdhci_configure_phase()
221 sdhci = sdhci_pltfm_priv(sdhci_priv(host)); in aspeed_sdhci_configure_phase()
223 if (!sdhci->phase_desc) in aspeed_sdhci_configure_phase()
226 params = &sdhci->phase_map.phase[host->timing]; in aspeed_sdhci_configure_phase()
228 aspeed_sdc_set_phase_taps(sdhci->parent, sdhci->phase_desc, taps); in aspeed_sdhci_configure_phase()
231 taps->in & ASPEED_SDHCI_NR_TAPS, in aspeed_sdhci_configure_phase()
232 taps->out & ASPEED_SDHCI_NR_TAPS, in aspeed_sdhci_configure_phase()
233 params->in_deg, params->out_deg, rate, host->timing); in aspeed_sdhci_configure_phase()
240 struct aspeed_sdhci *sdhci; in aspeed_sdhci_set_clock() local
245 sdhci = sdhci_pltfm_priv(pltfm_host); in aspeed_sdhci_set_clock()
247 parent = clk_get_rate(pltfm_host->clk); in aspeed_sdhci_set_clock()
254 if (WARN_ON(clock > host->max_clk)) in aspeed_sdhci_set_clock()
255 clock = host->max_clk; in aspeed_sdhci_set_clock()
266 * If you keep EMMC12C[7:6] = 0 and EMMC12C[15:8] as one-hot, in aspeed_sdhci_set_clock()
267 * 0x1/0x2/0x4/etc, you will find it is compatible to AST2400 or AST2500 in aspeed_sdhci_set_clock()
269 * Keep the one-hot behaviour for backwards compatibility except for in aspeed_sdhci_set_clock()
271 * the 0-value capability in clk_div_start. in aspeed_sdhci_set_clock()
273 for (div = sdhci->pdata->clk_div_start; div < 256; div *= 2) { in aspeed_sdhci_set_clock()
290 if (host->mmc->f_max) in aspeed_sdhci_get_max_clock()
291 return host->mmc->f_max; in aspeed_sdhci_get_max_clock()
305 aspeed_sdc = aspeed_sdhci->parent; in aspeed_sdhci_set_bus_width()
307 /* Set/clear 8-bit mode */ in aspeed_sdhci_set_bus_width()
322 u32 val = readl(host->ioaddr + reg); in aspeed_sdhci_readl()
325 (host->mmc->caps2 & MMC_CAP2_CD_ACTIVE_HIGH)) in aspeed_sdhci_readl()
352 return -EINVAL; in aspeed_sdhci_calculate_slot()
354 if (res->start < dev->parent->res->start) in aspeed_sdhci_calculate_slot()
355 return -EINVAL; in aspeed_sdhci_calculate_slot()
357 delta = res->start - dev->parent->res->start; in aspeed_sdhci_calculate_slot()
358 if (delta & (0x100 - 1)) in aspeed_sdhci_calculate_slot()
359 return -EINVAL; in aspeed_sdhci_calculate_slot()
361 return (delta / 0x100) - 1; in aspeed_sdhci_calculate_slot()
367 struct device_node *np = pdev->dev.of_node; in aspeed_sdhci_probe()
375 aspeed_pdata = of_device_get_match_data(&pdev->dev); in aspeed_sdhci_probe()
377 dev_err(&pdev->dev, "Missing platform configuration data\n"); in aspeed_sdhci_probe()
378 return -EINVAL; in aspeed_sdhci_probe()
387 dev->pdata = aspeed_pdata; in aspeed_sdhci_probe()
388 dev->parent = dev_get_drvdata(pdev->dev.parent); in aspeed_sdhci_probe()
396 return -EINVAL; in aspeed_sdhci_probe()
398 if (slot < dev->pdata->nr_phase_descs) { in aspeed_sdhci_probe()
399 dev->phase_desc = &dev->pdata->phase_desc[slot]; in aspeed_sdhci_probe()
401 dev_info(&pdev->dev, in aspeed_sdhci_probe()
403 dev->phase_desc = NULL; in aspeed_sdhci_probe()
406 dev->width_mask = !slot ? ASPEED_SDC_S0_MMC8 : ASPEED_SDC_S1_MMC8; in aspeed_sdhci_probe()
408 dev_info(&pdev->dev, "Configured for slot %d\n", slot); in aspeed_sdhci_probe()
412 if (of_property_read_bool(np, "mmc-hs200-1_8v") || in aspeed_sdhci_probe()
413 of_property_read_bool(np, "sd-uhs-sdr104")) { in aspeed_sdhci_probe()
414 aspeed_sdc_set_slot_capability(host, dev->parent, ASPEED_SDC_CAP1_1_8V, in aspeed_sdhci_probe()
418 if (of_property_read_bool(np, "sd-uhs-sdr104")) { in aspeed_sdhci_probe()
419 aspeed_sdc_set_slot_capability(host, dev->parent, ASPEED_SDC_CAP2_SDR104, in aspeed_sdhci_probe()
423 pltfm_host->clk = devm_clk_get(&pdev->dev, NULL); in aspeed_sdhci_probe()
424 if (IS_ERR(pltfm_host->clk)) in aspeed_sdhci_probe()
425 return PTR_ERR(pltfm_host->clk); in aspeed_sdhci_probe()
427 ret = clk_prepare_enable(pltfm_host->clk); in aspeed_sdhci_probe()
429 dev_err(&pdev->dev, "Unable to enable SDIO clock\n"); in aspeed_sdhci_probe()
433 ret = mmc_of_parse(host->mmc); in aspeed_sdhci_probe()
437 if (dev->phase_desc) in aspeed_sdhci_probe()
438 mmc_of_parse_clk_phase(&pdev->dev, &dev->phase_map); in aspeed_sdhci_probe()
447 clk_disable_unprepare(pltfm_host->clk); in aspeed_sdhci_probe()
463 clk_disable_unprepare(pltfm_host->clk); in aspeed_sdhci_remove()
473 /* SDHCI/Slot 0 */
486 /* SDHCI/Slot 1 */
508 { .compatible = "aspeed,ast2400-sdhci", .data = &ast2400_sdhci_pdata, },
509 { .compatible = "aspeed,ast2500-sdhci", .data = &ast2400_sdhci_pdata, },
510 { .compatible = "aspeed,ast2600-sdhci", .data = &ast2600_sdhci_pdata, },
517 .name = "sdhci-aspeed",
532 sdc = devm_kzalloc(&pdev->dev, sizeof(*sdc), GFP_KERNEL); in aspeed_sdc_probe()
534 return -ENOMEM; in aspeed_sdc_probe()
536 spin_lock_init(&sdc->lock); in aspeed_sdc_probe()
538 sdc->clk = devm_clk_get(&pdev->dev, NULL); in aspeed_sdc_probe()
539 if (IS_ERR(sdc->clk)) in aspeed_sdc_probe()
540 return PTR_ERR(sdc->clk); in aspeed_sdc_probe()
542 ret = clk_prepare_enable(sdc->clk); in aspeed_sdc_probe()
544 dev_err(&pdev->dev, "Unable to enable SDCLK\n"); in aspeed_sdc_probe()
548 sdc->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &sdc->res); in aspeed_sdc_probe()
549 if (IS_ERR(sdc->regs)) { in aspeed_sdc_probe()
550 ret = PTR_ERR(sdc->regs); in aspeed_sdc_probe()
554 dev_set_drvdata(&pdev->dev, sdc); in aspeed_sdc_probe()
556 parent = pdev->dev.of_node; in aspeed_sdc_probe()
560 cpdev = of_platform_device_create(child, NULL, &pdev->dev); in aspeed_sdc_probe()
563 ret = -ENODEV; in aspeed_sdc_probe()
571 clk_disable_unprepare(sdc->clk); in aspeed_sdc_probe()
577 struct aspeed_sdc *sdc = dev_get_drvdata(&pdev->dev); in aspeed_sdc_remove()
579 clk_disable_unprepare(sdc->clk); in aspeed_sdc_remove()
583 { .compatible = "aspeed,ast2400-sd-controller", },
584 { .compatible = "aspeed,ast2500-sd-controller", },
585 { .compatible = "aspeed,ast2600-sd-controller", },
593 .name = "sd-controller-aspeed",
603 #include "sdhci-of-aspeed-test.c"
629 MODULE_DESCRIPTION("Driver for the ASPEED SD/SDIO/SDHCI Controllers");