Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147237620
D19335.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D19335.diff
View Options
Index: sys/arm64/conf/GENERIC
===================================================================
--- sys/arm64/conf/GENERIC
+++ sys/arm64/conf/GENERIC
@@ -206,6 +206,7 @@
device ehci # EHCI USB interface (USB 2.0)
device ehci_mv # Marvell EHCI USB interface
device xhci # XHCI USB interface (USB 3.0)
+device rk_xhci # Rockchip XHCI USB interface (USB 3.0)
device usb # USB Bus (required)
device ukbd # Keyboard
device umass # Disks/Mass storage - Requires scbus and da
Index: sys/arm64/rockchip/rk_xhci.c
===================================================================
--- /dev/null
+++ sys/arm64/rockchip/rk_xhci.c
@@ -0,0 +1,127 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2019 Greg V <greg@unrelenting.technology>
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * The Rockchip glue node for the Synopsys DesignWare USB 3.0 controller
+ * enables clocks, deasserts resets, and attaches the actual controller.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <dev/fdt/simplebus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/hwreset/hwreset.h>
+
+static int
+rk_xhci_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+ if (!(ofw_bus_is_compatible(dev, "rockchip,rk3328-dwc3") ||
+ ofw_bus_is_compatible(dev, "rockchip,rk3399-dwc3")))
+ return (ENXIO);
+ device_set_desc(dev, "Rockchip DWC3 USB 3.0 Controller");
+ device_printf(dev, "probing rk_xhci\n");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+rk_xhci_attach(device_t dev)
+{
+ size_t off;
+ hwreset_t rst;
+ clk_t clk;
+ phandle_t node;
+
+ node = ofw_bus_get_node(dev);
+
+ if (OF_child(node) <= 0) {
+ device_printf(dev, "no child node found\n");
+ return (ENXIO);
+ }
+
+ for (off = 0; clk_get_by_ofw_index(dev, 0, off, &clk) == 0; off++) {
+ if (bootverbose)
+ device_printf(dev, "enabling clock %s\n",
+ clk_get_name(clk));
+ if (clk_enable(clk) != 0) {
+ device_printf(dev, "could not enable clock %s\n",
+ clk_get_name(clk));
+ return (ENXIO);
+ }
+ }
+
+ for (off = 0; hwreset_get_by_ofw_idx(dev, 0, off, &rst) == 0; off++) {
+ if (bootverbose)
+ device_printf(dev, "deasserting reset\n");
+ if (hwreset_deassert(rst) != 0) {
+ device_printf(dev, "could not deassert reset\n");
+ return (ENXIO);
+ }
+ }
+
+ simplebus_init(dev, node);
+ bus_generic_probe(dev);
+
+ /* Attach the actual DWC3 child device */
+ node = OF_child(node);
+ simplebus_add_device(dev, node, 0, NULL, -1, NULL);
+
+ return (bus_generic_attach(dev));
+}
+
+static device_method_t rk_xhci_methods[] = {
+ DEVMETHOD(device_probe, rk_xhci_probe),
+ DEVMETHOD(device_attach, rk_xhci_attach),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ DEVMETHOD_END
+};
+
+static devclass_t rk_xhci_devclass;
+
+DEFINE_CLASS_1(rk_xhci, rk_xhci_driver, rk_xhci_methods,
+ sizeof(struct simplebus_softc), simplebus_driver);
+DRIVER_MODULE(rk_xhci, simplebus, rk_xhci_driver, rk_xhci_devclass, 0, 0);
+MODULE_DEPEND(rk_xhci, xhci, 1, 1, 1);
Index: sys/conf/files.arm64
===================================================================
--- sys/conf/files.arm64
+++ sys/conf/files.arm64
@@ -268,6 +268,7 @@
dev/usb/controller/generic_xhci.c optional xhci
dev/usb/controller/generic_xhci_acpi.c optional xhci acpi
dev/usb/controller/generic_xhci_fdt.c optional xhci fdt
+dev/usb/controller/dwc_xhci.c optional xhci fdt
dev/vnic/mrml_bridge.c optional vnic fdt
dev/vnic/nic_main.c optional vnic pci
dev/vnic/nicvf_main.c optional vnic pci pci_iov
@@ -303,6 +304,7 @@
arm64/rockchip/rk_grf.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399
arm64/rockchip/rk_pinctrl.c optional fdt rk_pinctrl soc_rockchip_rk3328 | fdt rk_pinctrl soc_rockchip_rk3399
arm64/rockchip/rk_gpio.c optional fdt rk_gpio soc_rockchip_rk3328 | fdt rk_gpio soc_rockchip_rk3399
+arm64/rockchip/rk_xhci.c optional fdt rk_xhci soc_rockchip_rk3328 | fdt rk_xhci soc_rockchip_rk3399
arm64/rockchip/if_dwc_rk.c optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399
dev/dwc/if_dwc.c optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399
dev/dwc/if_dwc_if.m optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399
Index: sys/dev/usb/controller/dwc_xhci.c
===================================================================
--- /dev/null
+++ sys/dev/usb/controller/dwc_xhci.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2017 Mark kettenis <kettenis@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_bus.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/condvar.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/xhci.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#ifdef EXT_RESOURCES
+#include <dev/extres/phy/phy.h>
+#endif
+
+#include "generic_xhci.h"
+
+#define XHCI_DWC3_DEVSTR "Synopsys DesignWare USB 3.0 controller"
+#define XHCI_DWC3_VENDOR "Synopsys"
+
+static struct ofw_compat_data compat_data[] = {
+ {"synopsys,dwc3", true},
+ {"snps,dwc3", true},
+ {NULL, false}
+};
+
+static int
+dwc_xhci_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
+ return (ENXIO);
+
+ device_set_desc(dev, XHCI_DWC3_DEVSTR);
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+#define USB3_GCTL 0xc110
+#define USB3_GCTL_PRTCAPDIR_MASK (0x3 << 12)
+#define USB3_GCTL_PRTCAPDIR_HOST (0x1 << 12)
+#define USB3_GCTL_PRTCAPDIR_DEVICE (0x2 << 12)
+#define USB3_GUCTL1 0xc11c
+#define USB3_GUCTL1_TX_IPGAP_LINECHECK_DIS (1 << 28)
+#define USB3_GUSB2PHYCFG0 0xc200
+#define USB3_GUSB2PHYCFG0_U2_FREECLK_EXISTS (1 << 30)
+#define USB3_GUSB2PHYCFG0_USBTRDTIM(n) ((n) << 10)
+#define USB3_GUSB2PHYCFG0_ENBLSLPM (1 << 8)
+#define USB3_GUSB2PHYCFG0_SUSPENDUSB20 (1 << 6)
+#define USB3_GUSB2PHYCFG0_PHYIF (1 << 3)
+
+static void
+dwc3_init(struct xhci_softc *sc, phandle_t node)
+{
+ char phy_type[16] = { 0 };
+ uint32_t reg;
+
+ /* We don't support device mode, so always force host mode. */
+ reg = bus_space_read_4(sc->sc_io_tag, sc->sc_io_hdl, USB3_GCTL);
+ reg &= ~USB3_GCTL_PRTCAPDIR_MASK;
+ reg |= USB3_GCTL_PRTCAPDIR_HOST;
+ bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, USB3_GCTL, reg);
+
+ /* Configure USB2 PHY type and quirks. */
+ OF_getprop(node, "phy_type", phy_type, sizeof(phy_type));
+ reg = bus_space_read_4(sc->sc_io_tag, sc->sc_io_hdl, USB3_GUSB2PHYCFG0);
+ reg &= ~USB3_GUSB2PHYCFG0_USBTRDTIM(0xf);
+ if (strcmp(phy_type, "utmi_wide") == 0) {
+ reg |= USB3_GUSB2PHYCFG0_PHYIF;
+ reg |= USB3_GUSB2PHYCFG0_USBTRDTIM(0x5);
+ } else {
+ reg &= ~USB3_GUSB2PHYCFG0_PHYIF;
+ reg |= USB3_GUSB2PHYCFG0_USBTRDTIM(0x9);
+ }
+ if (OF_getproplen(node, "snps,dis-u2-freeclk-exists-quirk") == 0)
+ reg &= ~USB3_GUSB2PHYCFG0_U2_FREECLK_EXISTS;
+ if (OF_getproplen(node, "snps,dis_enblslpm_quirk") == 0)
+ reg &= ~USB3_GUSB2PHYCFG0_ENBLSLPM;
+ if (OF_getproplen(node, "snps,dis_u2_susphy_quirk") == 0)
+ reg &= ~USB3_GUSB2PHYCFG0_SUSPENDUSB20;
+ bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, USB3_GUSB2PHYCFG0, reg);
+
+ /* Configure USB3 quirks. */
+ reg = bus_space_read_4(sc->sc_io_tag, sc->sc_io_hdl, USB3_GUCTL1);
+ if (OF_getproplen(node, "snps,dis-tx-ipgap-linecheck-quirk") == 0)
+ reg |= USB3_GUCTL1_TX_IPGAP_LINECHECK_DIS;
+ bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, USB3_GUCTL1, reg);
+}
+
+static int
+dwc_xhci_attach(device_t dev)
+{
+ int err = 0;
+ struct xhci_softc *sc;
+ phandle_t node;
+#ifdef EXT_RESOURCES
+ phy_t phy;
+#endif
+
+ sc = device_get_softc(dev);
+ node = ofw_bus_get_node(dev);
+
+#ifdef EXT_RESOURCES
+ if (phy_get_by_ofw_property(dev, node, "usb2-phy", &phy) == 0)
+ if (phy_enable(phy) != 0)
+ device_printf(dev, "Cannot enable usb2-phy\n");
+
+ if (phy_get_by_ofw_property(dev, node, "usb3-phy", &phy) == 0)
+ if (phy_enable(phy) != 0)
+ device_printf(dev, "Cannot enable usb3-phy\n");
+#endif
+
+ err = generic_xhci_init_resources(dev);
+ if (err != 0)
+ return (err);
+
+ sprintf(sc->sc_vendor, XHCI_DWC3_VENDOR);
+ device_set_desc(sc->sc_bus.bdev, XHCI_DWC3_DEVSTR);
+
+ dwc3_init(sc, node);
+
+ return (generic_xhci_init_controller(dev));
+}
+
+static int
+dwc_xhci_detach(device_t dev)
+{
+ int err = 0;
+ phandle_t node;
+ phy_t phy;
+
+ err = generic_xhci_detach(dev);
+ if (err != 0)
+ return (err);
+
+ node = ofw_bus_get_node(dev);
+
+ if (phy_get_by_ofw_property(dev, node, "usb2-phy", &phy) == 0)
+ phy_release(phy);
+
+ if (phy_get_by_ofw_property(dev, node, "usb3-phy", &phy) == 0)
+ phy_release(phy);
+
+ return (0);
+}
+
+
+static device_method_t dwc_xhci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, dwc_xhci_probe),
+ DEVMETHOD(device_attach, dwc_xhci_attach),
+ DEVMETHOD(device_detach, dwc_xhci_detach),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(xhci, dwc_xhci_driver, dwc_xhci_methods,
+ sizeof(struct xhci_softc), generic_xhci_driver);
+
+static devclass_t dwc_xhci_devclass;
+
+DRIVER_MODULE(dwcxhci, simplebus, dwc_xhci_driver, dwc_xhci_devclass, 0, 0);
+MODULE_DEPEND(dwcxhci, usb, 1, 1, 1);
Index: sys/dev/usb/controller/generic_xhci.h
===================================================================
--- sys/dev/usb/controller/generic_xhci.h
+++ sys/dev/usb/controller/generic_xhci.h
@@ -33,6 +33,11 @@
extern driver_t generic_xhci_driver;
+/* For unusual controllers like DWC3, two parts of attach are available
+ * separately in order to allow custom initialization in between. */
+device_attach_t generic_xhci_init_resources;
+device_attach_t generic_xhci_init_controller;
+
device_attach_t generic_xhci_attach;
device_detach_t generic_xhci_detach;
Index: sys/dev/usb/controller/generic_xhci.c
===================================================================
--- sys/dev/usb/controller/generic_xhci.c
+++ sys/dev/usb/controller/generic_xhci.c
@@ -65,6 +65,18 @@
int
generic_xhci_attach(device_t dev)
+{
+ int err = 0;
+
+ err = generic_xhci_init_resources(dev);
+ if (err != 0)
+ return (err);
+
+ return (generic_xhci_init_controller(dev));
+}
+
+int
+generic_xhci_init_resources(device_t dev)
{
struct xhci_softc *sc = device_get_softc(dev);
int err = 0, rid = 0;
@@ -114,6 +126,15 @@
return (err);
}
+ return (0);
+}
+
+int
+generic_xhci_init_controller(device_t dev)
+{
+ struct xhci_softc *sc = device_get_softc(dev);
+ int err = 0;
+
err = xhci_init(sc, dev, IS_DMA_32B);
if (err != 0) {
device_printf(dev, "Failed to init XHCI, with error %d\n", err);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Mar 10, 8:42 AM (22 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29484117
Default Alt Text
D19335.diff (12 KB)
Attached To
Mode
D19335: Add USB 3.0 support for Rockchip RK3328/RK3399 SoC
Attached
Detach File
Event Timeline
Log In to Comment