diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2016-06-18 05:59:27 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2016-06-18 05:59:27 +0000 |
commit | ec3a50600dffe1c1ea70d3fd02c150b08f8b10d6 (patch) | |
tree | aee17dc40dc94a04a344df7fea47eb56c6c41a6f /sys/arch/armv7/omap | |
parent | a0fec8fc19a5b246013610bcb53e4a093a3f9372 (diff) |
Dynamically attach ommmc with fdt. Offset the start of the memory region
by 0x100 for nodes compatible with "ti,omap4-hsmmc" to get the same
offsets as omap3. Handle both the nintr 1 (omap3/am335x) and nintr 3
(omap4) cases in attach. Ideally the "interrupts" property will be
handled by the interrupt controller drivers directly in future.
Diffstat (limited to 'sys/arch/armv7/omap')
-rw-r--r-- | sys/arch/armv7/omap/files.omap | 4 | ||||
-rw-r--r-- | sys/arch/armv7/omap/omap.c | 7 | ||||
-rw-r--r-- | sys/arch/armv7/omap/ommmc.c | 64 |
3 files changed, 56 insertions, 19 deletions
diff --git a/sys/arch/armv7/omap/files.omap b/sys/arch/armv7/omap/files.omap index a50b93e6509..712aedf40f4 100644 --- a/sys/arch/armv7/omap/files.omap +++ b/sys/arch/armv7/omap/files.omap @@ -1,4 +1,4 @@ -# $OpenBSD: files.omap,v 1.8 2016/05/02 08:15:55 patrick Exp $ +# $OpenBSD: files.omap,v 1.9 2016/06/18 05:59:26 jsg Exp $ define omap {} device omap: omap @@ -10,7 +10,7 @@ file arch/armv7/omap/omap4.c file arch/armv7/omap/am335x.c device ommmc: sdmmcbus -attach ommmc at omap +attach ommmc at fdt file arch/armv7/omap/ommmc.c ommmc device cpsw: ether, ifnet, mii, ifmedia diff --git a/sys/arch/armv7/omap/omap.c b/sys/arch/armv7/omap/omap.c index 45e4a0d4c2b..30690dba403 100644 --- a/sys/arch/armv7/omap/omap.c +++ b/sys/arch/armv7/omap/omap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: omap.c,v 1.10 2016/06/04 18:09:16 jsg Exp $ */ +/* $OpenBSD: omap.c,v 1.11 2016/06/18 05:59:26 jsg Exp $ */ /* * Copyright (c) 2005,2008 Dale Rahn <drahn@openbsd.com> * @@ -48,7 +48,6 @@ struct board_dev beagleboard_devs[] = { { "omgpio", 3 }, { "omgpio", 4 }, { "omgpio", 5 }, - { "ommmc", 0 }, /* HSMMC1 */ { "com", 2 }, /* UART3 */ { NULL, 0 } }; @@ -68,8 +67,6 @@ struct board_dev beaglebone_devs[] = { { "tiiic", 0 }, { "tiiic", 1 }, { "tiiic", 2 }, - { "ommmc", 0 }, /* HSMMC0 */ - { "ommmc", 1 }, /* HSMMC1 */ { "com", 0 }, /* UART0 */ { "cpsw", 0 }, { NULL, 0 } @@ -87,7 +84,6 @@ struct board_dev overo_devs[] = { { "omgpio", 3 }, { "omgpio", 4 }, { "omgpio", 5 }, - { "ommmc", 0 }, /* HSMMC1 */ { "com", 2 }, /* UART3 */ { NULL, 0 } }; @@ -102,7 +98,6 @@ struct board_dev pandaboard_devs[] = { { "omgpio", 3 }, { "omgpio", 4 }, { "omgpio", 5 }, - { "ommmc", 0 }, /* HSMMC1 */ { "com", 2 }, /* UART3 */ { "ehci", 0 }, { NULL, 0 } diff --git a/sys/arch/armv7/omap/ommmc.c b/sys/arch/armv7/omap/ommmc.c index 07c12e209cc..38162cf1f8d 100644 --- a/sys/arch/armv7/omap/ommmc.c +++ b/sys/arch/armv7/omap/ommmc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ommmc.c,v 1.22 2016/06/05 07:56:07 jsg Exp $ */ +/* $OpenBSD: ommmc.c,v 1.23 2016/06/18 05:59:26 jsg Exp $ */ /* * Copyright (c) 2009 Dale Rahn <drahn@openbsd.org> @@ -27,6 +27,7 @@ #include <sys/malloc.h> #include <sys/systm.h> #include <machine/bus.h> +#include <machine/fdt.h> #include <dev/sdmmc/sdmmcchip.h> #include <dev/sdmmc/sdmmcvar.h> @@ -34,6 +35,8 @@ #include <armv7/armv7/armv7var.h> #include <armv7/omap/prcmvar.h> +#include <dev/ofw/openfirm.h> + /* * NOTE: on OMAP4430/AM335x these registers skew by 0x100 * this is handled by mapping at base address + 0x100 @@ -179,7 +182,8 @@ #define SDHC_BUFFER_TIMEOUT hz #define SDHC_TRANSFER_TIMEOUT hz -void ommmc_attach(struct device *parent, struct device *self, void *args); +int ommmc_match(struct device *, void *, void *); +void ommmc_attach(struct device *, struct device *, void *); struct ommmc_softc { struct device sc_dev; @@ -274,28 +278,66 @@ struct cfdriver ommmc_cd = { }; struct cfattach ommmc_ca = { - sizeof(struct ommmc_softc), NULL, ommmc_attach + sizeof(struct ommmc_softc), ommmc_match, ommmc_attach }; +int +ommmc_match(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *faa = aux; + + return (OF_is_compatible(faa->fa_node, "ti,omap3-hsmmc") || + OF_is_compatible(faa->fa_node, "ti,omap4-hsmmc")); +} + void -ommmc_attach(struct device *parent, struct device *self, void *args) +ommmc_attach(struct device *parent, struct device *self, void *aux) { struct ommmc_softc *sc = (struct ommmc_softc *) self; - struct armv7_attach_args *aa = args; + struct fdt_attach_args *faa = aux; struct sdmmcbus_attach_args saa; uint32_t caps; + uint32_t addr, size, irq; + int len, unit; + char hwmods[128]; + + if (faa->fa_nreg != 2 || (faa->fa_nintr != 1 && faa->fa_nintr != 3)) + return; + + if (faa->fa_reg[1] <= 0x100) + return; + + if (OF_is_compatible(faa->fa_node, "ti,omap4-hsmmc")) { + addr = faa->fa_reg[0] + 0x100; + size = faa->fa_reg[1] - 0x100; + } else { + addr = faa->fa_reg[0]; + size = faa->fa_reg[1]; + } + + if (faa->fa_nintr == 1) + irq = faa->fa_intr[0]; + else + irq = faa->fa_intr[1]; + + unit = 0; + if ((len = OF_getprop(faa->fa_node, "ti,hwmods", hwmods, + sizeof(hwmods))) == 5) { + if (!strncmp(hwmods, "mmc", 3) && + (hwmods[3] > '0') && (hwmods[3] <= '9')) + unit = hwmods[3] - '1'; + } - sc->sc_iot = aa->aa_iot; - if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, - aa->aa_dev->mem[0].size, 0, &sc->sc_ioh)) + sc->sc_iot = faa->fa_iot; + if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh)) panic("%s: bus_space_map failed!", __func__); printf("\n"); /* Enable ICLKEN, FCLKEN? */ - prcm_enablemodule(PRCM_MMC0 + aa->aa_dev->unit); + prcm_enablemodule(PRCM_MMC0 + unit); - sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_SDMMC, + sc->sc_ih = arm_intr_establish(irq, IPL_SDMMC, ommmc_intr, sc, DEVNAME(sc)); if (sc->sc_ih == NULL) { printf("%s: cannot map interrupt\n", DEVNAME(sc)); @@ -406,7 +448,7 @@ ommmc_attach(struct device *parent, struct device *self, void *args) err: if (sc->sc_ih != NULL) arm_intr_disestablish(sc->sc_ih); - bus_space_unmap(sc->sc_iot, sc->sc_ioh, aa->aa_dev->mem[0].size); + bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); } |