From 6ac2d6bf1cd17226c99d23c231de2cd687755daf Mon Sep 17 00:00:00 2001 From: kettenis Date: Sat, 9 Jul 2016 12:32:50 +0000 Subject: [PATCH] Dynamically attach i.MX6 ehci(4) using the FDT. ok jsg@ --- sys/arch/armv7/conf/GENERIC | 4 +- sys/arch/armv7/conf/RAMDISK | 4 +- sys/arch/armv7/imx/files.imx | 4 +- sys/arch/armv7/imx/imx.c | 10 +--- sys/arch/armv7/imx/imxehci.c | 105 +++++++++++++++++++++++------------ 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 * Copyright (c) 2012-2013 Patrick Wildt @@ -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 * @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -34,6 +35,8 @@ #include #include +#include + #include #include @@ -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; -- 2.20.1