Browse Source

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>
Pierre Ossman 18 years ago
parent
commit
077df88483
2 changed files with 17 additions and 0 deletions
  1. 15 0
      drivers/mmc/sdhci.c
  2. 2 0
      drivers/mmc/sdhci.h

+ 15 - 0
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);

+ 2 - 0
drivers/mmc/sdhci.h

@@ -71,6 +71,7 @@
 #define SDHCI_HOST_CONTROL 	0x28
 #define  SDHCI_CTRL_LED		0x01
 #define  SDHCI_CTRL_4BITBUS	0x02
+#define  SDHCI_CTRL_HISPD	0x04
 
 #define SDHCI_POWER_CONTROL	0x29
 #define  SDHCI_POWER_ON		0x01
@@ -138,6 +139,7 @@
 #define  SDHCI_CLOCK_BASE_SHIFT	8
 #define  SDHCI_MAX_BLOCK_MASK	0x00030000
 #define  SDHCI_MAX_BLOCK_SHIFT  16
+#define  SDHCI_CAN_DO_HISPD	0x00200000
 #define  SDHCI_CAN_DO_DMA	0x00400000
 #define  SDHCI_CAN_VDD_330	0x01000000
 #define  SDHCI_CAN_VDD_300	0x02000000