Newer versions of U-Boot may disable the USB PHYs and gate their clocks.
authorkettenis <kettenis@openbsd.org>
Fri, 29 Sep 2023 15:51:48 +0000 (15:51 +0000)
committerkettenis <kettenis@openbsd.org>
Fri, 29 Sep 2023 15:51:48 +0000 (15:51 +0000)
Add support for the rk3399 to rkusbphy(4) and implement support for the
required clocks.

ok kevlo@

sys/dev/fdt/rkclock.c
sys/dev/fdt/rkclock_clocks.h
sys/dev/fdt/rkusbphy.c

index 1655fbb..17a62a6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rkclock.c,v 1.82 2023/07/09 16:33:49 patrick Exp $    */
+/*     $OpenBSD: rkclock.c,v 1.83 2023/09/29 15:51:48 kettenis Exp $   */
 /*
  * Copyright (c) 2017, 2018 Mark Kettenis <kettenis@openbsd.org>
  *
@@ -2952,6 +2952,24 @@ rk3399_enable(void *cookie, uint32_t *cells, int on)
        }
 
        switch (idx) {
+       case RK3399_CLK_USB2PHY0_REF:
+               HWRITE4(sc, RK3399_CRU_CLKGATE_CON(6), (5 << 0) << 16);
+               break;
+       case RK3399_CLK_USB2PHY1_REF:
+               HWRITE4(sc, RK3399_CRU_CLKGATE_CON(6), (6 << 0) << 16);
+               break;
+       case RK3399_CLK_UPHY0_TCPDPHY_REF:
+               HWRITE4(sc, RK3399_CRU_CLKGATE_CON(13), (4 << 0) << 16);
+               break;
+       case RK3399_CLK_UPHY0_TCPDCORE:
+               HWRITE4(sc, RK3399_CRU_CLKGATE_CON(13), (5 << 0) << 16);
+               break;
+       case RK3399_CLK_UPHY1_TCPDPHY_REF:
+               HWRITE4(sc, RK3399_CRU_CLKGATE_CON(13), (6 << 0) << 16);
+               break;
+       case RK3399_CLK_UPHY1_TCPDCORE:
+               HWRITE4(sc, RK3399_CRU_CLKGATE_CON(13), (7 << 0) << 16);
+               break;
        case RK3399_ACLK_GMAC:
                HWRITE4(sc, RK3399_CRU_CLKGATE_CON(32), (1 << 0) << 16);
                break;
index 55f696f..d55078e 100644 (file)
 #define RK3399_CLK_MAC_RX              103
 #define RK3399_CLK_MAC_TX              104
 #define RK3399_CLK_MAC                 105
+#define RK3399_CLK_USB2PHY0_REF                123
+#define RK3399_CLK_USB2PHY1_REF                124
+#define RK3399_CLK_UPHY0_TCPDPHY_REF   125
 #define RK3399_CLK_UPHY0_TCPDCORE      126
+#define RK3399_CLK_UPHY1_TCPDPHY_REF   127
 #define RK3399_CLK_UPHY1_TCPDCORE      128
 #define RK3399_CLK_USB3OTG0_REF                129
 #define RK3399_CLK_USB3OTG1_REF                130
index 2f30f97..e722580 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rkusbphy.c,v 1.2 2023/04/03 01:21:31 dlg Exp $ */
+/*     $OpenBSD: rkusbphy.c,v 1.3 2023/09/29 15:51:48 kettenis Exp $ */
 
 /*
  * Copyright (c) 2023 David Gwynne <dlg@openbsd.org>
@@ -61,6 +61,54 @@ struct rkusbphy_chip {
        const struct rkusbphy_regs      *c_regs;
 };
 
+/*
+ * Since OpenBSD only supports USB ports in host mode, this driver
+ * actually powers down the OTG part of the PHY when it is enabled.
+ * This is why the OTG values in the tables below differ from this in
+ * (for example) Linux.
+ */
+
+/*
+ * RK3399 has two USB2PHY nodes that share a GRF.
+ */
+
+static const struct rkusbphy_regs rkusbphy_rk3399_usb0_regs = {
+       /*                              shift,  mask,   set */
+       .clk_enable =   { 0xe450,       4,      0x1,    0x0 },
+
+       .otg = {
+               .phy_enable =   { 0xe454,       0,      0x3,    0x2 },
+       },
+
+       .host = {
+               .phy_enable =   { 0xe458,       0,      0x3,    0x1 },
+       },
+};
+
+static const struct rkusbphy_regs rkusbphy_rk3399_usb1_regs = {
+       /*                              shift,  mask,   set */
+       .clk_enable =   { 0xe460,       4,      0x1,    0x0 },
+
+       .otg = {
+               .phy_enable =   { 0xe464,       0,      0x3,    0x2 },
+       },
+
+       .host = {
+               .phy_enable =   { 0xe468,       0,      0x3,    0x1 },
+       },
+};
+
+static const struct rkusbphy_chip rkusbphy_rk3399[] = {
+       {
+               .c_base_addr = 0xe450,
+               .c_regs = &rkusbphy_rk3399_usb0_regs,
+       },
+       {
+               .c_base_addr = 0xe460,
+               .c_regs = &rkusbphy_rk3399_usb1_regs,
+       },
+};
+
 /*
  * RK3568 has two USB2PHY nodes that have a GRF each. Each GRF has
  * the same register layout.
@@ -158,6 +206,7 @@ struct rkusbphy_id {
 #define RKUSBPHY_ID(_n, _c) { _n, _c, nitems(_c) }
 
 static const struct rkusbphy_id rkusbphy_ids[] = {
+       RKUSBPHY_ID("rockchip,rk3399-usb2phy", rkusbphy_rk3399),
        RKUSBPHY_ID("rockchip,rk3568-usb2phy", rkusbphy_rk3568),
 };
 
@@ -213,7 +262,10 @@ rkusbphy_attach(struct device *parent, struct device *self, void *aux)
        sc->sc_node = faa->fa_node;
 
        grfph = OF_getpropint(sc->sc_node, "rockchip,usbgrf", 0);
-       sc->sc_grf = regmap_byphandle(grfph);
+       if (grfph)
+               sc->sc_grf = regmap_byphandle(grfph);
+       else
+               sc->sc_grf = regmap_bynode(OF_parent(sc->sc_node));
        if (sc->sc_grf == NULL) {
                printf("%s: rockchip,usbgrf 0x%x not found\n", DEVNAME(sc),
                    grfph);