git: 7518736826a2 - stable/13 - sdhci_xenon: improve the VCCQ voltage switch sequence
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 07 Mar 2022 16:00:08 UTC
The branch stable/13 has been updated by mw:
URL: https://cgit.FreeBSD.org/src/commit/?id=7518736826a2569e2799595d444cbdf0c9c82e5a
commit 7518736826a2569e2799595d444cbdf0c9c82e5a
Author: Marcin Wojtas <mw@FreeBSD.org>
AuthorDate: 2021-05-27 18:39:12 +0000
Commit: Marcin Wojtas <mw@FreeBSD.org>
CommitDate: 2022-03-07 15:59:50 +0000
sdhci_xenon: improve the VCCQ voltage switch sequence
Improve the VCCQ voltage switch, so that to properly
handle the SDHCI_HOST_CONTROL2 register signaling
flags and along with manipulating the regulator.
Reviewed by: manu
Obtained from: Semihalf
Sponsored by: Marvell
Differential Revision: https://reviews.freebsd.org/D30564
MFC after: 2 weeks
(cherry picked from commit c80e2ca57e0c1b3647b55471584c6d32214232ea)
---
sys/dev/sdhci/sdhci_xenon.c | 84 ++++++++++++++++++++++++++++++++++++---------
1 file changed, 68 insertions(+), 16 deletions(-)
diff --git a/sys/dev/sdhci/sdhci_xenon.c b/sys/dev/sdhci/sdhci_xenon.c
index f92d02608abb..42f36b619b36 100644
--- a/sys/dev/sdhci/sdhci_xenon.c
+++ b/sys/dev/sdhci/sdhci_xenon.c
@@ -388,35 +388,87 @@ sdhci_xenon_switch_vccq(device_t brdev, device_t reqdev)
{
struct sdhci_xenon_softc *sc;
struct sdhci_slot *slot;
+ uint16_t hostctrl2;
int uvolt, err;
+ slot = device_get_ivars(reqdev);
+
+ if (slot->version < SDHCI_SPEC_300)
+ return (0);
+
sc = device_get_softc(brdev);
if (sc->mmc_helper.vqmmc_supply == NULL)
return EOPNOTSUPP;
- slot = device_get_ivars(reqdev);
+ err = 0;
+
+ hostctrl2 = bus_read_2(sc->mem_res, SDHCI_HOST_CONTROL2);
switch (slot->host.ios.vccq) {
- case vccq_180:
- uvolt = 1800000;
- break;
case vccq_330:
+ if (!(hostctrl2 & SDHCI_CTRL2_S18_ENABLE))
+ return (0);
+ hostctrl2 &= ~SDHCI_CTRL2_S18_ENABLE;
+ bus_write_2(sc->mem_res, SDHCI_HOST_CONTROL2, hostctrl2);
+
uvolt = 3300000;
- break;
+ err = regulator_set_voltage(sc->mmc_helper.vqmmc_supply,
+ uvolt, uvolt);
+ if (err != 0) {
+ device_printf(sc->dev,
+ "Cannot set vqmmc to %d<->%d\n",
+ uvolt,
+ uvolt);
+ return (err);
+ }
+
+ /*
+ * According to the 'SD Host Controller Simplified
+ * Specification 4.20 the host driver should take more
+ * than 5ms for stable time of host voltage regulator
+ * from changing 1.8V Signaling Enable.
+ */
+ DELAY(5000);
+ hostctrl2 = bus_read_2(sc->mem_res, SDHCI_HOST_CONTROL2);
+ if (!(hostctrl2 & SDHCI_CTRL2_S18_ENABLE))
+ return (0);
+ return EAGAIN;
+ case vccq_180:
+ if (!(slot->host.caps & MMC_CAP_SIGNALING_180)) {
+ return EINVAL;
+ }
+ if (hostctrl2 & SDHCI_CTRL2_S18_ENABLE)
+ return (0);
+ hostctrl2 |= SDHCI_CTRL2_S18_ENABLE;
+ bus_write_2(sc->mem_res, SDHCI_HOST_CONTROL2, hostctrl2);
+
+ uvolt = 1800000;
+ err = regulator_set_voltage(sc->mmc_helper.vqmmc_supply,
+ uvolt, uvolt);
+ if (err != 0) {
+ device_printf(sc->dev,
+ "Cannot set vqmmc to %d<->%d\n",
+ uvolt,
+ uvolt);
+ return (err);
+ }
+
+ /*
+ * According to the 'SD Host Controller Simplified
+ * Specification 4.20 the host driver should take more
+ * than 5ms for stable time of host voltage regulator
+ * from changing 1.8V Signaling Enable.
+ */
+ DELAY(5000);
+ hostctrl2 = bus_read_2(sc->mem_res, SDHCI_HOST_CONTROL2);
+ if (hostctrl2 & SDHCI_CTRL2_S18_ENABLE)
+ return (0);
+ return EAGAIN;
default:
+ device_printf(brdev,
+ "Attempt to set unsupported signaling voltage\n");
return EINVAL;
}
-
- err = regulator_set_voltage(sc->mmc_helper.vqmmc_supply, uvolt, uvolt);
- if (err != 0) {
- device_printf(sc->dev,
- "Cannot set vqmmc to %d<->%d\n",
- uvolt,
- uvolt);
- return (err);
- }
-
- return (0);
}
static int