aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc/sdhci.c
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2006-11-08 23:06:35 +0100
committerPierre Ossman <drzeus@drzeus.cx>2006-12-01 18:54:10 +0100
commit077df884835ebf2b5db16aacd9a24691d89902a0 (patch)
tree6d812005b3f5c9062ccd8dd2157a558a9bb1f0ed /drivers/mmc/sdhci.c
parent7ccd266e676a3f0c6f8f897f58b684cac3dd1650 (diff)
mmc: sdhci high speed support
The SDHCI spec implies that is is incorrect to set a clock frequency above 25 MHz without setting the high speed bit. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/sdhci.c')
-rw-r--r--drivers/mmc/sdhci.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 54990ed2677..cd98117632d 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -616,6 +616,7 @@ static void sdhci_finish_command(struct sdhci_host *host)
static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
{
int div;
+ u8 ctrl;
u16 clk;
unsigned long timeout;
@@ -624,6 +625,13 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
+ ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ if (clock > 25000000)
+ ctrl |= SDHCI_CTRL_HISPD;
+ else
+ ctrl &= ~SDHCI_CTRL_HISPD;
+ writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+
if (clock == 0)
goto out;
@@ -1291,6 +1299,13 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
else if (caps & SDHCI_CAN_VDD_180)
mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19;
+ if ((host->max_clk > 25000000) && !(caps & SDHCI_CAN_DO_HISPD)) {
+ printk(KERN_ERR "%s: Controller reports > 25 MHz base clock,"
+ " but no high speed support.\n",
+ host->slot_descr);
+ mmc->f_max = 25000000;
+ }
+
if (mmc->ocr_avail == 0) {
printk(KERN_ERR "%s: Hardware doesn't report any "
"support voltages.\n", host->slot_descr);