summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2016-07-09 12:32:51 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2016-07-09 12:32:51 +0000
commit1b1cc307e2f8fac441b7e6366d1a334f59be459d (patch)
treeb3ec033418fd22c1a91551ae71eb510073b76b0c
parentb6f269b8c9cc451c29a728d0fd141fe1a55d2740 (diff)
Dynamically attach i.MX6 ehci(4) using the FDT.
ok jsg@
-rw-r--r--sys/arch/armv7/conf/GENERIC4
-rw-r--r--sys/arch/armv7/conf/RAMDISK4
-rw-r--r--sys/arch/armv7/imx/files.imx4
-rw-r--r--sys/arch/armv7/imx/imx.c10
-rw-r--r--sys/arch/armv7/imx/imxehci.c105
5 files changed, 77 insertions, 50 deletions
diff --git a/sys/arch/armv7/conf/GENERIC b/sys/arch/armv7/conf/GENERIC
index 9176c2018f2..1ddd24fba9d 100644
--- a/sys/arch/armv7/conf/GENERIC
+++ b/sys/arch/armv7/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.27 2016/06/28 04:41:37 jmatthew Exp $
+# $OpenBSD: GENERIC,v 1.28 2016/07/09 12:32:50 kettenis Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -52,7 +52,7 @@ iic* at imxiic?
imxesdhc* at fdt? # SDHC controller
sdmmc* at imxesdhc? # SD/MMC bus
ahci* at fdt? # AHCI/SATA
-ehci* at imx? # EHCI (shim)
+ehci* at fdt? # EHCI (shim)
usb* at ehci?
# OMAP3xxx/OMAP4xxx SoC
diff --git a/sys/arch/armv7/conf/RAMDISK b/sys/arch/armv7/conf/RAMDISK
index 53585e59604..ecf7a2d0529 100644
--- a/sys/arch/armv7/conf/RAMDISK
+++ b/sys/arch/armv7/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.24 2016/06/28 04:41:37 jmatthew Exp $
+# $OpenBSD: RAMDISK,v 1.25 2016/07/09 12:32:50 kettenis Exp $
machine armv7 arm
@@ -51,7 +51,7 @@ iic* at imxiic?
imxesdhc* at fdt? # SDHC controller
sdmmc* at imxesdhc? # SD/MMC bus
ahci* at fdt? # AHCI/SATA
-ehci* at imx? # EHCI (shim)
+ehci* at fdt? # EHCI (shim)
usb* at ehci?
# OMAP3xxx/OMAP4xxx SoC
diff --git a/sys/arch/armv7/imx/files.imx b/sys/arch/armv7/imx/files.imx
index b38221dce13..ac30e0f4bb8 100644
--- a/sys/arch/armv7/imx/files.imx
+++ b/sys/arch/armv7/imx/files.imx
@@ -1,4 +1,4 @@
-# $OpenBSD: files.imx,v 1.11 2016/06/13 23:43:58 kettenis Exp $
+# $OpenBSD: files.imx,v 1.12 2016/07/09 12:32:50 kettenis Exp $
define imx {}
device imx: imx
@@ -40,7 +40,7 @@ device fec: ether, ifnet, mii, ifmedia
attach fec at fdt
file arch/armv7/imx/if_fec.c fec
-attach ehci at imx with imxehci
+attach ehci at fdt with imxehci
file arch/armv7/imx/imxehci.c imxehci
device imxesdhc: sdmmcbus
diff --git a/sys/arch/armv7/imx/imx.c b/sys/arch/armv7/imx/imx.c
index 56b6743e8b7..59b57a6d2a6 100644
--- a/sys/arch/armv7/imx/imx.c
+++ b/sys/arch/armv7/imx/imx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imx.c,v 1.20 2016/06/13 23:43:58 kettenis Exp $ */
+/* $OpenBSD: imx.c,v 1.21 2016/07/09 12:32:50 kettenis Exp $ */
/*
* Copyright (c) 2005,2008 Dale Rahn <drahn@openbsd.com>
* Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
@@ -47,8 +47,6 @@ struct board_dev hummingboard_devs[] = {
{ "imxgpio", 4 },
{ "imxgpio", 5 },
{ "imxgpio", 6 },
- { "ehci", 0 },
- { "ehci", 1 },
{ NULL, 0 }
};
@@ -63,7 +61,6 @@ struct board_dev sabrelite_devs[] = {
{ "imxgpio", 4 },
{ "imxgpio", 5 },
{ "imxgpio", 6 },
- { "ehci", 0 },
{ NULL, 0 }
};
@@ -79,7 +76,6 @@ struct board_dev sabresd_devs[] = {
{ "imxgpio", 4 },
{ "imxgpio", 5 },
{ "imxgpio", 6 },
- { "ehci", 0 },
{ NULL, 0 }
};
@@ -94,7 +90,6 @@ struct board_dev udoo_devs[] = {
{ "imxgpio", 4 },
{ "imxgpio", 5 },
{ "imxgpio", 6 },
- { "ehci", 0 },
{ NULL, 0 }
};
@@ -109,7 +104,6 @@ struct board_dev utilite_devs[] = {
{ "imxgpio", 4 },
{ "imxgpio", 5 },
{ "imxgpio", 6 },
- { "ehci", 0 },
{ NULL, 0 }
};
@@ -124,7 +118,6 @@ struct board_dev novena_devs[] = {
{ "imxgpio", 4 },
{ "imxgpio", 5 },
{ "imxgpio", 6 },
- { "ehci", 0 },
{ NULL, 0 }
};
@@ -139,7 +132,6 @@ struct board_dev wandboard_devs[] = {
{ "imxgpio", 4 },
{ "imxgpio", 5 },
{ "imxgpio", 6 },
- { "ehci", 0 },
{ NULL, 0 }
};
diff --git a/sys/arch/armv7/imx/imxehci.c b/sys/arch/armv7/imx/imxehci.c
index b85a18121df..cc216cf4768 100644
--- a/sys/arch/armv7/imx/imxehci.c
+++ b/sys/arch/armv7/imx/imxehci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imxehci.c,v 1.9 2016/05/19 09:54:18 jsg Exp $ */
+/* $OpenBSD: imxehci.c,v 1.10 2016/07/09 12:32:50 kettenis Exp $ */
/*
* Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
*
@@ -24,6 +24,7 @@
#include <machine/intr.h>
#include <machine/bus.h>
+#include <machine/fdt.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -34,6 +35,8 @@
#include <armv7/imx/imxccmvar.h>
#include <armv7/imx/imxgpiovar.h>
+#include <dev/ofw/openfirm.h>
+
#include <dev/usb/ehcireg.h>
#include <dev/usb/ehcivar.h>
@@ -50,6 +53,8 @@
#define USBPHY_CTRL_SFTRST (1U << 31)
/* ehci */
+#define USB_EHCI_OFFSET 0x100
+
#define EHCI_USBMODE 0xa8
#define EHCI_USBMODE_HOST (3 << 0)
@@ -64,12 +69,6 @@
#define USBNC_USB_UH1_CTRL_OVER_CUR_POL (1 << 8)
#define USBNC_USB_UH1_CTRL_OVER_CUR_DIS (1 << 7)
-/* port specific addresses */
-#define USBOTG_EHCI_ADDR 0x02184100
-#define USBUH1_EHCI_ADDR 0x02184300
-#define USBUH2_EHCI_ADDR 0x02184500
-#define USBUH3_EHCI_ADDR 0x02184700
-
/* board specific */
#define EHCI_HUMMINGBOARD_USB_H1_PWR 0
#define EHCI_HUMMINGBOARD_USB_OTG_PWR (2*32+22)
@@ -77,6 +76,7 @@
#define EHCI_SABRESD_USB_PWR (0*32+29)
#define EHCI_UTILITE_USB_HUB_RST (6*32+8)
+int imxehci_match(struct device *, void *, void *);
void imxehci_attach(struct device *, struct device *, void *);
int imxehci_detach(struct device *, int);
@@ -89,43 +89,81 @@ struct imxehci_softc {
};
struct cfattach imxehci_ca = {
- sizeof (struct imxehci_softc), NULL, imxehci_attach,
- imxehci_detach, NULL
+ sizeof (struct imxehci_softc), imxehci_match, imxehci_attach,
+ imxehci_detach
};
+int
+imxehci_match(struct device *parent, void *match, void *aux)
+{
+ struct fdt_attach_args *faa = aux;
+
+ return OF_is_compatible(faa->fa_node, "fsl,imx27-usb");
+}
+
void
imxehci_attach(struct device *parent, struct device *self, void *aux)
{
- struct imxehci_softc *sc = (struct imxehci_softc *)self;
- struct armv7_attach_args *aa = aux;
- usbd_status r;
+ struct imxehci_softc *sc = (struct imxehci_softc *)self;
+ struct fdt_attach_args *faa = aux;
+ usbd_status r;
char *devname = sc->sc.sc_bus.bdev.dv_xname;
+ uint32_t phy[1], misc[2];
+ uint32_t phy_reg[2];
+ uint32_t misc_reg[2];
+ int node;
- sc->sc.iot = aa->aa_iot;
- sc->sc.sc_bus.dmatag = aa->aa_dmat;
- sc->sc.sc_size = aa->aa_dev->mem[0].size;
+ if (faa->fa_nreg < 2 || faa->fa_nintr < 3)
+ return;
+
+ if (OF_getpropintarray(faa->fa_node, "fsl,usbphy",
+ phy, sizeof(phy)) != sizeof(phy))
+ return;
+
+ if (OF_getpropintarray(faa->fa_node, "fsl,usbmisc",
+ misc, sizeof(misc)) != sizeof(misc))
+ return;
+
+ node = OF_getnodebyphandle(phy[0]);
+ if (node == 0)
+ return;
+
+ if (OF_getpropintarray(node, "reg", phy_reg,
+ sizeof(phy_reg)) != sizeof(phy_reg))
+ return;
+
+ node = OF_getnodebyphandle(misc[0]);
+ if (node == 0)
+ return;
+
+ if (OF_getpropintarray(node, "reg", misc_reg,
+ sizeof(misc_reg)) != sizeof(misc_reg))
+ return;
+
+ sc->sc.iot = faa->fa_iot;
+ sc->sc.sc_bus.dmatag = faa->fa_dmat;
+ sc->sc.sc_size = faa->fa_reg[1] - USB_EHCI_OFFSET;
/* Map I/O space */
- if (bus_space_map(sc->sc.iot, aa->aa_dev->mem[0].addr,
- aa->aa_dev->mem[0].size, 0, &sc->sc.ioh)) {
+ if (bus_space_map(sc->sc.iot, faa->fa_reg[0],
+ faa->fa_reg[1], 0, &sc->uh_ioh)) {
printf(": cannot map mem space\n");
goto out;
}
-
- if (bus_space_map(sc->sc.iot, aa->aa_dev->mem[1].addr,
- aa->aa_dev->mem[1].size, 0, &sc->uh_ioh)) {
+ if (bus_space_subregion(sc->sc.iot, sc->uh_ioh, USB_EHCI_OFFSET,
+ sc->sc.sc_size, &sc->sc.ioh)) {
printf(": cannot map mem space\n");
goto mem0;
}
- if (bus_space_map(sc->sc.iot, aa->aa_dev->mem[2].addr,
- aa->aa_dev->mem[2].size, 0, &sc->ph_ioh)) {
+ if (bus_space_map(sc->sc.iot, phy_reg[0],
+ phy_reg[1], 0, &sc->ph_ioh)) {
printf(": cannot map mem space\n");
goto mem1;
}
- if (bus_space_map(sc->sc.iot, aa->aa_dev->mem[3].addr,
- aa->aa_dev->mem[3].size, 0, &sc->nc_ioh)) {
+ if (bus_space_map(sc->sc.iot, misc_reg[0],
+ misc_reg[1], 0, &sc->nc_ioh)) {
printf(": cannot map mem space\n");
goto mem2;
}
@@ -135,10 +173,9 @@ imxehci_attach(struct device *parent, struct device *self, void *aux)
imxccm_enable_usboh3();
delay(1000);
- if (aa->aa_dev->mem[0].addr == USBUH1_EHCI_ADDR) {
+ if (misc[1] == 1) {
/* enable usb port power */
- switch (board_id)
- {
+ switch (board_id) {
case BOARD_ID_IMX6_CUBOXI:
case BOARD_ID_IMX6_HUMMINGBOARD:
imxgpio_set_bit(EHCI_HUMMINGBOARD_USB_H1_PWR);
@@ -175,10 +212,9 @@ imxehci_attach(struct device *parent, struct device *self, void *aux)
bus_space_write_4(sc->sc.iot, sc->nc_ioh, USBNC_USB_UH1_CTRL,
bus_space_read_4(sc->sc.iot, sc->nc_ioh, USBNC_USB_UH1_CTRL) |
(USBNC_USB_UH1_CTRL_OVER_CUR_POL | USBNC_USB_UH1_CTRL_OVER_CUR_DIS));
- } else if (aa->aa_dev->mem[0].addr == USBOTG_EHCI_ADDR) {
+ } else if (misc[1] == 0) {
/* enable usb port power */
- switch (board_id)
- {
+ switch (board_id) {
case BOARD_ID_IMX6_CUBOXI:
case BOARD_ID_IMX6_HUMMINGBOARD:
imxgpio_set_dir(EHCI_HUMMINGBOARD_USB_OTG_PWR, IMXGPIO_DIR_OUT);
@@ -246,7 +282,7 @@ imxehci_attach(struct device *parent, struct device *self, void *aux)
EOWRITE4(&sc->sc, EHCI_PORTSC(1),
EOREAD4(&sc->sc, EHCI_PORTSC(1)) & ~EHCI_PS_PTS_UTMI_MASK);
- sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_USB,
+ sc->sc_ih = arm_intr_establish(faa->fa_intr[1], IPL_USB,
ehci_intr, &sc->sc, devname);
if (sc->sc_ih == NULL) {
printf(": unable to establish interrupt\n");
@@ -268,13 +304,12 @@ intr:
arm_intr_disestablish(sc->sc_ih);
sc->sc_ih = NULL;
mem3:
- bus_space_unmap(sc->sc.iot, sc->nc_ioh, aa->aa_dev->mem[3].addr);
+ bus_space_unmap(sc->sc.iot, sc->nc_ioh, misc_reg[1]);
mem2:
- bus_space_unmap(sc->sc.iot, sc->ph_ioh, aa->aa_dev->mem[2].addr);
+ bus_space_unmap(sc->sc.iot, sc->ph_ioh, phy_reg[1]);
mem1:
- bus_space_unmap(sc->sc.iot, sc->uh_ioh, aa->aa_dev->mem[1].addr);
mem0:
- bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
+ bus_space_unmap(sc->sc.iot, sc->sc.ioh, faa->fa_reg[1]);
sc->sc.sc_size = 0;
out:
return;