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 static u32 sdhci_st_readl(struct sdhci_host *host, int reg) 126 { 127 u32 ret; 128 129 switch (reg) { 130 case SDHCI_CAPABILITIES: 131 ret = readl_relaxed(host->ioaddr + reg); 132 /* Support 3.3V and 1.8V */ 133 ret &= ~SDHCI_CAN_VDD_300; 134 break; 135 default: 136 ret = readl_relaxed(host->ioaddr + reg); 137 } 138 return ret; 139 } 140 141 static const struct sdhci_ops sdhci_st_ops = { 142 .get_max_clock = sdhci_pltfm_clk_get_max_clock, 143 .set_clock = sdhci_set_clock, 144 .set_bus_width = sdhci_set_bus_width, 145 .read_l = sdhci_st_readl, 146 .reset = sdhci_reset, 147 }; 148 149 static const struct sdhci_pltfm_data sdhci_st_pdata = { 150 .ops = &sdhci_st_ops, 151 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | 152 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, 153 }; 154 155 156 static int sdhci_st_probe(struct platform_device *pdev) 157 { 158 struct sdhci_host *host; 159 struct st_mmc_platform_data *pdata; 160 struct sdhci_pltfm_host *pltfm_host; 161 struct clk *clk; 162 int ret = 0; 163 u16 host_version; 164 struct resource *res; 165 166 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 167 if (!pdata) 168 return -ENOMEM; 169 170 clk = devm_clk_get(&pdev->dev, "mmc"); 171 if (IS_ERR(clk)) { 172 dev_err(&pdev->dev, "Peripheral clk not found\n"); 173 return PTR_ERR(clk); 174 } 175 176 pdata->rstc = devm_reset_control_get(&pdev->dev, NULL); 177 if (IS_ERR(pdata->rstc)) 178 pdata->rstc = NULL; 179 else 180 reset_control_deassert(pdata->rstc); 181 182 host = sdhci_pltfm_init(pdev, &sdhci_st_pdata, 0); 183 if (IS_ERR(host)) { 184 dev_err(&pdev->dev, "Failed sdhci_pltfm_init\n"); 185 ret = PTR_ERR(host); 186 goto err_pltfm_init; 187 } 188 189 ret = mmc_of_parse(host->mmc); 190 if (ret) { 191 dev_err(&pdev->dev, "Failed mmc_of_parse\n"); 192 goto err_of; 193 } 194 195 clk_prepare_enable(clk); 196 197 /* Configure the FlashSS Top registers for setting eMMC TX/RX delay */ 198 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 199 "top-mmc-delay"); 200 pdata->top_ioaddr = devm_ioremap_resource(&pdev->dev, res); 201 if (IS_ERR(pdata->top_ioaddr)) { 202 dev_warn(&pdev->dev, "FlashSS Top Dly registers not available"); 203 pdata->top_ioaddr = NULL; 204 } 205 206 pltfm_host = sdhci_priv(host); 207 pltfm_host->priv = pdata; 208 pltfm_host->clk = clk; 209 210 ret = sdhci_add_host(host); 211 if (ret) { 212 dev_err(&pdev->dev, "Failed sdhci_add_host\n"); 213 goto err_out; 214 } 215 216 platform_set_drvdata(pdev, host); 217 218 host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION)); 219 220 dev_info(&pdev->dev, "SDHCI ST Initialised: Host Version: 0x%x Vendor Version 0x%x\n", 221 ((host_version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT), 222 ((host_version & SDHCI_VENDOR_VER_MASK) >> 223 SDHCI_VENDOR_VER_SHIFT)); 224 225 return 0; 226 227 err_out: 228 clk_disable_unprepare(clk); 229 err_of: 230 sdhci_pltfm_free(pdev); 231 err_pltfm_init: 232 if (pdata->rstc) 233 reset_control_assert(pdata->rstc); 234 235 return ret; 236 } 237 238 static int sdhci_st_remove(struct platform_device *pdev) 239 { 240 struct sdhci_host *host = platform_get_drvdata(pdev); 241 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 242 struct st_mmc_platform_data *pdata = pltfm_host->priv; 243 int ret; 244 245 ret = sdhci_pltfm_unregister(pdev); 246 247 if (pdata->rstc) 248 reset_control_assert(pdata->rstc); 249 250 return ret; 251 } 252 253 #ifdef CONFIG_PM_SLEEP 254 static int sdhci_st_suspend(struct device *dev) 255 { 256 struct sdhci_host *host = dev_get_drvdata(dev); 257 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 258 struct st_mmc_platform_data *pdata = pltfm_host->priv; 259 int ret = sdhci_suspend_host(host); 260 261 if (ret) 262 goto out; 263 264 if (pdata->rstc) 265 reset_control_assert(pdata->rstc); 266 267 clk_disable_unprepare(pltfm_host->clk); 268 out: 269 return ret; 270 } 271 272 static int sdhci_st_resume(struct device *dev) 273 { 274 struct sdhci_host *host = dev_get_drvdata(dev); 275 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 276 struct st_mmc_platform_data *pdata = pltfm_host->priv; 277 278 clk_prepare_enable(pltfm_host->clk); 279 280 if (pdata->rstc) 281 reset_control_deassert(pdata->rstc); 282 283 return sdhci_resume_host(host); 284 } 285 #endif 286 287 static SIMPLE_DEV_PM_OPS(sdhci_st_pmops, sdhci_st_suspend, sdhci_st_resume); 288 289 static const struct of_device_id st_sdhci_match[] = { 290 { .compatible = "st,sdhci" }, 291 {}, 292 }; 293 294 MODULE_DEVICE_TABLE(of, st_sdhci_match); 295 296 static struct platform_driver sdhci_st_driver = { 297 .probe = sdhci_st_probe, 298 .remove = sdhci_st_remove, 299 .driver = { 300 .name = "sdhci-st", 301 .pm = &sdhci_st_pmops, 302 .of_match_table = of_match_ptr(st_sdhci_match), 303 }, 304 }; 305 306 module_platform_driver(sdhci_st_driver); 307 308 MODULE_DESCRIPTION("SDHCI driver for STMicroelectronics SoCs"); 309 MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 310 MODULE_LICENSE("GPL v2"); 311 MODULE_ALIAS("platform:st-sdhci"); 312