summaryrefslogtreecommitdiff
path: root/sys/arch/armv7/omap
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2016-06-18 05:59:27 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2016-06-18 05:59:27 +0000
commitec3a50600dffe1c1ea70d3fd02c150b08f8b10d6 (patch)
treeaee17dc40dc94a04a344df7fea47eb56c6c41a6f /sys/arch/armv7/omap
parenta0fec8fc19a5b246013610bcb53e4a093a3f9372 (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.omap4
-rw-r--r--sys/arch/armv7/omap/omap.c7
-rw-r--r--sys/arch/armv7/omap/ommmc.c64
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);
}