1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * sdhci_am654.c - SDHCI driver for TI's AM654 SOCs 4 * 5 * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com 6 * 7 */ 8 #include <linux/clk.h> 9 #include <linux/of.h> 10 #include <linux/module.h> 11 #include <linux/pm_runtime.h> 12 #include <linux/property.h> 13 #include <linux/regmap.h> 14 15 #include "sdhci-pltfm.h" 16 17 /* CTL_CFG Registers */ 18 #define CTL_CFG_2 0x14 19 20 #define SLOTTYPE_MASK GENMASK(31, 30) 21 #define SLOTTYPE_EMBEDDED BIT(30) 22 23 /* PHY Registers */ 24 #define PHY_CTRL1 0x100 25 #define PHY_CTRL2 0x104 26 #define PHY_CTRL3 0x108 27 #define PHY_CTRL4 0x10C 28 #define PHY_CTRL5 0x110 29 #define PHY_CTRL6 0x114 30 #define PHY_STAT1 0x130 31 #define PHY_STAT2 0x134 32 33 #define IOMUX_ENABLE_SHIFT 31 34 #define IOMUX_ENABLE_MASK BIT(IOMUX_ENABLE_SHIFT) 35 #define OTAPDLYENA_SHIFT 20 36 #define OTAPDLYENA_MASK BIT(OTAPDLYENA_SHIFT) 37 #define OTAPDLYSEL_SHIFT 12 38 #define OTAPDLYSEL_MASK GENMASK(15, 12) 39 #define STRBSEL_SHIFT 24 40 #define STRBSEL_4BIT_MASK GENMASK(27, 24) 41 #define STRBSEL_8BIT_MASK GENMASK(31, 24) 42 #define SEL50_SHIFT 8 43 #define SEL50_MASK BIT(SEL50_SHIFT) 44 #define SEL100_SHIFT 9 45 #define SEL100_MASK BIT(SEL100_SHIFT) 46 #define FREQSEL_SHIFT 8 47 #define FREQSEL_MASK GENMASK(10, 8) 48 #define DLL_TRIM_ICP_SHIFT 4 49 #define DLL_TRIM_ICP_MASK GENMASK(7, 4) 50 #define DR_TY_SHIFT 20 51 #define DR_TY_MASK GENMASK(22, 20) 52 #define ENDLL_SHIFT 1 53 #define ENDLL_MASK BIT(ENDLL_SHIFT) 54 #define DLLRDY_SHIFT 0 55 #define DLLRDY_MASK BIT(DLLRDY_SHIFT) 56 #define PDB_SHIFT 0 57 #define PDB_MASK BIT(PDB_SHIFT) 58 #define CALDONE_SHIFT 1 59 #define CALDONE_MASK BIT(CALDONE_SHIFT) 60 #define RETRIM_SHIFT 17 61 #define RETRIM_MASK BIT(RETRIM_SHIFT) 62 63 #define DRIVER_STRENGTH_50_OHM 0x0 64 #define DRIVER_STRENGTH_33_OHM 0x1 65 #define DRIVER_STRENGTH_66_OHM 0x2 66 #define DRIVER_STRENGTH_100_OHM 0x3 67 #define DRIVER_STRENGTH_40_OHM 0x4 68 69 #define CLOCK_TOO_SLOW_HZ 400000 70 71 static struct regmap_config sdhci_am654_regmap_config = { 72 .reg_bits = 32, 73 .val_bits = 32, 74 .reg_stride = 4, 75 .fast_io = true, 76 }; 77 78 struct sdhci_am654_data { 79 struct regmap *base; 80 int otap_del_sel; 81 int trm_icp; 82 int drv_strength; 83 bool dll_on; 84 int strb_sel; 85 u32 flags; 86 }; 87 88 struct sdhci_am654_driver_data { 89 const struct sdhci_pltfm_data *pdata; 90 u32 flags; 91 #define IOMUX_PRESENT (1 << 0) 92 #define FREQSEL_2_BIT (1 << 1) 93 #define STRBSEL_4_BIT (1 << 2) 94 }; 95 96 static void sdhci_am654_set_clock(struct sdhci_host *host, unsigned int clock) 97 { 98 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 99 struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host); 100 int sel50, sel100, freqsel; 101 u32 mask, val; 102 int ret; 103 104 if (sdhci_am654->dll_on) { 105 regmap_update_bits(sdhci_am654->base, PHY_CTRL1, ENDLL_MASK, 0); 106 107 sdhci_am654->dll_on = false; 108 } 109 110 sdhci_set_clock(host, clock); 111 112 if (clock > CLOCK_TOO_SLOW_HZ) { 113 /* Setup DLL Output TAP delay */ 114 mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK; 115 val = (1 << OTAPDLYENA_SHIFT) | 116 (sdhci_am654->otap_del_sel << OTAPDLYSEL_SHIFT); 117 regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, val); 118 /* Write to STRBSEL for HS400 speed mode */ 119 if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { 120 if (sdhci_am654->flags & STRBSEL_4_BIT) 121 mask = STRBSEL_4BIT_MASK; 122 else 123 mask = STRBSEL_8BIT_MASK; 124 125 regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, 126 sdhci_am654->strb_sel << 127 STRBSEL_SHIFT); 128 } 129 130 if (sdhci_am654->flags & FREQSEL_2_BIT) { 131 switch (clock) { 132 case 200000000: 133 sel50 = 0; 134 sel100 = 0; 135 break; 136 case 100000000: 137 sel50 = 0; 138 sel100 = 1; 139 break; 140 default: 141 sel50 = 1; 142 sel100 = 0; 143 } 144 145 /* Configure PHY DLL frequency */ 146 mask = SEL50_MASK | SEL100_MASK; 147 val = (sel50 << SEL50_SHIFT) | (sel100 << SEL100_SHIFT); 148 regmap_update_bits(sdhci_am654->base, PHY_CTRL5, mask, 149 val); 150 } else { 151 switch (clock) { 152 case 200000000: 153 freqsel = 0x0; 154 break; 155 default: 156 freqsel = 0x4; 157 } 158 159 regmap_update_bits(sdhci_am654->base, PHY_CTRL5, 160 FREQSEL_MASK, 161 freqsel << FREQSEL_SHIFT); 162 } 163 164 /* Configure DLL TRIM */ 165 mask = DLL_TRIM_ICP_MASK; 166 val = sdhci_am654->trm_icp << DLL_TRIM_ICP_SHIFT; 167 168 /* Configure DLL driver strength */ 169 mask |= DR_TY_MASK; 170 val |= sdhci_am654->drv_strength << DR_TY_SHIFT; 171 regmap_update_bits(sdhci_am654->base, PHY_CTRL1, mask, val); 172 /* Enable DLL */ 173 regmap_update_bits(sdhci_am654->base, PHY_CTRL1, ENDLL_MASK, 174 0x1 << ENDLL_SHIFT); 175 /* 176 * Poll for DLL ready. Use a one second timeout. 177 * Works in all experiments done so far 178 */ 179 ret = regmap_read_poll_timeout(sdhci_am654->base, PHY_STAT1, 180 val, val & DLLRDY_MASK, 1000, 181 1000000); 182 if (ret) { 183 dev_err(mmc_dev(host->mmc), "DLL failed to relock\n"); 184 return; 185 } 186 187 sdhci_am654->dll_on = true; 188 } 189 } 190 191 static void sdhci_am654_set_power(struct sdhci_host *host, unsigned char mode, 192 unsigned short vdd) 193 { 194 if (!IS_ERR(host->mmc->supply.vmmc)) { 195 struct mmc_host *mmc = host->mmc; 196 197 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); 198 } 199 sdhci_set_power_noreg(host, mode, vdd); 200 } 201 202 static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg) 203 { 204 unsigned char timing = host->mmc->ios.timing; 205 206 if (reg == SDHCI_HOST_CONTROL) { 207 switch (timing) { 208 /* 209 * According to the data manual, HISPD bit 210 * should not be set in these speed modes. 211 */ 212 case MMC_TIMING_SD_HS: 213 case MMC_TIMING_MMC_HS: 214 case MMC_TIMING_UHS_SDR12: 215 case MMC_TIMING_UHS_SDR25: 216 val &= ~SDHCI_CTRL_HISPD; 217 } 218 } 219 220 writeb(val, host->ioaddr + reg); 221 } 222 223 static struct sdhci_ops sdhci_am654_ops = { 224 .get_max_clock = sdhci_pltfm_clk_get_max_clock, 225 .get_timeout_clock = sdhci_pltfm_clk_get_max_clock, 226 .set_uhs_signaling = sdhci_set_uhs_signaling, 227 .set_bus_width = sdhci_set_bus_width, 228 .set_power = sdhci_am654_set_power, 229 .set_clock = sdhci_am654_set_clock, 230 .write_b = sdhci_am654_write_b, 231 .reset = sdhci_reset, 232 }; 233 234 static const struct sdhci_pltfm_data sdhci_am654_pdata = { 235 .ops = &sdhci_am654_ops, 236 .quirks = SDHCI_QUIRK_INVERTED_WRITE_PROTECT | 237 SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, 238 .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, 239 }; 240 241 static const struct sdhci_am654_driver_data sdhci_am654_drvdata = { 242 .pdata = &sdhci_am654_pdata, 243 .flags = IOMUX_PRESENT | FREQSEL_2_BIT | STRBSEL_4_BIT, 244 }; 245 246 struct sdhci_ops sdhci_j721e_8bit_ops = { 247 .get_max_clock = sdhci_pltfm_clk_get_max_clock, 248 .get_timeout_clock = sdhci_pltfm_clk_get_max_clock, 249 .set_uhs_signaling = sdhci_set_uhs_signaling, 250 .set_bus_width = sdhci_set_bus_width, 251 .set_power = sdhci_am654_set_power, 252 .set_clock = sdhci_am654_set_clock, 253 .write_b = sdhci_am654_write_b, 254 .reset = sdhci_reset, 255 }; 256 257 static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = { 258 .ops = &sdhci_j721e_8bit_ops, 259 .quirks = SDHCI_QUIRK_INVERTED_WRITE_PROTECT | 260 SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, 261 .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, 262 }; 263 264 static const struct sdhci_am654_driver_data sdhci_j721e_8bit_drvdata = { 265 .pdata = &sdhci_j721e_8bit_pdata, 266 }; 267 268 static int sdhci_am654_init(struct sdhci_host *host) 269 { 270 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 271 struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host); 272 u32 ctl_cfg_2 = 0; 273 u32 mask; 274 u32 val; 275 int ret; 276 277 /* Reset OTAP to default value */ 278 mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK; 279 regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, 0x0); 280 281 regmap_read(sdhci_am654->base, PHY_STAT1, &val); 282 if (~val & CALDONE_MASK) { 283 /* Calibrate IO lines */ 284 regmap_update_bits(sdhci_am654->base, PHY_CTRL1, 285 PDB_MASK, PDB_MASK); 286 ret = regmap_read_poll_timeout(sdhci_am654->base, PHY_STAT1, 287 val, val & CALDONE_MASK, 1, 20); 288 if (ret) 289 return ret; 290 } 291 292 /* Enable pins by setting IO mux to 0 */ 293 if (sdhci_am654->flags & IOMUX_PRESENT) 294 regmap_update_bits(sdhci_am654->base, PHY_CTRL1, 295 IOMUX_ENABLE_MASK, 0); 296 297 /* Set slot type based on SD or eMMC */ 298 if (host->mmc->caps & MMC_CAP_NONREMOVABLE) 299 ctl_cfg_2 = SLOTTYPE_EMBEDDED; 300 301 regmap_update_bits(sdhci_am654->base, CTL_CFG_2, SLOTTYPE_MASK, 302 ctl_cfg_2); 303 304 return sdhci_add_host(host); 305 } 306 307 static int sdhci_am654_get_of_property(struct platform_device *pdev, 308 struct sdhci_am654_data *sdhci_am654) 309 { 310 struct device *dev = &pdev->dev; 311 int drv_strength; 312 int ret; 313 314 ret = device_property_read_u32(dev, "ti,trm-icp", 315 &sdhci_am654->trm_icp); 316 if (ret) 317 return ret; 318 319 ret = device_property_read_u32(dev, "ti,otap-del-sel", 320 &sdhci_am654->otap_del_sel); 321 if (ret) 322 return ret; 323 324 ret = device_property_read_u32(dev, "ti,driver-strength-ohm", 325 &drv_strength); 326 if (ret) 327 return ret; 328 329 switch (drv_strength) { 330 case 50: 331 sdhci_am654->drv_strength = DRIVER_STRENGTH_50_OHM; 332 break; 333 case 33: 334 sdhci_am654->drv_strength = DRIVER_STRENGTH_33_OHM; 335 break; 336 case 66: 337 sdhci_am654->drv_strength = DRIVER_STRENGTH_66_OHM; 338 break; 339 case 100: 340 sdhci_am654->drv_strength = DRIVER_STRENGTH_100_OHM; 341 break; 342 case 40: 343 sdhci_am654->drv_strength = DRIVER_STRENGTH_40_OHM; 344 break; 345 default: 346 dev_err(dev, "Invalid driver strength\n"); 347 return -EINVAL; 348 } 349 350 device_property_read_u32(dev, "ti,strobe-sel", &sdhci_am654->strb_sel); 351 352 sdhci_get_of_property(pdev); 353 354 return 0; 355 } 356 357 static const struct of_device_id sdhci_am654_of_match[] = { 358 { 359 .compatible = "ti,am654-sdhci-5.1", 360 .data = &sdhci_am654_drvdata, 361 }, 362 { 363 .compatible = "ti,j721e-sdhci-8bit", 364 .data = &sdhci_j721e_8bit_drvdata, 365 }, 366 { /* sentinel */ } 367 }; 368 369 static int sdhci_am654_probe(struct platform_device *pdev) 370 { 371 const struct sdhci_am654_driver_data *drvdata; 372 struct sdhci_pltfm_host *pltfm_host; 373 struct sdhci_am654_data *sdhci_am654; 374 const struct of_device_id *match; 375 struct sdhci_host *host; 376 struct resource *res; 377 struct clk *clk_xin; 378 struct device *dev = &pdev->dev; 379 void __iomem *base; 380 int ret; 381 382 match = of_match_node(sdhci_am654_of_match, pdev->dev.of_node); 383 drvdata = match->data; 384 host = sdhci_pltfm_init(pdev, drvdata->pdata, sizeof(*sdhci_am654)); 385 if (IS_ERR(host)) 386 return PTR_ERR(host); 387 388 pltfm_host = sdhci_priv(host); 389 sdhci_am654 = sdhci_pltfm_priv(pltfm_host); 390 sdhci_am654->flags = drvdata->flags; 391 392 clk_xin = devm_clk_get(dev, "clk_xin"); 393 if (IS_ERR(clk_xin)) { 394 dev_err(dev, "clk_xin clock not found.\n"); 395 ret = PTR_ERR(clk_xin); 396 goto err_pltfm_free; 397 } 398 399 pltfm_host->clk = clk_xin; 400 401 /* Clocks are enabled using pm_runtime */ 402 pm_runtime_enable(dev); 403 ret = pm_runtime_get_sync(dev); 404 if (ret < 0) { 405 pm_runtime_put_noidle(dev); 406 goto pm_runtime_disable; 407 } 408 409 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 410 base = devm_ioremap_resource(dev, res); 411 if (IS_ERR(base)) { 412 ret = PTR_ERR(base); 413 goto pm_runtime_put; 414 } 415 416 sdhci_am654->base = devm_regmap_init_mmio(dev, base, 417 &sdhci_am654_regmap_config); 418 if (IS_ERR(sdhci_am654->base)) { 419 dev_err(dev, "Failed to initialize regmap\n"); 420 ret = PTR_ERR(sdhci_am654->base); 421 goto pm_runtime_put; 422 } 423 424 ret = sdhci_am654_get_of_property(pdev, sdhci_am654); 425 if (ret) 426 goto pm_runtime_put; 427 428 ret = mmc_of_parse(host->mmc); 429 if (ret) { 430 dev_err(dev, "parsing dt failed (%d)\n", ret); 431 goto pm_runtime_put; 432 } 433 434 ret = sdhci_am654_init(host); 435 if (ret) 436 goto pm_runtime_put; 437 438 return 0; 439 440 pm_runtime_put: 441 pm_runtime_put_sync(dev); 442 pm_runtime_disable: 443 pm_runtime_disable(dev); 444 err_pltfm_free: 445 sdhci_pltfm_free(pdev); 446 return ret; 447 } 448 449 static int sdhci_am654_remove(struct platform_device *pdev) 450 { 451 struct sdhci_host *host = platform_get_drvdata(pdev); 452 int ret; 453 454 sdhci_remove_host(host, true); 455 ret = pm_runtime_put_sync(&pdev->dev); 456 if (ret < 0) 457 return ret; 458 459 pm_runtime_disable(&pdev->dev); 460 sdhci_pltfm_free(pdev); 461 462 return 0; 463 } 464 465 static struct platform_driver sdhci_am654_driver = { 466 .driver = { 467 .name = "sdhci-am654", 468 .of_match_table = sdhci_am654_of_match, 469 }, 470 .probe = sdhci_am654_probe, 471 .remove = sdhci_am654_remove, 472 }; 473 474 module_platform_driver(sdhci_am654_driver); 475 476 MODULE_DESCRIPTION("Driver for SDHCI Controller on TI's AM654 devices"); 477 MODULE_AUTHOR("Faiz Abbas <faiz_abbas@ti.com>"); 478 MODULE_LICENSE("GPL"); 479