Module Name: src Committed By: reinoud Date: Tue Sep 9 21:26:47 UTC 2014
Modified Files: src/sys/arch/arm/samsung: exynos_usb.c Log Message: Implement the XuhostPWREN/XuhostOVERCUR register selection Update the usb2 isolation. It ought to work for Exynos5 too. Only issue now is ohci not working To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/samsung/exynos_usb.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/samsung/exynos_usb.c diff -u src/sys/arch/arm/samsung/exynos_usb.c:1.8 src/sys/arch/arm/samsung/exynos_usb.c:1.9 --- src/sys/arch/arm/samsung/exynos_usb.c:1.8 Thu Sep 4 13:18:28 2014 +++ src/sys/arch/arm/samsung/exynos_usb.c Tue Sep 9 21:26:47 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: exynos_usb.c,v 1.8 2014/09/04 13:18:28 reinoud Exp $ */ +/* $NetBSD: exynos_usb.c,v 1.9 2014/09/09 21:26:47 reinoud Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: exynos_usb.c,v 1.8 2014/09/04 13:18:28 reinoud Exp $"); +__KERNEL_RCSID(1, "$NetBSD: exynos_usb.c,v 1.9 2014/09/09 21:26:47 reinoud Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -78,6 +78,7 @@ struct exynos_usb_softc { bus_space_handle_t sc_ohci_bsh; bus_space_handle_t sc_usb2phy_bsh; + bus_space_handle_t sc_sysregs_bsh; bus_space_handle_t sc_pmuregs_bsh; device_t sc_ohci_dev; @@ -92,11 +93,22 @@ struct exynos_usb_attach_args { }; -static struct exynos_gpio_pinset uhost_pwr_pinset = { +#ifdef EXYNOS4 +static struct exynos_gpio_pinset e4_uhost_pwr_pinset = { + .pinset_group = "ETC6", + .pinset_func = 0, + .pinset_mask = __BIT(6) | __BIT(7), +}; +#endif + + +#ifdef EXYNOS5 +static struct exynos_gpio_pinset e5_uhost_pwr_pinset = { .pinset_group = "ETC6", .pinset_func = 0, .pinset_mask = __BIT(5) | __BIT(6), }; +#endif static int exynos_usb_intr(void *arg); @@ -129,7 +141,8 @@ exynos_usb_attach(device_t parent, devic struct exyo_locators *loc = &exyoaa->exyo_loc; struct exynos_gpio_pindata XuhostOVERCUR; struct exynos_gpio_pindata XuhostPWREN; - bus_size_t ehci_offset, ohci_offset, usb2phy_offset, pmu_offset; + bus_size_t ehci_offset, ohci_offset, usb2phy_offset; + bus_size_t pmu_offset, sysreg_offset; /* no locators expected */ KASSERT(loc->loc_port == EXYOCF_PORT_DEFAULT); @@ -149,6 +162,7 @@ exynos_usb_attach(device_t parent, devic ehci_offset = EXYNOS4_USB2_HOST_EHCI_OFFSET; ohci_offset = EXYNOS4_USB2_HOST_OHCI_OFFSET; usb2phy_offset = EXYNOS4_USB2_HOST_PHYCTRL_OFFSET; + sysreg_offset = EXYNOS4_SYSREG_OFFSET; pmu_offset = EXYNOS4_PMU_OFFSET; } #endif @@ -157,6 +171,7 @@ exynos_usb_attach(device_t parent, devic ehci_offset = EXYNOS5_USB2_HOST_EHCI_OFFSET; ohci_offset = EXYNOS5_USB2_HOST_OHCI_OFFSET; usb2phy_offset = EXYNOS5_USB2_HOST_PHYCTRL_OFFSET; + sysreg_offset = EXYNOS5_SYSREG_OFFSET; pmu_offset = EXYNOS5_PMU_OFFSET; } #endif @@ -173,22 +188,39 @@ exynos_usb_attach(device_t parent, devic &sc->sc_usb2phy_bsh); bus_space_subregion(sc->sc_bst, exyoaa->exyo_core_bsh, + sysreg_offset, EXYNOS_BLOCK_SIZE, + &sc->sc_sysregs_bsh); + bus_space_subregion(sc->sc_bst, exyoaa->exyo_core_bsh, pmu_offset, EXYNOS_BLOCK_SIZE, &sc->sc_pmuregs_bsh); aprint_naive("\n"); aprint_normal("\n"); - /* power up USB subsystem XXX PWREN not working yet */ - exynos_gpio_pinset_acquire(&uhost_pwr_pinset); - exynos_gpio_pinset_to_pindata(&uhost_pwr_pinset, 5, &XuhostPWREN); - exynos_gpio_pinset_to_pindata(&uhost_pwr_pinset, 6, &XuhostOVERCUR); + /* power up USB subsystem */ +#ifdef EXYNOS4 + if (IS_EXYNOS4_P()) { + exynos_gpio_pinset_acquire(&e4_uhost_pwr_pinset); + exynos_gpio_pinset_to_pindata(&e4_uhost_pwr_pinset, 6, &XuhostPWREN); + exynos_gpio_pinset_to_pindata(&e4_uhost_pwr_pinset, 7, &XuhostOVERCUR); + } +#endif +#ifdef EXYNOS5 + if (IS_EXYNOS5_P()) { + exynos_gpio_pinset_acquire(&e5_uhost_pwr_pinset); + exynos_gpio_pinset_to_pindata(&e5_uhost_pwr_pinset, 5, &XuhostPWREN); + exynos_gpio_pinset_to_pindata(&e5_uhost_pwr_pinset, 6, &XuhostOVERCUR); + } +#endif /* enable power and set Xuhost OVERCUR to inactive by pulling it up */ exynos_gpio_pindata_ctl(&XuhostPWREN, GPIO_PIN_PULLUP); exynos_gpio_pindata_ctl(&XuhostOVERCUR, GPIO_PIN_PULLUP); DELAY(80000); + /* init USB phys */ + exynos_usb_phy_init(sc); + /* * Disable interrupts */ @@ -203,9 +235,6 @@ exynos_usb_attach(device_t parent, devic caplength + EHCI_USBINTR, 0); #endif - /* init USB phys */ - exynos_usb_phy_init(sc); - /* claim shared interrupt for OHCI/EHCI */ sc->sc_intrh = intr_establish(sc->sc_irq, IPL_USB, IST_LEVEL, exynos_usb_intr, sc); @@ -375,25 +404,37 @@ exynos_ehci_attach(device_t parent, devi * USB Phy init */ +/* XXX 5422 not handled since its unknown how it handles this XXX*/ static void exynos_usb2_set_isolation(struct exynos_usb_softc *sc, bool on) { - int val; + uint32_t en_mask, regval; + bus_addr_t reg; + + /* enable PHY */ + reg = EXYNOS_PMU_USB_PHY_CTRL; + + if (IS_EXYNOS5_P() || IS_EXYNOS4410_P()) { + /* set usbhost mode */ + regval = on ? 0 : USB20_PHY_HOST_LINK_EN; + bus_space_write_4(sc->sc_bst, sc->sc_sysregs_bsh, + EXYNOS5_SYSREG_USB20_PHY_TYPE, regval); + reg = EXYNOS_PMU_USBHOST_PHY_CTRL; + } + + /* do enable PHY */ + en_mask = PMU_PHY_ENABLE; + regval = bus_space_read_4(sc->sc_bst, sc->sc_pmuregs_bsh, reg); + regval = on ? regval & ~en_mask : regval | en_mask; + + bus_space_write_4(sc->sc_bst, sc->sc_pmuregs_bsh, + reg, regval); - /* XXX 5422 not handled XXX*/ - val = on ? PMU_PHY_DISABLE : PMU_PHY_ENABLE; if (IS_EXYNOS4X12_P()) { bus_space_write_4(sc->sc_bst, sc->sc_pmuregs_bsh, - EXYNOS_PMU_USB_PHY_CTRL, val); + EXYNOS_PMU_USB_HSIC_1_PHY_CTRL, regval); bus_space_write_4(sc->sc_bst, sc->sc_pmuregs_bsh, - EXYNOS_PMU_USB_HSIC_1_PHY_CTRL, val); - bus_space_write_4(sc->sc_bst, sc->sc_pmuregs_bsh, - EXYNOS_PMU_USB_HSIC_2_PHY_CTRL, val); - } else { - bus_space_write_4(sc->sc_bst, sc->sc_pmuregs_bsh, - EXYNOS_PMU_USBDEV_PHY_CTRL, val); - bus_space_write_4(sc->sc_bst, sc->sc_pmuregs_bsh, - EXYNOS_PMU_USBHOST_PHY_CTRL, val); + EXYNOS_PMU_USB_HSIC_2_PHY_CTRL, regval); } } @@ -404,9 +445,6 @@ exynos4_usb2phy_enable(struct exynos_usb { uint32_t phypwr, rstcon, clkreg; - /* disable phy isolation */ - exynos_usb2_set_isolation(sc, false); - /* write clock value */ clkreg = FSEL_CLKSEL_24M; bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh, @@ -468,9 +506,6 @@ exynos5410_usb2phy_enable(struct exynos_ { uint32_t phyhost, phyotg, phyhsic, ehcictrl, ohcictrl; - /* disable phy isolation */ - exynos_usb2_set_isolation(sc, false); - /* host configuration: */ phyhost = bus_space_read_4(sc->sc_bst, sc->sc_usb2phy_bsh, USB_PHY_HOST_CTRL0); @@ -555,15 +590,13 @@ exynos5410_usb2phy_enable(struct exynos_ ohcictrl |= HOST_OHCICTRL_SUSPLGCY; bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh, USB_PHY_HOST_OHCICTRL, ohcictrl); + DELAY(10000); } static void exynos5422_usb2phy_enable(struct exynos_usb_softc *sc) { - /* disable phy isolation */ - exynos_usb2_set_isolation(sc, false); - aprint_error_dev(sc->sc_self, "%s not implemented\n", __func__); } #endif @@ -572,6 +605,9 @@ exynos5422_usb2phy_enable(struct exynos_ static void exynos_usb_phy_init(struct exynos_usb_softc *sc) { + /* disable phy isolation */ + exynos_usb2_set_isolation(sc, false); + #ifdef EXYNOS4 if (IS_EXYNOS4_P()) exynos4_usb2phy_enable(sc);