Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107074475
D30122.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D30122.diff
View Options
diff --git a/sys/dev/sdhci/sdhci_fsl_fdt.c b/sys/dev/sdhci/sdhci_fsl_fdt.c
--- a/sys/dev/sdhci/sdhci_fsl_fdt.c
+++ b/sys/dev/sdhci/sdhci_fsl_fdt.c
@@ -45,6 +45,7 @@
#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 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 @@
((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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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),
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 10, 5:28 PM (14 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15744477
Default Alt Text
D30122.diff (4 KB)
Attached To
Mode
D30122: sdhci_fsl_fdt.c: Add a missing call to mmc_fdt_parse.
Attached
Detach File
Event Timeline
Log In to Comment