Module Name:    src
Committed By:   reinoud
Date:           Thu Sep  4 13:18:28 UTC 2014

Modified Files:
        src/sys/arch/arm/samsung: exynos_usb.c

Log Message:
Fix usb attachment and add an usb2 phy enable for exynos5410.

There is still an issue with ohci


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 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.7 src/sys/arch/arm/samsung/exynos_usb.c:1.8
--- src/sys/arch/arm/samsung/exynos_usb.c:1.7	Sat Jun 21 09:11:04 2014
+++ src/sys/arch/arm/samsung/exynos_usb.c	Thu Sep  4 13:18:28 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: exynos_usb.c,v 1.7 2014/06/21 09:11:04 skrll Exp $	*/
+/*	$NetBSD: exynos_usb.c,v 1.8 2014/09/04 13:18:28 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.7 2014/06/21 09:11:04 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exynos_usb.c,v 1.8 2014/09/04 13:18:28 reinoud Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -67,11 +67,6 @@ __KERNEL_RCSID(1, "$NetBSD: exynos_usb.c
 #include <arm/samsung/exynos_var.h>
 #include <arm/samsung/exynos_io.h>
 
-#define EHCI_OFFSET	(0)
-#define OHCI_OFFSET	(1*EXYNOS_BLOCK_SIZE)
-#define DEVLINK_OFFSET	(2*EXYNOS_BLOCK_SIZE)	/* Exynos5 */
-#define USB2PHY_OFFSET	(3*EXYNOS_BLOCK_SIZE)
-
 struct exynos_usb_softc {
 	device_t	 sc_self;
 
@@ -96,6 +91,7 @@ struct exynos_usb_attach_args {
 	const char *name;
 };
 
+
 static struct exynos_gpio_pinset uhost_pwr_pinset = {
 	.pinset_group = "ETC6",
 	.pinset_func  = 0,
@@ -133,7 +129,7 @@ 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 pmu_offset;
+	bus_size_t ehci_offset, ohci_offset, usb2phy_offset, pmu_offset;
 
 	/* no locators expected */
 	KASSERT(loc->loc_port == EXYOCF_PORT_DEFAULT);
@@ -148,26 +144,34 @@ exynos_usb_attach(device_t parent, devic
 	sc->sc_dmat = exyoaa->exyo_dmat;
 //	sc->sc_dmat = exyoaa->exyo_coherent_dmat;
 
+#ifdef EXYNOS4
+	if (IS_EXYNOS4_P()) {
+		ehci_offset    = EXYNOS4_USB2_HOST_EHCI_OFFSET;
+		ohci_offset    = EXYNOS4_USB2_HOST_OHCI_OFFSET;
+		usb2phy_offset = EXYNOS4_USB2_HOST_PHYCTRL_OFFSET;
+		pmu_offset     = EXYNOS4_PMU_OFFSET;
+	}
+#endif
+#ifdef EXYNOS5
+	if (IS_EXYNOS5_P()) {
+		ehci_offset    = EXYNOS5_USB2_HOST_EHCI_OFFSET;
+		ohci_offset    = EXYNOS5_USB2_HOST_OHCI_OFFSET;
+		usb2phy_offset = EXYNOS5_USB2_HOST_PHYCTRL_OFFSET;
+		pmu_offset     = EXYNOS5_PMU_OFFSET;
+	}
+#endif
+	KASSERT(ehci_offset);
+
 	bus_space_subregion(sc->sc_bst, exyoaa->exyo_core_bsh,
-		loc->loc_offset + EHCI_OFFSET, EXYNOS_BLOCK_SIZE,
+		ehci_offset, EXYNOS_BLOCK_SIZE,
 		&sc->sc_ehci_bsh);
 	bus_space_subregion(sc->sc_bst, exyoaa->exyo_core_bsh,
-		loc->loc_offset + OHCI_OFFSET, EXYNOS_BLOCK_SIZE,
+		ohci_offset, EXYNOS_BLOCK_SIZE,
 		&sc->sc_ohci_bsh);
 	bus_space_subregion(sc->sc_bst, exyoaa->exyo_core_bsh,
-		loc->loc_offset + USB2PHY_OFFSET, EXYNOS_BLOCK_SIZE,
+		usb2phy_offset, EXYNOS_BLOCK_SIZE,
 		&sc->sc_usb2phy_bsh);
 
-#ifdef EXYNOS4
-	if (IS_EXYNOS4_P())
-		pmu_offset = EXYNOS4_PMU_OFFSET;
-#endif
-#ifdef EXYNOS5
-	if (IS_EXYNOS5_P())
-		pmu_offset = EXYNOS5_ALIVE_OFFSET;
-#endif
-
-	KASSERT(pmu_offset);
 	bus_space_subregion(sc->sc_bst, exyoaa->exyo_core_bsh,
 		pmu_offset, EXYNOS_BLOCK_SIZE,
 		&sc->sc_pmuregs_bsh);
@@ -376,6 +380,7 @@ exynos_usb2_set_isolation(struct exynos_
 {
 	int val;
 
+	/* 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,
@@ -403,7 +408,7 @@ exynos4_usb2phy_enable(struct exynos_usb
 	exynos_usb2_set_isolation(sc, false);
 
 	/* write clock value */
-	clkreg = 5;	/* 24 Mhz */
+	clkreg = FSEL_CLKSEL_24M;
 	bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
 		USB_PHYCLK, clkreg);
 
@@ -459,7 +464,102 @@ exynos4_usb2phy_enable(struct exynos_usb
 
 #ifdef EXYNOS5
 static void
-exynos5_usb2phy_enable(struct exynos_usb_softc *sc)
+exynos5410_usb2phy_enable(struct exynos_usb_softc *sc)
+{
+	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);
+
+	/* host phy reference clock; assumption its 24 MHz now */
+	phyhost &= ~HOST_CTRL0_FSEL_MASK;
+	phyhost |= __SHIFTIN(HOST_CTRL0_FSEL_MASK, FSEL_CLKSEL_24M);
+
+	/* enable normal mode of operation */
+	phyhost &= ~(HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP);
+
+	/* host phy reset */
+	phyhost &= ~(HOST_CTRL0_PHY_SWRST | HOST_CTRL0_SIDDQ);
+			
+	/* host link reset */
+	phyhost |= HOST_CTRL0_LINK_SWRST | HOST_CTRL0_UTMI_SWRST |
+		HOST_CTRL0_COMMONON_N;
+
+	/* do the reset */
+	bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+		USB_PHY_HOST_CTRL0, phyhost);
+	DELAY(10000);
+	phyhost &= ~(HOST_CTRL0_LINK_SWRST | HOST_CTRL0_UTMI_SWRST);
+	bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+		USB_PHY_HOST_CTRL0, phyhost);
+
+	/* otg configuration: */
+	phyotg = bus_space_read_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+		USB_PHY_OTG_SYS);
+
+	/* otg phy refrence clock: assumption its 24 Mhz now */
+	phyotg &= ~OTG_SYS_FSEL_MASK;
+	phyotg |= __SHIFTIN(OTG_SYS_FSEL_MASK, FSEL_CLKSEL_24M);
+
+	/* enable normal mode of operation */
+	phyotg &= ~(OTG_SYS_FORCESUSPEND | OTG_SYS_FORCESLEEP |
+		OTG_SYS_SIDDQ_UOTG | OTG_SYS_REFCLKSEL_MASK |
+		OTG_SYS_COMMON_ON);
+
+	/* OTG phy and link reset */
+	phyotg |= OTG_SYS_PHY0_SWRST | OTG_SYS_PHYLINK_SWRST |
+		OTG_SYS_OTGDISABLE | OTG_SYS_REFCLKSEL_MASK;
+
+	/* do the reset */
+	bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+		USB_PHY_OTG_SYS, phyotg);
+	DELAY(10000);
+	phyotg &= ~(OTG_SYS_PHY0_SWRST | OTG_SYS_LINK_SWRST_UOTG |
+		OTG_SYS_PHYLINK_SWRST);
+	bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+		USB_PHY_OTG_SYS, phyotg);
+
+	/* HSIC phy configuration: */
+	phyhsic = REFCLKDIV_12 | REFCLKSEL_HSIC_DEFAULT |
+		HSIC_CTRL_PHY_SWRST;
+
+	bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+		USB_PHY_HSIC_CTRL1, phyhsic);
+	bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+		USB_PHY_HSIC_CTRL2, phyhsic);
+	DELAY(10000);
+	phyhsic &= ~HSIC_CTRL_PHY_SWRST;
+	bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+		USB_PHY_HSIC_CTRL1, phyhsic);
+	bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+		USB_PHY_HSIC_CTRL2, phyhsic);
+
+	DELAY(80000);
+
+	/* enable EHCI DMA burst: */
+	ehcictrl = bus_space_read_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+		USB_PHY_HOST_EHCICTRL);
+	ehcictrl |= HOST_EHCICTRL_ENA_INCRXALIGN |
+		HOST_EHCICTRL_ENA_INCR4 | HOST_EHCICTRL_ENA_INCR8 |
+		HOST_EHCICTRL_ENA_INCR16;
+	bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+		USB_PHY_HOST_EHCICTRL, ehcictrl);
+
+	/* suspend OHCI legacy (?) */
+	ohcictrl = bus_space_read_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+		USB_PHY_HOST_OHCICTRL);
+	ohcictrl |= HOST_OHCICTRL_SUSPLGCY;
+	bus_space_write_4(sc->sc_bst, sc->sc_usb2phy_bsh,
+		USB_PHY_HOST_OHCICTRL, ohcictrl);
+}
+
+
+static void
+exynos5422_usb2phy_enable(struct exynos_usb_softc *sc)
 {
 	/* disable phy isolation */
 	exynos_usb2_set_isolation(sc, false);
@@ -477,9 +577,15 @@ exynos_usb_phy_init(struct exynos_usb_so
 		exynos4_usb2phy_enable(sc);
 #endif
 #ifdef EXYNOS5
-	if (IS_EXYNOS5_P())
-		exynos5_usb2phy_enable(sc);
-	/* TBD: USB3 phy init */
+	if (IS_EXYNOS5410_P()) {
+		exynos5410_usb2phy_enable(sc);
+		/* TBD: USB3 phy init */
+	}
+	if (IS_EXYNOS5422_P()) {
+		exynos5422_usb2phy_enable(sc);
+		/* TBD: USB3 phy init */
+	}
+	/* XXX exynos5422 */
 #endif
 }
 

Reply via email to