diff options
author | Dan Williams <dan.j.williams@intel.com> | 2009-09-08 20:55:21 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2009-09-08 20:55:21 -0400 |
commit | bbb20089a3275a19e475dbc21320c3742e3ca423 (patch) | |
tree | 216fdc1cbef450ca688135c5b8969169482d9a48 /drivers/mmc/host/sdhci.c | |
parent | 3e48e656903e9fd8bc805c6a2c4264d7808d315b (diff) | |
parent | 657a77fa7284d8ae28dfa48f1dc5d919bf5b2843 (diff) |
Merge branch 'dmaengine' into async-tx-next
Conflicts:
crypto/async_tx/async_xor.c
drivers/dma/ioat/dma_v2.h
drivers/dma/ioat/pci.c
drivers/md/raid5.c
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 108 |
1 files changed, 79 insertions, 29 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 9234be2226e7..6779b4ecab18 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -78,6 +78,11 @@ static void sdhci_dumpregs(struct sdhci_host *host) | |||
78 | sdhci_readl(host, SDHCI_CAPABILITIES), | 78 | sdhci_readl(host, SDHCI_CAPABILITIES), |
79 | sdhci_readl(host, SDHCI_MAX_CURRENT)); | 79 | sdhci_readl(host, SDHCI_MAX_CURRENT)); |
80 | 80 | ||
81 | if (host->flags & SDHCI_USE_ADMA) | ||
82 | printk(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n", | ||
83 | readl(host->ioaddr + SDHCI_ADMA_ERROR), | ||
84 | readl(host->ioaddr + SDHCI_ADMA_ADDRESS)); | ||
85 | |||
81 | printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n"); | 86 | printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n"); |
82 | } | 87 | } |
83 | 88 | ||
@@ -579,7 +584,7 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data) | |||
579 | * longer to time out, but that's much better than having a too-short | 584 | * longer to time out, but that's much better than having a too-short |
580 | * timeout value. | 585 | * timeout value. |
581 | */ | 586 | */ |
582 | if ((host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL)) | 587 | if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL) |
583 | return 0xE; | 588 | return 0xE; |
584 | 589 | ||
585 | /* timeout in us */ | 590 | /* timeout in us */ |
@@ -1005,12 +1010,34 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) | |||
1005 | { | 1010 | { |
1006 | u8 pwr; | 1011 | u8 pwr; |
1007 | 1012 | ||
1008 | if (host->power == power) | 1013 | if (power == (unsigned short)-1) |
1014 | pwr = 0; | ||
1015 | else { | ||
1016 | switch (1 << power) { | ||
1017 | case MMC_VDD_165_195: | ||
1018 | pwr = SDHCI_POWER_180; | ||
1019 | break; | ||
1020 | case MMC_VDD_29_30: | ||
1021 | case MMC_VDD_30_31: | ||
1022 | pwr = SDHCI_POWER_300; | ||
1023 | break; | ||
1024 | case MMC_VDD_32_33: | ||
1025 | case MMC_VDD_33_34: | ||
1026 | pwr = SDHCI_POWER_330; | ||
1027 | break; | ||
1028 | default: | ||
1029 | BUG(); | ||
1030 | } | ||
1031 | } | ||
1032 | |||
1033 | if (host->pwr == pwr) | ||
1009 | return; | 1034 | return; |
1010 | 1035 | ||
1011 | if (power == (unsigned short)-1) { | 1036 | host->pwr = pwr; |
1037 | |||
1038 | if (pwr == 0) { | ||
1012 | sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); | 1039 | sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); |
1013 | goto out; | 1040 | return; |
1014 | } | 1041 | } |
1015 | 1042 | ||
1016 | /* | 1043 | /* |
@@ -1020,35 +1047,23 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) | |||
1020 | if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) | 1047 | if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) |
1021 | sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); | 1048 | sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); |
1022 | 1049 | ||
1023 | pwr = SDHCI_POWER_ON; | ||
1024 | |||
1025 | switch (1 << power) { | ||
1026 | case MMC_VDD_165_195: | ||
1027 | pwr |= SDHCI_POWER_180; | ||
1028 | break; | ||
1029 | case MMC_VDD_29_30: | ||
1030 | case MMC_VDD_30_31: | ||
1031 | pwr |= SDHCI_POWER_300; | ||
1032 | break; | ||
1033 | case MMC_VDD_32_33: | ||
1034 | case MMC_VDD_33_34: | ||
1035 | pwr |= SDHCI_POWER_330; | ||
1036 | break; | ||
1037 | default: | ||
1038 | BUG(); | ||
1039 | } | ||
1040 | |||
1041 | /* | 1050 | /* |
1042 | * At least the Marvell CaFe chip gets confused if we set the voltage | 1051 | * At least the Marvell CaFe chip gets confused if we set the voltage |
1043 | * and set turn on power at the same time, so set the voltage first. | 1052 | * and set turn on power at the same time, so set the voltage first. |
1044 | */ | 1053 | */ |
1045 | if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)) | 1054 | if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER) |
1046 | sdhci_writeb(host, pwr & ~SDHCI_POWER_ON, SDHCI_POWER_CONTROL); | 1055 | sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); |
1056 | |||
1057 | pwr |= SDHCI_POWER_ON; | ||
1047 | 1058 | ||
1048 | sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); | 1059 | sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); |
1049 | 1060 | ||
1050 | out: | 1061 | /* |
1051 | host->power = power; | 1062 | * Some controllers need an extra 10ms delay of 10ms before they |
1063 | * can apply clock after applying power | ||
1064 | */ | ||
1065 | if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER) | ||
1066 | mdelay(10); | ||
1052 | } | 1067 | } |
1053 | 1068 | ||
1054 | /*****************************************************************************\ | 1069 | /*****************************************************************************\ |
@@ -1374,6 +1389,35 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) | |||
1374 | sdhci_finish_command(host); | 1389 | sdhci_finish_command(host); |
1375 | } | 1390 | } |
1376 | 1391 | ||
1392 | #ifdef DEBUG | ||
1393 | static void sdhci_show_adma_error(struct sdhci_host *host) | ||
1394 | { | ||
1395 | const char *name = mmc_hostname(host->mmc); | ||
1396 | u8 *desc = host->adma_desc; | ||
1397 | __le32 *dma; | ||
1398 | __le16 *len; | ||
1399 | u8 attr; | ||
1400 | |||
1401 | sdhci_dumpregs(host); | ||
1402 | |||
1403 | while (true) { | ||
1404 | dma = (__le32 *)(desc + 4); | ||
1405 | len = (__le16 *)(desc + 2); | ||
1406 | attr = *desc; | ||
1407 | |||
1408 | DBG("%s: %p: DMA 0x%08x, LEN 0x%04x, Attr=0x%02x\n", | ||
1409 | name, desc, le32_to_cpu(*dma), le16_to_cpu(*len), attr); | ||
1410 | |||
1411 | desc += 8; | ||
1412 | |||
1413 | if (attr & 2) | ||
1414 | break; | ||
1415 | } | ||
1416 | } | ||
1417 | #else | ||
1418 | static void sdhci_show_adma_error(struct sdhci_host *host) { } | ||
1419 | #endif | ||
1420 | |||
1377 | static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | 1421 | static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) |
1378 | { | 1422 | { |
1379 | BUG_ON(intmask == 0); | 1423 | BUG_ON(intmask == 0); |
@@ -1403,8 +1447,11 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | |||
1403 | host->data->error = -ETIMEDOUT; | 1447 | host->data->error = -ETIMEDOUT; |
1404 | else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT)) | 1448 | else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT)) |
1405 | host->data->error = -EILSEQ; | 1449 | host->data->error = -EILSEQ; |
1406 | else if (intmask & SDHCI_INT_ADMA_ERROR) | 1450 | else if (intmask & SDHCI_INT_ADMA_ERROR) { |
1451 | printk(KERN_ERR "%s: ADMA error\n", mmc_hostname(host->mmc)); | ||
1452 | sdhci_show_adma_error(host); | ||
1407 | host->data->error = -EIO; | 1453 | host->data->error = -EIO; |
1454 | } | ||
1408 | 1455 | ||
1409 | if (host->data->error) | 1456 | if (host->data->error) |
1410 | sdhci_finish_data(host); | 1457 | sdhci_finish_data(host); |
@@ -1721,7 +1768,10 @@ int sdhci_add_host(struct sdhci_host *host) | |||
1721 | mmc->ops = &sdhci_ops; | 1768 | mmc->ops = &sdhci_ops; |
1722 | mmc->f_min = host->max_clk / 256; | 1769 | mmc->f_min = host->max_clk / 256; |
1723 | mmc->f_max = host->max_clk; | 1770 | mmc->f_max = host->max_clk; |
1724 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; | 1771 | mmc->caps = MMC_CAP_SDIO_IRQ; |
1772 | |||
1773 | if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) | ||
1774 | mmc->caps |= MMC_CAP_4_BIT_DATA; | ||
1725 | 1775 | ||
1726 | if (caps & SDHCI_CAN_DO_HISPD) | 1776 | if (caps & SDHCI_CAN_DO_HISPD) |
1727 | mmc->caps |= MMC_CAP_SD_HIGHSPEED; | 1777 | mmc->caps |= MMC_CAP_SD_HIGHSPEED; |
@@ -1794,7 +1844,7 @@ int sdhci_add_host(struct sdhci_host *host) | |||
1794 | /* | 1844 | /* |
1795 | * Maximum block count. | 1845 | * Maximum block count. |
1796 | */ | 1846 | */ |
1797 | mmc->max_blk_count = 65535; | 1847 | mmc->max_blk_count = (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535; |
1798 | 1848 | ||
1799 | /* | 1849 | /* |
1800 | * Init tasklets. | 1850 | * Init tasklets. |