Module Name:    src
Committed By:   jmcneill
Date:           Tue Jul  3 16:09:04 UTC 2018

Modified Files:
        src/sys/arch/arm/samsung: exynos_ehci.c exynos_ohci.c exynos_usbphy.c
            files.exynos
Added Files:
        src/sys/arch/arm/samsung: exynos_usbdrdphy.c
Removed Files:
        src/sys/arch/arm/samsung: exynos_usb3.c

Log Message:
Add support for Samsung Exynos USB.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/samsung/exynos_ehci.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/samsung/exynos_ohci.c
cvs rdiff -u -r1.1 -r0 src/sys/arch/arm/samsung/exynos_usb3.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/samsung/exynos_usbdrdphy.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/samsung/exynos_usbphy.c
cvs rdiff -u -r1.27 -r1.28 src/sys/arch/arm/samsung/files.exynos

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_ehci.c
diff -u src/sys/arch/arm/samsung/exynos_ehci.c:1.3 src/sys/arch/arm/samsung/exynos_ehci.c:1.4
--- src/sys/arch/arm/samsung/exynos_ehci.c:1.3	Mon Apr  9 16:21:09 2018
+++ src/sys/arch/arm/samsung/exynos_ehci.c	Tue Jul  3 16:09:04 2018
@@ -1,12 +1,9 @@
-/*	$NetBSD: exynos_ehci.c,v 1.3 2018/04/09 16:21:09 jakllsch Exp $	*/
+/* $NetBSD: exynos_ehci.c,v 1.4 2018/07/03 16:09:04 jmcneill Exp $ */
 
 /*-
- * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2015-2018 Jared McNeill <jmcne...@invisible.ca>
  * All rights reserved.
  *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Reinoud Zandijk.
- *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -16,107 +13,132 @@
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
-#include "locators.h"
-#include "ohci.h"
-#include "ehci.h"
-
 #include <sys/cdefs.h>
-
-__KERNEL_RCSID(1, "$NetBSD: exynos_ehci.c,v 1.3 2018/04/09 16:21:09 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exynos_ehci.c,v 1.4 2018/07/03 16:09:04 jmcneill Exp $");
 
 #include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/intr.h>
 #include <sys/bus.h>
 #include <sys/device.h>
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/kmem.h>
-#include <sys/gpio.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdivar.h>
 #include <dev/usb/usb_mem.h>
-
 #include <dev/usb/ehcireg.h>
 #include <dev/usb/ehcivar.h>
 
-#include <arm/samsung/exynos_reg.h>
-#include <arm/samsung/exynos_var.h>
-
 #include <dev/fdt/fdtvar.h>
 
 static int	exynos_ehci_match(device_t, cfdata_t, void *);
 static void	exynos_ehci_attach(device_t, device_t, void *);
 
-CFATTACH_DECL_NEW(exynos_ehci, sizeof(struct ehci_softc),
-    exynos_ehci_match, exynos_ehci_attach, NULL, NULL);
-
+CFATTACH_DECL2_NEW(exynos_ehci, sizeof(struct ehci_softc),
+	exynos_ehci_match, exynos_ehci_attach, NULL,
+	ehci_activate, NULL, ehci_childdet);
 
 static int
 exynos_ehci_match(device_t parent, cfdata_t cf, void *aux)
 {
-	const char * const compatible[] = { "samsung,exynos5-ehci",
-					    NULL };
+	const char * const compatible[] = {
+		"samsung,exynos4210-ehci",
+		NULL
+	};
 	struct fdt_attach_args * const faa = aux;
+
 	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
-
 static void
 exynos_ehci_attach(device_t parent, device_t self, void *aux)
 {
-	struct ehci_softc *sc = device_private(self);
+	struct ehci_softc * const sc = device_private(self);
 	struct fdt_attach_args * const faa = aux;
+	const int phandle = faa->faa_phandle;
+	struct fdtbus_phy *phy;
+	struct clk *clk;
+	char intrstr[128];
 	bus_addr_t addr;
 	bus_size_t size;
-	int error;
+	int error, child;
+	void *ih;
 
-	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
 		aprint_error(": couldn't get registers\n");
 		return;
 	}
 
+	/* Enable clocks */
+	clk = fdtbus_clock_get(phandle, "usbhost");
+	if (clk == NULL || clk_enable(clk) != 0) {
+		aprint_error(": couldn't enable clock\n");
+		return;
+	}
+
+	/* Enable phys for each port */
+	for (child = OF_child(phandle); child; child = OF_peer(child)) {
+		phy = fdtbus_phy_get_index(child, 0);
+		if (phy && fdtbus_phy_enable(phy, true) != 0)
+			aprint_error(": couldn't enable phy for %s\n",
+			    fdtbus_get_string(child, "name"));
+	}
+
 	sc->sc_dev = self;
-	sc->iot = faa->faa_bst;
-	sc->sc_size = size;
-	sc->sc_bus.ub_dmatag = faa->faa_dmat;
 	sc->sc_bus.ub_hcpriv = sc;
+	sc->sc_bus.ub_dmatag = faa->faa_dmat;
 	sc->sc_bus.ub_revision = USBREV_2_0;
-	sc->sc_ncomp = 0;
-
-	error = bus_space_map(sc->iot, addr, size, 0, &sc->ioh);
-	if (error) {
-		aprint_error(": couldn't map %#llx: %d",
-			     (uint64_t)addr, error);
+	if (of_hasprop(phandle, "has-transaction-translator"))
+		sc->sc_flags |= EHCIF_ETTF;
+	else
+		sc->sc_ncomp = 1;
+	sc->sc_size = size;
+	sc->iot = faa->faa_bst;
+	if (bus_space_map(sc->iot, addr, size, 0, &sc->ioh) != 0) {
+		aprint_error(": couldn't map registers\n");
 		return;
 	}
 
+	aprint_naive("\n");
+	aprint_normal(": Exynos EHCI\n");
+
+	/* Disable interrupts */
+	sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
+	EOWRITE4(sc, EHCI_USBINTR, 0);
+
+	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
+		return;
+	}
 
-	aprint_naive(": EHCI USB controller\n");
-	aprint_normal(": EHCI NOT IMPLEMENTED\n");
+	ih = fdtbus_intr_establish(phandle, 0, IPL_USB, FDT_INTR_MPSAFE,
+	    ehci_intr, sc);
+	if (ih == NULL) {
+		aprint_error_dev(self, "couldn't establish interrupt on %s\n",
+		    intrstr);
+		return;
+	}
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
-	/* attach */
 	error = ehci_init(sc);
 	if (error) {
 		aprint_error_dev(self, "init failed, error = %d\n", error);
-		/* disable : TBD */
 		return;
 	}
+
 	sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
 }

Index: src/sys/arch/arm/samsung/exynos_ohci.c
diff -u src/sys/arch/arm/samsung/exynos_ohci.c:1.2 src/sys/arch/arm/samsung/exynos_ohci.c:1.3
--- src/sys/arch/arm/samsung/exynos_ohci.c:1.2	Sat Apr 23 10:15:28 2016
+++ src/sys/arch/arm/samsung/exynos_ohci.c	Tue Jul  3 16:09:04 2018
@@ -1,12 +1,9 @@
-/*	$NetBSD: exynos_ohci.c,v 1.2 2016/04/23 10:15:28 skrll Exp $	*/
+/* $NetBSD: exynos_ohci.c,v 1.3 2018/07/03 16:09:04 jmcneill Exp $ */
 
 /*-
- * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2015-2018 Jared McNeill <jmcne...@invisible.ca>
  * All rights reserved.
  *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Reinoud Zandijk.
- *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -16,105 +13,128 @@
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
-#include "locators.h"
-#include "ohci.h"
-#include "ehci.h"
-
 #include <sys/cdefs.h>
-
-__KERNEL_RCSID(1, "$NetBSD: exynos_ohci.c,v 1.2 2016/04/23 10:15:28 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exynos_ohci.c,v 1.3 2018/07/03 16:09:04 jmcneill Exp $");
 
 #include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/intr.h>
 #include <sys/bus.h>
 #include <sys/device.h>
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/kmem.h>
-#include <sys/gpio.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdivar.h>
 #include <dev/usb/usb_mem.h>
-
 #include <dev/usb/ohcireg.h>
 #include <dev/usb/ohcivar.h>
 
-#include <arm/samsung/exynos_reg.h>
-#include <arm/samsung/exynos_var.h>
-
 #include <dev/fdt/fdtvar.h>
 
 static int	exynos_ohci_match(device_t, cfdata_t, void *);
 static void	exynos_ohci_attach(device_t, device_t, void *);
 
-CFATTACH_DECL_NEW(exynos_ohci, sizeof(struct ohci_softc),
-    exynos_ohci_match, exynos_ohci_attach, NULL, NULL);
-
+CFATTACH_DECL2_NEW(exynos_ohci, sizeof(struct ohci_softc),
+	exynos_ohci_match, exynos_ohci_attach, NULL,
+	ohci_activate, NULL, ohci_childdet);
 
 static int
 exynos_ohci_match(device_t parent, cfdata_t cf, void *aux)
 {
-	const char * const compatible[] = { "samsung,exynos5-ohci",
-					    NULL };
+	const char * const compatible[] = {
+		"samsung,exynos4210-ohci",
+		NULL
+	};
 	struct fdt_attach_args * const faa = aux;
+
 	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
-
 static void
 exynos_ohci_attach(device_t parent, device_t self, void *aux)
 {
-	struct ohci_softc *sc = device_private(self);
+	struct ohci_softc * const sc = device_private(self);
 	struct fdt_attach_args * const faa = aux;
+	const int phandle = faa->faa_phandle;
+	struct fdtbus_phy *phy;
+	struct clk *clk;
+	char intrstr[128];
 	bus_addr_t addr;
 	bus_size_t size;
-	int error;
+	int error, child;
+	void *ih;
 
-	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
 		aprint_error(": couldn't get registers\n");
 		return;
 	}
 
+	/* Enable clocks */
+	clk = fdtbus_clock_get(phandle, "usbhost");
+	if (clk == NULL || clk_enable(clk) != 0) {
+		aprint_error(": couldn't enable clock\n");
+		return;
+	}
+
+	/* Enable phys for each port */
+	for (child = OF_child(phandle); child; child = OF_peer(child)) {
+		phy = fdtbus_phy_get_index(child, 0);
+		if (phy && fdtbus_phy_enable(phy, true) != 0)
+			aprint_error(": couldn't enable phy for %s\n",
+			    fdtbus_get_string(child, "name"));
+	}
+
 	sc->sc_dev = self;
-	sc->iot = faa->faa_bst;
-	sc->sc_size = size;
-	sc->sc_bus.ub_dmatag = faa->faa_dmat;
 	sc->sc_bus.ub_hcpriv = sc;
+	sc->sc_bus.ub_dmatag = faa->faa_dmat;
+	sc->sc_flags = 0;
+	sc->sc_size = size;
+	sc->iot = faa->faa_bst;
+	if (bus_space_map(sc->iot, addr, size, 0, &sc->ioh) != 0) {
+		aprint_error(": couldn't map registers\n");
+		return;
+	}
 
-	error = bus_space_map(sc->iot, addr, size, 0, &sc->ioh);
-	if (error) {
-		aprint_error(": couldn't map %#llx: %d",
-			     (uint64_t)addr, error);
+	aprint_naive("\n");
+	aprint_normal(": Exynos OHCI\n");
+
+	/* Disable interrupts */
+	bus_space_write_4(sc->iot, sc->ioh, OHCI_INTERRUPT_DISABLE,
+	    OHCI_ALL_INTRS);
+
+	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
 		return;
 	}
 
-	aprint_naive(": OHCI USB controller\n");
-	aprint_normal(": OHCI NOT IMPLEMENTED\n");
+	ih = fdtbus_intr_establish(phandle, 0, IPL_USB, FDT_INTR_MPSAFE,
+	    ohci_intr, sc);
+	if (ih == NULL) {
+		aprint_error_dev(self, "couldn't establish interrupt on %s\n",
+		    intrstr);
+		return;
+	}
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
-	/* attach */
 	error = ohci_init(sc);
 	if (error) {
 		aprint_error_dev(self, "init failed, error = %d\n", error);
-		/* disable : TBD */
 		return;
 	}
+
 	sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
 }
-

Index: src/sys/arch/arm/samsung/exynos_usbphy.c
diff -u src/sys/arch/arm/samsung/exynos_usbphy.c:1.1 src/sys/arch/arm/samsung/exynos_usbphy.c:1.2
--- src/sys/arch/arm/samsung/exynos_usbphy.c:1.1	Sun Dec 27 02:54:12 2015
+++ src/sys/arch/arm/samsung/exynos_usbphy.c	Tue Jul  3 16:09:04 2018
@@ -1,12 +1,9 @@
-/*	$NetBSD: exynos_usbphy.c,v 1.1 2015/12/27 02:54:12 marty Exp $	*/
+/* $NetBSD: exynos_usbphy.c,v 1.2 2018/07/03 16:09:04 jmcneill Exp $ */
 
 /*-
- * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
  * All rights reserved.
  *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Reinoud Zandijk.
- *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -29,81 +26,268 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "locators.h"
-#include "ohci.h"
-#include "ehci.h"
-
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: exynos_usbphy.c,v 1.1 2015/12/27 02:54:12 marty Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exynos_usbphy.c,v 1.2 2018/07/03 16:09:04 jmcneill Exp $");
 
 #include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/intr.h>
 #include <sys/bus.h>
 #include <sys/device.h>
-#include <sys/proc.h>
-#include <sys/queue.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
 #include <sys/kmem.h>
-#include <sys/gpio.h>
 
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
+#include <dev/fdt/fdtvar.h>
+#include <dev/fdt/syscon.h>
 
 #include <arm/samsung/exynos_reg.h>
-#include <arm/samsung/exynos_var.h>
+#include <arm/samsung/exynos5_reg.h>
 
-#include <dev/fdt/fdtvar.h>
+/*
+ * System Registers
+ */
+#define	USB20PHY_CFG			0x230
+#define	 USB20PHY_CFG_HOST_LINK_EN	__BIT(0)
+
+/*
+ * PMU Registers
+ */
+#define	USBHOST_PHY_CTRL		0x708
+#define	 USBHOST_PHY_CTRL_EN		__BIT(0)
+
+enum {
+	PHY_ID_DEVICE = 0,
+	PHY_ID_HOST,
+	PHY_ID_HSIC0,
+	PHY_ID_HSIC1,
+	NPHY_ID
+};
+
+static int exynos_usbphy_match(device_t, cfdata_t, void *);
+static void exynos_usbphy_attach(device_t, device_t, void *);
+
+static const struct of_compat_data compat_data[] = {
+	{ "samsung,exynos5250-usb2-phy",	0 },
+	{ NULL }
+};
+
+struct exynos_usbphy_softc;
+
+struct exynos_usbphy {
+	struct exynos_usbphy_softc *phy_sc;
+	u_int			phy_index;
+};
 
 struct exynos_usbphy_softc {
-	device_t	 sc_dev;
-	bus_space_tag_t  sc_bst;
-	bus_space_handle_t sc_bsh;
+	device_t		sc_dev;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+	int			sc_phandle;
+
+	struct syscon		*sc_sysreg;
+	struct syscon		*sc_pmureg;
+
+	u_int			sc_refcnt;
+
+	struct exynos_usbphy	*sc_phy;
+	u_int			sc_nphy;
+
+	struct fdtbus_gpio_pin	*sc_gpio_id_det;
+	struct fdtbus_gpio_pin	*sc_gpio_vbus_det;
 };
 
-static int	exynos_usbphy_match(device_t, cfdata_t, void *);
-static void	exynos_usbphy_attach(device_t, device_t, void *);
+#define	PHY_READ(sc, reg)				\
+	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+#define	PHY_WRITE(sc, reg, val)				\
+	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
 
 CFATTACH_DECL_NEW(exynos_usbphy, sizeof(struct exynos_usbphy_softc),
-    exynos_usbphy_match, exynos_usbphy_attach, NULL, NULL);
+	exynos_usbphy_match, exynos_usbphy_attach, NULL, NULL);
+
+static void *
+exynos_usbphy_acquire(device_t dev, const void *data, size_t len)
+{
+	struct exynos_usbphy_softc * const sc = device_private(dev);
+
+	if (len != 4)
+		return NULL;
+
+	const u_int index = be32dec(data);
+	if (index >= sc->sc_nphy)
+		return NULL;
+
+	return &sc->sc_phy[index];
+}
+
+static void
+exynos_usbphy_release(device_t dev, void *priv)
+{
+}
+
+static int
+exynos_usbphy_enable(device_t dev, void *priv, bool enable)
+{
+	struct exynos_usbphy * const phy = priv;
+	struct exynos_usbphy_softc * const sc = phy->phy_sc;
+	bool do_common;
+	uint32_t val;
+
+	if (enable) {
+		sc->sc_refcnt++;
+	} else {
+		KASSERT(sc->sc_refcnt > 0);
+		sc->sc_refcnt--;
+	}
+	do_common = sc->sc_refcnt == enable;
+
+	if (do_common) {
+		syscon_lock(sc->sc_sysreg);
+		val = syscon_read_4(sc->sc_sysreg, USB20PHY_CFG);
+		if (enable)
+			val |= USB20PHY_CFG_HOST_LINK_EN;
+		else
+			val &= ~USB20PHY_CFG_HOST_LINK_EN;
+		syscon_write_4(sc->sc_sysreg, USB20PHY_CFG, val);
+		syscon_unlock(sc->sc_sysreg);
+
+		syscon_lock(sc->sc_pmureg);
+		val = syscon_read_4(sc->sc_pmureg, USBHOST_PHY_CTRL);
+		if (enable)
+			val |= USBHOST_PHY_CTRL_EN;
+		else
+			val &= ~USBHOST_PHY_CTRL_EN;
+		syscon_write_4(sc->sc_pmureg, USBHOST_PHY_CTRL, val);
+		syscon_unlock(sc->sc_pmureg);
+
+		if (enable) {
+			val = PHY_READ(sc, USB_PHY_HOST_CTRL0);
+			val &= ~HOST_CTRL0_COMMONON_N;
+			val &= ~HOST_CTRL0_PHY_SWRST;
+			val &= ~HOST_CTRL0_PHY_SWRST_ALL;
+			val &= ~HOST_CTRL0_SIDDQ;
+			val &= ~HOST_CTRL0_FORCESUSPEND;
+			val &= ~HOST_CTRL0_FORCESLEEP;
+			val &= ~HOST_CTRL0_FSEL_MASK;
+			val |= __SHIFTIN(FSEL_CLKSEL_24M, HOST_CTRL0_FSEL_MASK);
+			val |= HOST_CTRL0_LINK_SWRST;
+			val |= HOST_CTRL0_UTMI_SWRST;
+			PHY_WRITE(sc, USB_PHY_HOST_CTRL0, val);
+
+			delay(10000);
+
+			val &= ~HOST_CTRL0_LINK_SWRST;
+			val &= ~HOST_CTRL0_UTMI_SWRST;
+			PHY_WRITE(sc, USB_PHY_HOST_CTRL0, val);
+
+			delay(10000);
+		}
+	}
+
+	switch (phy->phy_index) {
+	case PHY_ID_HSIC0:
+	case PHY_ID_HSIC1:
+		if (enable) {
+			const bus_size_t reg = phy->phy_index == PHY_ID_HSIC0 ?
+			    USB_PHY_HSIC_CTRL1 : USB_PHY_HSIC_CTRL2;
+
+			val = HSIC_CTRL_PHY_SWRST;
+			val |= __SHIFTIN(HSIC_CTRL_REFCLKDIV_12, HSIC_CTRL_REFCLKDIV_MASK);
+			val |= __SHIFTIN(HSIC_CTRL_REFCLKSEL_DEFAULT, HSIC_CTRL_REFCLKSEL_MASK);
+			PHY_WRITE(sc, reg, val);
+
+			delay(10000);
+
+			val &= ~HSIC_CTRL_PHY_SWRST;
+			PHY_WRITE(sc, reg, val);
+
+			delay(10000);
+		}
+		break;
+	}
+
+	if (do_common) {
+		if (enable) {
+			val = PHY_READ(sc, USB_PHY_HOST_EHCICTRL);
+			val |= HOST_EHCICTRL_ENA_INCRXALIGN;
+			val |= HOST_EHCICTRL_ENA_INCR4;
+			val |= HOST_EHCICTRL_ENA_INCR8;
+			val |= HOST_EHCICTRL_ENA_INCR16;
+			PHY_WRITE(sc, USB_PHY_HOST_EHCICTRL, val);
+		}
+	}
+
+	return 0;
+}
 
+const struct fdtbus_phy_controller_func exynos_usbphy_funcs = {
+	.acquire = exynos_usbphy_acquire,
+	.release = exynos_usbphy_release,
+	.enable = exynos_usbphy_enable,
+};
 
 static int
 exynos_usbphy_match(device_t parent, cfdata_t cf, void *aux)
 {
-	const char * const compatible[] = { "samsung,exynos5-usb2phy",
-					    NULL };
 	struct fdt_attach_args * const faa = aux;
-	return of_match_compatible(faa->faa_phandle, compatible);
-}
 
+	return of_match_compat_data(faa->faa_phandle, compat_data);
+}
 
 static void
 exynos_usbphy_attach(device_t parent, device_t self, void *aux)
 {
-	struct exynos_usbphy_softc *sc = device_private(self);
+	struct exynos_usbphy_softc * const sc = device_private(self);
 	struct fdt_attach_args * const faa = aux;
+	const int phandle = faa->faa_phandle;
+	struct clk *clk;
 	bus_addr_t addr;
 	bus_size_t size;
-	int error;
+	u_int n;
 
-	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
-		aprint_error(": couldn't get registers\n");
+	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get phy registers\n");
 		return;
 	}
 
 	sc->sc_dev = self;
+	sc->sc_phandle = phandle;
 	sc->sc_bst = faa->faa_bst;
+	if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
+		aprint_error(": couldn't map phy registers\n");
+		return;
+	}
+	sc->sc_nphy = NPHY_ID;
+	sc->sc_phy = kmem_alloc(sizeof(*sc->sc_phy) * sc->sc_nphy, KM_SLEEP);
+	for (n = 0; n < sc->sc_nphy; n++) {
+		sc->sc_phy[n].phy_sc = sc;
+		sc->sc_phy[n].phy_index = n;
+	}
 
-	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
-	if (error) {
-		aprint_error(": couldn't map %#llx: %d",
-			     (uint64_t)addr, error);
+	sc->sc_sysreg = fdtbus_syscon_acquire(phandle, "samsung,sysreg-phandle");
+	if (sc->sc_sysreg == NULL) {
+		aprint_error(": couldn't acquire sysreg syscon\n");
 		return;
 	}
+	sc->sc_pmureg = fdtbus_syscon_acquire(phandle, "samsung,pmureg-phandle");
+	if (sc->sc_pmureg == NULL) {
+		aprint_error(": couldn't acquire pmureg syscon\n");
+		return;
+	}
+
+	/* Enable clocks */
+	clk = fdtbus_clock_get(phandle, "phy");
+	if (clk == NULL || clk_enable(clk) != 0) {
+		aprint_error(": couldn't enable phy clock\n");
+		return;
+	}
+	clk = fdtbus_clock_get(phandle, "ref");
+	if (clk == NULL || clk_enable(clk) != 0) {
+		aprint_error(": couldn't enable ref clock\n");
+		return;
+	}
+
+	aprint_naive("\n");
+	aprint_normal(": USB2 PHY\n");
 
-	aprint_normal(": USB 2 PHY NOT IMPLEMENTED\n");
+	fdtbus_register_phy_controller(self, phandle, &exynos_usbphy_funcs);
 }

Index: src/sys/arch/arm/samsung/files.exynos
diff -u src/sys/arch/arm/samsung/files.exynos:1.27 src/sys/arch/arm/samsung/files.exynos:1.28
--- src/sys/arch/arm/samsung/files.exynos:1.27	Mon Jul  2 12:53:51 2018
+++ src/sys/arch/arm/samsung/files.exynos	Tue Jul  3 16:09:04 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: files.exynos,v 1.27 2018/07/02 12:53:51 jmcneill Exp $
+#	$NetBSD: files.exynos,v 1.28 2018/07/03 16:09:04 jmcneill Exp $
 #
 # Configuration info for Samsung Exynos SoC ARM Peripherals
 #
@@ -79,25 +79,24 @@ attach  exyopctl at fdt with exynos_pinc
 file	arch/arm/samsung/exynos_pinctrl.c	exynos_pinctrl needs-flag
 file	arch/arm/samsung/exynos_gpio.c		exynos_pinctrl needs-flag
 
-# USB2 phy
-device  exyousbphy
-attach  exyousbphy at fdt with exynos_usbphy
+# USB2 PHY
+device	exusbphy
+attach  exusbphy at fdt with exynos_usbphy
 file    arch/arm/samsung/exynos_usbphy.c	exynos_usbphy
 
+# USB DRD PHY
+device	exusbdrdphy
+attach	exusbdrdphy at fdt with exynos_usbdrdphy
+file	arch/arm/samsung/exynos_usbdrdphy.c	exynos_usbdrdphy
+
 # USB2 Host Controller (OHCI)
 attach	ohci at fdt with exynos_ohci
 file	arch/arm/samsung/exynos_ohci.c		exynos_ohci
 
-#USB 2 Host Controller (EHCI)
+# USB 2 Host Controller (EHCI)
 attach	ehci at fdt with exynos_ehci
 file	arch/arm/samsung/exynos_ehci.c		exynos_ehci
 
-# USB3 Host Controller (xHCI)
-device	exyousb : fdtbus
-attach	exyousb at fdt with exynos_usb
-attach  xhci at fdt
-file	arch/arm/samsung/exynos_usb3.c		exynos_usb
-
 # SD/MMC Host Controller
 attach	dwcmmc at fdt with exynos_dwcmmc
 file	arch/arm/samsung/exynos_dwcmmc.c	exynos_dwcmmc

Added files:

Index: src/sys/arch/arm/samsung/exynos_usbdrdphy.c
diff -u /dev/null src/sys/arch/arm/samsung/exynos_usbdrdphy.c:1.1
--- /dev/null	Tue Jul  3 16:09:04 2018
+++ src/sys/arch/arm/samsung/exynos_usbdrdphy.c	Tue Jul  3 16:09:04 2018
@@ -0,0 +1,288 @@
+/* $NetBSD: exynos_usbdrdphy.c,v 1.1 2018/07/03 16:09:04 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+__KERNEL_RCSID(0, "$NetBSD: exynos_usbdrdphy.c,v 1.1 2018/07/03 16:09:04 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kmem.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <dev/fdt/syscon.h>
+
+/*
+ * PHY Registers
+ */
+#define	PHY_LINK_SYSTEM			0x04
+#define	 PHY_LINK_SYSTEM_XHCI_VERCTL	__BIT(27)
+#define	 PHY_LINK_SYSTEM_FLADJ		__BITS(6,1)
+#define	PHY_UTMI			0x08
+#define	 PHY_UTMI_OTGDISABLE		__BIT(6)
+#define	PHY_CLK_RST			0x10
+#define	 PHY_CLK_RST_SSC_REFCLKSEL	__BITS(30,23)
+#define	 PHY_CLK_RST_SSC_EN		__BIT(20)
+#define	 PHY_CLK_RST_REF_SSP_EN		__BIT(19)
+#define	 PHY_CLK_RST_MPLL_MULT		__BITS(17,11)
+#define	  PHY_CLK_RST_MPLL_MULT_24M	0x68
+#define	 PHY_CLK_RST_FSEL		__BITS(10,5)
+#define	  PHY_CLK_RST_FSEL_24M		0x2a
+#define	 PHY_CLK_RST_RETENABLEN		__BIT(4)
+#define	 PHY_CLK_RST_REFCLKSEL		__BITS(3,2)
+#define	  PHY_CLK_RST_REFCLKSEL_EXT	3
+#define	 PHY_CLK_RST_PORTRESET		__BIT(1)
+#define	 PHY_CLK_RST_COMMONONN		__BIT(0)
+#define	PHY_REG0			0x14
+#define	PHY_PARAM0			0x1c
+#define	 PHY_PARAM0_REF_USE_PAD		__BIT(31)
+#define	 PHY_PARAM0_REF_LOSLEVEL	__BITS(30,26)
+#define	PHY_PARAM1			0x20
+#define	 PHY_PARAM1_TXDEEMPH		__BITS(4,0)
+#define	PHY_TEST			0x28
+#define	 PHY_TEST_POWERDOWN_SSP		__BIT(3)
+#define	 PHY_TEST_POWERDOWN_HSP		__BIT(2)
+#define	PHY_BATCHG			0x30
+#define	 PHY_BATCHG_UTMI_CLKSEL		__BIT(2)
+#define	PHY_RESUME			0x34
+
+/*
+ * PMU Registers
+ */
+#define	USBDRD_PHY_CTRL(n)		(0x704 + (n) * 4)
+#define	 USBDRD_PHY_CTRL_EN		__BIT(0)
+
+static int exynos_usbdrdphy_match(device_t, cfdata_t, void *);
+static void exynos_usbdrdphy_attach(device_t, device_t, void *);
+
+enum {
+	PHY_ID_UTMI_PLUS = 0,
+	PHY_ID_PIPE3,
+	NPHY_ID
+};
+
+static const struct of_compat_data compat_data[] = {
+	{ "samsung,exynos5420-usbdrd-phy",	0 },
+	{ NULL }
+};
+
+struct exynos_usbdrdphy_softc;
+
+struct exynos_usbdrdphy {
+	struct exynos_usbdrdphy_softc *phy_sc;
+	u_int			phy_index;
+};
+
+struct exynos_usbdrdphy_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+	int			sc_phandle;
+	struct syscon		*sc_pmureg;
+
+	struct exynos_usbdrdphy	*sc_phy;
+	u_int			sc_nphy;
+
+	struct fdtbus_gpio_pin	*sc_gpio_id_det;
+	struct fdtbus_gpio_pin	*sc_gpio_vbus_det;
+};
+
+#define	PHY_READ(sc, reg)				\
+	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+#define	PHY_WRITE(sc, reg, val)				\
+	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+
+CFATTACH_DECL_NEW(exynos_usbdrdphy, sizeof(struct exynos_usbdrdphy_softc),
+	exynos_usbdrdphy_match, exynos_usbdrdphy_attach, NULL, NULL);
+
+static void *
+exynos_usbdrdphy_acquire(device_t dev, const void *data, size_t len)
+{
+	struct exynos_usbdrdphy_softc * const sc = device_private(dev);
+
+	if (len != 4)
+		return NULL;
+
+	const u_int index = be32dec(data);
+	if (index >= sc->sc_nphy)
+		return NULL;
+
+	return &sc->sc_phy[index];
+}
+
+static void
+exynos_usbdrdphy_release(device_t dev, void *priv)
+{
+}
+
+static int
+exynos_usbdrdphy_enable(device_t dev, void *priv, bool enable)
+{
+	struct exynos_usbdrdphy * const phy = priv;
+	struct exynos_usbdrdphy_softc * const sc = phy->phy_sc;
+	uint32_t val;
+
+	syscon_lock(sc->sc_pmureg);
+	val = syscon_read_4(sc->sc_pmureg, USBDRD_PHY_CTRL(phy->phy_index));
+	if (enable)
+		val |= USBDRD_PHY_CTRL_EN;
+	else
+		val &= ~USBDRD_PHY_CTRL_EN;
+	syscon_write_4(sc->sc_pmureg, USBDRD_PHY_CTRL(phy->phy_index), val);
+	syscon_unlock(sc->sc_pmureg);
+
+	return 0;
+}
+
+const struct fdtbus_phy_controller_func exynos_usbdrdphy_funcs = {
+	.acquire = exynos_usbdrdphy_acquire,
+	.release = exynos_usbdrdphy_release,
+	.enable = exynos_usbdrdphy_enable,
+};
+
+static void
+exynos_usbdrdphy_init(struct exynos_usbdrdphy_softc *sc)
+{
+	uint32_t val;
+
+	PHY_WRITE(sc, PHY_REG0, 0);
+
+	val = PHY_READ(sc, PHY_PARAM0);
+	val &= ~PHY_PARAM0_REF_USE_PAD;
+	val &= ~PHY_PARAM0_REF_LOSLEVEL;
+	val |= __SHIFTIN(9, PHY_PARAM0_REF_LOSLEVEL);
+	PHY_WRITE(sc, PHY_PARAM0, val);
+
+	PHY_WRITE(sc, PHY_RESUME, 0);
+
+	val = PHY_READ(sc, PHY_LINK_SYSTEM);
+	val |= PHY_LINK_SYSTEM_XHCI_VERCTL;
+	val &= ~PHY_LINK_SYSTEM_FLADJ;
+	val |= __SHIFTIN(0x20, PHY_LINK_SYSTEM_FLADJ);
+	PHY_WRITE(sc, PHY_LINK_SYSTEM, val);
+
+	val = PHY_READ(sc, PHY_PARAM1);
+	val &= ~PHY_PARAM1_TXDEEMPH;
+	val |= __SHIFTIN(0x1c, PHY_PARAM1_TXDEEMPH);
+	PHY_WRITE(sc, PHY_PARAM1, val);
+
+	val = PHY_READ(sc, PHY_BATCHG);
+	val |= PHY_BATCHG_UTMI_CLKSEL;
+	PHY_WRITE(sc, PHY_BATCHG, val);
+
+	val = PHY_READ(sc, PHY_TEST);
+	val &= ~PHY_TEST_POWERDOWN_SSP;
+	val &= ~PHY_TEST_POWERDOWN_HSP;
+	PHY_WRITE(sc, PHY_TEST, val);
+
+	PHY_WRITE(sc, PHY_UTMI, PHY_UTMI_OTGDISABLE);
+
+	val = __SHIFTIN(PHY_CLK_RST_REFCLKSEL_EXT, PHY_CLK_RST_REFCLKSEL);
+	val |= __SHIFTIN(PHY_CLK_RST_FSEL_24M, PHY_CLK_RST_FSEL);
+	val |= __SHIFTIN(PHY_CLK_RST_MPLL_MULT_24M, PHY_CLK_RST_MPLL_MULT);
+	val |= __SHIFTIN(0x88, PHY_CLK_RST_SSC_REFCLKSEL);
+	val |= PHY_CLK_RST_PORTRESET;
+	val |= PHY_CLK_RST_RETENABLEN;
+	val |= PHY_CLK_RST_REF_SSP_EN;
+	val |= PHY_CLK_RST_SSC_EN;
+	val |= PHY_CLK_RST_COMMONONN;
+	PHY_WRITE(sc, PHY_CLK_RST, val);
+
+	delay(50000);
+
+	val &= ~PHY_CLK_RST_PORTRESET;
+	PHY_WRITE(sc, PHY_CLK_RST, val);
+}
+
+static int
+exynos_usbdrdphy_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compat_data(faa->faa_phandle, compat_data);
+}
+
+static void
+exynos_usbdrdphy_attach(device_t parent, device_t self, void *aux)
+{
+	struct exynos_usbdrdphy_softc * const sc = device_private(self);
+	struct fdt_attach_args * const faa = aux;
+	const int phandle = faa->faa_phandle;
+	struct clk *clk;
+	bus_addr_t addr;
+	bus_size_t size;
+	u_int n;
+
+	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get phy registers\n");
+		return;
+	}
+
+	sc->sc_dev = self;
+	sc->sc_phandle = phandle;
+	sc->sc_bst = faa->faa_bst;
+	if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
+		aprint_error(": couldn't map phy registers\n");
+		return;
+	}
+
+	sc->sc_nphy = NPHY_ID;
+	sc->sc_phy = kmem_alloc(sizeof(*sc->sc_phy) * sc->sc_nphy, KM_SLEEP);
+	for (n = 0; n < sc->sc_nphy; n++) {
+		sc->sc_phy[n].phy_sc = sc;
+		sc->sc_phy[n].phy_index = n;
+	}
+
+	sc->sc_pmureg = fdtbus_syscon_acquire(phandle, "samsung,pmu-syscon");
+	if (sc->sc_pmureg == NULL) {
+		aprint_error(": couldn't acquire pmureg syscon\n");
+		return;
+	}
+
+	/* Enable clocks */
+	clk = fdtbus_clock_get(phandle, "phy");
+	if (clk == NULL || clk_enable(clk) != 0) {
+		aprint_error(": couldn't enable phy clock\n");
+		return;
+	}
+	clk = fdtbus_clock_get(phandle, "ref");
+	if (clk == NULL || clk_enable(clk) != 0) {
+		aprint_error(": couldn't enable ref clock\n");
+		return;
+	}
+
+	aprint_naive("\n");
+	aprint_normal(": USB DRD PHY\n");
+
+	exynos_usbdrdphy_init(sc);
+
+	fdtbus_register_phy_controller(self, phandle, &exynos_usbdrdphy_funcs);
+}

Reply via email to