sdhci-of-dwcmshc.c (14393B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Driver for Synopsys DesignWare Cores Mobile Storage Host Controller 4 * 5 * Copyright (C) 2018 Synaptics Incorporated 6 * 7 * Author: Jisheng Zhang <jszhang@kernel.org> 8 */ 9 10#include <linux/acpi.h> 11#include <linux/clk.h> 12#include <linux/dma-mapping.h> 13#include <linux/iopoll.h> 14#include <linux/kernel.h> 15#include <linux/module.h> 16#include <linux/of.h> 17#include <linux/of_device.h> 18#include <linux/sizes.h> 19 20#include "sdhci-pltfm.h" 21 22#define SDHCI_DWCMSHC_ARG2_STUFF GENMASK(31, 16) 23 24/* DWCMSHC specific Mode Select value */ 25#define DWCMSHC_CTRL_HS400 0x7 26 27/* DWC IP vendor area 1 pointer */ 28#define DWCMSHC_P_VENDOR_AREA1 0xe8 29#define DWCMSHC_AREA1_MASK GENMASK(11, 0) 30/* Offset inside the vendor area 1 */ 31#define DWCMSHC_HOST_CTRL3 0x8 32#define DWCMSHC_EMMC_CONTROL 0x2c 33#define DWCMSHC_ENHANCED_STROBE BIT(8) 34#define DWCMSHC_EMMC_ATCTRL 0x40 35 36/* Rockchip specific Registers */ 37#define DWCMSHC_EMMC_DLL_CTRL 0x800 38#define DWCMSHC_EMMC_DLL_RXCLK 0x804 39#define DWCMSHC_EMMC_DLL_TXCLK 0x808 40#define DWCMSHC_EMMC_DLL_STRBIN 0x80c 41#define DLL_STRBIN_TAPNUM_FROM_SW BIT(24) 42#define DWCMSHC_EMMC_DLL_STATUS0 0x840 43#define DWCMSHC_EMMC_DLL_START BIT(0) 44#define DWCMSHC_EMMC_DLL_LOCKED BIT(8) 45#define DWCMSHC_EMMC_DLL_TIMEOUT BIT(9) 46#define DWCMSHC_EMMC_DLL_RXCLK_SRCSEL 29 47#define DWCMSHC_EMMC_DLL_START_POINT 16 48#define DWCMSHC_EMMC_DLL_INC 8 49#define DWCMSHC_EMMC_DLL_DLYENA BIT(27) 50#define DLL_TXCLK_TAPNUM_DEFAULT 0x8 51#define DLL_STRBIN_TAPNUM_DEFAULT 0x8 52#define DLL_TXCLK_TAPNUM_FROM_SW BIT(24) 53#define DLL_RXCLK_NO_INVERTER 1 54#define DLL_RXCLK_INVERTER 0 55#define DLL_LOCK_WO_TMOUT(x) \ 56 ((((x) & DWCMSHC_EMMC_DLL_LOCKED) == DWCMSHC_EMMC_DLL_LOCKED) && \ 57 (((x) & DWCMSHC_EMMC_DLL_TIMEOUT) == 0)) 58#define RK3568_MAX_CLKS 3 59 60#define BOUNDARY_OK(addr, len) \ 61 ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1))) 62 63struct rk3568_priv { 64 /* Rockchip specified optional clocks */ 65 struct clk_bulk_data rockchip_clks[RK3568_MAX_CLKS]; 66 u8 txclk_tapnum; 67}; 68 69struct dwcmshc_priv { 70 struct clk *bus_clk; 71 int vendor_specific_area1; /* P_VENDOR_SPECIFIC_AREA reg */ 72 void *priv; /* pointer to SoC private stuff */ 73}; 74 75/* 76 * If DMA addr spans 128MB boundary, we split the DMA transfer into two 77 * so that each DMA transfer doesn't exceed the boundary. 78 */ 79static void dwcmshc_adma_write_desc(struct sdhci_host *host, void **desc, 80 dma_addr_t addr, int len, unsigned int cmd) 81{ 82 int tmplen, offset; 83 84 if (likely(!len || BOUNDARY_OK(addr, len))) { 85 sdhci_adma_write_desc(host, desc, addr, len, cmd); 86 return; 87 } 88 89 offset = addr & (SZ_128M - 1); 90 tmplen = SZ_128M - offset; 91 sdhci_adma_write_desc(host, desc, addr, tmplen, cmd); 92 93 addr += tmplen; 94 len -= tmplen; 95 sdhci_adma_write_desc(host, desc, addr, len, cmd); 96} 97 98static unsigned int dwcmshc_get_max_clock(struct sdhci_host *host) 99{ 100 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 101 102 if (pltfm_host->clk) 103 return sdhci_pltfm_clk_get_max_clock(host); 104 else 105 return pltfm_host->clock; 106} 107 108static void dwcmshc_check_auto_cmd23(struct mmc_host *mmc, 109 struct mmc_request *mrq) 110{ 111 struct sdhci_host *host = mmc_priv(mmc); 112 113 /* 114 * No matter V4 is enabled or not, ARGUMENT2 register is 32-bit 115 * block count register which doesn't support stuff bits of 116 * CMD23 argument on dwcmsch host controller. 117 */ 118 if (mrq->sbc && (mrq->sbc->arg & SDHCI_DWCMSHC_ARG2_STUFF)) 119 host->flags &= ~SDHCI_AUTO_CMD23; 120 else 121 host->flags |= SDHCI_AUTO_CMD23; 122} 123 124static void dwcmshc_request(struct mmc_host *mmc, struct mmc_request *mrq) 125{ 126 dwcmshc_check_auto_cmd23(mmc, mrq); 127 128 sdhci_request(mmc, mrq); 129} 130 131static void dwcmshc_set_uhs_signaling(struct sdhci_host *host, 132 unsigned int timing) 133{ 134 u16 ctrl_2; 135 136 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); 137 /* Select Bus Speed Mode for host */ 138 ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; 139 if ((timing == MMC_TIMING_MMC_HS200) || 140 (timing == MMC_TIMING_UHS_SDR104)) 141 ctrl_2 |= SDHCI_CTRL_UHS_SDR104; 142 else if (timing == MMC_TIMING_UHS_SDR12) 143 ctrl_2 |= SDHCI_CTRL_UHS_SDR12; 144 else if ((timing == MMC_TIMING_UHS_SDR25) || 145 (timing == MMC_TIMING_MMC_HS)) 146 ctrl_2 |= SDHCI_CTRL_UHS_SDR25; 147 else if (timing == MMC_TIMING_UHS_SDR50) 148 ctrl_2 |= SDHCI_CTRL_UHS_SDR50; 149 else if ((timing == MMC_TIMING_UHS_DDR50) || 150 (timing == MMC_TIMING_MMC_DDR52)) 151 ctrl_2 |= SDHCI_CTRL_UHS_DDR50; 152 else if (timing == MMC_TIMING_MMC_HS400) 153 ctrl_2 |= DWCMSHC_CTRL_HS400; 154 sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); 155} 156 157static void dwcmshc_hs400_enhanced_strobe(struct mmc_host *mmc, 158 struct mmc_ios *ios) 159{ 160 u32 vendor; 161 struct sdhci_host *host = mmc_priv(mmc); 162 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 163 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host); 164 int reg = priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL; 165 166 vendor = sdhci_readl(host, reg); 167 if (ios->enhanced_strobe) 168 vendor |= DWCMSHC_ENHANCED_STROBE; 169 else 170 vendor &= ~DWCMSHC_ENHANCED_STROBE; 171 172 sdhci_writel(host, vendor, reg); 173} 174 175static void dwcmshc_rk3568_set_clock(struct sdhci_host *host, unsigned int clock) 176{ 177 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 178 struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host); 179 struct rk3568_priv *priv = dwc_priv->priv; 180 u8 txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT; 181 u32 extra, reg; 182 int err; 183 184 host->mmc->actual_clock = 0; 185 186 /* 187 * DO NOT TOUCH THIS SETTING. RX clk inverter unit is enabled 188 * by default, but it shouldn't be enabled. We should anyway 189 * disable it before issuing any cmds. 190 */ 191 extra = DWCMSHC_EMMC_DLL_DLYENA | 192 DLL_RXCLK_NO_INVERTER << DWCMSHC_EMMC_DLL_RXCLK_SRCSEL; 193 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK); 194 195 if (clock == 0) 196 return; 197 198 /* Rockchip platform only support 375KHz for identify mode */ 199 if (clock <= 400000) 200 clock = 375000; 201 202 err = clk_set_rate(pltfm_host->clk, clock); 203 if (err) 204 dev_err(mmc_dev(host->mmc), "fail to set clock %d", clock); 205 206 sdhci_set_clock(host, clock); 207 208 /* Disable cmd conflict check */ 209 reg = dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3; 210 extra = sdhci_readl(host, reg); 211 extra &= ~BIT(0); 212 sdhci_writel(host, extra, reg); 213 214 if (clock <= 400000) { 215 /* Disable DLL to reset sample clock */ 216 sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL); 217 return; 218 } 219 220 /* Reset DLL */ 221 sdhci_writel(host, BIT(1), DWCMSHC_EMMC_DLL_CTRL); 222 udelay(1); 223 sdhci_writel(host, 0x0, DWCMSHC_EMMC_DLL_CTRL); 224 225 /* Init DLL settings */ 226 extra = 0x5 << DWCMSHC_EMMC_DLL_START_POINT | 227 0x2 << DWCMSHC_EMMC_DLL_INC | 228 DWCMSHC_EMMC_DLL_START; 229 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_CTRL); 230 err = readl_poll_timeout(host->ioaddr + DWCMSHC_EMMC_DLL_STATUS0, 231 extra, DLL_LOCK_WO_TMOUT(extra), 1, 232 500 * USEC_PER_MSEC); 233 if (err) { 234 dev_err(mmc_dev(host->mmc), "DLL lock timeout!\n"); 235 return; 236 } 237 238 extra = 0x1 << 16 | /* tune clock stop en */ 239 0x2 << 17 | /* pre-change delay */ 240 0x3 << 19; /* post-change delay */ 241 sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); 242 243 if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 || 244 host->mmc->ios.timing == MMC_TIMING_MMC_HS400) 245 txclk_tapnum = priv->txclk_tapnum; 246 247 extra = DWCMSHC_EMMC_DLL_DLYENA | 248 DLL_TXCLK_TAPNUM_FROM_SW | 249 txclk_tapnum; 250 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_TXCLK); 251 252 extra = DWCMSHC_EMMC_DLL_DLYENA | 253 DLL_STRBIN_TAPNUM_DEFAULT | 254 DLL_STRBIN_TAPNUM_FROM_SW; 255 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN); 256} 257 258static const struct sdhci_ops sdhci_dwcmshc_ops = { 259 .set_clock = sdhci_set_clock, 260 .set_bus_width = sdhci_set_bus_width, 261 .set_uhs_signaling = dwcmshc_set_uhs_signaling, 262 .get_max_clock = dwcmshc_get_max_clock, 263 .reset = sdhci_reset, 264 .adma_write_desc = dwcmshc_adma_write_desc, 265}; 266 267static const struct sdhci_ops sdhci_dwcmshc_rk3568_ops = { 268 .set_clock = dwcmshc_rk3568_set_clock, 269 .set_bus_width = sdhci_set_bus_width, 270 .set_uhs_signaling = dwcmshc_set_uhs_signaling, 271 .get_max_clock = sdhci_pltfm_clk_get_max_clock, 272 .reset = sdhci_reset, 273 .adma_write_desc = dwcmshc_adma_write_desc, 274}; 275 276static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { 277 .ops = &sdhci_dwcmshc_ops, 278 .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, 279 .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, 280}; 281 282static const struct sdhci_pltfm_data sdhci_dwcmshc_rk3568_pdata = { 283 .ops = &sdhci_dwcmshc_rk3568_ops, 284 .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | 285 SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, 286 .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | 287 SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, 288}; 289 290static int dwcmshc_rk3568_init(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv) 291{ 292 int err; 293 struct rk3568_priv *priv = dwc_priv->priv; 294 295 priv->rockchip_clks[0].id = "axi"; 296 priv->rockchip_clks[1].id = "block"; 297 priv->rockchip_clks[2].id = "timer"; 298 err = devm_clk_bulk_get_optional(mmc_dev(host->mmc), RK3568_MAX_CLKS, 299 priv->rockchip_clks); 300 if (err) { 301 dev_err(mmc_dev(host->mmc), "failed to get clocks %d\n", err); 302 return err; 303 } 304 305 err = clk_bulk_prepare_enable(RK3568_MAX_CLKS, priv->rockchip_clks); 306 if (err) { 307 dev_err(mmc_dev(host->mmc), "failed to enable clocks %d\n", err); 308 return err; 309 } 310 311 if (of_property_read_u8(mmc_dev(host->mmc)->of_node, "rockchip,txclk-tapnum", 312 &priv->txclk_tapnum)) 313 priv->txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT; 314 315 /* Disable cmd conflict check */ 316 sdhci_writel(host, 0x0, dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3); 317 /* Reset previous settings */ 318 sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK); 319 sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_STRBIN); 320 321 return 0; 322} 323 324static const struct of_device_id sdhci_dwcmshc_dt_ids[] = { 325 { 326 .compatible = "rockchip,rk3568-dwcmshc", 327 .data = &sdhci_dwcmshc_rk3568_pdata, 328 }, 329 { 330 .compatible = "snps,dwcmshc-sdhci", 331 .data = &sdhci_dwcmshc_pdata, 332 }, 333 {}, 334}; 335MODULE_DEVICE_TABLE(of, sdhci_dwcmshc_dt_ids); 336 337#ifdef CONFIG_ACPI 338static const struct acpi_device_id sdhci_dwcmshc_acpi_ids[] = { 339 { .id = "MLNXBF30" }, 340 {} 341}; 342#endif 343 344static int dwcmshc_probe(struct platform_device *pdev) 345{ 346 struct device *dev = &pdev->dev; 347 struct sdhci_pltfm_host *pltfm_host; 348 struct sdhci_host *host; 349 struct dwcmshc_priv *priv; 350 struct rk3568_priv *rk_priv = NULL; 351 const struct sdhci_pltfm_data *pltfm_data; 352 int err; 353 u32 extra; 354 355 pltfm_data = of_device_get_match_data(&pdev->dev); 356 if (!pltfm_data) { 357 dev_err(&pdev->dev, "Error: No device match data found\n"); 358 return -ENODEV; 359 } 360 361 host = sdhci_pltfm_init(pdev, pltfm_data, 362 sizeof(struct dwcmshc_priv)); 363 if (IS_ERR(host)) 364 return PTR_ERR(host); 365 366 /* 367 * extra adma table cnt for cross 128M boundary handling. 368 */ 369 extra = DIV_ROUND_UP_ULL(dma_get_required_mask(dev), SZ_128M); 370 if (extra > SDHCI_MAX_SEGS) 371 extra = SDHCI_MAX_SEGS; 372 host->adma_table_cnt += extra; 373 374 pltfm_host = sdhci_priv(host); 375 priv = sdhci_pltfm_priv(pltfm_host); 376 377 if (dev->of_node) { 378 pltfm_host->clk = devm_clk_get(dev, "core"); 379 if (IS_ERR(pltfm_host->clk)) { 380 err = PTR_ERR(pltfm_host->clk); 381 dev_err(dev, "failed to get core clk: %d\n", err); 382 goto free_pltfm; 383 } 384 err = clk_prepare_enable(pltfm_host->clk); 385 if (err) 386 goto free_pltfm; 387 388 priv->bus_clk = devm_clk_get(dev, "bus"); 389 if (!IS_ERR(priv->bus_clk)) 390 clk_prepare_enable(priv->bus_clk); 391 } 392 393 err = mmc_of_parse(host->mmc); 394 if (err) 395 goto err_clk; 396 397 sdhci_get_of_property(pdev); 398 399 priv->vendor_specific_area1 = 400 sdhci_readl(host, DWCMSHC_P_VENDOR_AREA1) & DWCMSHC_AREA1_MASK; 401 402 host->mmc_host_ops.request = dwcmshc_request; 403 host->mmc_host_ops.hs400_enhanced_strobe = dwcmshc_hs400_enhanced_strobe; 404 405 if (pltfm_data == &sdhci_dwcmshc_rk3568_pdata) { 406 rk_priv = devm_kzalloc(&pdev->dev, sizeof(struct rk3568_priv), GFP_KERNEL); 407 if (!rk_priv) { 408 err = -ENOMEM; 409 goto err_clk; 410 } 411 412 priv->priv = rk_priv; 413 414 err = dwcmshc_rk3568_init(host, priv); 415 if (err) 416 goto err_clk; 417 } 418 419 host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; 420 421 err = sdhci_add_host(host); 422 if (err) 423 goto err_clk; 424 425 return 0; 426 427err_clk: 428 clk_disable_unprepare(pltfm_host->clk); 429 clk_disable_unprepare(priv->bus_clk); 430 if (rk_priv) 431 clk_bulk_disable_unprepare(RK3568_MAX_CLKS, 432 rk_priv->rockchip_clks); 433free_pltfm: 434 sdhci_pltfm_free(pdev); 435 return err; 436} 437 438static int dwcmshc_remove(struct platform_device *pdev) 439{ 440 struct sdhci_host *host = platform_get_drvdata(pdev); 441 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 442 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host); 443 struct rk3568_priv *rk_priv = priv->priv; 444 445 sdhci_remove_host(host, 0); 446 447 clk_disable_unprepare(pltfm_host->clk); 448 clk_disable_unprepare(priv->bus_clk); 449 if (rk_priv) 450 clk_bulk_disable_unprepare(RK3568_MAX_CLKS, 451 rk_priv->rockchip_clks); 452 sdhci_pltfm_free(pdev); 453 454 return 0; 455} 456 457#ifdef CONFIG_PM_SLEEP 458static int dwcmshc_suspend(struct device *dev) 459{ 460 struct sdhci_host *host = dev_get_drvdata(dev); 461 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 462 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host); 463 struct rk3568_priv *rk_priv = priv->priv; 464 int ret; 465 466 ret = sdhci_suspend_host(host); 467 if (ret) 468 return ret; 469 470 clk_disable_unprepare(pltfm_host->clk); 471 if (!IS_ERR(priv->bus_clk)) 472 clk_disable_unprepare(priv->bus_clk); 473 474 if (rk_priv) 475 clk_bulk_disable_unprepare(RK3568_MAX_CLKS, 476 rk_priv->rockchip_clks); 477 478 return ret; 479} 480 481static int dwcmshc_resume(struct device *dev) 482{ 483 struct sdhci_host *host = dev_get_drvdata(dev); 484 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 485 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host); 486 struct rk3568_priv *rk_priv = priv->priv; 487 int ret; 488 489 ret = clk_prepare_enable(pltfm_host->clk); 490 if (ret) 491 return ret; 492 493 if (!IS_ERR(priv->bus_clk)) { 494 ret = clk_prepare_enable(priv->bus_clk); 495 if (ret) 496 return ret; 497 } 498 499 if (rk_priv) { 500 ret = clk_bulk_prepare_enable(RK3568_MAX_CLKS, 501 rk_priv->rockchip_clks); 502 if (ret) 503 return ret; 504 } 505 506 return sdhci_resume_host(host); 507} 508#endif 509 510static SIMPLE_DEV_PM_OPS(dwcmshc_pmops, dwcmshc_suspend, dwcmshc_resume); 511 512static struct platform_driver sdhci_dwcmshc_driver = { 513 .driver = { 514 .name = "sdhci-dwcmshc", 515 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 516 .of_match_table = sdhci_dwcmshc_dt_ids, 517 .acpi_match_table = ACPI_PTR(sdhci_dwcmshc_acpi_ids), 518 .pm = &dwcmshc_pmops, 519 }, 520 .probe = dwcmshc_probe, 521 .remove = dwcmshc_remove, 522}; 523module_platform_driver(sdhci_dwcmshc_driver); 524 525MODULE_DESCRIPTION("SDHCI platform driver for Synopsys DWC MSHC"); 526MODULE_AUTHOR("Jisheng Zhang <jszhang@kernel.org>"); 527MODULE_LICENSE("GPL v2");