Skip to content

Commit

Permalink
MFC r359924-r359925, r359927, r359932, r359965
Browse files Browse the repository at this point in the history
r359924:
Those functions are here to help fdt mmc controller drivers to parse
the dts to find the supported speeds and the regulators.
Not all DTS have every settings properly defined so host controller
will still have to add some caps themselves.
It also add a mmc_fdt_gpio_setup function which will read the cd-gpios
property and register it as the CD pin.
If the pin support interrupts one will be registered and the cd_helper
function will be called.
If the pin doesn't support interrupts the internal taskqueue will poll
for change and call the same cd_helper function.
mmc_fdt_gpio_setup will also parse the wp-gpio property and MMC drivers
can know the write-protect pin value by calling the
mmc_fdt_gpio_get_readonly function.

Differential Revision:	https://reviews.freebsd.org/D23267

r359925:
arm: allwinner: aw_mmc: Use the mmc_fdt_helper

The fdt properties are now parsed via the help of mmc_fdt_helper functions.
This also adds card detection.
Note that on some boards (like the Pine64) card detection is broken due to
a missing resistor on the cd pin.

Differential Revision:	https://reviews.freebsd.org/D23268

r359927:
arm: dwmmc: Use mmc_fdt_helpers

Use the mmc_fdt_parse function instead of parsing everything in the
driver.

r359932:
files: Add mmc_fdt_helpers for mmccam enabled config

X-MFC-With:	r359924

r359965:
mmc_fdt_helpers: Do not schedule a card detection is there is no cd gpio

If the fdt node doesn't have a cd-gpios properties or if the node is set
as non-removable we do not init the card detection timeout task as it is
useless so don't schedule it too.

X-MFC-With:	r359924
  • Loading branch information
evadot committed Jun 19, 2020
1 parent a4fa9f1 commit 2b585db
Show file tree
Hide file tree
Showing 10 changed files with 569 additions and 84 deletions.
127 changes: 61 additions & 66 deletions sys/arm/allwinner/aw_mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ __FBSDID("$FreeBSD$");
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>

#include <machine/bus.h>

Expand All @@ -49,6 +51,7 @@ __FBSDID("$FreeBSD$");

#include <dev/mmc/bridge.h>
#include <dev/mmc/mmcbrvar.h>
#include <dev/mmc/mmc_fdt_helpers.h>

#include <arm/allwinner/aw_mmc.h>
#include <dev/extres/clk/clk.h>
Expand Down Expand Up @@ -122,6 +125,7 @@ struct aw_mmc_softc {
int aw_timeout;
struct callout aw_timeoutc;
struct mmc_host aw_host;
struct mmc_fdt_helper mmc_helper;
#ifdef MMCCAM
union ccb * ccb;
struct cam_devq * devq;
Expand All @@ -136,9 +140,8 @@ struct aw_mmc_softc {
uint32_t aw_intr;
uint32_t aw_intr_wait;
void * aw_intrhand;
regulator_t aw_reg_vmmc;
regulator_t aw_reg_vqmmc;
unsigned int aw_clock;
device_t child;

/* Fields required for DMA access. */
bus_addr_t aw_dma_desc_phys;
Expand All @@ -164,6 +167,7 @@ static int aw_mmc_reset(struct aw_mmc_softc *);
static int aw_mmc_init(struct aw_mmc_softc *);
static void aw_mmc_intr(void *);
static int aw_mmc_update_clock(struct aw_mmc_softc *, uint32_t);
static void aw_mmc_helper_cd_handler(device_t, bool);

static void aw_mmc_print_error(uint32_t);
static int aw_mmc_update_ios(device_t, device_t);
Expand Down Expand Up @@ -380,6 +384,40 @@ aw_mmc_cam_request(struct aw_mmc_softc *sc, union ccb *ccb)
}
#endif /* MMCCAM */

static void
aw_mmc_helper_cd_handler(device_t dev, bool present)
{
struct aw_mmc_softc *sc;

sc = device_get_softc(dev);
AW_MMC_LOCK(sc);
if (present) {
if (sc->child == NULL) {
if (bootverbose)
device_printf(sc->aw_dev, "Card inserted\n");

sc->child = device_add_child(sc->aw_dev, "mmc", -1);
AW_MMC_UNLOCK(sc);
if (sc->child) {
device_set_ivars(sc->child, sc);
(void)device_probe_and_attach(sc->child);
}
} else
AW_MMC_UNLOCK(sc);
} else {
/* Card isn't present, detach if necessary */
if (sc->child != NULL) {
if (bootverbose)
device_printf(sc->aw_dev, "Card removed\n");

AW_MMC_UNLOCK(sc);
device_delete_child(sc->aw_dev, sc->child);
sc->child = NULL;
} else
AW_MMC_UNLOCK(sc);
}
}

static int
aw_mmc_probe(device_t dev)
{
Expand All @@ -397,15 +435,11 @@ aw_mmc_probe(device_t dev)
static int
aw_mmc_attach(device_t dev)
{
device_t child;
struct aw_mmc_softc *sc;
struct sysctl_ctx_list *ctx;
struct sysctl_oid_list *tree;
uint32_t bus_width, max_freq;
phandle_t node;
int error;

node = ofw_bus_get_node(dev);
sc = device_get_softc(dev);
sc->aw_dev = dev;

Expand All @@ -419,7 +453,7 @@ aw_mmc_attach(device_t dev)
return (ENXIO);
}
if (bus_setup_intr(dev, sc->aw_res[AW_MMC_IRQRES],
INTR_TYPE_MISC | INTR_MPSAFE, NULL, aw_mmc_intr, sc,
INTR_TYPE_NET | INTR_MPSAFE, NULL, aw_mmc_intr, sc,
&sc->aw_intrhand)) {
bus_release_resources(dev, aw_mmc_res_spec, sc->aw_res);
device_printf(dev, "cannot setup interrupt handler\n");
Expand Down Expand Up @@ -483,47 +517,15 @@ aw_mmc_attach(device_t dev)
goto fail;
}

if (OF_getencprop(node, "bus-width", &bus_width, sizeof(uint32_t)) <= 0)
bus_width = 4;

if (regulator_get_by_ofw_property(dev, 0, "vmmc-supply",
&sc->aw_reg_vmmc) == 0) {
if (bootverbose)
device_printf(dev, "vmmc-supply regulator found\n");
}
if (regulator_get_by_ofw_property(dev, 0, "vqmmc-supply",
&sc->aw_reg_vqmmc) == 0 && bootverbose) {
if (bootverbose)
device_printf(dev, "vqmmc-supply regulator found\n");
}

/* Set some defaults for freq and supported mode */
sc->aw_host.f_min = 400000;

if (OF_getencprop(node, "max-frequency", &max_freq,
sizeof(uint32_t)) <= 0)
max_freq = 52000000;
sc->aw_host.f_max = max_freq;

sc->aw_host.f_max = 52000000;
sc->aw_host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
sc->aw_host.caps = MMC_CAP_HSPEED | MMC_CAP_UHS_SDR12 |
MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 |
MMC_CAP_UHS_DDR50 | MMC_CAP_MMC_DDR52;

if (sc->aw_reg_vqmmc != NULL) {
if (regulator_check_voltage(sc->aw_reg_vqmmc, 1800000) == 0)
sc->aw_host.caps |= MMC_CAP_SIGNALING_180;
if (regulator_check_voltage(sc->aw_reg_vqmmc, 3300000) == 0)
sc->aw_host.caps |= MMC_CAP_SIGNALING_330;
} else
sc->aw_host.caps |= MMC_CAP_SIGNALING_330;

if (bus_width >= 4)
sc->aw_host.caps |= MMC_CAP_4_BIT_DATA;
if (bus_width >= 8)
sc->aw_host.caps |= MMC_CAP_8_BIT_DATA;
sc->aw_host.caps |= MMC_CAP_HSPEED | MMC_CAP_SIGNALING_330;
mmc_fdt_parse(dev, 0, &sc->mmc_helper, &sc->aw_host);
mmc_fdt_gpio_setup(dev, 0, &sc->mmc_helper, aw_mmc_helper_cd_handler);

#ifdef MMCCAM
child = NULL; /* Not used by MMCCAM, need to silence compiler warnings */
sc->ccb = NULL;
if ((sc->devq = cam_simq_alloc(1)) == NULL) {
goto fail;
Expand All @@ -550,18 +552,8 @@ aw_mmc_attach(device_t dev)
}

mtx_unlock(&sc->sim_mtx);
#else /* !MMCCAM */
child = device_add_child(dev, "mmc", -1);
if (child == NULL) {
device_printf(dev, "attaching MMC bus failed!\n");
goto fail;
}
if (device_probe_and_attach(child) != 0) {
device_printf(dev, "attaching MMC child failed!\n");
device_delete_child(dev, child);
goto fail;
}
#endif /* MMCCAM */

return (0);

fail:
Expand Down Expand Up @@ -1314,7 +1306,7 @@ aw_mmc_switch_vccq(device_t bus, device_t child)

sc = device_get_softc(bus);

if (sc->aw_reg_vqmmc == NULL)
if (sc->mmc_helper.vqmmc_supply == NULL)
return EOPNOTSUPP;

switch (sc->aw_host.ios.vccq) {
Expand All @@ -1328,7 +1320,7 @@ aw_mmc_switch_vccq(device_t bus, device_t child)
return EINVAL;
}

err = regulator_set_voltage(sc->aw_reg_vqmmc, uvolt, uvolt);
err = regulator_set_voltage(sc->mmc_helper.vqmmc_supply, uvolt, uvolt);
if (err != 0) {
device_printf(sc->aw_dev,
"Cannot set vqmmc to %d<->%d\n",
Expand Down Expand Up @@ -1373,21 +1365,21 @@ aw_mmc_update_ios(device_t bus, device_t child)
if (bootverbose)
device_printf(sc->aw_dev, "Powering down sd/mmc\n");

if (sc->aw_reg_vmmc)
regulator_disable(sc->aw_reg_vmmc);
if (sc->aw_reg_vqmmc)
regulator_disable(sc->aw_reg_vqmmc);
if (sc->mmc_helper.vmmc_supply)
regulator_disable(sc->mmc_helper.vmmc_supply);
if (sc->mmc_helper.vqmmc_supply)
regulator_disable(sc->mmc_helper.vqmmc_supply);

aw_mmc_reset(sc);
break;
case power_up:
if (bootverbose)
device_printf(sc->aw_dev, "Powering up sd/mmc\n");

if (sc->aw_reg_vmmc)
regulator_enable(sc->aw_reg_vmmc);
if (sc->aw_reg_vqmmc)
regulator_enable(sc->aw_reg_vqmmc);
if (sc->mmc_helper.vmmc_supply)
regulator_enable(sc->mmc_helper.vmmc_supply);
if (sc->mmc_helper.vqmmc_supply)
regulator_enable(sc->mmc_helper.vqmmc_supply);
aw_mmc_init(sc);
break;
};
Expand Down Expand Up @@ -1463,8 +1455,11 @@ aw_mmc_update_ios(device_t bus, device_t child)
static int
aw_mmc_get_ro(device_t bus, device_t child)
{
struct aw_mmc_softc *sc;

return (0);
sc = device_get_softc(bus);

return (mmc_fdt_gpio_get_readonly(&sc->mmc_helper));
}

static int
Expand Down
1 change: 1 addition & 0 deletions sys/conf/files
Original file line number Diff line number Diff line change
Expand Up @@ -2473,6 +2473,7 @@ dev/mmc/mmc.c optional mmc !mmccam
dev/mmc/mmcbr_if.m standard
dev/mmc/mmcbus_if.m standard
dev/mmc/mmcsd.c optional mmcsd !mmccam
dev/mmc/mmc_fdt_helpers.c optional mmc fdt | mmccam fdt
dev/mmcnull/mmcnull.c optional mmcnull
dev/mn/if_mn.c optional mn pci
dev/mpr/mpr.c optional mpr
Expand Down
26 changes: 8 additions & 18 deletions sys/dev/mmc/host/dwmmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");

#include <dev/mmc/bridge.h>
#include <dev/mmc/mmcbrvar.h>
#include <dev/mmc/mmc_fdt_helpers.h>

#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
Expand Down Expand Up @@ -446,7 +447,6 @@ dwmmc_card_task(void *arg, int pending __unused)
}
} else
DWMMC_UNLOCK(sc);

} else {
/* Card isn't present, detach if necessary */
if (sc->child != NULL) {
Expand All @@ -466,7 +466,7 @@ parse_fdt(struct dwmmc_softc *sc)
{
pcell_t dts_value[3];
phandle_t node;
uint32_t bus_hz = 0, bus_width;
uint32_t bus_hz = 0;
int len;
#ifdef EXT_RESOURCES
int error;
Expand All @@ -475,17 +475,12 @@ parse_fdt(struct dwmmc_softc *sc)
if ((node = ofw_bus_get_node(sc->dev)) == -1)
return (ENXIO);

/* bus-width */
if (OF_getencprop(node, "bus-width", &bus_width, sizeof(uint32_t)) <= 0)
bus_width = 4;
if (bus_width >= 4)
sc->host.caps |= MMC_CAP_4_BIT_DATA;
if (bus_width >= 8)
sc->host.caps |= MMC_CAP_8_BIT_DATA;

/* max-frequency */
if (OF_getencprop(node, "max-frequency", &sc->host.f_max, sizeof(uint32_t)) <= 0)
sc->host.f_max = 200000000;
/* Set some defaults for freq and supported mode */
sc->host.f_min = 400000;
sc->host.f_max = 200000000;
sc->host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
sc->host.caps = MMC_CAP_HSPEED | MMC_CAP_SIGNALING_330;
mmc_fdt_parse(sc->dev, node, &sc->mmc_helper, &sc->host);

/* fifo-depth */
if ((len = OF_getproplen(node, "fifo-depth")) > 0) {
Expand Down Expand Up @@ -722,11 +717,6 @@ dwmmc_attach(device_t dev)
SDMMC_INTMASK_CD));
WRITE4(sc, SDMMC_CTRL, SDMMC_CTRL_INT_ENABLE);

sc->host.f_min = 400000;
sc->host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
sc->host.caps |= MMC_CAP_HSPEED;
sc->host.caps |= MMC_CAP_SIGNALING_330;

TASK_INIT(&sc->card_task, 0, dwmmc_card_task, sc);
TIMEOUT_TASK_INIT(taskqueue_swi_giant, &sc->card_delayed_task, 0,
dwmmc_card_task, sc);
Expand Down
1 change: 1 addition & 0 deletions sys/dev/mmc/host/dwmmc_altera.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>

#include <dev/mmc/bridge.h>
#include <dev/mmc/mmc_fdt_helpers.h>

#include <dev/ofw/ofw_bus_subr.h>

Expand Down
1 change: 1 addition & 0 deletions sys/dev/mmc/host/dwmmc_hisi.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>

#include <dev/mmc/bridge.h>
#include <dev/mmc/mmc_fdt_helpers.h>

#include <dev/ofw/ofw_bus_subr.h>

Expand Down
1 change: 1 addition & 0 deletions sys/dev/mmc/host/dwmmc_rockchip.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>

#include <dev/mmc/bridge.h>
#include <dev/mmc/mmc_fdt_helpers.h>

#include <dev/ofw/ofw_bus_subr.h>

Expand Down
1 change: 1 addition & 0 deletions sys/dev/mmc/host/dwmmc_samsung.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>

#include <dev/mmc/bridge.h>
#include <dev/mmc/mmc_fdt_helpers.h>

#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
Expand Down
1 change: 1 addition & 0 deletions sys/dev/mmc/host/dwmmc_var.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct dwmmc_softc {
device_t dev;
void *intr_cookie;
struct mmc_host host;
struct mmc_fdt_helper mmc_helper;
struct mtx sc_mtx;
struct mmc_request *req;
struct mmc_command *curcmd;
Expand Down
Loading

0 comments on commit 2b585db

Please sign in to comment.