1 // SPDX-License-Identifier: GPL-2.0
3 * sdhci_am654.c - SDHCI driver for TI's AM654 SOCs
5 * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
10 #include <linux/module.h>
11 #include <linux/pm_runtime.h>
12 #include <linux/property.h>
13 #include <linux/regmap.h>
16 #include "sdhci-pltfm.h"
18 /* CTL_CFG Registers */
19 #define CTL_CFG_2 0x14
21 #define SLOTTYPE_MASK GENMASK(31, 30)
22 #define SLOTTYPE_EMBEDDED BIT(30)
25 #define PHY_CTRL1 0x100
26 #define PHY_CTRL2 0x104
27 #define PHY_CTRL3 0x108
28 #define PHY_CTRL4 0x10C
29 #define PHY_CTRL5 0x110
30 #define PHY_CTRL6 0x114
31 #define PHY_STAT1 0x130
32 #define PHY_STAT2 0x134
34 #define IOMUX_ENABLE_SHIFT 31
35 #define IOMUX_ENABLE_MASK BIT(IOMUX_ENABLE_SHIFT)
36 #define OTAPDLYENA_SHIFT 20
37 #define OTAPDLYENA_MASK BIT(OTAPDLYENA_SHIFT)
38 #define OTAPDLYSEL_SHIFT 12
39 #define OTAPDLYSEL_MASK GENMASK(15, 12)
40 #define STRBSEL_SHIFT 24
41 #define STRBSEL_4BIT_MASK GENMASK(27, 24)
42 #define STRBSEL_8BIT_MASK GENMASK(31, 24)
44 #define SEL50_MASK BIT(SEL50_SHIFT)
45 #define SEL100_SHIFT 9
46 #define SEL100_MASK BIT(SEL100_SHIFT)
47 #define FREQSEL_SHIFT 8
48 #define FREQSEL_MASK GENMASK(10, 8)
49 #define DLL_TRIM_ICP_SHIFT 4
50 #define DLL_TRIM_ICP_MASK GENMASK(7, 4)
51 #define DR_TY_SHIFT 20
52 #define DR_TY_MASK GENMASK(22, 20)
54 #define ENDLL_MASK BIT(ENDLL_SHIFT)
55 #define DLLRDY_SHIFT 0
56 #define DLLRDY_MASK BIT(DLLRDY_SHIFT)
58 #define PDB_MASK BIT(PDB_SHIFT)
59 #define CALDONE_SHIFT 1
60 #define CALDONE_MASK BIT(CALDONE_SHIFT)
61 #define RETRIM_SHIFT 17
62 #define RETRIM_MASK BIT(RETRIM_SHIFT)
64 #define DRIVER_STRENGTH_50_OHM 0x0
65 #define DRIVER_STRENGTH_33_OHM 0x1
66 #define DRIVER_STRENGTH_66_OHM 0x2
67 #define DRIVER_STRENGTH_100_OHM 0x3
68 #define DRIVER_STRENGTH_40_OHM 0x4
70 #define CLOCK_TOO_SLOW_HZ 400000
72 /* Command Queue Host Controller Interface Base address */
73 #define SDHCI_AM654_CQE_BASE_ADDR 0x200
75 static struct regmap_config sdhci_am654_regmap_config
= {
82 struct sdhci_am654_data
{
92 struct sdhci_am654_driver_data
{
93 const struct sdhci_pltfm_data
*pdata
;
95 #define IOMUX_PRESENT (1 << 0)
96 #define FREQSEL_2_BIT (1 << 1)
97 #define STRBSEL_4_BIT (1 << 2)
98 #define DLL_PRESENT (1 << 3)
101 static void sdhci_am654_set_clock(struct sdhci_host
*host
, unsigned int clock
)
103 struct sdhci_pltfm_host
*pltfm_host
= sdhci_priv(host
);
104 struct sdhci_am654_data
*sdhci_am654
= sdhci_pltfm_priv(pltfm_host
);
105 int sel50
, sel100
, freqsel
;
109 if (sdhci_am654
->dll_on
) {
110 regmap_update_bits(sdhci_am654
->base
, PHY_CTRL1
, ENDLL_MASK
, 0);
112 sdhci_am654
->dll_on
= false;
115 sdhci_set_clock(host
, clock
);
117 if (clock
> CLOCK_TOO_SLOW_HZ
) {
118 /* Setup DLL Output TAP delay */
119 mask
= OTAPDLYENA_MASK
| OTAPDLYSEL_MASK
;
120 val
= (1 << OTAPDLYENA_SHIFT
) |
121 (sdhci_am654
->otap_del_sel
<< OTAPDLYSEL_SHIFT
);
122 regmap_update_bits(sdhci_am654
->base
, PHY_CTRL4
, mask
, val
);
123 /* Write to STRBSEL for HS400 speed mode */
124 if (host
->mmc
->ios
.timing
== MMC_TIMING_MMC_HS400
) {
125 if (sdhci_am654
->flags
& STRBSEL_4_BIT
)
126 mask
= STRBSEL_4BIT_MASK
;
128 mask
= STRBSEL_8BIT_MASK
;
130 regmap_update_bits(sdhci_am654
->base
, PHY_CTRL4
, mask
,
131 sdhci_am654
->strb_sel
<<
135 if (sdhci_am654
->flags
& FREQSEL_2_BIT
) {
150 /* Configure PHY DLL frequency */
151 mask
= SEL50_MASK
| SEL100_MASK
;
152 val
= (sel50
<< SEL50_SHIFT
) | (sel100
<< SEL100_SHIFT
);
153 regmap_update_bits(sdhci_am654
->base
, PHY_CTRL5
, mask
,
164 regmap_update_bits(sdhci_am654
->base
, PHY_CTRL5
,
166 freqsel
<< FREQSEL_SHIFT
);
169 /* Configure DLL TRIM */
170 mask
= DLL_TRIM_ICP_MASK
;
171 val
= sdhci_am654
->trm_icp
<< DLL_TRIM_ICP_SHIFT
;
173 /* Configure DLL driver strength */
175 val
|= sdhci_am654
->drv_strength
<< DR_TY_SHIFT
;
176 regmap_update_bits(sdhci_am654
->base
, PHY_CTRL1
, mask
, val
);
178 regmap_update_bits(sdhci_am654
->base
, PHY_CTRL1
, ENDLL_MASK
,
181 * Poll for DLL ready. Use a one second timeout.
182 * Works in all experiments done so far
184 ret
= regmap_read_poll_timeout(sdhci_am654
->base
, PHY_STAT1
,
185 val
, val
& DLLRDY_MASK
, 1000,
188 dev_err(mmc_dev(host
->mmc
), "DLL failed to relock\n");
192 sdhci_am654
->dll_on
= true;
196 static void sdhci_j721e_4bit_set_clock(struct sdhci_host
*host
,
199 struct sdhci_pltfm_host
*pltfm_host
= sdhci_priv(host
);
200 struct sdhci_am654_data
*sdhci_am654
= sdhci_pltfm_priv(pltfm_host
);
203 mask
= OTAPDLYENA_MASK
| OTAPDLYSEL_MASK
;
204 val
= (1 << OTAPDLYENA_SHIFT
) |
205 (sdhci_am654
->otap_del_sel
<< OTAPDLYSEL_SHIFT
);
206 regmap_update_bits(sdhci_am654
->base
, PHY_CTRL4
, mask
, val
);
208 sdhci_set_clock(host
, clock
);
211 static void sdhci_am654_set_power(struct sdhci_host
*host
, unsigned char mode
,
214 if (!IS_ERR(host
->mmc
->supply
.vmmc
)) {
215 struct mmc_host
*mmc
= host
->mmc
;
217 mmc_regulator_set_ocr(mmc
, mmc
->supply
.vmmc
, vdd
);
219 sdhci_set_power_noreg(host
, mode
, vdd
);
222 static void sdhci_am654_write_b(struct sdhci_host
*host
, u8 val
, int reg
)
224 unsigned char timing
= host
->mmc
->ios
.timing
;
226 if (reg
== SDHCI_HOST_CONTROL
) {
229 * According to the data manual, HISPD bit
230 * should not be set in these speed modes.
232 case MMC_TIMING_SD_HS
:
233 case MMC_TIMING_MMC_HS
:
234 case MMC_TIMING_UHS_SDR12
:
235 case MMC_TIMING_UHS_SDR25
:
236 val
&= ~SDHCI_CTRL_HISPD
;
240 writeb(val
, host
->ioaddr
+ reg
);
243 static int sdhci_am654_execute_tuning(struct mmc_host
*mmc
, u32 opcode
)
245 struct sdhci_host
*host
= mmc_priv(mmc
);
246 int err
= sdhci_execute_tuning(mmc
, opcode
);
251 * Tuning data remains in the buffer after tuning.
252 * Do a command and data reset to get rid of it
254 sdhci_reset(host
, SDHCI_RESET_CMD
| SDHCI_RESET_DATA
);
259 static u32
sdhci_am654_cqhci_irq(struct sdhci_host
*host
, u32 intmask
)
264 if (!sdhci_cqe_irq(host
, intmask
, &cmd_error
, &data_error
))
267 cqhci_irq(host
->mmc
, intmask
, cmd_error
, data_error
);
272 static struct sdhci_ops sdhci_am654_ops
= {
273 .get_max_clock
= sdhci_pltfm_clk_get_max_clock
,
274 .get_timeout_clock
= sdhci_pltfm_clk_get_max_clock
,
275 .set_uhs_signaling
= sdhci_set_uhs_signaling
,
276 .set_bus_width
= sdhci_set_bus_width
,
277 .set_power
= sdhci_am654_set_power
,
278 .set_clock
= sdhci_am654_set_clock
,
279 .write_b
= sdhci_am654_write_b
,
280 .irq
= sdhci_am654_cqhci_irq
,
281 .reset
= sdhci_reset
,
284 static const struct sdhci_pltfm_data sdhci_am654_pdata
= {
285 .ops
= &sdhci_am654_ops
,
286 .quirks
= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12
,
287 .quirks2
= SDHCI_QUIRK2_PRESET_VALUE_BROKEN
,
290 static const struct sdhci_am654_driver_data sdhci_am654_drvdata
= {
291 .pdata
= &sdhci_am654_pdata
,
292 .flags
= IOMUX_PRESENT
| FREQSEL_2_BIT
| STRBSEL_4_BIT
| DLL_PRESENT
,
295 static struct sdhci_ops sdhci_j721e_8bit_ops
= {
296 .get_max_clock
= sdhci_pltfm_clk_get_max_clock
,
297 .get_timeout_clock
= sdhci_pltfm_clk_get_max_clock
,
298 .set_uhs_signaling
= sdhci_set_uhs_signaling
,
299 .set_bus_width
= sdhci_set_bus_width
,
300 .set_power
= sdhci_am654_set_power
,
301 .set_clock
= sdhci_am654_set_clock
,
302 .write_b
= sdhci_am654_write_b
,
303 .irq
= sdhci_am654_cqhci_irq
,
304 .reset
= sdhci_reset
,
307 static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata
= {
308 .ops
= &sdhci_j721e_8bit_ops
,
309 .quirks
= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12
,
310 .quirks2
= SDHCI_QUIRK2_PRESET_VALUE_BROKEN
,
313 static const struct sdhci_am654_driver_data sdhci_j721e_8bit_drvdata
= {
314 .pdata
= &sdhci_j721e_8bit_pdata
,
315 .flags
= DLL_PRESENT
,
318 static struct sdhci_ops sdhci_j721e_4bit_ops
= {
319 .get_max_clock
= sdhci_pltfm_clk_get_max_clock
,
320 .get_timeout_clock
= sdhci_pltfm_clk_get_max_clock
,
321 .set_uhs_signaling
= sdhci_set_uhs_signaling
,
322 .set_bus_width
= sdhci_set_bus_width
,
323 .set_power
= sdhci_am654_set_power
,
324 .set_clock
= sdhci_j721e_4bit_set_clock
,
325 .write_b
= sdhci_am654_write_b
,
326 .irq
= sdhci_am654_cqhci_irq
,
327 .reset
= sdhci_reset
,
330 static const struct sdhci_pltfm_data sdhci_j721e_4bit_pdata
= {
331 .ops
= &sdhci_j721e_4bit_ops
,
332 .quirks
= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12
,
333 .quirks2
= SDHCI_QUIRK2_PRESET_VALUE_BROKEN
,
336 static const struct sdhci_am654_driver_data sdhci_j721e_4bit_drvdata
= {
337 .pdata
= &sdhci_j721e_4bit_pdata
,
338 .flags
= IOMUX_PRESENT
,
341 static void sdhci_am654_dumpregs(struct mmc_host
*mmc
)
343 sdhci_dumpregs(mmc_priv(mmc
));
346 static const struct cqhci_host_ops sdhci_am654_cqhci_ops
= {
347 .enable
= sdhci_cqe_enable
,
348 .disable
= sdhci_cqe_disable
,
349 .dumpregs
= sdhci_am654_dumpregs
,
352 static int sdhci_am654_cqe_add_host(struct sdhci_host
*host
)
354 struct cqhci_host
*cq_host
;
357 cq_host
= devm_kzalloc(host
->mmc
->parent
, sizeof(struct cqhci_host
),
362 cq_host
->mmio
= host
->ioaddr
+ SDHCI_AM654_CQE_BASE_ADDR
;
363 cq_host
->quirks
|= CQHCI_QUIRK_SHORT_TXFR_DESC_SZ
;
364 cq_host
->caps
|= CQHCI_TASK_DESC_SZ_128
;
365 cq_host
->ops
= &sdhci_am654_cqhci_ops
;
367 host
->mmc
->caps2
|= MMC_CAP2_CQE
;
369 ret
= cqhci_init(cq_host
, host
->mmc
, 1);
374 static int sdhci_am654_init(struct sdhci_host
*host
)
376 struct sdhci_pltfm_host
*pltfm_host
= sdhci_priv(host
);
377 struct sdhci_am654_data
*sdhci_am654
= sdhci_pltfm_priv(pltfm_host
);
383 /* Reset OTAP to default value */
384 mask
= OTAPDLYENA_MASK
| OTAPDLYSEL_MASK
;
385 regmap_update_bits(sdhci_am654
->base
, PHY_CTRL4
, mask
, 0x0);
387 if (sdhci_am654
->flags
& DLL_PRESENT
) {
388 regmap_read(sdhci_am654
->base
, PHY_STAT1
, &val
);
389 if (~val
& CALDONE_MASK
) {
390 /* Calibrate IO lines */
391 regmap_update_bits(sdhci_am654
->base
, PHY_CTRL1
,
393 ret
= regmap_read_poll_timeout(sdhci_am654
->base
,
402 /* Enable pins by setting IO mux to 0 */
403 if (sdhci_am654
->flags
& IOMUX_PRESENT
)
404 regmap_update_bits(sdhci_am654
->base
, PHY_CTRL1
,
405 IOMUX_ENABLE_MASK
, 0);
407 /* Set slot type based on SD or eMMC */
408 if (host
->mmc
->caps
& MMC_CAP_NONREMOVABLE
)
409 ctl_cfg_2
= SLOTTYPE_EMBEDDED
;
411 regmap_update_bits(sdhci_am654
->base
, CTL_CFG_2
, SLOTTYPE_MASK
,
414 ret
= sdhci_setup_host(host
);
418 ret
= sdhci_am654_cqe_add_host(host
);
420 goto err_cleanup_host
;
422 ret
= __sdhci_add_host(host
);
424 goto err_cleanup_host
;
429 sdhci_cleanup_host(host
);
433 static int sdhci_am654_get_of_property(struct platform_device
*pdev
,
434 struct sdhci_am654_data
*sdhci_am654
)
436 struct device
*dev
= &pdev
->dev
;
440 ret
= device_property_read_u32(dev
, "ti,otap-del-sel",
441 &sdhci_am654
->otap_del_sel
);
445 if (sdhci_am654
->flags
& DLL_PRESENT
) {
446 ret
= device_property_read_u32(dev
, "ti,trm-icp",
447 &sdhci_am654
->trm_icp
);
451 ret
= device_property_read_u32(dev
, "ti,driver-strength-ohm",
456 switch (drv_strength
) {
458 sdhci_am654
->drv_strength
= DRIVER_STRENGTH_50_OHM
;
461 sdhci_am654
->drv_strength
= DRIVER_STRENGTH_33_OHM
;
464 sdhci_am654
->drv_strength
= DRIVER_STRENGTH_66_OHM
;
467 sdhci_am654
->drv_strength
= DRIVER_STRENGTH_100_OHM
;
470 sdhci_am654
->drv_strength
= DRIVER_STRENGTH_40_OHM
;
473 dev_err(dev
, "Invalid driver strength\n");
478 device_property_read_u32(dev
, "ti,strobe-sel", &sdhci_am654
->strb_sel
);
480 sdhci_get_of_property(pdev
);
485 static const struct of_device_id sdhci_am654_of_match
[] = {
487 .compatible
= "ti,am654-sdhci-5.1",
488 .data
= &sdhci_am654_drvdata
,
491 .compatible
= "ti,j721e-sdhci-8bit",
492 .data
= &sdhci_j721e_8bit_drvdata
,
495 .compatible
= "ti,j721e-sdhci-4bit",
496 .data
= &sdhci_j721e_4bit_drvdata
,
501 static int sdhci_am654_probe(struct platform_device
*pdev
)
503 const struct sdhci_am654_driver_data
*drvdata
;
504 struct sdhci_pltfm_host
*pltfm_host
;
505 struct sdhci_am654_data
*sdhci_am654
;
506 const struct of_device_id
*match
;
507 struct sdhci_host
*host
;
509 struct device
*dev
= &pdev
->dev
;
513 match
= of_match_node(sdhci_am654_of_match
, pdev
->dev
.of_node
);
514 drvdata
= match
->data
;
515 host
= sdhci_pltfm_init(pdev
, drvdata
->pdata
, sizeof(*sdhci_am654
));
517 return PTR_ERR(host
);
519 pltfm_host
= sdhci_priv(host
);
520 sdhci_am654
= sdhci_pltfm_priv(pltfm_host
);
521 sdhci_am654
->flags
= drvdata
->flags
;
523 clk_xin
= devm_clk_get(dev
, "clk_xin");
524 if (IS_ERR(clk_xin
)) {
525 dev_err(dev
, "clk_xin clock not found.\n");
526 ret
= PTR_ERR(clk_xin
);
530 pltfm_host
->clk
= clk_xin
;
532 /* Clocks are enabled using pm_runtime */
533 pm_runtime_enable(dev
);
534 ret
= pm_runtime_get_sync(dev
);
536 pm_runtime_put_noidle(dev
);
537 goto pm_runtime_disable
;
540 base
= devm_platform_ioremap_resource(pdev
, 1);
546 sdhci_am654
->base
= devm_regmap_init_mmio(dev
, base
,
547 &sdhci_am654_regmap_config
);
548 if (IS_ERR(sdhci_am654
->base
)) {
549 dev_err(dev
, "Failed to initialize regmap\n");
550 ret
= PTR_ERR(sdhci_am654
->base
);
554 ret
= sdhci_am654_get_of_property(pdev
, sdhci_am654
);
558 ret
= mmc_of_parse(host
->mmc
);
560 dev_err(dev
, "parsing dt failed (%d)\n", ret
);
564 host
->mmc_host_ops
.execute_tuning
= sdhci_am654_execute_tuning
;
566 ret
= sdhci_am654_init(host
);
573 pm_runtime_put_sync(dev
);
575 pm_runtime_disable(dev
);
577 sdhci_pltfm_free(pdev
);
581 static int sdhci_am654_remove(struct platform_device
*pdev
)
583 struct sdhci_host
*host
= platform_get_drvdata(pdev
);
586 sdhci_remove_host(host
, true);
587 ret
= pm_runtime_put_sync(&pdev
->dev
);
591 pm_runtime_disable(&pdev
->dev
);
592 sdhci_pltfm_free(pdev
);
597 static struct platform_driver sdhci_am654_driver
= {
599 .name
= "sdhci-am654",
600 .of_match_table
= sdhci_am654_of_match
,
602 .probe
= sdhci_am654_probe
,
603 .remove
= sdhci_am654_remove
,
606 module_platform_driver(sdhci_am654_driver
);
608 MODULE_DESCRIPTION("Driver for SDHCI Controller on TI's AM654 devices");
609 MODULE_AUTHOR("Faiz Abbas <faiz_abbas@ti.com>");
610 MODULE_LICENSE("GPL");