Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/sdmmc Skip setting power when the voltage doesn't ch...
details: https://anonhg.NetBSD.org/src/rev/c4dd67e8ac4c
branches: trunk
changeset: 464879:c4dd67e8ac4c
user: mlelstv <mlelstv%NetBSD.org@localhost>
date: Mon Oct 28 06:00:14 2019 +0000
description:
Skip setting power when the voltage doesn't change.
Also increase some timeouts.
diffstat:
sys/dev/sdmmc/sdhc.c | 48 ++++++++++++++++++++++++++++++++++++------------
1 files changed, 36 insertions(+), 12 deletions(-)
diffs (137 lines):
diff -r ce9d53e0a7c6 -r c4dd67e8ac4c sys/dev/sdmmc/sdhc.c
--- a/sys/dev/sdmmc/sdhc.c Mon Oct 28 03:01:55 2019 +0000
+++ b/sys/dev/sdmmc/sdhc.c Mon Oct 28 06:00:14 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sdhc.c,v 1.104 2019/10/23 05:20:52 hkenken Exp $ */
+/* $NetBSD: sdhc.c,v 1.105 2019/10/28 06:00:14 mlelstv Exp $ */
/* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */
/*
@@ -23,7 +23,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.104 2019/10/23 05:20:52 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.105 2019/10/28 06:00:14 mlelstv Exp $");
#ifdef _KERNEL_OPT
#include "opt_sdmmc.h"
@@ -98,6 +98,8 @@
bus_dmamap_t adma_map;
bus_dma_segment_t adma_segs[1];
void *adma2;
+
+ uint8_t vdd; /* last vdd setting */
};
#define HDEVNAME(hp) (device_xname((hp)->sc->sc_dev))
@@ -156,10 +158,16 @@
}
}
+static void
+hwrite4(struct sdhc_host *hp, bus_size_t o, uint32_t val)
+{
+
+ bus_space_write_4(hp->iot, hp->ioh, o, val);
+}
+
#define HWRITE1(hp, reg, val) hwrite1(hp, reg, val)
#define HWRITE2(hp, reg, val) hwrite2(hp, reg, val)
-#define HWRITE4(hp, reg, val) \
- bus_space_write_4((hp)->iot, (hp)->ioh, (reg), (val))
+#define HWRITE4(hp, reg, val) hwrite4(hp, reg, val)
#define HCLR1(hp, reg, bits) \
do if (bits) HWRITE1((hp), (reg), HREAD1((hp), (reg)) & ~(bits)); while (0)
@@ -788,6 +796,9 @@
HWRITE2(hp, SDHC_NINTR_SIGNAL_EN, 0);
}
+ /* Let sdhc_bus_power restore power */
+ hp->vdd = 0;
+
/*
* Reset the entire host controller and wait up to 100ms for
* the controller to clear the reset bit.
@@ -902,6 +913,7 @@
int error = 0;
const uint32_t pcmask =
~(SDHC_BUS_POWER | (SDHC_VOLTAGE_MASK << SDHC_VOLTAGE_SHIFT));
+ uint32_t reg;
mutex_enter(&hp->intr_lock);
@@ -909,8 +921,10 @@
* Disable bus power before voltage change.
*/
if (!ISSET(hp->sc->sc_flags, SDHC_FLAG_32BIT_ACCESS)
- && !ISSET(hp->sc->sc_flags, SDHC_FLAG_NO_PWR0))
+ && !ISSET(hp->sc->sc_flags, SDHC_FLAG_NO_PWR0)) {
+ hp->vdd = 0;
HWRITE1(hp, SDHC_POWER_CTL, 0);
+ }
/* If power is disabled, reset the host and return now. */
if (ocr == 0) {
@@ -935,6 +949,12 @@
goto out;
}
+ /*
+ * Did voltage change ?
+ */
+ if (vdd == hp->vdd)
+ goto out;
+
if (!ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) {
/*
* Enable bus power. Wait at least 1 ms (or 74 clocks) plus
@@ -945,13 +965,14 @@
HWRITE1(hp, SDHC_POWER_CTL,
(vdd << SDHC_VOLTAGE_SHIFT) | SDHC_BUS_POWER);
} else {
- HWRITE1(hp, SDHC_POWER_CTL,
- HREAD1(hp, SDHC_POWER_CTL) & pcmask);
+ reg = HREAD1(hp, SDHC_POWER_CTL) & pcmask;
+ HWRITE1(hp, SDHC_POWER_CTL, reg);
sdmmc_delay(1);
- HWRITE1(hp, SDHC_POWER_CTL,
- (vdd << SDHC_VOLTAGE_SHIFT));
+ reg |= (vdd << SDHC_VOLTAGE_SHIFT);
+ HWRITE1(hp, SDHC_POWER_CTL, reg);
sdmmc_delay(1);
- HSET1(hp, SDHC_POWER_CTL, SDHC_BUS_POWER);
+ reg |= SDHC_BUS_POWER;
+ HWRITE1(hp, SDHC_POWER_CTL, reg);
sdmmc_delay(10000);
}
@@ -966,6 +987,9 @@
}
}
+ /* power successfully changed */
+ hp->vdd = vdd;
+
out:
mutex_exit(&hp->intr_lock);
@@ -1522,7 +1546,7 @@
uint32_t state;
int timeout;
- for (timeout = 10000; timeout > 0; timeout--) {
+ for (timeout = 100000; timeout > 0; timeout--) {
if (((state = HREAD4(hp, SDHC_PRESENT_STATE)) & mask) == value)
return 0;
sdmmc_delay(10);
@@ -1587,7 +1611,7 @@
* is marked done for any other reason.
*/
probing = (cmd->c_flags & SCF_TOUT_OK) != 0;
- if (!sdhc_wait_intr(hp, SDHC_COMMAND_COMPLETE, SDHC_COMMAND_TIMEOUT, probing)) {
+ if (!sdhc_wait_intr(hp, SDHC_COMMAND_COMPLETE, SDHC_COMMAND_TIMEOUT*3, probing)) {
DPRINTF(1,("%s: timeout for command\n", __func__));
sdmmc_delay(50);
cmd->c_error = ETIMEDOUT;
Home |
Main Index |
Thread Index |
Old Index