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);

Reply via email to