Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 14 May 2021 08:53:22 GMT
From:      Marcin Wojtas <mw@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: f0a9d7d79956 - main - sdhci_fsl_fdt.c: Add a missing call to mmc_fdt_parse.
Message-ID:  <202105140853.14E8rMEC017312@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by mw:

URL: https://cgit.FreeBSD.org/src/commit/?id=f0a9d7d7995641901e3132242d1d9bf22dc333f6

commit f0a9d7d7995641901e3132242d1d9bf22dc333f6
Author:     Marcin Wojtas <mw@FreeBSD.org>
AuthorDate: 2021-04-22 10:54:41 +0000
Commit:     Marcin Wojtas <mw@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@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),



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202105140853.14E8rMEC017312>