Move imx_sdhci driver over to a dev/sdhci in preparation for QorIQ support.
Freescale uses eSDHC in both i.MX (ARM) and QorIQ (PowerPC), with slight differences. This is part one in unifying the drivers. Reviewed by: imp
This commit is contained in:
parent
06d706238b
commit
3d9df07abf
@ -32,7 +32,7 @@ arm/freescale/imx/imx51_ccm.c standard
|
||||
dev/ata/chipsets/ata-fsl.c optional imxata
|
||||
|
||||
# SDHCI/MMC
|
||||
arm/freescale/imx/imx_sdhci.c optional sdhci
|
||||
dev/sdhci/fsl_sdhci.c optional sdhci
|
||||
|
||||
# USB OH3 controller (1 OTG, 3 EHCI)
|
||||
arm/freescale/imx/imx_nop_usbphy.c optional ehci
|
||||
|
@ -32,7 +32,7 @@ arm/freescale/imx/imx6_ipu.c optional vt
|
||||
#
|
||||
# Optional devices.
|
||||
#
|
||||
arm/freescale/imx/imx_sdhci.c optional sdhci
|
||||
dev/sdhci/fsl_sdhci.c optional sdhci
|
||||
|
||||
arm/freescale/imx/imx_wdog.c optional imxwdt
|
||||
|
||||
|
@ -66,7 +66,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/sdhci/sdhci.h>
|
||||
#include "sdhci_if.h"
|
||||
|
||||
struct imx_sdhci_softc {
|
||||
struct fsl_sdhci_softc {
|
||||
device_t dev;
|
||||
struct resource * mem_res;
|
||||
struct resource * irq_res;
|
||||
@ -88,8 +88,8 @@ struct imx_sdhci_softc {
|
||||
#define R1BFIX_AC12 2 /* Wait for busy after auto command 12. */
|
||||
|
||||
#define HWTYPE_NONE 0 /* Hardware not recognized/supported. */
|
||||
#define HWTYPE_ESDHC 1 /* imx5x and earlier. */
|
||||
#define HWTYPE_USDHC 2 /* imx6. */
|
||||
#define HWTYPE_ESDHC 1 /* fsl5x and earlier. */
|
||||
#define HWTYPE_USDHC 2 /* fsl6. */
|
||||
|
||||
/*
|
||||
* Freescale-specific registers, or in some cases the layout of bits within the
|
||||
@ -172,28 +172,28 @@ static struct ofw_compat_data compat_data[] = {
|
||||
{NULL, HWTYPE_NONE},
|
||||
};
|
||||
|
||||
static uint16_t imx_sdhc_get_clock(struct imx_sdhci_softc *sc);
|
||||
static void imx_sdhc_set_clock(struct imx_sdhci_softc *sc, uint16_t val);
|
||||
static void imx_sdhci_r1bfix_func(void *arg);
|
||||
static uint16_t fsl_sdhc_get_clock(struct fsl_sdhci_softc *sc);
|
||||
static void fsl_sdhc_set_clock(struct fsl_sdhci_softc *sc, uint16_t val);
|
||||
static void fsl_sdhci_r1bfix_func(void *arg);
|
||||
|
||||
static inline uint32_t
|
||||
RD4(struct imx_sdhci_softc *sc, bus_size_t off)
|
||||
RD4(struct fsl_sdhci_softc *sc, bus_size_t off)
|
||||
{
|
||||
|
||||
return (bus_read_4(sc->mem_res, off));
|
||||
}
|
||||
|
||||
static inline void
|
||||
WR4(struct imx_sdhci_softc *sc, bus_size_t off, uint32_t val)
|
||||
WR4(struct fsl_sdhci_softc *sc, bus_size_t off, uint32_t val)
|
||||
{
|
||||
|
||||
bus_write_4(sc->mem_res, off, val);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
imx_sdhci_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
||||
fsl_sdhci_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
||||
{
|
||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
||||
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||
uint32_t val32, wrk32;
|
||||
|
||||
/*
|
||||
@ -246,9 +246,9 @@ imx_sdhci_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
imx_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
||||
fsl_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
||||
{
|
||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
||||
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||
uint32_t val32;
|
||||
|
||||
if (sc->hwtype == HWTYPE_USDHC) {
|
||||
@ -297,16 +297,16 @@ imx_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
||||
* hardware type, complex enough to have their own function.
|
||||
*/
|
||||
if (off == SDHCI_CLOCK_CONTROL) {
|
||||
return (imx_sdhc_get_clock(sc));
|
||||
return (fsl_sdhc_get_clock(sc));
|
||||
}
|
||||
|
||||
return ((RD4(sc, off & ~3) >> (off & 3) * 8) & 0xffff);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
imx_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
||||
fsl_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
||||
{
|
||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
||||
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||
uint32_t val32, wrk32;
|
||||
|
||||
val32 = RD4(sc, off);
|
||||
@ -348,7 +348,7 @@ imx_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
||||
}
|
||||
|
||||
/*
|
||||
* imx_sdhci_intr() can synthesize a DATA_END interrupt following a
|
||||
* fsl_sdhci_intr() can synthesize a DATA_END interrupt following a
|
||||
* command with an R1B response, mix it into the hardware status.
|
||||
*/
|
||||
if (off == SDHCI_INT_STATUS) {
|
||||
@ -359,18 +359,18 @@ imx_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
||||
}
|
||||
|
||||
static void
|
||||
imx_sdhci_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
|
||||
fsl_sdhci_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
|
||||
uint32_t *data, bus_size_t count)
|
||||
{
|
||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
||||
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||
|
||||
bus_read_multi_4(sc->mem_res, off, data, count);
|
||||
}
|
||||
|
||||
static void
|
||||
imx_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t val)
|
||||
fsl_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t val)
|
||||
{
|
||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
||||
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||
uint32_t val32;
|
||||
|
||||
/*
|
||||
@ -406,9 +406,9 @@ imx_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t
|
||||
}
|
||||
|
||||
static void
|
||||
imx_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val)
|
||||
fsl_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val)
|
||||
{
|
||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
||||
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||
uint32_t val32;
|
||||
|
||||
/*
|
||||
@ -416,7 +416,7 @@ imx_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_
|
||||
* that can handle the ESDHC versus USDHC differences.
|
||||
*/
|
||||
if (off == SDHCI_CLOCK_CONTROL) {
|
||||
imx_sdhc_set_clock(sc, val);
|
||||
fsl_sdhc_set_clock(sc, val);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -432,7 +432,7 @@ imx_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_
|
||||
* there's a control bit for it (bit 3) in the vendor register.
|
||||
* When we're starting a command that needs a manual DAT0 line check at
|
||||
* interrupt time, we leave ourselves a note in r1bfix_type so that we
|
||||
* can do the extra work in imx_sdhci_intr().
|
||||
* can do the extra work in fsl_sdhci_intr().
|
||||
*/
|
||||
if (off == SDHCI_COMMAND_FLAGS) {
|
||||
if (val & SDHCI_CMD_DATA) {
|
||||
@ -485,9 +485,9 @@ imx_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_
|
||||
}
|
||||
|
||||
static void
|
||||
imx_sdhci_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t val)
|
||||
fsl_sdhci_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t val)
|
||||
{
|
||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
||||
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||
|
||||
/* Clear synthesized interrupts, then pass the value to the hardware. */
|
||||
if (off == SDHCI_INT_STATUS) {
|
||||
@ -498,16 +498,16 @@ imx_sdhci_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_
|
||||
}
|
||||
|
||||
static void
|
||||
imx_sdhci_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
|
||||
fsl_sdhci_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
|
||||
uint32_t *data, bus_size_t count)
|
||||
{
|
||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
||||
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||
|
||||
bus_write_multi_4(sc->mem_res, off, data, count);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
imx_sdhc_get_clock(struct imx_sdhci_softc *sc)
|
||||
fsl_sdhc_get_clock(struct fsl_sdhci_softc *sc)
|
||||
{
|
||||
uint16_t val;
|
||||
|
||||
@ -551,7 +551,7 @@ imx_sdhc_get_clock(struct imx_sdhci_softc *sc)
|
||||
}
|
||||
|
||||
static void
|
||||
imx_sdhc_set_clock(struct imx_sdhci_softc *sc, uint16_t val)
|
||||
fsl_sdhc_set_clock(struct fsl_sdhci_softc *sc, uint16_t val)
|
||||
{
|
||||
uint32_t divisor, freq, prescale, val32;
|
||||
|
||||
@ -629,7 +629,7 @@ imx_sdhc_set_clock(struct imx_sdhci_softc *sc, uint16_t val)
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
imx_sdhci_r1bfix_is_wait_done(struct imx_sdhci_softc *sc)
|
||||
fsl_sdhci_r1bfix_is_wait_done(struct fsl_sdhci_softc *sc)
|
||||
{
|
||||
uint32_t inhibit;
|
||||
|
||||
@ -646,7 +646,7 @@ imx_sdhci_r1bfix_is_wait_done(struct imx_sdhci_softc *sc)
|
||||
|
||||
if (inhibit && getsbinuptime() < sc->r1bfix_timeout_at) {
|
||||
callout_reset_sbt(&sc->r1bfix_callout, SBT_1MS, 0,
|
||||
imx_sdhci_r1bfix_func, sc, 0);
|
||||
fsl_sdhci_r1bfix_func, sc, 0);
|
||||
return (false);
|
||||
}
|
||||
|
||||
@ -670,22 +670,22 @@ imx_sdhci_r1bfix_is_wait_done(struct imx_sdhci_softc *sc)
|
||||
}
|
||||
|
||||
static void
|
||||
imx_sdhci_r1bfix_func(void * arg)
|
||||
fsl_sdhci_r1bfix_func(void * arg)
|
||||
{
|
||||
struct imx_sdhci_softc *sc = arg;
|
||||
struct fsl_sdhci_softc *sc = arg;
|
||||
boolean_t r1bwait_done;
|
||||
|
||||
mtx_lock(&sc->slot.mtx);
|
||||
r1bwait_done = imx_sdhci_r1bfix_is_wait_done(sc);
|
||||
r1bwait_done = fsl_sdhci_r1bfix_is_wait_done(sc);
|
||||
mtx_unlock(&sc->slot.mtx);
|
||||
if (r1bwait_done)
|
||||
sdhci_generic_intr(&sc->slot);
|
||||
}
|
||||
|
||||
static void
|
||||
imx_sdhci_intr(void *arg)
|
||||
fsl_sdhci_intr(void *arg)
|
||||
{
|
||||
struct imx_sdhci_softc *sc = arg;
|
||||
struct fsl_sdhci_softc *sc = arg;
|
||||
uint32_t intmask;
|
||||
|
||||
mtx_lock(&sc->slot.mtx);
|
||||
@ -721,7 +721,7 @@ imx_sdhci_intr(void *arg)
|
||||
}
|
||||
if (intmask) {
|
||||
sc->r1bfix_timeout_at = getsbinuptime() + 250 * SBT_1MS;
|
||||
if (!imx_sdhci_r1bfix_is_wait_done(sc)) {
|
||||
if (!fsl_sdhci_r1bfix_is_wait_done(sc)) {
|
||||
WR4(sc, SDHC_INT_STATUS, intmask);
|
||||
bus_barrier(sc->mem_res, SDHC_INT_STATUS, 4,
|
||||
BUS_SPACE_BARRIER_WRITE);
|
||||
@ -733,23 +733,23 @@ imx_sdhci_intr(void *arg)
|
||||
}
|
||||
|
||||
static int
|
||||
imx_sdhci_get_ro(device_t bus, device_t child)
|
||||
fsl_sdhci_get_ro(device_t bus, device_t child)
|
||||
{
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
static int
|
||||
imx_sdhci_detach(device_t dev)
|
||||
fsl_sdhci_detach(device_t dev)
|
||||
{
|
||||
|
||||
return (EBUSY);
|
||||
}
|
||||
|
||||
static int
|
||||
imx_sdhci_attach(device_t dev)
|
||||
fsl_sdhci_attach(device_t dev)
|
||||
{
|
||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
||||
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||
int rid, err;
|
||||
phandle_t node;
|
||||
|
||||
@ -757,7 +757,7 @@ imx_sdhci_attach(device_t dev)
|
||||
|
||||
sc->hwtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
|
||||
if (sc->hwtype == HWTYPE_NONE)
|
||||
panic("Impossible: not compatible in imx_sdhci_attach()");
|
||||
panic("Impossible: not compatible in fsl_sdhci_attach()");
|
||||
|
||||
rid = 0;
|
||||
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
|
||||
@ -778,7 +778,7 @@ imx_sdhci_attach(device_t dev)
|
||||
}
|
||||
|
||||
if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
|
||||
NULL, imx_sdhci_intr, sc, &sc->intr_cookie)) {
|
||||
NULL, fsl_sdhci_intr, sc, &sc->intr_cookie)) {
|
||||
device_printf(dev, "cannot setup interrupt handler\n");
|
||||
err = ENXIO;
|
||||
goto fail;
|
||||
@ -853,7 +853,7 @@ imx_sdhci_attach(device_t dev)
|
||||
}
|
||||
|
||||
static int
|
||||
imx_sdhci_probe(device_t dev)
|
||||
fsl_sdhci_probe(device_t dev)
|
||||
{
|
||||
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
@ -872,11 +872,11 @@ imx_sdhci_probe(device_t dev)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static device_method_t imx_sdhci_methods[] = {
|
||||
static device_method_t fsl_sdhci_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, imx_sdhci_probe),
|
||||
DEVMETHOD(device_attach, imx_sdhci_attach),
|
||||
DEVMETHOD(device_detach, imx_sdhci_detach),
|
||||
DEVMETHOD(device_probe, fsl_sdhci_probe),
|
||||
DEVMETHOD(device_attach, fsl_sdhci_attach),
|
||||
DEVMETHOD(device_detach, fsl_sdhci_detach),
|
||||
|
||||
/* Bus interface */
|
||||
DEVMETHOD(bus_read_ivar, sdhci_generic_read_ivar),
|
||||
@ -886,32 +886,32 @@ static device_method_t imx_sdhci_methods[] = {
|
||||
/* MMC bridge interface */
|
||||
DEVMETHOD(mmcbr_update_ios, sdhci_generic_update_ios),
|
||||
DEVMETHOD(mmcbr_request, sdhci_generic_request),
|
||||
DEVMETHOD(mmcbr_get_ro, imx_sdhci_get_ro),
|
||||
DEVMETHOD(mmcbr_get_ro, fsl_sdhci_get_ro),
|
||||
DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host),
|
||||
DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host),
|
||||
|
||||
/* SDHCI registers accessors */
|
||||
DEVMETHOD(sdhci_read_1, imx_sdhci_read_1),
|
||||
DEVMETHOD(sdhci_read_2, imx_sdhci_read_2),
|
||||
DEVMETHOD(sdhci_read_4, imx_sdhci_read_4),
|
||||
DEVMETHOD(sdhci_read_multi_4, imx_sdhci_read_multi_4),
|
||||
DEVMETHOD(sdhci_write_1, imx_sdhci_write_1),
|
||||
DEVMETHOD(sdhci_write_2, imx_sdhci_write_2),
|
||||
DEVMETHOD(sdhci_write_4, imx_sdhci_write_4),
|
||||
DEVMETHOD(sdhci_write_multi_4, imx_sdhci_write_multi_4),
|
||||
DEVMETHOD(sdhci_read_1, fsl_sdhci_read_1),
|
||||
DEVMETHOD(sdhci_read_2, fsl_sdhci_read_2),
|
||||
DEVMETHOD(sdhci_read_4, fsl_sdhci_read_4),
|
||||
DEVMETHOD(sdhci_read_multi_4, fsl_sdhci_read_multi_4),
|
||||
DEVMETHOD(sdhci_write_1, fsl_sdhci_write_1),
|
||||
DEVMETHOD(sdhci_write_2, fsl_sdhci_write_2),
|
||||
DEVMETHOD(sdhci_write_4, fsl_sdhci_write_4),
|
||||
DEVMETHOD(sdhci_write_multi_4, fsl_sdhci_write_multi_4),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static devclass_t imx_sdhci_devclass;
|
||||
static devclass_t fsl_sdhci_devclass;
|
||||
|
||||
static driver_t imx_sdhci_driver = {
|
||||
"sdhci_imx",
|
||||
imx_sdhci_methods,
|
||||
sizeof(struct imx_sdhci_softc),
|
||||
static driver_t fsl_sdhci_driver = {
|
||||
"sdhci_fsl",
|
||||
fsl_sdhci_methods,
|
||||
sizeof(struct fsl_sdhci_softc),
|
||||
};
|
||||
|
||||
DRIVER_MODULE(sdhci_imx, simplebus, imx_sdhci_driver, imx_sdhci_devclass, 0, 0);
|
||||
MODULE_DEPEND(sdhci_imx, sdhci, 1, 1, 1);
|
||||
DRIVER_MODULE(mmc, sdhci_imx, mmc_driver, mmc_devclass, NULL, NULL);
|
||||
MODULE_DEPEND(sdhci_imx, mmc, 1, 1, 1);
|
||||
DRIVER_MODULE(sdhci_fsl, simplebus, fsl_sdhci_driver, fsl_sdhci_devclass, 0, 0);
|
||||
MODULE_DEPEND(sdhci_fsl, sdhci, 1, 1, 1);
|
||||
DRIVER_MODULE(mmc, sdhci_fsl, mmc_driver, mmc_devclass, NULL, NULL);
|
||||
MODULE_DEPEND(sdhci_fsl, mmc, 1, 1, 1);
|
Loading…
Reference in New Issue
Block a user