diff options
author | Hebbar, Gururaja <gururaja.hebbar@ti.com> | 2012-11-19 11:29:58 -0500 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2012-12-06 13:54:56 -0500 |
commit | cd587096c0e2b85a67e77721a753679bac89b394 (patch) | |
tree | 22ae2292f85cb8d36530535bc087bacdb8889158 /drivers/mmc/host/omap_hsmmc.c | |
parent | dc7745bd32272a614a6598c05db4510548ef18f2 (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.c | 30 |
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 |