From 2479590b5a388e13e4156f0ee29903004934bd76 Mon Sep 17 00:00:00 2001 From: kettenis Date: Fri, 29 Sep 2023 15:51:48 +0000 Subject: [PATCH] Newer versions of U-Boot may disable the USB PHYs and gate their clocks. Add support for the rk3399 to rkusbphy(4) and implement support for the required clocks. ok kevlo@ --- sys/dev/fdt/rkclock.c | 20 ++++++++++++- sys/dev/fdt/rkclock_clocks.h | 4 +++ sys/dev/fdt/rkusbphy.c | 56 ++++++++++++++++++++++++++++++++++-- 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/sys/dev/fdt/rkclock.c b/sys/dev/fdt/rkclock.c index 1655fbb574b..17a62a6ea7b 100644 --- a/sys/dev/fdt/rkclock.c +++ b/sys/dev/fdt/rkclock.c @@ -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 * @@ -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; diff --git a/sys/dev/fdt/rkclock_clocks.h b/sys/dev/fdt/rkclock_clocks.h index 55f696f194e..d55078ec527 100644 --- a/sys/dev/fdt/rkclock_clocks.h +++ b/sys/dev/fdt/rkclock_clocks.h @@ -187,7 +187,11 @@ #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 diff --git a/sys/dev/fdt/rkusbphy.c b/sys/dev/fdt/rkusbphy.c index 2f30f97cd88..e72258024c2 100644 --- a/sys/dev/fdt/rkusbphy.c +++ b/sys/dev/fdt/rkusbphy.c @@ -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 @@ -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); -- 2.20.1