aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci.c
diff options
context:
space:
mode:
authorKevin Liu <kliu5@marvell.com>2013-01-30 22:31:37 -0500
committerChris Ball <cjb@laptop.org>2013-02-24 14:37:11 -0500
commit52983382c74f59a3953e622d7661a24e1bc4388a (patch)
treed5cfafd53be0b85a8921e28e22f1be64615d18fb /drivers/mmc/host/sdhci.c
parent073350f7b562d06df0aedd36c963508e36437b3c (diff)
mmc: sdhci: enhance preset value function
4d55c5a1 ("mmc: sdhci: enable preset value after uhs initialization") added preset value support and enabled it by default during sd card init. Below are the enhancements introduced by this patch: 1. In current code, preset value is enabled after setting clock finished, which means the clock is manually set by driver firstly and then suddenly switched to preset value at this point. So the first setting is useless and unnecessary. What's more, the first clock setting may differ from the preset one. The better way is enable preset value just after switch to UHS mode so the preset value can take effect immediately. So move preset value enable from mmc_sd_init_card to sdhci_set_ios which will be called during set timing. 2. In current code, preset value is disabled at the beginning of mmc_attach_sd. It's too late since low freq (400khz) should be set in mmc_power_up. So move preset value disable to sdhci_set_ios which will be called during power up. 3. host->clock and ios->drv_type should also be updated according to the preset value if it's enabled. Current code missed this. 4. This patch also introduce a quirk to disable preset value in case preset value doesn't work. This patch has been verified on sdhci-pxav3 platform with both preset enabled and disabled. Signed-off-by: Kevin Liu <kliu5@marvell.com> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r--drivers/mmc/host/sdhci.c129
1 files changed, 89 insertions, 40 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index efb112684787..ba586ae99252 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -53,6 +53,7 @@ static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
53static void sdhci_finish_command(struct sdhci_host *); 53static void sdhci_finish_command(struct sdhci_host *);
54static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); 54static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
55static void sdhci_tuning_timer(unsigned long data); 55static void sdhci_tuning_timer(unsigned long data);
56static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable);
56 57
57#ifdef CONFIG_PM_RUNTIME 58#ifdef CONFIG_PM_RUNTIME
58static int sdhci_runtime_pm_get(struct sdhci_host *host); 59static int sdhci_runtime_pm_get(struct sdhci_host *host);
@@ -1082,6 +1083,37 @@ static void sdhci_finish_command(struct sdhci_host *host)
1082 } 1083 }
1083} 1084}
1084 1085
1086static u16 sdhci_get_preset_value(struct sdhci_host *host)
1087{
1088 u16 ctrl, preset = 0;
1089
1090 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1091
1092 switch (ctrl & SDHCI_CTRL_UHS_MASK) {
1093 case SDHCI_CTRL_UHS_SDR12:
1094 preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
1095 break;
1096 case SDHCI_CTRL_UHS_SDR25:
1097 preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR25);
1098 break;
1099 case SDHCI_CTRL_UHS_SDR50:
1100 preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR50);
1101 break;
1102 case SDHCI_CTRL_UHS_SDR104:
1103 preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104);
1104 break;
1105 case SDHCI_CTRL_UHS_DDR50:
1106 preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50);
1107 break;
1108 default:
1109 pr_warn("%s: Invalid UHS-I mode selected\n",
1110 mmc_hostname(host->mmc));
1111 preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
1112 break;
1113 }
1114 return preset;
1115}
1116
1085static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) 1117static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
1086{ 1118{
1087 int div = 0; /* Initialized for compiler warning */ 1119 int div = 0; /* Initialized for compiler warning */
@@ -1106,35 +1138,43 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
1106 goto out; 1138 goto out;
1107 1139
1108 if (host->version >= SDHCI_SPEC_300) { 1140 if (host->version >= SDHCI_SPEC_300) {
1141 if (sdhci_readw(host, SDHCI_HOST_CONTROL2) &
1142 SDHCI_CTRL_PRESET_VAL_ENABLE) {
1143 u16 pre_val;
1144
1145 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
1146 pre_val = sdhci_get_preset_value(host);
1147 div = (pre_val & SDHCI_PRESET_SDCLK_FREQ_MASK)
1148 >> SDHCI_PRESET_SDCLK_FREQ_SHIFT;
1149 if (host->clk_mul &&
1150 (pre_val & SDHCI_PRESET_CLKGEN_SEL_MASK)) {
1151 clk = SDHCI_PROG_CLOCK_MODE;
1152 real_div = div + 1;
1153 clk_mul = host->clk_mul;
1154 } else {
1155 real_div = max_t(int, 1, div << 1);
1156 }
1157 goto clock_set;
1158 }
1159
1109 /* 1160 /*
1110 * Check if the Host Controller supports Programmable Clock 1161 * Check if the Host Controller supports Programmable Clock
1111 * Mode. 1162 * Mode.
1112 */ 1163 */
1113 if (host->clk_mul) { 1164 if (host->clk_mul) {
1114 u16 ctrl; 1165 for (div = 1; div <= 1024; div++) {
1115 1166 if ((host->max_clk * host->clk_mul / div)
1167 <= clock)
1168 break;
1169 }
1116 /* 1170 /*
1117 * We need to figure out whether the Host Driver needs 1171 * Set Programmable Clock Mode in the Clock
1118 * to select Programmable Clock Mode, or the value can 1172 * Control register.
1119 * be set automatically by the Host Controller based on
1120 * the Preset Value registers.
1121 */ 1173 */
1122 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1174 clk = SDHCI_PROG_CLOCK_MODE;
1123 if (!(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) { 1175 real_div = div;
1124 for (div = 1; div <= 1024; div++) { 1176 clk_mul = host->clk_mul;
1125 if (((host->max_clk * host->clk_mul) / 1177 div--;
1126 div) <= clock)
1127 break;
1128 }
1129 /*
1130 * Set Programmable Clock Mode in the Clock
1131 * Control register.
1132 */
1133 clk = SDHCI_PROG_CLOCK_MODE;
1134 real_div = div;
1135 clk_mul = host->clk_mul;
1136 div--;
1137 }
1138 } else { 1178 } else {
1139 /* Version 3.00 divisors must be a multiple of 2. */ 1179 /* Version 3.00 divisors must be a multiple of 2. */
1140 if (host->max_clk <= clock) 1180 if (host->max_clk <= clock)
@@ -1159,6 +1199,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
1159 div >>= 1; 1199 div >>= 1;
1160 } 1200 }
1161 1201
1202clock_set:
1162 if (real_div) 1203 if (real_div)
1163 host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div; 1204 host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div;
1164 1205
@@ -1376,6 +1417,10 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
1376 sdhci_reinit(host); 1417 sdhci_reinit(host);
1377 } 1418 }
1378 1419
1420 if (host->version >= SDHCI_SPEC_300 &&
1421 (ios->power_mode == MMC_POWER_UP))
1422 sdhci_enable_preset_value(host, false);
1423
1379 sdhci_set_clock(host, ios->clock); 1424 sdhci_set_clock(host, ios->clock);
1380 1425
1381 if (ios->power_mode == MMC_POWER_OFF) 1426 if (ios->power_mode == MMC_POWER_OFF)
@@ -1496,6 +1541,20 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
1496 sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); 1541 sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
1497 } 1542 }
1498 1543
1544 if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
1545 ((ios->timing == MMC_TIMING_UHS_SDR12) ||
1546 (ios->timing == MMC_TIMING_UHS_SDR25) ||
1547 (ios->timing == MMC_TIMING_UHS_SDR50) ||
1548 (ios->timing == MMC_TIMING_UHS_SDR104) ||
1549 (ios->timing == MMC_TIMING_UHS_DDR50))) {
1550 u16 preset;
1551
1552 sdhci_enable_preset_value(host, true);
1553 preset = sdhci_get_preset_value(host);
1554 ios->drv_type = (preset & SDHCI_PRESET_DRV_MASK)
1555 >> SDHCI_PRESET_DRV_SHIFT;
1556 }
1557
1499 /* Re-enable SD Clock */ 1558 /* Re-enable SD Clock */
1500 sdhci_update_clock(host); 1559 sdhci_update_clock(host);
1501 } else 1560 } else
@@ -1925,17 +1984,15 @@ out:
1925 return err; 1984 return err;
1926} 1985}
1927 1986
1928static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable) 1987
1988static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)
1929{ 1989{
1930 u16 ctrl; 1990 u16 ctrl;
1931 unsigned long flags;
1932 1991
1933 /* Host Controller v3.00 defines preset value registers */ 1992 /* Host Controller v3.00 defines preset value registers */
1934 if (host->version < SDHCI_SPEC_300) 1993 if (host->version < SDHCI_SPEC_300)
1935 return; 1994 return;
1936 1995
1937 spin_lock_irqsave(&host->lock, flags);
1938
1939 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1996 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1940 1997
1941 /* 1998 /*
@@ -1951,17 +2008,6 @@ static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable)
1951 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 2008 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1952 host->flags &= ~SDHCI_PV_ENABLED; 2009 host->flags &= ~SDHCI_PV_ENABLED;
1953 } 2010 }
1954
1955 spin_unlock_irqrestore(&host->lock, flags);
1956}
1957
1958static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable)
1959{
1960 struct sdhci_host *host = mmc_priv(mmc);
1961
1962 sdhci_runtime_pm_get(host);
1963 sdhci_do_enable_preset_value(host, enable);
1964 sdhci_runtime_pm_put(host);
1965} 2011}
1966 2012
1967static void sdhci_card_event(struct mmc_host *mmc) 2013static void sdhci_card_event(struct mmc_host *mmc)
@@ -1997,7 +2043,6 @@ static const struct mmc_host_ops sdhci_ops = {
1997 .enable_sdio_irq = sdhci_enable_sdio_irq, 2043 .enable_sdio_irq = sdhci_enable_sdio_irq,
1998 .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, 2044 .start_signal_voltage_switch = sdhci_start_signal_voltage_switch,
1999 .execute_tuning = sdhci_execute_tuning, 2045 .execute_tuning = sdhci_execute_tuning,
2000 .enable_preset_value = sdhci_enable_preset_value,
2001 .card_event = sdhci_card_event, 2046 .card_event = sdhci_card_event,
2002 .card_busy = sdhci_card_busy, 2047 .card_busy = sdhci_card_busy,
2003}; 2048};
@@ -2591,8 +2636,12 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
2591 sdhci_do_set_ios(host, &host->mmc->ios); 2636 sdhci_do_set_ios(host, &host->mmc->ios);
2592 2637
2593 sdhci_do_start_signal_voltage_switch(host, &host->mmc->ios); 2638 sdhci_do_start_signal_voltage_switch(host, &host->mmc->ios);
2594 if (host_flags & SDHCI_PV_ENABLED) 2639 if ((host_flags & SDHCI_PV_ENABLED) &&
2595 sdhci_do_enable_preset_value(host, true); 2640 !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) {
2641 spin_lock_irqsave(&host->lock, flags);
2642 sdhci_enable_preset_value(host, true);
2643 spin_unlock_irqrestore(&host->lock, flags);
2644 }
2596 2645
2597 /* Set the re-tuning expiration flag */ 2646 /* Set the re-tuning expiration flag */
2598 if (host->flags & SDHCI_USING_RETUNING_TIMER) 2647 if (host->flags & SDHCI_USING_RETUNING_TIMER)