0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/io.h>
0013 #include <linux/of.h>
0014 #include <linux/module.h>
0015 #include <linux/err.h>
0016 #include <linux/mmc/host.h>
0017 #include <linux/reset.h>
0018 #include "sdhci-pltfm.h"
0019
0020 struct st_mmc_platform_data {
0021 struct reset_control *rstc;
0022 struct clk *icnclk;
0023 void __iomem *top_ioaddr;
0024 };
0025
0026
0027
0028 #define ST_MMC_CCONFIG_REG_1 0x400
0029 #define ST_MMC_CCONFIG_TIMEOUT_CLK_UNIT BIT(24)
0030 #define ST_MMC_CCONFIG_TIMEOUT_CLK_FREQ BIT(12)
0031 #define ST_MMC_CCONFIG_TUNING_COUNT_DEFAULT BIT(8)
0032 #define ST_MMC_CCONFIG_ASYNC_WAKEUP BIT(0)
0033 #define ST_MMC_CCONFIG_1_DEFAULT \
0034 ((ST_MMC_CCONFIG_TIMEOUT_CLK_UNIT) | \
0035 (ST_MMC_CCONFIG_TIMEOUT_CLK_FREQ) | \
0036 (ST_MMC_CCONFIG_TUNING_COUNT_DEFAULT))
0037
0038 #define ST_MMC_CCONFIG_REG_2 0x404
0039 #define ST_MMC_CCONFIG_HIGH_SPEED BIT(28)
0040 #define ST_MMC_CCONFIG_ADMA2 BIT(24)
0041 #define ST_MMC_CCONFIG_8BIT BIT(20)
0042 #define ST_MMC_CCONFIG_MAX_BLK_LEN 16
0043 #define MAX_BLK_LEN_1024 1
0044 #define MAX_BLK_LEN_2048 2
0045 #define BASE_CLK_FREQ_200 0xc8
0046 #define BASE_CLK_FREQ_100 0x64
0047 #define BASE_CLK_FREQ_50 0x32
0048 #define ST_MMC_CCONFIG_2_DEFAULT \
0049 (ST_MMC_CCONFIG_HIGH_SPEED | ST_MMC_CCONFIG_ADMA2 | \
0050 ST_MMC_CCONFIG_8BIT | \
0051 (MAX_BLK_LEN_1024 << ST_MMC_CCONFIG_MAX_BLK_LEN))
0052
0053 #define ST_MMC_CCONFIG_REG_3 0x408
0054 #define ST_MMC_CCONFIG_EMMC_SLOT_TYPE BIT(28)
0055 #define ST_MMC_CCONFIG_64BIT BIT(24)
0056 #define ST_MMC_CCONFIG_ASYNCH_INTR_SUPPORT BIT(20)
0057 #define ST_MMC_CCONFIG_1P8_VOLT BIT(16)
0058 #define ST_MMC_CCONFIG_3P0_VOLT BIT(12)
0059 #define ST_MMC_CCONFIG_3P3_VOLT BIT(8)
0060 #define ST_MMC_CCONFIG_SUSP_RES_SUPPORT BIT(4)
0061 #define ST_MMC_CCONFIG_SDMA BIT(0)
0062 #define ST_MMC_CCONFIG_3_DEFAULT \
0063 (ST_MMC_CCONFIG_ASYNCH_INTR_SUPPORT | \
0064 ST_MMC_CCONFIG_3P3_VOLT | \
0065 ST_MMC_CCONFIG_SUSP_RES_SUPPORT | \
0066 ST_MMC_CCONFIG_SDMA)
0067
0068 #define ST_MMC_CCONFIG_REG_4 0x40c
0069 #define ST_MMC_CCONFIG_D_DRIVER BIT(20)
0070 #define ST_MMC_CCONFIG_C_DRIVER BIT(16)
0071 #define ST_MMC_CCONFIG_A_DRIVER BIT(12)
0072 #define ST_MMC_CCONFIG_DDR50 BIT(8)
0073 #define ST_MMC_CCONFIG_SDR104 BIT(4)
0074 #define ST_MMC_CCONFIG_SDR50 BIT(0)
0075 #define ST_MMC_CCONFIG_4_DEFAULT 0
0076
0077 #define ST_MMC_CCONFIG_REG_5 0x410
0078 #define ST_MMC_CCONFIG_TUNING_FOR_SDR50 BIT(8)
0079 #define RETUNING_TIMER_CNT_MAX 0xf
0080 #define ST_MMC_CCONFIG_5_DEFAULT 0
0081
0082
0083 #define ST_MMC_GP_OUTPUT 0x450
0084 #define ST_MMC_GP_OUTPUT_CD BIT(12)
0085
0086 #define ST_MMC_STATUS_R 0x460
0087
0088 #define ST_TOP_MMC_DLY_FIX_OFF(x) (x - 0x8)
0089
0090
0091 #define ST_TOP_MMC_TX_CLK_DLY ST_TOP_MMC_DLY_FIX_OFF(0x8)
0092 #define ST_TOP_MMC_RX_CLK_DLY ST_TOP_MMC_DLY_FIX_OFF(0xc)
0093
0094 #define ST_TOP_MMC_DLY_CTRL ST_TOP_MMC_DLY_FIX_OFF(0x18)
0095 #define ST_TOP_MMC_DLY_CTRL_DLL_BYPASS_CMD BIT(0)
0096 #define ST_TOP_MMC_DLY_CTRL_DLL_BYPASS_PH_SEL BIT(1)
0097 #define ST_TOP_MMC_DLY_CTRL_TX_DLL_ENABLE BIT(8)
0098 #define ST_TOP_MMC_DLY_CTRL_RX_DLL_ENABLE BIT(9)
0099 #define ST_TOP_MMC_DLY_CTRL_ATUNE_NOT_CFG_DLY BIT(10)
0100 #define ST_TOP_MMC_START_DLL_LOCK BIT(11)
0101
0102
0103 #define ST_TOP_MMC_TX_DLL_STEP_DLY ST_TOP_MMC_DLY_FIX_OFF(0x1c)
0104 #define ST_TOP_MMC_RX_DLL_STEP_DLY ST_TOP_MMC_DLY_FIX_OFF(0x20)
0105 #define ST_TOP_MMC_RX_CMD_STEP_DLY ST_TOP_MMC_DLY_FIX_OFF(0x24)
0106
0107
0108 #define ST_TOP_MMC_TX_DLL_STEP_DLY_VALID 0x6
0109
0110 #define ST_TOP_MMC_DLY_MAX 0xf
0111
0112 #define ST_TOP_MMC_DYN_DLY_CONF \
0113 (ST_TOP_MMC_DLY_CTRL_TX_DLL_ENABLE | \
0114 ST_TOP_MMC_DLY_CTRL_ATUNE_NOT_CFG_DLY | \
0115 ST_TOP_MMC_START_DLL_LOCK)
0116
0117
0118
0119
0120
0121 #define CLK_TO_CHECK_DLL_LOCK 90000000
0122
0123 static inline void st_mmcss_set_static_delay(void __iomem *ioaddr)
0124 {
0125 if (!ioaddr)
0126 return;
0127
0128 writel_relaxed(0x0, ioaddr + ST_TOP_MMC_DLY_CTRL);
0129 writel_relaxed(ST_TOP_MMC_DLY_MAX,
0130 ioaddr + ST_TOP_MMC_TX_CLK_DLY);
0131 }
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 static void st_mmcss_cconfig(struct device_node *np, struct sdhci_host *host)
0143 {
0144 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
0145 struct mmc_host *mhost = host->mmc;
0146 u32 cconf2, cconf3, cconf4, cconf5;
0147
0148 if (!of_device_is_compatible(np, "st,sdhci-stih407"))
0149 return;
0150
0151 cconf2 = ST_MMC_CCONFIG_2_DEFAULT;
0152 cconf3 = ST_MMC_CCONFIG_3_DEFAULT;
0153 cconf4 = ST_MMC_CCONFIG_4_DEFAULT;
0154 cconf5 = ST_MMC_CCONFIG_5_DEFAULT;
0155
0156 writel_relaxed(ST_MMC_CCONFIG_1_DEFAULT,
0157 host->ioaddr + ST_MMC_CCONFIG_REG_1);
0158
0159
0160
0161
0162 switch (mhost->f_max) {
0163 case 200000000:
0164 clk_set_rate(pltfm_host->clk, mhost->f_max);
0165 cconf2 |= BASE_CLK_FREQ_200;
0166 break;
0167 case 100000000:
0168 clk_set_rate(pltfm_host->clk, mhost->f_max);
0169 cconf2 |= BASE_CLK_FREQ_100;
0170 break;
0171 default:
0172 clk_set_rate(pltfm_host->clk, 50000000);
0173 cconf2 |= BASE_CLK_FREQ_50;
0174 }
0175
0176 writel_relaxed(cconf2, host->ioaddr + ST_MMC_CCONFIG_REG_2);
0177
0178 if (!mmc_card_is_removable(mhost))
0179 cconf3 |= ST_MMC_CCONFIG_EMMC_SLOT_TYPE;
0180 else
0181
0182 writel_relaxed(ST_MMC_GP_OUTPUT_CD,
0183 host->ioaddr + ST_MMC_GP_OUTPUT);
0184
0185 if (mhost->caps & MMC_CAP_UHS_SDR50) {
0186
0187 cconf3 |= ST_MMC_CCONFIG_1P8_VOLT;
0188 cconf4 |= ST_MMC_CCONFIG_SDR50;
0189
0190 cconf5 |= ST_MMC_CCONFIG_TUNING_FOR_SDR50;
0191
0192 cconf5 |= RETUNING_TIMER_CNT_MAX;
0193 }
0194
0195 if (mhost->caps & MMC_CAP_UHS_SDR104) {
0196
0197
0198
0199
0200 cconf3 |= ST_MMC_CCONFIG_1P8_VOLT;
0201 cconf4 |= ST_MMC_CCONFIG_SDR104;
0202
0203 cconf5 |= RETUNING_TIMER_CNT_MAX;
0204 }
0205
0206 if (mhost->caps & MMC_CAP_UHS_DDR50)
0207 cconf4 |= ST_MMC_CCONFIG_DDR50;
0208
0209 writel_relaxed(cconf3, host->ioaddr + ST_MMC_CCONFIG_REG_3);
0210 writel_relaxed(cconf4, host->ioaddr + ST_MMC_CCONFIG_REG_4);
0211 writel_relaxed(cconf5, host->ioaddr + ST_MMC_CCONFIG_REG_5);
0212 }
0213
0214 static inline void st_mmcss_set_dll(void __iomem *ioaddr)
0215 {
0216 if (!ioaddr)
0217 return;
0218
0219 writel_relaxed(ST_TOP_MMC_DYN_DLY_CONF, ioaddr + ST_TOP_MMC_DLY_CTRL);
0220 writel_relaxed(ST_TOP_MMC_TX_DLL_STEP_DLY_VALID,
0221 ioaddr + ST_TOP_MMC_TX_DLL_STEP_DLY);
0222 }
0223
0224 static int st_mmcss_lock_dll(void __iomem *ioaddr)
0225 {
0226 unsigned long curr, value;
0227 unsigned long finish = jiffies + HZ;
0228
0229
0230 do {
0231 curr = jiffies;
0232 value = readl(ioaddr + ST_MMC_STATUS_R);
0233 if (value & 0x1)
0234 return 0;
0235
0236 cpu_relax();
0237 } while (!time_after_eq(curr, finish));
0238
0239 return -EBUSY;
0240 }
0241
0242 static int sdhci_st_set_dll_for_clock(struct sdhci_host *host)
0243 {
0244 int ret = 0;
0245 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
0246 struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
0247
0248 if (host->clock > CLK_TO_CHECK_DLL_LOCK) {
0249 st_mmcss_set_dll(pdata->top_ioaddr);
0250 ret = st_mmcss_lock_dll(host->ioaddr);
0251 }
0252
0253 return ret;
0254 }
0255
0256 static void sdhci_st_set_uhs_signaling(struct sdhci_host *host,
0257 unsigned int uhs)
0258 {
0259 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
0260 struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
0261 u16 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
0262 int ret = 0;
0263
0264
0265 ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
0266 switch (uhs) {
0267
0268
0269
0270
0271
0272 case MMC_TIMING_UHS_SDR12:
0273 st_mmcss_set_static_delay(pdata->top_ioaddr);
0274 ctrl_2 |= SDHCI_CTRL_UHS_SDR12 | SDHCI_CTRL_VDD_180;
0275 break;
0276 case MMC_TIMING_UHS_SDR25:
0277 st_mmcss_set_static_delay(pdata->top_ioaddr);
0278 ctrl_2 |= SDHCI_CTRL_UHS_SDR25 | SDHCI_CTRL_VDD_180;
0279 break;
0280 case MMC_TIMING_UHS_SDR50:
0281 st_mmcss_set_static_delay(pdata->top_ioaddr);
0282 ctrl_2 |= SDHCI_CTRL_UHS_SDR50 | SDHCI_CTRL_VDD_180;
0283 ret = sdhci_st_set_dll_for_clock(host);
0284 break;
0285 case MMC_TIMING_UHS_SDR104:
0286 case MMC_TIMING_MMC_HS200:
0287 st_mmcss_set_static_delay(pdata->top_ioaddr);
0288 ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180;
0289 ret = sdhci_st_set_dll_for_clock(host);
0290 break;
0291 case MMC_TIMING_UHS_DDR50:
0292 case MMC_TIMING_MMC_DDR52:
0293 st_mmcss_set_static_delay(pdata->top_ioaddr);
0294 ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180;
0295 break;
0296 }
0297
0298 if (ret)
0299 dev_warn(mmc_dev(host->mmc), "Error setting dll for clock "
0300 "(uhs %d)\n", uhs);
0301
0302 dev_dbg(mmc_dev(host->mmc), "uhs %d, ctrl_2 %04X\n", uhs, ctrl_2);
0303
0304 sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
0305 }
0306
0307 static u32 sdhci_st_readl(struct sdhci_host *host, int reg)
0308 {
0309 u32 ret;
0310
0311 switch (reg) {
0312 case SDHCI_CAPABILITIES:
0313 ret = readl_relaxed(host->ioaddr + reg);
0314
0315 ret &= ~SDHCI_CAN_VDD_300;
0316 break;
0317 default:
0318 ret = readl_relaxed(host->ioaddr + reg);
0319 }
0320 return ret;
0321 }
0322
0323 static const struct sdhci_ops sdhci_st_ops = {
0324 .get_max_clock = sdhci_pltfm_clk_get_max_clock,
0325 .set_clock = sdhci_set_clock,
0326 .set_bus_width = sdhci_set_bus_width,
0327 .read_l = sdhci_st_readl,
0328 .reset = sdhci_reset,
0329 .set_uhs_signaling = sdhci_st_set_uhs_signaling,
0330 };
0331
0332 static const struct sdhci_pltfm_data sdhci_st_pdata = {
0333 .ops = &sdhci_st_ops,
0334 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
0335 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
0336 SDHCI_QUIRK_NO_HISPD_BIT,
0337 .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
0338 SDHCI_QUIRK2_STOP_WITH_TC,
0339 };
0340
0341
0342 static int sdhci_st_probe(struct platform_device *pdev)
0343 {
0344 struct device_node *np = pdev->dev.of_node;
0345 struct sdhci_host *host;
0346 struct st_mmc_platform_data *pdata;
0347 struct sdhci_pltfm_host *pltfm_host;
0348 struct clk *clk, *icnclk;
0349 int ret = 0;
0350 u16 host_version;
0351 struct resource *res;
0352 struct reset_control *rstc;
0353
0354 clk = devm_clk_get(&pdev->dev, "mmc");
0355 if (IS_ERR(clk)) {
0356 dev_err(&pdev->dev, "Peripheral clk not found\n");
0357 return PTR_ERR(clk);
0358 }
0359
0360
0361 icnclk = devm_clk_get(&pdev->dev, "icn");
0362 if (IS_ERR(icnclk))
0363 icnclk = NULL;
0364
0365 rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
0366 if (IS_ERR(rstc))
0367 return PTR_ERR(rstc);
0368 reset_control_deassert(rstc);
0369
0370 host = sdhci_pltfm_init(pdev, &sdhci_st_pdata, sizeof(*pdata));
0371 if (IS_ERR(host)) {
0372 dev_err(&pdev->dev, "Failed sdhci_pltfm_init\n");
0373 ret = PTR_ERR(host);
0374 goto err_pltfm_init;
0375 }
0376
0377 pltfm_host = sdhci_priv(host);
0378 pdata = sdhci_pltfm_priv(pltfm_host);
0379 pdata->rstc = rstc;
0380
0381 ret = mmc_of_parse(host->mmc);
0382 if (ret) {
0383 dev_err(&pdev->dev, "Failed mmc_of_parse\n");
0384 goto err_of;
0385 }
0386
0387 ret = clk_prepare_enable(clk);
0388 if (ret) {
0389 dev_err(&pdev->dev, "Failed to prepare clock\n");
0390 goto err_of;
0391 }
0392
0393 ret = clk_prepare_enable(icnclk);
0394 if (ret) {
0395 dev_err(&pdev->dev, "Failed to prepare icn clock\n");
0396 goto err_icnclk;
0397 }
0398
0399
0400 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
0401 "top-mmc-delay");
0402 pdata->top_ioaddr = devm_ioremap_resource(&pdev->dev, res);
0403 if (IS_ERR(pdata->top_ioaddr))
0404 pdata->top_ioaddr = NULL;
0405
0406 pltfm_host->clk = clk;
0407 pdata->icnclk = icnclk;
0408
0409
0410 st_mmcss_cconfig(np, host);
0411
0412 ret = sdhci_add_host(host);
0413 if (ret)
0414 goto err_out;
0415
0416 host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION));
0417
0418 dev_info(&pdev->dev, "SDHCI ST Initialised: Host Version: 0x%x Vendor Version 0x%x\n",
0419 ((host_version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT),
0420 ((host_version & SDHCI_VENDOR_VER_MASK) >>
0421 SDHCI_VENDOR_VER_SHIFT));
0422
0423 return 0;
0424
0425 err_out:
0426 clk_disable_unprepare(icnclk);
0427 err_icnclk:
0428 clk_disable_unprepare(clk);
0429 err_of:
0430 sdhci_pltfm_free(pdev);
0431 err_pltfm_init:
0432 reset_control_assert(rstc);
0433
0434 return ret;
0435 }
0436
0437 static int sdhci_st_remove(struct platform_device *pdev)
0438 {
0439 struct sdhci_host *host = platform_get_drvdata(pdev);
0440 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
0441 struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
0442 struct reset_control *rstc = pdata->rstc;
0443
0444 sdhci_pltfm_unregister(pdev);
0445
0446 clk_disable_unprepare(pdata->icnclk);
0447
0448 reset_control_assert(rstc);
0449
0450 return 0;
0451 }
0452
0453 #ifdef CONFIG_PM_SLEEP
0454 static int sdhci_st_suspend(struct device *dev)
0455 {
0456 struct sdhci_host *host = dev_get_drvdata(dev);
0457 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
0458 struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
0459 int ret;
0460
0461 if (host->tuning_mode != SDHCI_TUNING_MODE_3)
0462 mmc_retune_needed(host->mmc);
0463
0464 ret = sdhci_suspend_host(host);
0465 if (ret)
0466 goto out;
0467
0468 reset_control_assert(pdata->rstc);
0469
0470 clk_disable_unprepare(pdata->icnclk);
0471 clk_disable_unprepare(pltfm_host->clk);
0472 out:
0473 return ret;
0474 }
0475
0476 static int sdhci_st_resume(struct device *dev)
0477 {
0478 struct sdhci_host *host = dev_get_drvdata(dev);
0479 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
0480 struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
0481 struct device_node *np = dev->of_node;
0482 int ret;
0483
0484 ret = clk_prepare_enable(pltfm_host->clk);
0485 if (ret)
0486 return ret;
0487
0488 ret = clk_prepare_enable(pdata->icnclk);
0489 if (ret) {
0490 clk_disable_unprepare(pltfm_host->clk);
0491 return ret;
0492 }
0493
0494 reset_control_deassert(pdata->rstc);
0495
0496 st_mmcss_cconfig(np, host);
0497
0498 return sdhci_resume_host(host);
0499 }
0500 #endif
0501
0502 static SIMPLE_DEV_PM_OPS(sdhci_st_pmops, sdhci_st_suspend, sdhci_st_resume);
0503
0504 static const struct of_device_id st_sdhci_match[] = {
0505 { .compatible = "st,sdhci" },
0506 {},
0507 };
0508
0509 MODULE_DEVICE_TABLE(of, st_sdhci_match);
0510
0511 static struct platform_driver sdhci_st_driver = {
0512 .probe = sdhci_st_probe,
0513 .remove = sdhci_st_remove,
0514 .driver = {
0515 .name = "sdhci-st",
0516 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
0517 .pm = &sdhci_st_pmops,
0518 .of_match_table = st_sdhci_match,
0519 },
0520 };
0521
0522 module_platform_driver(sdhci_st_driver);
0523
0524 MODULE_DESCRIPTION("SDHCI driver for STMicroelectronics SoCs");
0525 MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
0526 MODULE_LICENSE("GPL v2");
0527 MODULE_ALIAS("platform:sdhci-st");