diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-11-22 11:03:09 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-11-22 11:03:09 +0000 |
commit | 783bece3cebfe1a1b07f4a06ee9f29c23f756ea0 (patch) | |
tree | 8700d0421aeced0c85efc73805455ac99c662160 /sys/arch/armv7 | |
parent | 4389bab0c47e42cf6444056b310bcdc3c5f67114 (diff) |
Add support for the sun9i USB PHYs and attach to the sun9i EHCI controllers.
Doesn't work yet, but it is a step in the right direction.
Diffstat (limited to 'sys/arch/armv7')
-rw-r--r-- | sys/arch/armv7/sunxi/sxiehci.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/sys/arch/armv7/sunxi/sxiehci.c b/sys/arch/armv7/sunxi/sxiehci.c index 3bc90ed94e1..1b266853bf7 100644 --- a/sys/arch/armv7/sunxi/sxiehci.c +++ b/sys/arch/armv7/sunxi/sxiehci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sxiehci.c,v 1.9 2016/08/27 16:40:31 kettenis Exp $ */ +/* $OpenBSD: sxiehci.c,v 1.10 2016/11/22 11:03:08 kettenis Exp $ */ /* * Copyright (c) 2005 David Gwynne <dlg@openbsd.org> @@ -74,6 +74,7 @@ #define AHB_INCRX_ALIGN (1 << 8) #define AHB_INCR4 (1 << 9) #define AHB_INCR8 (1 << 10) +#define AHB_INCR16 (1 << 11) struct sxiehci_softc { struct ehci_softc sc; @@ -91,7 +92,8 @@ struct cfattach sxiehci_ca = { sxiehci_detach, sxiehci_activate }; -void sxiehci_attach_phy(struct sxiehci_softc *); +void sxiehci_attach_sun4i_phy(struct sxiehci_softc *); +void sxiehci_attach_sun9i_phy(struct sxiehci_softc *); int sxiehci_match(struct device *parent, void *match, void *aux) @@ -106,6 +108,8 @@ sxiehci_match(struct device *parent, void *match, void *aux) return 1; if (OF_is_compatible(faa->fa_node, "allwinner,sun8i-h3-ehci")) return 1; + if (OF_is_compatible(faa->fa_node, "allwinner,sun9i-a80-ehci")) + return 1; return 0; } @@ -136,7 +140,11 @@ sxiehci_attach(struct device *parent, struct device *self, void *aux) clock_enable_all(sc->sc_node); reset_deassert_all(sc->sc_node); - sxiehci_attach_phy(sc); + + if (OF_is_compatible(sc->sc_node, "allwinner,sun9i-a80-ehci")) + sxiehci_attach_sun9i_phy(sc); + else + sxiehci_attach_sun4i_phy(sc); /* Disable interrupts, so we don't get any spurious ones. */ sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); @@ -179,7 +187,7 @@ out: } void -sxiehci_attach_phy(struct sxiehci_softc *sc) +sxiehci_attach_sun4i_phy(struct sxiehci_softc *sc) { uint32_t vbus_supply; uint32_t phys[2]; @@ -226,6 +234,39 @@ sxiehci_attach_phy(struct sxiehci_softc *sc) regulator_enable(vbus_supply); } +void +sxiehci_attach_sun9i_phy(struct sxiehci_softc *sc) +{ + uint32_t phy_supply; + uint32_t phys[1]; + uint32_t val; + int node; + + if (OF_getpropintarray(sc->sc_node, "phys", phys, + sizeof(phys)) != sizeof(phys)) + return; + + node = OF_getnodebyphandle(phys[0]); + if (node == -1) + return; + + pinctrl_byname(node, "default"); + clock_enable(node, "phy"); + reset_deassert(node, "phy"); + + val = bus_space_read_4(sc->sc.iot, sc->sc.ioh, USB_PMU_IRQ_ENABLE); + val |= AHB_INCR16; + val |= AHB_INCR8; /* AHB INCR8 enable */ + val |= AHB_INCR4; /* AHB burst type INCR4 enable */ + val |= AHB_INCRX_ALIGN; /* AHB INCRX align enable */ + val |= ULPI_BYPASS; /* ULPI bypass enable */ + bus_space_write_4(sc->sc.iot, sc->sc.ioh, USB_PMU_IRQ_ENABLE, val); + + phy_supply = OF_getpropint(node, "phy-supply", 0); + if (phy_supply) + regulator_enable(phy_supply); +} + int sxiehci_detach(struct device *self, int flags) { |