git: f0a9d7d79956 - main - sdhci_fsl_fdt.c: Add a missing call to mmc_fdt_parse.
Marcin Wojtas
mw at FreeBSD.org
Fri May 14 08:53:23 UTC 2021
The branch main has been updated by mw:
URL: https://cgit.FreeBSD.org/src/commit/?id=f0a9d7d7995641901e3132242d1d9bf22dc333f6
commit f0a9d7d7995641901e3132242d1d9bf22dc333f6
Author: Marcin Wojtas <mw at FreeBSD.org>
AuthorDate: 2021-04-22 10:54:41 +0000
Commit: Marcin Wojtas <mw at FreeBSD.org>
CommitDate: 2021-05-14 08:29:31 +0000
sdhci_fsl_fdt.c: Add a missing call to mmc_fdt_parse.
Add a missing call to mmc_fdt_parse, without it some dts properties
are not parsed.
Submitted by: Lukasz Hajec <lha at semihalf.com>
Reviewed by: manu
Obtained from: Semihalf
Sponsored by: Alstom Group
Differential Revision: https://reviews.freebsd.org/D30122
---
sys/dev/sdhci/sdhci_fsl_fdt.c | 110 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 106 insertions(+), 4 deletions(-)
diff --git a/sys/dev/sdhci/sdhci_fsl_fdt.c b/sys/dev/sdhci/sdhci_fsl_fdt.c
index 695176a17218..c2330a679963 100644
--- a/sys/dev/sdhci/sdhci_fsl_fdt.c
+++ b/sys/dev/sdhci/sdhci_fsl_fdt.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <dev/extres/clk/clk.h>
#include <dev/mmc/bridge.h>
#include <dev/mmc/mmcbrvar.h>
+#include <dev/mmc/mmc_fdt_helpers.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/sdhci/sdhci.h>
@@ -96,11 +97,13 @@ struct sdhci_fsl_fdt_softc {
struct resource *irq_res;
void *irq_cookie;
uint32_t baseclk_hz;
+ uint32_t maxclk_hz;
struct sdhci_fdt_gpio *gpio;
struct sdhci_slot slot;
bool slot_init_done;
uint32_t cmd_and_mode;
uint16_t sdclk_bits;
+ struct mmc_fdt_helper fdt_helper;
uint32_t (* read)(struct sdhci_fsl_fdt_softc *, bus_size_t);
void (* write)(struct sdhci_fsl_fdt_softc *, bus_size_t, uint32_t);
@@ -194,9 +197,9 @@ fsl_sdhc_fdt_set_clock(struct sdhci_fsl_fdt_softc *sc, uint16_t val)
((val >> SDHCI_DIVIDER_HI_SHIFT) & SDHCI_DIVIDER_HI_MASK) <<
SDHCI_DIVIDER_MASK_LEN;
if (div == 0)
- freq = sc->baseclk_hz;
+ freq = sc->maxclk_hz;
else
- freq = sc->baseclk_hz / (2 * div);
+ freq = sc->maxclk_hz / (2 * div);
for (prescale = 2; freq < sc->baseclk_hz / (prescale * 16); )
prescale <<= 1;
@@ -445,6 +448,86 @@ sdhci_fsl_fdt_irq(void *arg)
return;
}
+static int
+sdhci_fsl_fdt_update_ios(device_t brdev, device_t reqdev)
+{
+ int err;
+ struct sdhci_fsl_fdt_softc *sc;
+ struct mmc_ios *ios;
+ struct sdhci_slot *slot;
+
+ err = sdhci_generic_update_ios(brdev, reqdev);
+ if (err != 0)
+ return (err);
+
+ sc = device_get_softc(brdev);
+ slot = device_get_ivars(reqdev);
+ ios = &slot->host.ios;
+
+ switch (ios->power_mode) {
+ case power_on:
+ break;
+ case power_off:
+ if (bootverbose)
+ device_printf(sc->dev, "Powering down sd/mmc\n");
+
+ if (sc->fdt_helper.vmmc_supply)
+ regulator_disable(sc->fdt_helper.vmmc_supply);
+ if (sc->fdt_helper.vqmmc_supply)
+ regulator_disable(sc->fdt_helper.vqmmc_supply);
+ break;
+ case power_up:
+ if (bootverbose)
+ device_printf(sc->dev, "Powering up sd/mmc\n");
+
+ if (sc->fdt_helper.vmmc_supply)
+ regulator_enable(sc->fdt_helper.vmmc_supply);
+ if (sc->fdt_helper.vqmmc_supply)
+ regulator_enable(sc->fdt_helper.vqmmc_supply);
+ break;
+ };
+
+ return (0);
+}
+
+static int
+sdhci_fsl_fdt_switch_vccq(device_t brdev, device_t reqdev)
+{
+ struct sdhci_fsl_fdt_softc *sc;
+ struct sdhci_slot *slot;
+ int uvolt, err;
+
+ err = sdhci_generic_switch_vccq(brdev, reqdev);
+ if (err != 0)
+ return (err);
+
+ sc = device_get_softc(brdev);
+
+ if (sc->fdt_helper.vqmmc_supply == NULL)
+ return EOPNOTSUPP;
+
+ slot = device_get_ivars(reqdev);
+ switch (slot->host.ios.vccq) {
+ case vccq_180:
+ uvolt = 1800000;
+ break;
+ case vccq_330:
+ uvolt = 3300000;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ err = regulator_set_voltage(sc->fdt_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
sdhci_fsl_fdt_get_ro(device_t bus, device_t child)
{
@@ -463,10 +546,24 @@ sdhci_fsl_fdt_get_card_present(device_t dev, struct sdhci_slot *slot)
return (sdhci_fdt_gpio_get_present(sc->gpio));
}
+static void
+sdhci_fsl_fdt_of_parse(device_t dev)
+{
+ struct sdhci_fsl_fdt_softc *sc;
+ phandle_t node;
+
+ sc = device_get_softc(dev);
+ node = ofw_bus_get_node(dev);
+
+ /* Call mmc_fdt_parse in order to get mmc related properties. */
+ mmc_fdt_parse(dev, node, &sc->fdt_helper, &sc->slot.host);
+}
+
static int
sdhci_fsl_fdt_attach(device_t dev)
{
struct sdhci_fsl_fdt_softc *sc;
+ struct mmc_host *host;
uint32_t val, buf_order;
uintptr_t ocd_data;
uint64_t clk_hz;
@@ -481,6 +578,7 @@ sdhci_fsl_fdt_attach(device_t dev)
sc->soc_data = (struct sdhci_fsl_fdt_soc_data *)ocd_data;
sc->dev = dev;
sc->slot.quirks = sc->soc_data->quirks;
+ host = &sc->slot.host;
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
@@ -534,6 +632,9 @@ sdhci_fsl_fdt_attach(device_t dev)
buf_order = SDHCI_FSL_PROT_CTRL_BYTE_SWAP;
}
+ sdhci_fsl_fdt_of_parse(dev);
+ sc->maxclk_hz = host->f_max ? host->f_max : sc->baseclk_hz;
+
/*
* Setting this register affects byte order in SDHCI_BUFFER only.
* If the eSDHC block is connected over a big-endian bus, the data
@@ -555,7 +656,7 @@ sdhci_fsl_fdt_attach(device_t dev)
WR4(sc, SDHCI_CLOCK_CONTROL, val & ~SDHCI_FSL_CLK_SDCLKEN);
val = RD4(sc, SDHCI_FSL_ESDHC_CTRL);
WR4(sc, SDHCI_FSL_ESDHC_CTRL, val | SDHCI_FSL_ESDHC_CTRL_CLK_DIV2);
- sc->slot.max_clk = sc->baseclk_hz;
+ sc->slot.max_clk = sc->maxclk_hz;
sc->gpio = sdhci_fdt_gpio_setup(dev, &sc->slot);
/*
@@ -656,11 +757,12 @@ static const device_method_t sdhci_fsl_fdt_methods[] = {
DEVMETHOD(bus_write_ivar, sdhci_generic_write_ivar),
/* MMC bridge interface. */
- DEVMETHOD(mmcbr_update_ios, sdhci_generic_update_ios),
DEVMETHOD(mmcbr_request, sdhci_generic_request),
DEVMETHOD(mmcbr_get_ro, sdhci_fsl_fdt_get_ro),
DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host),
DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host),
+ DEVMETHOD(mmcbr_switch_vccq, sdhci_fsl_fdt_switch_vccq),
+ DEVMETHOD(mmcbr_update_ios, sdhci_fsl_fdt_update_ios),
/* SDHCI accessors. */
DEVMETHOD(sdhci_read_1, sdhci_fsl_fdt_read_1),
More information about the dev-commits-src-main
mailing list