aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2007-02-18 06:07:47 -0500
committerPierre Ossman <drzeus@drzeus.cx>2007-03-06 07:26:55 -0500
commitcd9277c011a99769fa371521b460ed57f6d280b1 (patch)
tree8ae2566bf8c9dac5a01a7f4f04457596ca42465a
parentc5f93cf19df633a8dbd7adf8130d604eec96e145 (diff)
mmc: require explicit support for high-speed
The new high-speed timings are similar to each other and the old system, but not identical. And although things "just work" most of the time, sometimes it does not. So we need to start marking which hosts are known to fully comply with the new timings. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
-rw-r--r--drivers/mmc/mmc.c83
-rw-r--r--drivers/mmc/sdhci.c25
-rw-r--r--include/linux/mmc/host.h8
3 files changed, 66 insertions, 50 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 5046a1661342..4a73e8b2428d 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -376,10 +376,11 @@ static inline void mmc_set_ios(struct mmc_host *host)
376{ 376{
377 struct mmc_ios *ios = &host->ios; 377 struct mmc_ios *ios = &host->ios;
378 378
379 pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", 379 pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u "
380 "width %u timing %u\n",
380 mmc_hostname(host), ios->clock, ios->bus_mode, 381 mmc_hostname(host), ios->clock, ios->bus_mode,
381 ios->power_mode, ios->chip_select, ios->vdd, 382 ios->power_mode, ios->chip_select, ios->vdd,
382 ios->bus_width); 383 ios->bus_width, ios->timing);
383 384
384 host->ops->set_ios(host, ios); 385 host->ops->set_ios(host, ios);
385} 386}
@@ -809,6 +810,7 @@ static void mmc_power_up(struct mmc_host *host)
809 host->ios.chip_select = MMC_CS_DONTCARE; 810 host->ios.chip_select = MMC_CS_DONTCARE;
810 host->ios.power_mode = MMC_POWER_UP; 811 host->ios.power_mode = MMC_POWER_UP;
811 host->ios.bus_width = MMC_BUS_WIDTH_1; 812 host->ios.bus_width = MMC_BUS_WIDTH_1;
813 host->ios.timing = MMC_TIMING_LEGACY;
812 mmc_set_ios(host); 814 mmc_set_ios(host);
813 815
814 mmc_delay(1); 816 mmc_delay(1);
@@ -828,6 +830,7 @@ static void mmc_power_off(struct mmc_host *host)
828 host->ios.chip_select = MMC_CS_DONTCARE; 830 host->ios.chip_select = MMC_CS_DONTCARE;
829 host->ios.power_mode = MMC_POWER_OFF; 831 host->ios.power_mode = MMC_POWER_OFF;
830 host->ios.bus_width = MMC_BUS_WIDTH_1; 832 host->ios.bus_width = MMC_BUS_WIDTH_1;
833 host->ios.timing = MMC_TIMING_LEGACY;
831 mmc_set_ios(host); 834 mmc_set_ios(host);
832} 835}
833 836
@@ -1112,46 +1115,50 @@ static void mmc_process_ext_csds(struct mmc_host *host)
1112 continue; 1115 continue;
1113 } 1116 }
1114 1117
1115 /* Activate highspeed support. */ 1118 if (host->caps & MMC_CAP_MMC_HIGHSPEED) {
1116 cmd.opcode = MMC_SWITCH; 1119 /* Activate highspeed support. */
1117 cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | 1120 cmd.opcode = MMC_SWITCH;
1118 (EXT_CSD_HS_TIMING << 16) | 1121 cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
1119 (1 << 8) | 1122 (EXT_CSD_HS_TIMING << 16) |
1120 EXT_CSD_CMD_SET_NORMAL; 1123 (1 << 8) |
1121 cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; 1124 EXT_CSD_CMD_SET_NORMAL;
1125 cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
1122 1126
1123 err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); 1127 err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
1124 if (err != MMC_ERR_NONE) { 1128 if (err != MMC_ERR_NONE) {
1125 printk("%s: failed to switch card to mmc v4 " 1129 printk("%s: failed to switch card to mmc v4 "
1126 "high-speed mode.\n", 1130 "high-speed mode.\n",
1127 mmc_hostname(card->host)); 1131 mmc_hostname(card->host));
1128 continue; 1132 continue;
1129 } 1133 }
1130 1134
1131 mmc_card_set_highspeed(card); 1135 mmc_card_set_highspeed(card);
1132 1136
1133 /* Check for host support for wide-bus modes. */ 1137 host->ios.timing = MMC_TIMING_SD_HS;
1134 if (!(host->caps & MMC_CAP_4_BIT_DATA)) { 1138 mmc_set_ios(host);
1135 continue;
1136 } 1139 }
1137 1140
1138 /* Activate 4-bit support. */ 1141 /* Check for host support for wide-bus modes. */
1139 cmd.opcode = MMC_SWITCH; 1142 if (host->caps & MMC_CAP_4_BIT_DATA) {
1140 cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | 1143 /* Activate 4-bit support. */
1141 (EXT_CSD_BUS_WIDTH << 16) | 1144 cmd.opcode = MMC_SWITCH;
1142 (EXT_CSD_BUS_WIDTH_4 << 8) | 1145 cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
1143 EXT_CSD_CMD_SET_NORMAL; 1146 (EXT_CSD_BUS_WIDTH << 16) |
1144 cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; 1147 (EXT_CSD_BUS_WIDTH_4 << 8) |
1148 EXT_CSD_CMD_SET_NORMAL;
1149 cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
1145 1150
1146 err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); 1151 err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
1147 if (err != MMC_ERR_NONE) { 1152 if (err != MMC_ERR_NONE) {
1148 printk("%s: failed to switch card to " 1153 printk("%s: failed to switch card to "
1149 "mmc v4 4-bit bus mode.\n", 1154 "mmc v4 4-bit bus mode.\n",
1150 mmc_hostname(card->host)); 1155 mmc_hostname(card->host));
1151 continue; 1156 continue;
1152 } 1157 }
1153 1158
1154 host->ios.bus_width = MMC_BUS_WIDTH_4; 1159 host->ios.bus_width = MMC_BUS_WIDTH_4;
1160 mmc_set_ios(host);
1161 }
1155 } 1162 }
1156 1163
1157 kfree(ext_csd); 1164 kfree(ext_csd);
@@ -1241,6 +1248,9 @@ static void mmc_read_switch_caps(struct mmc_host *host)
1241 unsigned char *status; 1248 unsigned char *status;
1242 struct scatterlist sg; 1249 struct scatterlist sg;
1243 1250
1251 if (!(host->caps & MMC_CAP_SD_HIGHSPEED))
1252 return;
1253
1244 status = kmalloc(64, GFP_KERNEL); 1254 status = kmalloc(64, GFP_KERNEL);
1245 if (!status) { 1255 if (!status) {
1246 printk(KERN_WARNING "%s: Unable to allocate buffer for " 1256 printk(KERN_WARNING "%s: Unable to allocate buffer for "
@@ -1332,6 +1342,9 @@ static void mmc_read_switch_caps(struct mmc_host *host)
1332 } 1342 }
1333 1343
1334 mmc_card_set_highspeed(card); 1344 mmc_card_set_highspeed(card);
1345
1346 host->ios.timing = MMC_TIMING_SD_HS;
1347 mmc_set_ios(host);
1335 } 1348 }
1336 1349
1337 kfree(status); 1350 kfree(status);
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 7522f76b15ec..c52b167e8585 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -606,7 +606,6 @@ static void sdhci_finish_command(struct sdhci_host *host)
606static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) 606static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
607{ 607{
608 int div; 608 int div;
609 u8 ctrl;
610 u16 clk; 609 u16 clk;
611 unsigned long timeout; 610 unsigned long timeout;
612 611
@@ -615,13 +614,6 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
615 614
616 writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); 615 writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
617 616
618 ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
619 if (clock > 25000000)
620 ctrl |= SDHCI_CTRL_HISPD;
621 else
622 ctrl &= ~SDHCI_CTRL_HISPD;
623 writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
624
625 if (clock == 0) 617 if (clock == 0)
626 goto out; 618 goto out;
627 619
@@ -761,10 +753,17 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
761 sdhci_set_power(host, ios->vdd); 753 sdhci_set_power(host, ios->vdd);
762 754
763 ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); 755 ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
756
764 if (ios->bus_width == MMC_BUS_WIDTH_4) 757 if (ios->bus_width == MMC_BUS_WIDTH_4)
765 ctrl |= SDHCI_CTRL_4BITBUS; 758 ctrl |= SDHCI_CTRL_4BITBUS;
766 else 759 else
767 ctrl &= ~SDHCI_CTRL_4BITBUS; 760 ctrl &= ~SDHCI_CTRL_4BITBUS;
761
762 if (ios->timing == MMC_TIMING_SD_HS)
763 ctrl |= SDHCI_CTRL_HISPD;
764 else
765 ctrl &= ~SDHCI_CTRL_HISPD;
766
768 writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); 767 writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
769 768
770 mmiowb(); 769 mmiowb();
@@ -1274,6 +1273,9 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1274 mmc->f_max = host->max_clk; 1273 mmc->f_max = host->max_clk;
1275 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK; 1274 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
1276 1275
1276 if (caps & SDHCI_CAN_DO_HISPD)
1277 mmc->caps |= MMC_CAP_SD_HIGHSPEED;
1278
1277 mmc->ocr_avail = 0; 1279 mmc->ocr_avail = 0;
1278 if (caps & SDHCI_CAN_VDD_330) 1280 if (caps & SDHCI_CAN_VDD_330)
1279 mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34; 1281 mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
@@ -1282,13 +1284,6 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1282 if (caps & SDHCI_CAN_VDD_180) 1284 if (caps & SDHCI_CAN_VDD_180)
1283 mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19; 1285 mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19;
1284 1286
1285 if ((host->max_clk > 25000000) && !(caps & SDHCI_CAN_DO_HISPD)) {
1286 printk(KERN_ERR "%s: Controller reports > 25 MHz base clock,"
1287 " but no high speed support.\n",
1288 host->slot_descr);
1289 mmc->f_max = 25000000;
1290 }
1291
1292 if (mmc->ocr_avail == 0) { 1287 if (mmc->ocr_avail == 0) {
1293 printk(KERN_ERR "%s: Hardware doesn't report any " 1288 printk(KERN_ERR "%s: Hardware doesn't report any "
1294 "support voltages.\n", host->slot_descr); 1289 "support voltages.\n", host->slot_descr);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 913e5752569f..bfcef8a1ad8b 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -62,6 +62,12 @@ struct mmc_ios {
62 62
63#define MMC_BUS_WIDTH_1 0 63#define MMC_BUS_WIDTH_1 0
64#define MMC_BUS_WIDTH_4 2 64#define MMC_BUS_WIDTH_4 2
65
66 unsigned char timing; /* timing specification used */
67
68#define MMC_TIMING_LEGACY 0
69#define MMC_TIMING_MMC_HS 1
70#define MMC_TIMING_SD_HS 2
65}; 71};
66 72
67struct mmc_host_ops { 73struct mmc_host_ops {
@@ -87,6 +93,8 @@ struct mmc_host {
87#define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */ 93#define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */
88#define MMC_CAP_MULTIWRITE (1 << 1) /* Can accurately report bytes sent to card on error */ 94#define MMC_CAP_MULTIWRITE (1 << 1) /* Can accurately report bytes sent to card on error */
89#define MMC_CAP_BYTEBLOCK (1 << 2) /* Can do non-log2 block sizes */ 95#define MMC_CAP_BYTEBLOCK (1 << 2) /* Can do non-log2 block sizes */
96#define MMC_CAP_MMC_HIGHSPEED (1 << 3) /* Can do MMC high-speed timing */
97#define MMC_CAP_SD_HIGHSPEED (1 << 4) /* Can do SD high-speed timing */
90 98
91 /* host specific block data */ 99 /* host specific block data */
92 unsigned int max_seg_size; /* see blk_queue_max_segment_size */ 100 unsigned int max_seg_size; /* see blk_queue_max_segment_size */