Lines Matching +full:no +full:- +full:mmc +full:- +full:hs400

1 // SPDX-License-Identifier: GPL-2.0
11 #include <linux/arm-smccc.h>
14 #include <linux/dma-mapping.h>
25 #include "sdhci-pltfm.h"
42 /* Tuning and auto-tuning fields in AT_CTRL_R control register */
52 #define AT_CTRL_PRE_CHANGE_DLY 0x1 /* 2-cycle latency */
54 #define AT_CTRL_POST_CHANGE_DLY 0x3 /* 4-cycle latency */
152 #define PHY_PAD_TXSLEW_CTRL_P 0x3 /* Slew control for P-Type pad TX */
154 #define PHY_PAD_TXSLEW_CTRL_N 0x3 /* Slew control for N-Type pad TX */
155 #define PHY_PAD_TXSLEW_CTRL_N_SG2042 0x2 /* Slew control for N-Type pad TX for SG2042 */
166 #define PHY_SDCLKDL_DC_HS400 0x18 /* delay code for HS400 mode */
200 ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))
206 /* SMC call for BlueField-3 eMMC RST_N */
249 return -EINVAL; in dwcmshc_get_enable_other_clks()
252 priv->other_clks[i].id = clk_ids[i]; in dwcmshc_get_enable_other_clks()
254 err = devm_clk_bulk_get_optional(dev, num_clks, priv->other_clks); in dwcmshc_get_enable_other_clks()
260 err = clk_bulk_prepare_enable(num_clks, priv->other_clks); in dwcmshc_get_enable_other_clks()
264 priv->num_other_clks = num_clks; in dwcmshc_get_enable_other_clks()
283 offset = addr & (SZ_128M - 1); in dwcmshc_adma_write_desc()
284 tmplen = SZ_128M - offset; in dwcmshc_adma_write_desc()
288 len -= tmplen; in dwcmshc_adma_write_desc()
309 if (pltfm_host->clk) in dwcmshc_get_max_clock()
312 return pltfm_host->clock; in dwcmshc_get_max_clock()
319 return clk_round_rate(pltfm_host->clk, ULONG_MAX); in rk35xx_get_max_clock()
322 static void dwcmshc_check_auto_cmd23(struct mmc_host *mmc, in dwcmshc_check_auto_cmd23() argument
325 struct sdhci_host *host = mmc_priv(mmc); in dwcmshc_check_auto_cmd23()
328 * No matter V4 is enabled or not, ARGUMENT2 register is 32-bit in dwcmshc_check_auto_cmd23()
332 if (mrq->sbc && (mrq->sbc->arg & SDHCI_DWCMSHC_ARG2_STUFF)) in dwcmshc_check_auto_cmd23()
333 host->flags &= ~SDHCI_AUTO_CMD23; in dwcmshc_check_auto_cmd23()
335 host->flags |= SDHCI_AUTO_CMD23; in dwcmshc_check_auto_cmd23()
338 static void dwcmshc_request(struct mmc_host *mmc, struct mmc_request *mrq) in dwcmshc_request() argument
340 dwcmshc_check_auto_cmd23(mmc, mrq); in dwcmshc_request()
342 sdhci_request(mmc, mrq); in dwcmshc_request()
352 if (priv->flags & FLAG_IO_FIXED_1V8 || in dwcmshc_phy_init()
353 host->mmc->ios.timing & MMC_SIGNAL_VOLTAGE_180) in dwcmshc_phy_init()
366 sdhci_writeb(host, priv->delay_line, PHY_SDCLKDL_DC_R); in dwcmshc_phy_init()
414 if ((host->mmc->caps2 & emmc_caps) == emmc_caps) { in th1520_sdhci_set_phy()
415 emmc_ctrl = sdhci_readw(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in th1520_sdhci_set_phy()
417 sdhci_writew(host, emmc_ctrl, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in th1520_sdhci_set_phy()
448 /* set CARD_IS_EMMC bit to enable Data Strobe for HS400 */ in dwcmshc_set_uhs_signaling()
449 ctrl = sdhci_readw(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in dwcmshc_set_uhs_signaling()
451 sdhci_writew(host, ctrl, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in dwcmshc_set_uhs_signaling()
456 if (priv->flags & FLAG_IO_FIXED_1V8) in dwcmshc_set_uhs_signaling()
469 priv->delay_line = PHY_SDCLKDL_DC_HS400; in th1520_set_uhs_signaling()
475 static void dwcmshc_hs400_enhanced_strobe(struct mmc_host *mmc, in dwcmshc_hs400_enhanced_strobe() argument
479 struct sdhci_host *host = mmc_priv(mmc); in dwcmshc_hs400_enhanced_strobe()
482 int reg = priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL; in dwcmshc_hs400_enhanced_strobe()
485 if (ios->enhanced_strobe) in dwcmshc_hs400_enhanced_strobe()
493 static int dwcmshc_execute_tuning(struct mmc_host *mmc, u32 opcode) in dwcmshc_execute_tuning() argument
495 int err = sdhci_execute_tuning(mmc, opcode); in dwcmshc_execute_tuning()
496 struct sdhci_host *host = mmc_priv(mmc); in dwcmshc_execute_tuning()
519 cqhci_irq(host->mmc, intmask, cmd_error, data_error); in dwcmshc_cqe_irq_handler()
524 static void dwcmshc_sdhci_cqe_enable(struct mmc_host *mmc) in dwcmshc_sdhci_cqe_enable() argument
526 struct sdhci_host *host = mmc_priv(mmc); in dwcmshc_sdhci_cqe_enable()
531 sdhci_cqe_enable(mmc); in dwcmshc_sdhci_cqe_enable()
538 * Selection of 32-bit/64-bit System Addressing: in dwcmshc_sdhci_cqe_enable()
539 * either 32-bit or 64-bit system addressing is selected by in dwcmshc_sdhci_cqe_enable()
540 * 64-bit Addressing bit in Host Control 2 register. in dwcmshc_sdhci_cqe_enable()
562 offset = addr & (SZ_128M - 1); in dwcmshc_set_tran_desc()
563 tmplen = SZ_128M - offset; in dwcmshc_set_tran_desc()
567 len -= tmplen; in dwcmshc_set_tran_desc()
568 *desc += cq_host->trans_desc_len; in dwcmshc_set_tran_desc()
572 static void dwcmshc_cqhci_dumpregs(struct mmc_host *mmc) in dwcmshc_cqhci_dumpregs() argument
574 sdhci_dumpregs(mmc_priv(mmc)); in dwcmshc_cqhci_dumpregs()
581 struct rk35xx_priv *priv = dwc_priv->priv; in dwcmshc_rk3568_set_clock()
586 host->mmc->actual_clock = 0; in dwcmshc_rk3568_set_clock()
598 err = clk_set_rate(pltfm_host->clk, clock); in dwcmshc_rk3568_set_clock()
600 dev_err(mmc_dev(host->mmc), "fail to set clock %d", clock); in dwcmshc_rk3568_set_clock()
605 reg = dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3; in dwcmshc_rk3568_set_clock()
641 if (priv->devtype == DWCMSHC_RK3568) in dwcmshc_rk3568_set_clock()
650 err = readl_poll_timeout(host->ioaddr + DWCMSHC_EMMC_DLL_STATUS0, in dwcmshc_rk3568_set_clock()
654 dev_err(mmc_dev(host->mmc), "DLL lock timeout!\n"); in dwcmshc_rk3568_set_clock()
659 0x3 << 17 | /* pre-change delay */ in dwcmshc_rk3568_set_clock()
660 0x3 << 19; /* post-change delay */ in dwcmshc_rk3568_set_clock()
661 sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in dwcmshc_rk3568_set_clock()
663 if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 || in dwcmshc_rk3568_set_clock()
664 host->mmc->ios.timing == MMC_TIMING_MMC_HS400) in dwcmshc_rk3568_set_clock()
665 txclk_tapnum = priv->txclk_tapnum; in dwcmshc_rk3568_set_clock()
667 if ((priv->devtype == DWCMSHC_RK3588) && host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { in dwcmshc_rk3568_set_clock()
694 struct rk35xx_priv *priv = dwc_priv->priv; in rk35xx_sdhci_reset()
696 if (mask & SDHCI_RESET_ALL && priv->reset) { in rk35xx_sdhci_reset()
697 reset_control_assert(priv->reset); in rk35xx_sdhci_reset()
699 reset_control_deassert(priv->reset); in rk35xx_sdhci_reset()
714 return -ENOMEM; in dwcmshc_rk35xx_init()
716 if (of_device_is_compatible(dev->of_node, "rockchip,rk3588-dwcmshc")) in dwcmshc_rk35xx_init()
717 priv->devtype = DWCMSHC_RK3588; in dwcmshc_rk35xx_init()
719 priv->devtype = DWCMSHC_RK3568; in dwcmshc_rk35xx_init()
721 priv->reset = devm_reset_control_array_get_optional_exclusive(mmc_dev(host->mmc)); in dwcmshc_rk35xx_init()
722 if (IS_ERR(priv->reset)) { in dwcmshc_rk35xx_init()
723 err = PTR_ERR(priv->reset); in dwcmshc_rk35xx_init()
724 dev_err(mmc_dev(host->mmc), "failed to get reset control %d\n", err); in dwcmshc_rk35xx_init()
728 err = dwcmshc_get_enable_other_clks(mmc_dev(host->mmc), dwc_priv, in dwcmshc_rk35xx_init()
733 if (of_property_read_u8(mmc_dev(host->mmc)->of_node, "rockchip,txclk-tapnum", in dwcmshc_rk35xx_init()
734 &priv->txclk_tapnum)) in dwcmshc_rk35xx_init()
735 priv->txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT; in dwcmshc_rk35xx_init()
738 sdhci_writel(host, 0x0, dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3); in dwcmshc_rk35xx_init()
743 dwc_priv->priv = priv; in dwcmshc_rk35xx_init()
754 if (host->mmc->f_max <= 52000000) { in dwcmshc_rk35xx_postinit()
755 dev_info(mmc_dev(host->mmc), "Disabling HS200/HS400, frequency too low (%d)\n", in dwcmshc_rk35xx_postinit()
756 host->mmc->f_max); in dwcmshc_rk35xx_postinit()
757 host->mmc->caps2 &= ~(MMC_CAP2_HS200 | MMC_CAP2_HS400); in dwcmshc_rk35xx_postinit()
758 host->mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR); in dwcmshc_rk35xx_postinit()
764 struct device *dev = mmc_dev(host->mmc); in dwcmshc_rk3576_postinit()
770 * RK3576 is in, never come back the same way once it's run-time in dwcmshc_rk3576_postinit()
771 * suspended once. This can happen during early kernel boot if no driver in dwcmshc_rk3576_postinit()
778 if (ret && ret != -EOPNOTSUPP) in dwcmshc_rk3576_postinit()
791 if (host->flags & SDHCI_HS400_TUNING) in th1520_execute_tuning()
796 val = sdhci_readl(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in th1520_execute_tuning()
800 * - center phase select code driven in block gap interval in th1520_execute_tuning()
801 * - disable reporting of framing errors in th1520_execute_tuning()
802 * - disable software managed tuning in th1520_execute_tuning()
803 * - disable user selection of sampling window edges, in th1520_execute_tuning()
811 * - enable auto-tuning in th1520_execute_tuning()
812 * - enable sampling window threshold in th1520_execute_tuning()
813 * - stop clocks during phase code change in th1520_execute_tuning()
814 * - set max latency in cycles between tx and rx clocks in th1520_execute_tuning()
815 * - set max latency in cycles to switch output phase in th1520_execute_tuning()
816 * - set max sampling window threshold value in th1520_execute_tuning()
823 sdhci_writel(host, val, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in th1520_execute_tuning()
824 val = sdhci_readl(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in th1520_execute_tuning()
828 host->tuning_loop_count = 128; in th1520_execute_tuning()
829 host->tuning_err = __sdhci_execute_tuning(host, opcode); in th1520_execute_tuning()
830 if (host->tuning_err) { in th1520_execute_tuning()
831 /* disable auto-tuning upon tuning error */ in th1520_execute_tuning()
833 sdhci_writel(host, val, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in th1520_execute_tuning()
834 dev_err(mmc_dev(host->mmc), "tuning failed: %d\n", host->tuning_err); in th1520_execute_tuning()
835 return -EIO; in th1520_execute_tuning()
850 if (priv->flags & FLAG_IO_FIXED_1V8) { in th1520_sdhci_reset()
863 dwc_priv->delay_line = PHY_SDCLKDL_DC_DEFAULT; in th1520_init()
865 if (device_property_read_bool(dev, "mmc-ddr-1_8v") || in th1520_init()
866 device_property_read_bool(dev, "mmc-hs200-1_8v") || in th1520_init()
867 device_property_read_bool(dev, "mmc-hs400-1_8v")) in th1520_init()
868 dwc_priv->flags |= FLAG_IO_FIXED_1V8; in th1520_init()
870 dwc_priv->flags &= ~FLAG_IO_FIXED_1V8; in th1520_init()
878 if (dwc_priv->flags & FLAG_IO_FIXED_1V8) { in th1520_init()
879 host->flags &= ~SDHCI_SIGNALING_330; in th1520_init()
880 host->flags |= SDHCI_SIGNALING_180; in th1520_init()
896 if ((host->mmc->caps2 & emmc_caps) == emmc_caps) { in cv18xx_sdhci_reset()
897 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_reset()
899 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_reset()
902 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_reset()
904 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_reset()
906 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_CONFIG); in cv18xx_sdhci_reset()
908 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_CONFIG); in cv18xx_sdhci_reset()
914 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_TX_RX_DLY); in cv18xx_sdhci_reset()
928 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_set_tap()
930 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_set_tap()
935 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_TX_RX_DLY); in cv18xx_sdhci_set_tap()
937 sdhci_writel(host, 0, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_CONFIG); in cv18xx_sdhci_set_tap()
944 static int cv18xx_retry_tuning(struct mmc_host *mmc, u32 opcode, int *cmd_error) in cv18xx_retry_tuning() argument
949 ret = mmc_send_tuning(mmc, opcode, NULL); in cv18xx_retry_tuning()
983 if (!cv18xx_retry_tuning(host->mmc, opcode, NULL)) in cv18xx_sdhci_execute_tuning()
992 if (cv18xx_retry_tuning(host->mmc, opcode, NULL)) { in cv18xx_sdhci_execute_tuning()
993 max -= CV18XX_TUNE_STEP; in cv18xx_sdhci_execute_tuning()
999 win_length = max - min + 1; in cv18xx_sdhci_execute_tuning()
1016 ret = mmc_send_tuning(host->mmc, opcode, NULL); in cv18xx_sdhci_execute_tuning()
1018 dev_dbg(mmc_dev(host->mmc), "tuning %s at 0x%x ret %d\n", in cv18xx_sdhci_execute_tuning()
1099 return dwcmshc_get_enable_other_clks(mmc_dev(host->mmc), dwc_priv, in sg2042_init()
1121 pr_err("%s: RST_N failed.\n", mmc_hostname(host->mmc)); in dwcmshc_bf3_hw_reset()
1262 host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; in dwcmshc_cqhci_init()
1263 cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL); in dwcmshc_cqhci_init()
1265 dev_err(mmc_dev(host->mmc), "Unable to setup CQE: not enough memory\n"); in dwcmshc_cqhci_init()
1278 dev_err(mmc_dev(host->mmc), "Unable to setup CQE: internal clock enable error\n"); in dwcmshc_cqhci_init()
1282 cq_host->mmio = host->ioaddr + priv->vendor_specific_area2; in dwcmshc_cqhci_init()
1283 cq_host->ops = &dwcmshc_cqhci_ops; in dwcmshc_cqhci_init()
1285 /* Enable using of 128-bit task descriptors */ in dwcmshc_cqhci_init()
1286 dma64 = host->flags & SDHCI_USE_64_BIT_DMA; in dwcmshc_cqhci_init()
1288 dev_dbg(mmc_dev(host->mmc), "128-bit task descriptors\n"); in dwcmshc_cqhci_init()
1289 cq_host->caps |= CQHCI_TASK_DESC_SZ_128; in dwcmshc_cqhci_init()
1291 err = cqhci_init(cq_host, host->mmc, dma64); in dwcmshc_cqhci_init()
1293 dev_err(mmc_dev(host->mmc), "Unable to setup CQE: error %d\n", err); in dwcmshc_cqhci_init()
1297 dev_dbg(mmc_dev(host->mmc), "CQE init done\n"); in dwcmshc_cqhci_init()
1307 devm_kfree(&pdev->dev, cq_host); in dwcmshc_cqhci_init()
1310 host->mmc->caps2 &= ~(MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD); in dwcmshc_cqhci_init()
1315 .compatible = "rockchip,rk3588-dwcmshc",
1319 .compatible = "rockchip,rk3576-dwcmshc",
1323 .compatible = "rockchip,rk3568-dwcmshc",
1327 .compatible = "snps,dwcmshc-sdhci",
1331 .compatible = "sophgo,cv1800b-dwcmshc",
1335 .compatible = "sophgo,sg2002-dwcmshc",
1339 .compatible = "thead,th1520-dwcmshc",
1343 .compatible = "sophgo,sg2042-dwcmshc",
1363 struct device *dev = &pdev->dev; in dwcmshc_probe()
1371 pltfm_data = device_get_match_data(&pdev->dev); in dwcmshc_probe()
1373 dev_err(&pdev->dev, "Error: No device match data found\n"); in dwcmshc_probe()
1374 return -ENODEV; in dwcmshc_probe()
1377 host = sdhci_pltfm_init(pdev, &pltfm_data->pdata, in dwcmshc_probe()
1388 host->adma_table_cnt += extra; in dwcmshc_probe()
1393 if (dev->of_node) { in dwcmshc_probe()
1394 pltfm_host->clk = devm_clk_get(dev, "core"); in dwcmshc_probe()
1395 if (IS_ERR(pltfm_host->clk)) in dwcmshc_probe()
1396 return dev_err_probe(dev, PTR_ERR(pltfm_host->clk), in dwcmshc_probe()
1399 err = clk_prepare_enable(pltfm_host->clk); in dwcmshc_probe()
1403 priv->bus_clk = devm_clk_get(dev, "bus"); in dwcmshc_probe()
1404 if (!IS_ERR(priv->bus_clk)) in dwcmshc_probe()
1405 clk_prepare_enable(priv->bus_clk); in dwcmshc_probe()
1408 err = mmc_of_parse(host->mmc); in dwcmshc_probe()
1414 priv->vendor_specific_area1 = in dwcmshc_probe()
1417 host->mmc_host_ops.request = dwcmshc_request; in dwcmshc_probe()
1418 host->mmc_host_ops.hs400_enhanced_strobe = dwcmshc_hs400_enhanced_strobe; in dwcmshc_probe()
1419 host->mmc_host_ops.execute_tuning = dwcmshc_execute_tuning; in dwcmshc_probe()
1421 if (pltfm_data->init) { in dwcmshc_probe()
1422 err = pltfm_data->init(&pdev->dev, host, priv); in dwcmshc_probe()
1436 host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; in dwcmshc_probe()
1447 if (device_property_read_bool(&pdev->dev, "supports-cqe")) { in dwcmshc_probe()
1448 priv->vendor_specific_area2 = in dwcmshc_probe()
1454 if (pltfm_data->postinit) in dwcmshc_probe()
1455 pltfm_data->postinit(host, priv); in dwcmshc_probe()
1471 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_probe()
1472 clk_disable_unprepare(priv->bus_clk); in dwcmshc_probe()
1473 clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks); in dwcmshc_probe()
1494 pm_runtime_get_sync(&pdev->dev); in dwcmshc_remove()
1495 pm_runtime_disable(&pdev->dev); in dwcmshc_remove()
1496 pm_runtime_put_noidle(&pdev->dev); in dwcmshc_remove()
1502 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_remove()
1503 clk_disable_unprepare(priv->bus_clk); in dwcmshc_remove()
1504 clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks); in dwcmshc_remove()
1516 if (host->mmc->caps2 & MMC_CAP2_CQE) { in dwcmshc_suspend()
1517 ret = cqhci_suspend(host->mmc); in dwcmshc_suspend()
1526 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_suspend()
1527 if (!IS_ERR(priv->bus_clk)) in dwcmshc_suspend()
1528 clk_disable_unprepare(priv->bus_clk); in dwcmshc_suspend()
1530 clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks); in dwcmshc_suspend()
1542 ret = clk_prepare_enable(pltfm_host->clk); in dwcmshc_resume()
1546 if (!IS_ERR(priv->bus_clk)) { in dwcmshc_resume()
1547 ret = clk_prepare_enable(priv->bus_clk); in dwcmshc_resume()
1552 ret = clk_bulk_prepare_enable(priv->num_other_clks, priv->other_clks); in dwcmshc_resume()
1560 if (host->mmc->caps2 & MMC_CAP2_CQE) { in dwcmshc_resume()
1561 ret = cqhci_resume(host->mmc); in dwcmshc_resume()
1569 clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks); in dwcmshc_resume()
1571 if (!IS_ERR(priv->bus_clk)) in dwcmshc_resume()
1572 clk_disable_unprepare(priv->bus_clk); in dwcmshc_resume()
1574 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_resume()
1614 .name = "sdhci-dwcmshc",