aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/omap_hsmmc.c
diff options
context:
space:
mode:
authorHebbar, Gururaja <gururaja.hebbar@ti.com>2012-11-19 11:29:58 -0500
committerChris Ball <cjb@laptop.org>2012-12-06 13:54:56 -0500
commitcd587096c0e2b85a67e77721a753679bac89b394 (patch)
tree22ae2292f85cb8d36530535bc087bacdb8889158 /drivers/mmc/host/omap_hsmmc.c
parentdc7745bd32272a614a6598c05db4510548ef18f2 (diff)
mmc: omap_hsmmc: Enable HSPE bit for high speed cards
HSMMC IP on AM33xx need a special setting to handle High-speed cards. Other platforms like TI81xx, OMAP4 may need this as-well. This depends on the HSMMC IP timing closure done for the high speed cards. From AM335x TRM (SPRUH73F - 18.3.12 Output Signals Generation): The MMC/SD/SDIO output signals can be driven on either falling edge or rising edge depending on the SD_HCTL[2] HSPE bit. This feature allows to reach better timing performance, and thus to increase data transfer frequency. There are few pre-requisites for enabling the HSPE bit - Controller should support High-Speed-Enable Bit and - Controller should not be using DDR Mode and - Controller should advertise that it supports High Speed in capabilities register and - MMC/SD clock coming out of controller > 25MHz Signed-off-by: Hebbar, Gururaja <gururaja.hebbar@ti.com> Signed-off-by: Venkatraman S <svenkatr@ti.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host/omap_hsmmc.c')
-rw-r--r--drivers/mmc/host/omap_hsmmc.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 571cd80521c7..18d3f19ef4e5 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -63,6 +63,7 @@
63 63
64#define VS18 (1 << 26) 64#define VS18 (1 << 26)
65#define VS30 (1 << 25) 65#define VS30 (1 << 25)
66#define HSS (1 << 21)
66#define SDVS18 (0x5 << 9) 67#define SDVS18 (0x5 << 9)
67#define SDVS30 (0x6 << 9) 68#define SDVS30 (0x6 << 9)
68#define SDVS33 (0x7 << 9) 69#define SDVS33 (0x7 << 9)
@@ -90,6 +91,7 @@
90#define MSBS (1 << 5) 91#define MSBS (1 << 5)
91#define BCE (1 << 1) 92#define BCE (1 << 1)
92#define FOUR_BIT (1 << 1) 93#define FOUR_BIT (1 << 1)
94#define HSPE (1 << 2)
93#define DDR (1 << 19) 95#define DDR (1 << 19)
94#define DW8 (1 << 5) 96#define DW8 (1 << 5)
95#define CC 0x1 97#define CC 0x1
@@ -495,6 +497,7 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
495 struct mmc_ios *ios = &host->mmc->ios; 497 struct mmc_ios *ios = &host->mmc->ios;
496 unsigned long regval; 498 unsigned long regval;
497 unsigned long timeout; 499 unsigned long timeout;
500 unsigned long clkdiv;
498 501
499 dev_vdbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock); 502 dev_vdbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock);
500 503
@@ -502,7 +505,8 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
502 505
503 regval = OMAP_HSMMC_READ(host->base, SYSCTL); 506 regval = OMAP_HSMMC_READ(host->base, SYSCTL);
504 regval = regval & ~(CLKD_MASK | DTO_MASK); 507 regval = regval & ~(CLKD_MASK | DTO_MASK);
505 regval = regval | (calc_divisor(host, ios) << 6) | (DTO << 16); 508 clkdiv = calc_divisor(host, ios);
509 regval = regval | (clkdiv << 6) | (DTO << 16);
506 OMAP_HSMMC_WRITE(host->base, SYSCTL, regval); 510 OMAP_HSMMC_WRITE(host->base, SYSCTL, regval);
507 OMAP_HSMMC_WRITE(host->base, SYSCTL, 511 OMAP_HSMMC_WRITE(host->base, SYSCTL,
508 OMAP_HSMMC_READ(host->base, SYSCTL) | ICE); 512 OMAP_HSMMC_READ(host->base, SYSCTL) | ICE);
@@ -513,6 +517,27 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
513 && time_before(jiffies, timeout)) 517 && time_before(jiffies, timeout))
514 cpu_relax(); 518 cpu_relax();
515 519
520 /*
521 * Enable High-Speed Support
522 * Pre-Requisites
523 * - Controller should support High-Speed-Enable Bit
524 * - Controller should not be using DDR Mode
525 * - Controller should advertise that it supports High Speed
526 * in capabilities register
527 * - MMC/SD clock coming out of controller > 25MHz
528 */
529 if ((mmc_slot(host).features & HSMMC_HAS_HSPE_SUPPORT) &&
530 (ios->timing != MMC_TIMING_UHS_DDR50) &&
531 ((OMAP_HSMMC_READ(host->base, CAPA) & HSS) == HSS)) {
532 regval = OMAP_HSMMC_READ(host->base, HCTL);
533 if (clkdiv && (clk_get_rate(host->fclk)/clkdiv) > 25000000)
534 regval |= HSPE;
535 else
536 regval &= ~HSPE;
537
538 OMAP_HSMMC_WRITE(host->base, HCTL, regval);
539 }
540
516 omap_hsmmc_start_clock(host); 541 omap_hsmmc_start_clock(host);
517} 542}
518 543
@@ -1715,6 +1740,9 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
1715 if (!of_property_read_u32(np, "max-frequency", &max_freq)) 1740 if (!of_property_read_u32(np, "max-frequency", &max_freq))
1716 pdata->max_freq = max_freq; 1741 pdata->max_freq = max_freq;
1717 1742
1743 if (of_find_property(np, "ti,needs-special-hs-handling", NULL))
1744 pdata->slots[0].features |= HSMMC_HAS_HSPE_SUPPORT;
1745
1718 return pdata; 1746 return pdata;
1719} 1747}
1720#else 1748#else