Lines Matching +full:sdhci +full:- +full:caps +full:- +full:mask

1 // SPDX-License-Identifier: GPL-2.0
12 #include <linux/dma-mapping.h>
22 #include "sdhci-pltfm.h"
83 ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))
137 offset = addr & (SZ_128M - 1); in dwcmshc_adma_write_desc()
138 tmplen = SZ_128M - offset; in dwcmshc_adma_write_desc()
142 len -= tmplen; in dwcmshc_adma_write_desc()
150 if (pltfm_host->clk) in dwcmshc_get_max_clock()
153 return pltfm_host->clock; in dwcmshc_get_max_clock()
162 * No matter V4 is enabled or not, ARGUMENT2 register is 32-bit in dwcmshc_check_auto_cmd23()
166 if (mrq->sbc && (mrq->sbc->arg & SDHCI_DWCMSHC_ARG2_STUFF)) in dwcmshc_check_auto_cmd23()
167 host->flags &= ~SDHCI_AUTO_CMD23; in dwcmshc_check_auto_cmd23()
169 host->flags |= SDHCI_AUTO_CMD23; in dwcmshc_check_auto_cmd23()
204 ctrl = sdhci_readw(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in dwcmshc_set_uhs_signaling()
206 sdhci_writew(host, ctrl, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in dwcmshc_set_uhs_signaling()
221 int reg = priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL; in dwcmshc_hs400_enhanced_strobe()
224 if (ios->enhanced_strobe) in dwcmshc_hs400_enhanced_strobe()
236 struct rk35xx_priv *priv = dwc_priv->priv; in dwcmshc_rk3568_set_clock()
237 const struct dwcmshc_driver_data *drv_data = priv->drv_data; in dwcmshc_rk3568_set_clock()
242 host->mmc->actual_clock = 0; in dwcmshc_rk3568_set_clock()
254 if (priv->acpi_en) { in dwcmshc_rk3568_set_clock()
262 acpi_evaluate_object(ACPI_HANDLE(mmc_dev(host->mmc)), "SCLK", &param_objects, NULL); in dwcmshc_rk3568_set_clock()
264 err = clk_set_rate(pltfm_host->clk, clock); in dwcmshc_rk3568_set_clock()
266 dev_err(mmc_dev(host->mmc), "fail to set clock %d", clock); in dwcmshc_rk3568_set_clock()
272 reg = dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3; in dwcmshc_rk3568_set_clock()
298 drv_data->ddr50_strbin_delay_num << DLL_STRBIN_DELAY_NUM_OFFSET; in dwcmshc_rk3568_set_clock()
315 err = readl_poll_timeout(host->ioaddr + DWCMSHC_EMMC_DLL_STATUS0, in dwcmshc_rk3568_set_clock()
319 dev_err(mmc_dev(host->mmc), "DLL lock timeout!\n"); in dwcmshc_rk3568_set_clock()
326 0x3 << 17 | /* pre-change delay */ in dwcmshc_rk3568_set_clock()
327 0x3 << 19; /* post-change delay */ in dwcmshc_rk3568_set_clock()
328 sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in dwcmshc_rk3568_set_clock()
331 if (drv_data->flags & RK_RXCLK_NO_INVERTER) in dwcmshc_rk3568_set_clock()
333 if (drv_data->flags & RK_TAP_VALUE_SEL) in dwcmshc_rk3568_set_clock()
337 txclk_tapnum = drv_data->hs200_tx_tap; in dwcmshc_rk3568_set_clock()
338 if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { in dwcmshc_rk3568_set_clock()
339 txclk_tapnum = drv_data->hs400_tx_tap; in dwcmshc_rk3568_set_clock()
341 if (drv_data->flags & RK_DLL_CMD_OUT) { in dwcmshc_rk3568_set_clock()
345 drv_data->hs400_cmd_tap | in dwcmshc_rk3568_set_clock()
347 if (drv_data->flags & RK_TAP_VALUE_SEL) in dwcmshc_rk3568_set_clock()
356 if (drv_data->flags & RK_TAP_VALUE_SEL) in dwcmshc_rk3568_set_clock()
361 drv_data->hs400_strbin_tap | in dwcmshc_rk3568_set_clock()
363 if (drv_data->flags & RK_TAP_VALUE_SEL) in dwcmshc_rk3568_set_clock()
372 static void rk35xx_sdhci_reset(struct sdhci_host *host, u8 mask) in rk35xx_sdhci_reset() argument
376 struct rk35xx_priv *priv = dwc_priv->priv; in rk35xx_sdhci_reset()
378 if (mask & SDHCI_RESET_ALL && priv->reset) { in rk35xx_sdhci_reset()
379 reset_control_assert(priv->reset); in rk35xx_sdhci_reset()
381 reset_control_deassert(priv->reset); in rk35xx_sdhci_reset()
384 sdhci_reset(host, mask); in rk35xx_sdhci_reset()
389 if (mmc_hsq_finalize_request(host->mmc, mrq)) in sdhci_dwcmshc_request_done()
392 mmc_request_done(host->mmc, mrq); in sdhci_dwcmshc_request_done()
439 struct rk35xx_priv *priv = dwc_priv->priv; in dwcmshc_rk35xx_init()
441 priv->reset = devm_reset_control_array_get_optional_exclusive(mmc_dev(host->mmc)); in dwcmshc_rk35xx_init()
442 if (IS_ERR(priv->reset)) { in dwcmshc_rk35xx_init()
443 err = PTR_ERR(priv->reset); in dwcmshc_rk35xx_init()
444 dev_err(mmc_dev(host->mmc), "failed to get reset control %d\n", err); in dwcmshc_rk35xx_init()
448 priv->rockchip_clks[0].id = "axi"; in dwcmshc_rk35xx_init()
449 priv->rockchip_clks[1].id = "block"; in dwcmshc_rk35xx_init()
450 priv->rockchip_clks[2].id = "timer"; in dwcmshc_rk35xx_init()
451 err = devm_clk_bulk_get_optional(mmc_dev(host->mmc), RK35xx_MAX_CLKS, in dwcmshc_rk35xx_init()
452 priv->rockchip_clks); in dwcmshc_rk35xx_init()
454 dev_err(mmc_dev(host->mmc), "failed to get clocks %d\n", err); in dwcmshc_rk35xx_init()
458 err = clk_bulk_prepare_enable(RK35xx_MAX_CLKS, priv->rockchip_clks); in dwcmshc_rk35xx_init()
460 dev_err(mmc_dev(host->mmc), "failed to enable clocks %d\n", err); in dwcmshc_rk35xx_init()
464 if (of_property_read_u8(mmc_dev(host->mmc)->of_node, "rockchip,txclk-tapnum", in dwcmshc_rk35xx_init()
465 &priv->txclk_tapnum)) in dwcmshc_rk35xx_init()
466 priv->txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT; in dwcmshc_rk35xx_init()
469 sdhci_writel(host, 0x0, dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3); in dwcmshc_rk35xx_init()
483 if (host->mmc->f_max <= 52000000) { in dwcmshc_rk35xx_postinit()
484 dev_info(mmc_dev(host->mmc), "Disabling HS200/HS400, frequency too low (%d)\n", in dwcmshc_rk35xx_postinit()
485 host->mmc->f_max); in dwcmshc_rk35xx_postinit()
486 host->mmc->caps2 &= ~(MMC_CAP2_HS200 | MMC_CAP2_HS400); in dwcmshc_rk35xx_postinit()
487 host->mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR); in dwcmshc_rk35xx_postinit()
538 .compatible = "rockchip,rk3588-dwcmshc",
542 .compatible = "rockchip,rk3568-dwcmshc",
546 .compatible = "rockchip,rk3528-dwcmshc",
550 .compatible = "rockchip,rk3562-dwcmshc",
554 .compatible = "snps,dwcmshc-sdhci",
573 struct device *dev = &pdev->dev; in dwcmshc_probe()
584 drv_data = device_get_match_data(&pdev->dev); in dwcmshc_probe()
586 dev_err(&pdev->dev, "Error: No device match data found\n"); in dwcmshc_probe()
587 return -ENODEV; in dwcmshc_probe()
589 pltfm_data = drv_data->pdata; in dwcmshc_probe()
602 host->adma_table_cnt += extra; in dwcmshc_probe()
607 if (dev->of_node) { in dwcmshc_probe()
608 pltfm_host->clk = devm_clk_get(dev, "core"); in dwcmshc_probe()
609 if (IS_ERR(pltfm_host->clk)) { in dwcmshc_probe()
610 err = PTR_ERR(pltfm_host->clk); in dwcmshc_probe()
614 err = clk_prepare_enable(pltfm_host->clk); in dwcmshc_probe()
618 priv->bus_clk = devm_clk_get(dev, "bus"); in dwcmshc_probe()
619 if (!IS_ERR(priv->bus_clk)) in dwcmshc_probe()
620 clk_prepare_enable(priv->bus_clk); in dwcmshc_probe()
623 err = mmc_of_parse(host->mmc); in dwcmshc_probe()
629 priv->vendor_specific_area1 = in dwcmshc_probe()
632 host->mmc_host_ops.request = dwcmshc_request; in dwcmshc_probe()
633 host->mmc_host_ops.hs400_enhanced_strobe = dwcmshc_hs400_enhanced_strobe; in dwcmshc_probe()
635 hsq = devm_kzalloc(&pdev->dev, sizeof(*hsq), GFP_KERNEL); in dwcmshc_probe()
637 err = -ENOMEM; in dwcmshc_probe()
641 err = mmc_hsq_init(hsq, host->mmc); in dwcmshc_probe()
645 if (drv_data->flags & RK_PLATFROM) { in dwcmshc_probe()
646 rk_priv = devm_kzalloc(&pdev->dev, sizeof(struct rk35xx_priv), GFP_KERNEL); in dwcmshc_probe()
648 err = -ENOMEM; in dwcmshc_probe()
652 rk_priv->drv_data = drv_data; in dwcmshc_probe()
653 rk_priv->acpi_en = has_acpi_companion(&pdev->dev); in dwcmshc_probe()
655 if (of_device_is_compatible(pdev->dev.of_node, "rockchip,rk3588-dwcmshc")) in dwcmshc_probe()
656 rk_priv->devtype = DWCMSHC_RK3588; in dwcmshc_probe()
658 rk_priv->devtype = DWCMSHC_RK3568; in dwcmshc_probe()
660 priv->priv = rk_priv; in dwcmshc_probe()
667 host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; in dwcmshc_probe()
680 if (rk_priv && !rk_priv->acpi_en) { in dwcmshc_probe()
681 pm_runtime_get_noresume(&pdev->dev); in dwcmshc_probe()
682 pm_runtime_set_active(&pdev->dev); in dwcmshc_probe()
683 pm_runtime_enable(&pdev->dev); in dwcmshc_probe()
684 pm_runtime_set_autosuspend_delay(&pdev->dev, 50); in dwcmshc_probe()
685 pm_runtime_use_autosuspend(&pdev->dev); in dwcmshc_probe()
686 pm_runtime_put_autosuspend(&pdev->dev); in dwcmshc_probe()
694 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_probe()
695 clk_disable_unprepare(priv->bus_clk); in dwcmshc_probe()
698 rk_priv->rockchip_clks); in dwcmshc_probe()
709 struct rk35xx_priv *rk_priv = priv->priv; in dwcmshc_remove()
713 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_remove()
714 clk_disable_unprepare(priv->bus_clk); in dwcmshc_remove()
717 rk_priv->rockchip_clks); in dwcmshc_remove()
729 struct rk35xx_priv *rk_priv = priv->priv; in dwcmshc_suspend()
732 mmc_hsq_suspend(host->mmc); in dwcmshc_suspend()
738 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_suspend()
739 if (!IS_ERR(priv->bus_clk)) in dwcmshc_suspend()
740 clk_disable_unprepare(priv->bus_clk); in dwcmshc_suspend()
744 rk_priv->rockchip_clks); in dwcmshc_suspend()
754 struct rk35xx_priv *rk_priv = priv->priv; in dwcmshc_resume()
757 ret = clk_prepare_enable(pltfm_host->clk); in dwcmshc_resume()
761 if (!IS_ERR(priv->bus_clk)) { in dwcmshc_resume()
762 ret = clk_prepare_enable(priv->bus_clk); in dwcmshc_resume()
769 rk_priv->rockchip_clks); in dwcmshc_resume()
778 return mmc_hsq_resume(host->mmc); in dwcmshc_resume()
813 .name = "sdhci-dwcmshc",
824 MODULE_DESCRIPTION("SDHCI platform driver for Synopsys DWC MSHC");