1 /* 2 * Support for SDHCI on STMicroelectronics SoCs 3 * 4 * Copyright (C) 2014 STMicroelectronics Ltd 5 * Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 6 * Contributors: Peter Griffin <peter.griffin@linaro.org> 7 * 8 * Based on sdhci-cns3xxx.c 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 */ 20 21 #include <linux/io.h> 22 #include <linux/of.h> 23 #include <linux/module.h> 24 #include <linux/err.h> 25 #include <linux/mmc/host.h> 26 #include <linux/reset.h> 27 #include "sdhci-pltfm.h" 28 29 struct st_mmc_platform_data { 30 struct reset_control *rstc; 31 void __iomem *top_ioaddr; 32 }; 33 34 /* MMCSS glue logic to setup the HC on some ST SoCs (e.g. STiH407 family) */ 35 36 #define ST_MMC_CCONFIG_REG_1 0x400 37 #define ST_MMC_CCONFIG_TIMEOUT_CLK_UNIT BIT(24) 38 #define ST_MMC_CCONFIG_TIMEOUT_CLK_FREQ BIT(12) 39 #define ST_MMC_CCONFIG_TUNING_COUNT_DEFAULT BIT(8) 40 #define ST_MMC_CCONFIG_ASYNC_WAKEUP BIT(0) 41 #define ST_MMC_CCONFIG_1_DEFAULT \ 42 ((ST_MMC_CCONFIG_TIMEOUT_CLK_UNIT) | \ 43 (ST_MMC_CCONFIG_TIMEOUT_CLK_FREQ) | \ 44 (ST_MMC_CCONFIG_TUNING_COUNT_DEFAULT)) 45 46 #define ST_MMC_CCONFIG_REG_2 0x404 47 #define ST_MMC_CCONFIG_HIGH_SPEED BIT(28) 48 #define ST_MMC_CCONFIG_ADMA2 BIT(24) 49 #define ST_MMC_CCONFIG_8BIT BIT(20) 50 #define ST_MMC_CCONFIG_MAX_BLK_LEN 16 51 #define MAX_BLK_LEN_1024 1 52 #define MAX_BLK_LEN_2048 2 53 #define BASE_CLK_FREQ_200 0xc8 54 #define BASE_CLK_FREQ_100 0x64 55 #define BASE_CLK_FREQ_50 0x32 56 #define ST_MMC_CCONFIG_2_DEFAULT \ 57 (ST_MMC_CCONFIG_HIGH_SPEED | ST_MMC_CCONFIG_ADMA2 | \ 58 ST_MMC_CCONFIG_8BIT | \ 59 (MAX_BLK_LEN_1024 << ST_MMC_CCONFIG_MAX_BLK_LEN)) 60 61 #define ST_MMC_CCONFIG_REG_3 0x408 62 #define ST_MMC_CCONFIG_EMMC_SLOT_TYPE BIT(28) 63 #define ST_MMC_CCONFIG_64BIT BIT(24) 64 #define ST_MMC_CCONFIG_ASYNCH_INTR_SUPPORT BIT(20) 65 #define ST_MMC_CCONFIG_1P8_VOLT BIT(16) 66 #define ST_MMC_CCONFIG_3P0_VOLT BIT(12) 67 #define ST_MMC_CCONFIG_3P3_VOLT BIT(8) 68 #define ST_MMC_CCONFIG_SUSP_RES_SUPPORT BIT(4) 69 #define ST_MMC_CCONFIG_SDMA BIT(0) 70 #define ST_MMC_CCONFIG_3_DEFAULT \ 71 (ST_MMC_CCONFIG_ASYNCH_INTR_SUPPORT | \ 72 ST_MMC_CCONFIG_3P3_VOLT | \ 73 ST_MMC_CCONFIG_SUSP_RES_SUPPORT | \ 74 ST_MMC_CCONFIG_SDMA) 75 76 #define ST_MMC_CCONFIG_REG_4 0x40c 77 #define ST_MMC_CCONFIG_D_DRIVER BIT(20) 78 #define ST_MMC_CCONFIG_C_DRIVER BIT(16) 79 #define ST_MMC_CCONFIG_A_DRIVER BIT(12) 80 #define ST_MMC_CCONFIG_DDR50 BIT(8) 81 #define ST_MMC_CCONFIG_SDR104 BIT(4) 82 #define ST_MMC_CCONFIG_SDR50 BIT(0) 83 #define ST_MMC_CCONFIG_4_DEFAULT 0 84 85 #define ST_MMC_CCONFIG_REG_5 0x410 86 #define ST_MMC_CCONFIG_TUNING_FOR_SDR50 BIT(8) 87 #define RETUNING_TIMER_CNT_MAX 0xf 88 #define ST_MMC_CCONFIG_5_DEFAULT 0 89 90 /* I/O configuration for Arasan IP */ 91 #define ST_MMC_GP_OUTPUT 0x450 92 #define ST_MMC_GP_OUTPUT_CD BIT(12) 93 94 #define ST_MMC_STATUS_R 0x460 95 96 #define ST_TOP_MMC_DLY_FIX_OFF(x) (x - 0x8) 97 98 /* TOP config registers to manage static and dynamic delay */ 99 #define ST_TOP_MMC_TX_CLK_DLY ST_TOP_MMC_DLY_FIX_OFF(0x8) 100 #define ST_TOP_MMC_RX_CLK_DLY ST_TOP_MMC_DLY_FIX_OFF(0xc) 101 /* MMC delay control register */ 102 #define ST_TOP_MMC_DLY_CTRL ST_TOP_MMC_DLY_FIX_OFF(0x18) 103 #define ST_TOP_MMC_DLY_CTRL_DLL_BYPASS_CMD BIT(0) 104 #define ST_TOP_MMC_DLY_CTRL_DLL_BYPASS_PH_SEL BIT(1) 105 #define ST_TOP_MMC_DLY_CTRL_TX_DLL_ENABLE BIT(8) 106 #define ST_TOP_MMC_DLY_CTRL_RX_DLL_ENABLE BIT(9) 107 #define ST_TOP_MMC_DLY_CTRL_ATUNE_NOT_CFG_DLY BIT(10) 108 #define ST_TOP_MMC_START_DLL_LOCK BIT(11) 109 110 /* register to provide the phase-shift value for DLL */ 111 #define ST_TOP_MMC_TX_DLL_STEP_DLY ST_TOP_MMC_DLY_FIX_OFF(0x1c) 112 #define ST_TOP_MMC_RX_DLL_STEP_DLY ST_TOP_MMC_DLY_FIX_OFF(0x20) 113 #define ST_TOP_MMC_RX_CMD_STEP_DLY ST_TOP_MMC_DLY_FIX_OFF(0x24) 114 115 /* phase shift delay on the tx clk 2.188ns */ 116 #define ST_TOP_MMC_TX_DLL_STEP_DLY_VALID 0x6 117 118 #define ST_TOP_MMC_DLY_MAX 0xf 119 120 #define ST_TOP_MMC_DYN_DLY_CONF \ 121 (ST_TOP_MMC_DLY_CTRL_TX_DLL_ENABLE | \ 122 ST_TOP_MMC_DLY_CTRL_ATUNE_NOT_CFG_DLY | \ 123 ST_TOP_MMC_START_DLL_LOCK) 124 125 /* 126 * For clock speeds greater than 90MHz, we need to check that the 127 * DLL procedure has finished before switching to ultra-speed modes. 128 */ 129 #define CLK_TO_CHECK_DLL_LOCK 90000000 130 131 static inline void st_mmcss_set_static_delay(void __iomem *ioaddr) 132 { 133 if (!ioaddr) 134 return; 135 136 writel_relaxed(0x0, ioaddr + ST_TOP_MMC_DLY_CTRL); 137 writel_relaxed(ST_TOP_MMC_DLY_MAX, 138 ioaddr + ST_TOP_MMC_TX_CLK_DLY); 139 } 140 141 static inline void st_mmcss_set_dll(void __iomem *ioaddr) 142 { 143 if (!ioaddr) 144 return; 145 146 writel_relaxed(ST_TOP_MMC_DYN_DLY_CONF, ioaddr + ST_TOP_MMC_DLY_CTRL); 147 writel_relaxed(ST_TOP_MMC_TX_DLL_STEP_DLY_VALID, 148 ioaddr + ST_TOP_MMC_TX_DLL_STEP_DLY); 149 } 150 151 static int st_mmcss_lock_dll(void __iomem *ioaddr) 152 { 153 unsigned long curr, value; 154 unsigned long finish = jiffies + HZ; 155 156 /* Checks if the DLL procedure is finished */ 157 do { 158 curr = jiffies; 159 value = readl(ioaddr + ST_MMC_STATUS_R); 160 if (value & 0x1) 161 return 0; 162 163 cpu_relax(); 164 } while (!time_after_eq(curr, finish)); 165 166 return -EBUSY; 167 } 168 169 static int sdhci_st_set_dll_for_clock(struct sdhci_host *host) 170 { 171 int ret = 0; 172 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 173 struct st_mmc_platform_data *pdata = pltfm_host->priv; 174 175 if (host->clock > CLK_TO_CHECK_DLL_LOCK) { 176 st_mmcss_set_dll(pdata->top_ioaddr); 177 ret = st_mmcss_lock_dll(host->ioaddr); 178 } 179 180 return ret; 181 } 182 183 184 static u32 sdhci_st_readl(struct sdhci_host *host, int reg) 185 { 186 u32 ret; 187 188 switch (reg) { 189 case SDHCI_CAPABILITIES: 190 ret = readl_relaxed(host->ioaddr + reg); 191 /* Support 3.3V and 1.8V */ 192 ret &= ~SDHCI_CAN_VDD_300; 193 break; 194 default: 195 ret = readl_relaxed(host->ioaddr + reg); 196 } 197 return ret; 198 } 199 200 static const struct sdhci_ops sdhci_st_ops = { 201 .get_max_clock = sdhci_pltfm_clk_get_max_clock, 202 .set_clock = sdhci_set_clock, 203 .set_bus_width = sdhci_set_bus_width, 204 .read_l = sdhci_st_readl, 205 .reset = sdhci_reset, 206 }; 207 208 static const struct sdhci_pltfm_data sdhci_st_pdata = { 209 .ops = &sdhci_st_ops, 210 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | 211 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, 212 }; 213 214 215 static int sdhci_st_probe(struct platform_device *pdev) 216 { 217 struct sdhci_host *host; 218 struct st_mmc_platform_data *pdata; 219 struct sdhci_pltfm_host *pltfm_host; 220 struct clk *clk; 221 int ret = 0; 222 u16 host_version; 223 struct resource *res; 224 225 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 226 if (!pdata) 227 return -ENOMEM; 228 229 clk = devm_clk_get(&pdev->dev, "mmc"); 230 if (IS_ERR(clk)) { 231 dev_err(&pdev->dev, "Peripheral clk not found\n"); 232 return PTR_ERR(clk); 233 } 234 235 pdata->rstc = devm_reset_control_get(&pdev->dev, NULL); 236 if (IS_ERR(pdata->rstc)) 237 pdata->rstc = NULL; 238 else 239 reset_control_deassert(pdata->rstc); 240 241 host = sdhci_pltfm_init(pdev, &sdhci_st_pdata, 0); 242 if (IS_ERR(host)) { 243 dev_err(&pdev->dev, "Failed sdhci_pltfm_init\n"); 244 ret = PTR_ERR(host); 245 goto err_pltfm_init; 246 } 247 248 ret = mmc_of_parse(host->mmc); 249 if (ret) { 250 dev_err(&pdev->dev, "Failed mmc_of_parse\n"); 251 goto err_of; 252 } 253 254 clk_prepare_enable(clk); 255 256 /* Configure the FlashSS Top registers for setting eMMC TX/RX delay */ 257 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 258 "top-mmc-delay"); 259 pdata->top_ioaddr = devm_ioremap_resource(&pdev->dev, res); 260 if (IS_ERR(pdata->top_ioaddr)) { 261 dev_warn(&pdev->dev, "FlashSS Top Dly registers not available"); 262 pdata->top_ioaddr = NULL; 263 } 264 265 pltfm_host = sdhci_priv(host); 266 pltfm_host->priv = pdata; 267 pltfm_host->clk = clk; 268 269 ret = sdhci_add_host(host); 270 if (ret) { 271 dev_err(&pdev->dev, "Failed sdhci_add_host\n"); 272 goto err_out; 273 } 274 275 platform_set_drvdata(pdev, host); 276 277 host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION)); 278 279 dev_info(&pdev->dev, "SDHCI ST Initialised: Host Version: 0x%x Vendor Version 0x%x\n", 280 ((host_version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT), 281 ((host_version & SDHCI_VENDOR_VER_MASK) >> 282 SDHCI_VENDOR_VER_SHIFT)); 283 284 return 0; 285 286 err_out: 287 clk_disable_unprepare(clk); 288 err_of: 289 sdhci_pltfm_free(pdev); 290 err_pltfm_init: 291 if (pdata->rstc) 292 reset_control_assert(pdata->rstc); 293 294 return ret; 295 } 296 297 static int sdhci_st_remove(struct platform_device *pdev) 298 { 299 struct sdhci_host *host = platform_get_drvdata(pdev); 300 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 301 struct st_mmc_platform_data *pdata = pltfm_host->priv; 302 int ret; 303 304 ret = sdhci_pltfm_unregister(pdev); 305 306 if (pdata->rstc) 307 reset_control_assert(pdata->rstc); 308 309 return ret; 310 } 311 312 #ifdef CONFIG_PM_SLEEP 313 static int sdhci_st_suspend(struct device *dev) 314 { 315 struct sdhci_host *host = dev_get_drvdata(dev); 316 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 317 struct st_mmc_platform_data *pdata = pltfm_host->priv; 318 int ret = sdhci_suspend_host(host); 319 320 if (ret) 321 goto out; 322 323 if (pdata->rstc) 324 reset_control_assert(pdata->rstc); 325 326 clk_disable_unprepare(pltfm_host->clk); 327 out: 328 return ret; 329 } 330 331 static int sdhci_st_resume(struct device *dev) 332 { 333 struct sdhci_host *host = dev_get_drvdata(dev); 334 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 335 struct st_mmc_platform_data *pdata = pltfm_host->priv; 336 337 clk_prepare_enable(pltfm_host->clk); 338 339 if (pdata->rstc) 340 reset_control_deassert(pdata->rstc); 341 342 return sdhci_resume_host(host); 343 } 344 #endif 345 346 static SIMPLE_DEV_PM_OPS(sdhci_st_pmops, sdhci_st_suspend, sdhci_st_resume); 347 348 static const struct of_device_id st_sdhci_match[] = { 349 { .compatible = "st,sdhci" }, 350 {}, 351 }; 352 353 MODULE_DEVICE_TABLE(of, st_sdhci_match); 354 355 static struct platform_driver sdhci_st_driver = { 356 .probe = sdhci_st_probe, 357 .remove = sdhci_st_remove, 358 .driver = { 359 .name = "sdhci-st", 360 .pm = &sdhci_st_pmops, 361 .of_match_table = of_match_ptr(st_sdhci_match), 362 }, 363 }; 364 365 module_platform_driver(sdhci_st_driver); 366 367 MODULE_DESCRIPTION("SDHCI driver for STMicroelectronics SoCs"); 368 MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 369 MODULE_LICENSE("GPL v2"); 370 MODULE_ALIAS("platform:st-sdhci"); 371