1 1.1 rjs /* $NetBSD: rk_tcphy.c,v 1.1 2025/06/03 19:10:26 rjs Exp $ */ 2 1.1 rjs /* $OpenBSD: rktcphy.c,v 1.2 2022/04/06 18:59:28 naddy Exp $ */ 3 1.1 rjs /*- 4 1.1 rjs * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 5 1.1 rjs * 6 1.1 rjs * Copyright (c) 2019 Emmanuel Vadot <manu (at) FreeBSD.Org> 7 1.1 rjs * 8 1.1 rjs * Redistribution and use in source and binary forms, with or without 9 1.1 rjs * modification, are permitted provided that the following conditions 10 1.1 rjs * are met: 11 1.1 rjs * 1. Redistributions of source code must retain the above copyright 12 1.1 rjs * notice, this list of conditions and the following disclaimer. 13 1.1 rjs * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 rjs * notice, this list of conditions and the following disclaimer in the 15 1.1 rjs * documentation and/or other materials provided with the distribution. 16 1.1 rjs * 17 1.1 rjs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 1.1 rjs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 1.1 rjs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 1.1 rjs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 1.1 rjs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 1.1 rjs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 1.1 rjs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 1.1 rjs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 1.1 rjs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 1.1 rjs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 1.1 rjs * SUCH DAMAGE. 28 1.1 rjs */ 29 1.1 rjs 30 1.1 rjs /* 31 1.1 rjs * Rockchip PHY TYPEC 32 1.1 rjs */ 33 1.1 rjs 34 1.1 rjs #include <sys/param.h> 35 1.1 rjs #include <sys/systm.h> 36 1.1 rjs #include <sys/device.h> 37 1.1 rjs 38 1.1 rjs #include <dev/fdt/fdtvar.h> 39 1.1 rjs #include <dev/fdt/syscon.h> 40 1.1 rjs 41 1.1 rjs #define GRF_USB3OTG_BASE(x) (0x2430 + (0x10 * x)) 42 1.1 rjs #define GRF_USB3OTG_CON0(x) (GRF_USB3OTG_BASE(x) + 0x0) 43 1.1 rjs #define GRF_USB3OTG_CON1(x) (GRF_USB3OTG_BASE(x) + 0x4) 44 1.1 rjs #define USB3OTG_CON1_U3_DIS (1 << 0) 45 1.1 rjs 46 1.1 rjs #define GRF_USB3PHY_BASE(x) (0x0e580 + (0xc * (x))) 47 1.1 rjs #define GRF_USB3PHY_CON0(x) (GRF_USB3PHY_BASE(x) + 0x0) 48 1.1 rjs #define USB3PHY_CON0_USB2_ONLY (1 << 3) 49 1.1 rjs #define GRF_USB3PHY_CON1(x) (GRF_USB3PHY_BASE(x) + 0x4) 50 1.1 rjs #define GRF_USB3PHY_CON2(x) (GRF_USB3PHY_BASE(x) + 0x8) 51 1.1 rjs #define GRF_USB3PHY_STATUS0 0x0e5c0 52 1.1 rjs #define GRF_USB3PHY_STATUS1 0x0e5c4 53 1.1 rjs 54 1.1 rjs #define CMN_PLL0_VCOCAL_INIT (0x84 << 2) 55 1.1 rjs #define CMN_PLL0_VCOCAL_ITER (0x85 << 2) 56 1.1 rjs #define CMN_PLL0_INTDIV (0x94 << 2) 57 1.1 rjs #define CMN_PLL0_FRACDIV (0x95 << 2) 58 1.1 rjs #define CMN_PLL0_HIGH_THR (0x96 << 2) 59 1.1 rjs #define CMN_PLL0_DSM_DIAG (0x97 << 2) 60 1.1 rjs #define CMN_PLL0_SS_CTRL1 (0x98 << 2) 61 1.1 rjs #define CMN_PLL0_SS_CTRL2 (0x99 << 2) 62 1.1 rjs #define CMN_DIAG_PLL0_FBH_OVRD (0x1c0 << 2) 63 1.1 rjs #define CMN_DIAG_PLL0_FBL_OVRD (0x1c1 << 2) 64 1.1 rjs #define CMN_DIAG_PLL0_OVRD (0x1c2 << 2) 65 1.1 rjs #define CMN_DIAG_PLL0_V2I_TUNE (0x1c5 << 2) 66 1.1 rjs #define CMN_DIAG_PLL0_CP_TUNE (0x1c6 << 2) 67 1.1 rjs #define CMN_DIAG_PLL0_LF_PROG (0x1c7 << 2) 68 1.1 rjs #define CMN_DIAG_HSCLK_SEL (0x1e0 << 2) 69 1.1 rjs #define CMN_DIAG_HSCLK_SEL_PLL_CONFIG 0x30 70 1.1 rjs #define CMN_DIAG_HSCLK_SEL_PLL_MASK 0x33 71 1.1 rjs 72 1.1 rjs #define TX_TXCC_MGNFS_MULT_000(lane) ((0x4050 | ((lane) << 9)) << 2) 73 1.1 rjs #define XCVR_DIAG_BIDI_CTRL(lane) ((0x40e8 | ((lane) << 9)) << 2) 74 1.1 rjs #define XCVR_DIAG_LANE_FCM_EN_MGN(lane) ((0x40f2 | ((lane) << 9)) << 2) 75 1.1 rjs #define TX_PSC_A0(lane) ((0x4100 | ((lane) << 9)) << 2) 76 1.1 rjs #define TX_PSC_A1(lane) ((0x4101 | ((lane) << 9)) << 2) 77 1.1 rjs #define TX_PSC_A2(lane) ((0x4102 | ((lane) << 9)) << 2) 78 1.1 rjs #define TX_PSC_A3(lane) ((0x4103 | ((lane) << 9)) << 2) 79 1.1 rjs #define TX_RCVDET_EN_TMR(lane) ((0x4122 | ((lane) << 9)) << 2) 80 1.1 rjs #define TX_RCVDET_ST_TMR(lane) ((0x4123 | ((lane) << 9)) << 2) 81 1.1 rjs 82 1.1 rjs #define RX_PSC_A0(lane) ((0x8000 | ((lane) << 9)) << 2) 83 1.1 rjs #define RX_PSC_A1(lane) ((0x8001 | ((lane) << 9)) << 2) 84 1.1 rjs #define RX_PSC_A2(lane) ((0x8002 | ((lane) << 9)) << 2) 85 1.1 rjs #define RX_PSC_A3(lane) ((0x8003 | ((lane) << 9)) << 2) 86 1.1 rjs #define RX_PSC_CAL(lane) ((0x8006 | ((lane) << 9)) << 2) 87 1.1 rjs #define RX_PSC_RDY(lane) ((0x8007 | ((lane) << 9)) << 2) 88 1.1 rjs #define RX_SIGDET_HL_FILT_TMR(lane) ((0x8090 | ((lane) << 9)) << 2) 89 1.1 rjs #define RX_REE_CTRL_DATA_MASK(lane) ((0x81bb | ((lane) << 9)) << 2) 90 1.1 rjs #define RX_DIAG_SIGDET_TUNE(lane) ((0x81dc | ((lane) << 9)) << 2) 91 1.1 rjs 92 1.1 rjs #define PMA_LANE_CFG (0xc000 << 2) 93 1.1 rjs #define PIN_ASSIGN_D_F 0x5100 94 1.1 rjs #define DP_MODE_CTL (0xc008 << 2) 95 1.1 rjs #define DP_MODE_ENTER_A2 0xc104 96 1.1 rjs #define PMA_CMN_CTRL1 (0xc800 << 2) 97 1.1 rjs #define PMA_CMN_CTRL1_READY (1 << 0) 98 1.1 rjs 99 1.1 rjs #define HREAD4(sc, reg) \ 100 1.1 rjs (bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))) 101 1.1 rjs #define HWRITE4(sc, reg, val) \ 102 1.1 rjs bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 103 1.1 rjs #define HSET4(sc, reg, bits) \ 104 1.1 rjs HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits)) 105 1.1 rjs #define HCLR4(sc, reg, bits) \ 106 1.1 rjs HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits)) 107 1.1 rjs 108 1.1 rjs static int rk_typec_match(device_t, cfdata_t, void *); 109 1.1 rjs static void rk_typec_attach(device_t, device_t, void *); 110 1.1 rjs 111 1.1 rjs static const struct device_compatible_entry compat_data[] = { 112 1.1 rjs { .compat = "rockchip,rk3399-typec-phy" }, 113 1.1 rjs DEVICE_COMPAT_EOL 114 1.1 rjs }; 115 1.1 rjs 116 1.1 rjs struct rk_typec_softc { 117 1.1 rjs device_t sc_dev; 118 1.1 rjs bus_space_tag_t sc_bst; 119 1.1 rjs bus_space_handle_t sc_bsh; 120 1.1 rjs int sc_phandle; 121 1.1 rjs 122 1.1 rjs struct syscon *sc_grf; 123 1.1 rjs struct clk *sc_core_clk; 124 1.1 rjs struct clk *sc_phy_ref_clk; 125 1.1 rjs struct fdtbus_reset *sc_rst; 126 1.1 rjs struct fdtbus_reset *sc_rst_pipe; 127 1.1 rjs struct fdtbus_reset *sc_rst_tcphy; 128 1.1 rjs 129 1.1 rjs int sc_mode; 130 1.1 rjs int sc_phy_ctrl_id; 131 1.1 rjs }; 132 1.1 rjs 133 1.1 rjs CFATTACH_DECL_NEW(rk_typec, sizeof(struct rk_typec_softc), 134 1.1 rjs rk_typec_match, rk_typec_attach, NULL, NULL); 135 1.1 rjs 136 1.1 rjs int 137 1.1 rjs rk_typec_match(device_t parent, cfdata_t match, void *aux) 138 1.1 rjs { 139 1.1 rjs struct fdt_attach_args * const faa = aux; 140 1.1 rjs 141 1.1 rjs return of_compatible_match(faa->faa_phandle, compat_data); 142 1.1 rjs } 143 1.1 rjs 144 1.1 rjs void 145 1.1 rjs rk_typec_attach(device_t parent, device_t self, void *aux) 146 1.1 rjs { 147 1.1 rjs struct rk_typec_softc * const sc = device_private(self); 148 1.1 rjs struct fdt_attach_args * const faa = aux; 149 1.1 rjs const int phandle = faa->faa_phandle; 150 1.1 rjs bus_addr_t addr; 151 1.1 rjs bus_size_t size; 152 1.1 rjs int child; 153 1.1 rjs 154 1.1 rjs sc->sc_dev = self; 155 1.1 rjs sc->sc_phandle = faa->faa_phandle; 156 1.1 rjs sc->sc_bst = faa->faa_bst; 157 1.1 rjs 158 1.1 rjs if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 159 1.1 rjs aprint_error(": couldn't get registers\n"); 160 1.1 rjs return; 161 1.1 rjs } 162 1.1 rjs if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 163 1.1 rjs aprint_error(": couldn't map registers\n"); 164 1.1 rjs return; 165 1.1 rjs }; 166 1.1 rjs 167 1.1 rjs /* 168 1.1 rjs * Find out which phy we are. There is no property for this so we need 169 1.1 rjs * to know the address to use the correct GRF registers. 170 1.1 rjs */ 171 1.1 rjs switch (addr) { 172 1.1 rjs case 0xff7c0000: 173 1.1 rjs sc->sc_phy_ctrl_id = 0; 174 1.1 rjs break; 175 1.1 rjs case 0xff800000: 176 1.1 rjs sc->sc_phy_ctrl_id = 1; 177 1.1 rjs break; 178 1.1 rjs default: 179 1.1 rjs aprint_error(": unknown address 0x%lx\n", addr); 180 1.1 rjs return; 181 1.1 rjs } 182 1.1 rjs 183 1.1 rjs sc->sc_grf = fdtbus_syscon_acquire(phandle, "rockchip,grf"); 184 1.1 rjs if (sc->sc_grf == NULL) { 185 1.1 rjs aprint_error(": couldn't get grf syscon\n"); 186 1.1 rjs return; 187 1.1 rjs } 188 1.1 rjs 189 1.1 rjs sc->sc_rst = fdtbus_reset_get(phandle, "uphy"); 190 1.1 rjs if (sc->sc_rst == NULL) { 191 1.1 rjs aprint_error(": couldn't get reset uphy\n"); 192 1.1 rjs return; 193 1.1 rjs } 194 1.1 rjs sc->sc_rst_pipe = fdtbus_reset_get(phandle, "uphy-pipe"); 195 1.1 rjs if (sc->sc_rst_pipe == NULL) { 196 1.1 rjs aprint_error(": couldn't get reset uphy-pipe\n"); 197 1.1 rjs return; 198 1.1 rjs } 199 1.1 rjs sc->sc_rst_tcphy = fdtbus_reset_get(phandle, "uphy-tcphy"); 200 1.1 rjs if (sc->sc_rst_tcphy == NULL) { 201 1.1 rjs aprint_error(": couldn't get reset uphy-tcphy\n"); 202 1.1 rjs return; 203 1.1 rjs } 204 1.1 rjs fdtbus_reset_assert(sc->sc_rst); 205 1.1 rjs fdtbus_reset_assert(sc->sc_rst_pipe); 206 1.1 rjs fdtbus_reset_assert(sc->sc_rst_tcphy); 207 1.1 rjs 208 1.1 rjs fdtbus_clock_assign(phandle); 209 1.1 rjs sc->sc_core_clk = fdtbus_clock_get(phandle, "tcpdcore"); 210 1.1 rjs if (sc->sc_core_clk == NULL) { 211 1.1 rjs aprint_error(": couldn't get tcpdcore clock\n"); 212 1.1 rjs return; 213 1.1 rjs } 214 1.1 rjs sc->sc_phy_ref_clk = fdtbus_clock_get(phandle, "tcpdphy-ref"); 215 1.1 rjs if (sc->sc_phy_ref_clk == NULL) { 216 1.1 rjs aprint_error(": couldn't get tcpdphy-ref clock\n"); 217 1.1 rjs return; 218 1.1 rjs } 219 1.1 rjs 220 1.1 rjs aprint_naive("\n"); 221 1.1 rjs aprint_normal(": USB-C PHY\n"); 222 1.1 rjs 223 1.1 rjs for (child = OF_child(phandle); child; child = OF_peer(child)) { 224 1.1 rjs if (!fdtbus_status_okay(child)) 225 1.1 rjs continue; 226 1.1 rjs 227 1.1 rjs struct fdt_attach_args cfaa = *faa; 228 1.1 rjs cfaa.faa_phandle = child; 229 1.1 rjs cfaa.faa_name = fdtbus_get_string(child, "name"); 230 1.1 rjs cfaa.faa_quiet = false; 231 1.1 rjs 232 1.1 rjs config_found(self, &cfaa, NULL, CFARGS_NONE); 233 1.1 rjs } 234 1.1 rjs } 235 1.1 rjs 236 1.1 rjs /* 237 1.1 rjs * USB3 phy 238 1.1 rjs */ 239 1.1 rjs 240 1.1 rjs static int rk_tcphy_match(device_t, cfdata_t, void *); 241 1.1 rjs static void rk_tcphy_attach(device_t, device_t, void *); 242 1.1 rjs 243 1.1 rjs struct rk_tcphy_softc { 244 1.1 rjs device_t sc_dev; 245 1.1 rjs int sc_phandle; 246 1.1 rjs }; 247 1.1 rjs 248 1.1 rjs CFATTACH_DECL_NEW(rk_tcphy, sizeof(struct rk_tcphy_softc), 249 1.1 rjs rk_tcphy_match, rk_tcphy_attach, NULL, NULL); 250 1.1 rjs 251 1.1 rjs static void * 252 1.1 rjs rk_tcphy_usb3_acquire(device_t dev, const void *data, size_t len) 253 1.1 rjs { 254 1.1 rjs struct rk_tcphy_softc * const sc = device_private(dev); 255 1.1 rjs 256 1.1 rjs return sc; 257 1.1 rjs } 258 1.1 rjs 259 1.1 rjs static void 260 1.1 rjs rk_tcphy_set_usb2_only(struct rk_typec_softc *sc, int usb2only) 261 1.1 rjs { 262 1.1 rjs uint32_t reg; 263 1.1 rjs 264 1.1 rjs /* Disable usb3tousb2 only */ 265 1.1 rjs syscon_lock(sc->sc_grf); 266 1.1 rjs reg = syscon_read_4(sc->sc_grf, GRF_USB3PHY_CON0(sc->sc_phy_ctrl_id)); 267 1.1 rjs if (usb2only) 268 1.1 rjs reg |= USB3PHY_CON0_USB2_ONLY; 269 1.1 rjs else 270 1.1 rjs reg &= ~USB3PHY_CON0_USB2_ONLY; 271 1.1 rjs /* Write Mask */ 272 1.1 rjs reg |= (USB3PHY_CON0_USB2_ONLY) << 16; 273 1.1 rjs syscon_write_4(sc->sc_grf, GRF_USB3PHY_CON0(sc->sc_phy_ctrl_id), reg); 274 1.1 rjs 275 1.1 rjs /* Enable the USB3 Super Speed port */ 276 1.1 rjs reg = syscon_read_4(sc->sc_grf, GRF_USB3OTG_CON1(sc->sc_phy_ctrl_id)); 277 1.1 rjs if (usb2only) 278 1.1 rjs reg |= USB3OTG_CON1_U3_DIS; 279 1.1 rjs else 280 1.1 rjs reg &= ~USB3OTG_CON1_U3_DIS; 281 1.1 rjs /* Write Mask */ 282 1.1 rjs reg |= (USB3OTG_CON1_U3_DIS) << 16; 283 1.1 rjs syscon_write_4(sc->sc_grf, GRF_USB3OTG_CON1(sc->sc_phy_ctrl_id), reg); 284 1.1 rjs syscon_unlock(sc->sc_grf); 285 1.1 rjs } 286 1.1 rjs 287 1.1 rjs static int 288 1.1 rjs rk_tcphy_usb3_enable(device_t dev, void *priv, bool enable) 289 1.1 rjs { 290 1.1 rjs struct rk_typec_softc * const sc = device_private(device_parent(dev)); 291 1.1 rjs uint32_t reg; 292 1.1 rjs int i; 293 1.1 rjs 294 1.1 rjs aprint_normal_dev(dev, "enable %d\n", enable); 295 1.1 rjs if (enable == false) 296 1.1 rjs return 0; 297 1.1 rjs 298 1.1 rjs rk_tcphy_set_usb2_only(sc, false); 299 1.1 rjs 300 1.1 rjs clk_enable(sc->sc_core_clk); 301 1.1 rjs clk_enable(sc->sc_phy_ref_clk); 302 1.1 rjs 303 1.1 rjs fdtbus_reset_deassert(sc->sc_rst_tcphy); 304 1.1 rjs 305 1.1 rjs /* 24M configuration, magic values from rockchip */ 306 1.1 rjs HWRITE4(sc, PMA_CMN_CTRL1, 0x830); 307 1.1 rjs for (i = 0; i < 4; i++) { 308 1.1 rjs HWRITE4(sc, XCVR_DIAG_LANE_FCM_EN_MGN(i), 0x90); 309 1.1 rjs HWRITE4(sc, TX_RCVDET_EN_TMR(i), 0x960); 310 1.1 rjs HWRITE4(sc, TX_RCVDET_ST_TMR(i), 0x30); 311 1.1 rjs } 312 1.1 rjs reg = HREAD4(sc, CMN_DIAG_HSCLK_SEL); 313 1.1 rjs reg &= ~CMN_DIAG_HSCLK_SEL_PLL_MASK; 314 1.1 rjs reg |= CMN_DIAG_HSCLK_SEL_PLL_CONFIG; 315 1.1 rjs HWRITE4(sc, CMN_DIAG_HSCLK_SEL, reg); 316 1.1 rjs 317 1.1 rjs /* PLL configuration, magic values from rockchip */ 318 1.1 rjs HWRITE4(sc, CMN_PLL0_VCOCAL_INIT, 0xf0); 319 1.1 rjs HWRITE4(sc, CMN_PLL0_VCOCAL_ITER, 0x18); 320 1.1 rjs HWRITE4(sc, CMN_PLL0_INTDIV, 0xd0); 321 1.1 rjs HWRITE4(sc, CMN_PLL0_FRACDIV, 0x4a4a); 322 1.1 rjs HWRITE4(sc, CMN_PLL0_HIGH_THR, 0x34); 323 1.1 rjs HWRITE4(sc, CMN_PLL0_SS_CTRL1, 0x1ee); 324 1.1 rjs HWRITE4(sc, CMN_PLL0_SS_CTRL2, 0x7f03); 325 1.1 rjs HWRITE4(sc, CMN_PLL0_DSM_DIAG, 0x20); 326 1.1 rjs HWRITE4(sc, CMN_DIAG_PLL0_OVRD, 0); 327 1.1 rjs HWRITE4(sc, CMN_DIAG_PLL0_FBH_OVRD, 0); 328 1.1 rjs HWRITE4(sc, CMN_DIAG_PLL0_FBL_OVRD, 0); 329 1.1 rjs HWRITE4(sc, CMN_DIAG_PLL0_V2I_TUNE, 0x7); 330 1.1 rjs HWRITE4(sc, CMN_DIAG_PLL0_CP_TUNE, 0x45); 331 1.1 rjs HWRITE4(sc, CMN_DIAG_PLL0_LF_PROG, 0x8); 332 1.1 rjs 333 1.1 rjs /* Configure the TX and RX line, magic values from rockchip */ 334 1.1 rjs HWRITE4(sc, TX_PSC_A0(0), 0x7799); 335 1.1 rjs HWRITE4(sc, TX_PSC_A1(0), 0x7798); 336 1.1 rjs HWRITE4(sc, TX_PSC_A2(0), 0x5098); 337 1.1 rjs HWRITE4(sc, TX_PSC_A3(0), 0x5098); 338 1.1 rjs HWRITE4(sc, TX_TXCC_MGNFS_MULT_000(0), 0x0); 339 1.1 rjs HWRITE4(sc, XCVR_DIAG_BIDI_CTRL(0), 0xbf); 340 1.1 rjs 341 1.1 rjs HWRITE4(sc, RX_PSC_A0(1), 0xa6fd); 342 1.1 rjs HWRITE4(sc, RX_PSC_A1(1), 0xa6fd); 343 1.1 rjs HWRITE4(sc, RX_PSC_A2(1), 0xa410); 344 1.1 rjs HWRITE4(sc, RX_PSC_A3(1), 0x2410); 345 1.1 rjs HWRITE4(sc, RX_PSC_CAL(1), 0x23ff); 346 1.1 rjs HWRITE4(sc, RX_SIGDET_HL_FILT_TMR(1), 0x13); 347 1.1 rjs HWRITE4(sc, RX_REE_CTRL_DATA_MASK(1), 0x03e7); 348 1.1 rjs HWRITE4(sc, RX_DIAG_SIGDET_TUNE(1), 0x1004); 349 1.1 rjs HWRITE4(sc, RX_PSC_RDY(1), 0x2010); 350 1.1 rjs HWRITE4(sc, XCVR_DIAG_BIDI_CTRL(1), 0xfb); 351 1.1 rjs 352 1.1 rjs HWRITE4(sc, PMA_LANE_CFG, PIN_ASSIGN_D_F); 353 1.1 rjs 354 1.1 rjs HWRITE4(sc, DP_MODE_CTL, DP_MODE_ENTER_A2); 355 1.1 rjs 356 1.1 rjs fdtbus_reset_deassert(sc->sc_rst); 357 1.1 rjs 358 1.1 rjs for (i = 10000; i > 0; i--) { 359 1.1 rjs reg = HREAD4(sc, PMA_CMN_CTRL1); 360 1.1 rjs if (reg & PMA_CMN_CTRL1_READY) 361 1.1 rjs break; 362 1.1 rjs delay(10); 363 1.1 rjs } 364 1.1 rjs if (i == 0) { 365 1.1 rjs aprint_error_dev(sc->sc_dev, "timeout waiting for PMA\n"); 366 1.1 rjs return ENXIO; 367 1.1 rjs } 368 1.1 rjs 369 1.1 rjs fdtbus_reset_deassert(sc->sc_rst_pipe); 370 1.1 rjs 371 1.1 rjs return 0; 372 1.1 rjs } 373 1.1 rjs 374 1.1 rjs const struct fdtbus_phy_controller_func rk_tcphy_usb3_funcs = { 375 1.1 rjs .acquire = rk_tcphy_usb3_acquire, 376 1.1 rjs .release = (void *)voidop, 377 1.1 rjs .enable = rk_tcphy_usb3_enable, 378 1.1 rjs }; 379 1.1 rjs 380 1.1 rjs static int 381 1.1 rjs rk_tcphy_match(device_t parent, cfdata_t cf, void *aux) 382 1.1 rjs { 383 1.1 rjs struct fdt_attach_args * const faa = aux; 384 1.1 rjs const int phandle = faa->faa_phandle; 385 1.1 rjs const char *name = fdtbus_get_string(phandle, "name"); 386 1.1 rjs 387 1.1 rjs if (strcmp(name, "usb3-port") == 0) 388 1.1 rjs return 1; 389 1.1 rjs #if 0 390 1.1 rjs if (strcmp(name, "dp-port") == 0) 391 1.1 rjs return 1; 392 1.1 rjs #endif 393 1.1 rjs return 0; 394 1.1 rjs } 395 1.1 rjs 396 1.1 rjs static void 397 1.1 rjs rk_tcphy_attach(device_t parent, device_t self, void *aux) 398 1.1 rjs { 399 1.1 rjs struct rk_tcphy_softc * const sc = device_private(self); 400 1.1 rjs struct fdt_attach_args * const faa = aux; 401 1.1 rjs const int phandle = faa->faa_phandle; 402 1.1 rjs const char *name = fdtbus_get_string(phandle, "name"); 403 1.1 rjs 404 1.1 rjs sc->sc_dev = self; 405 1.1 rjs sc->sc_phandle = phandle; 406 1.1 rjs 407 1.1 rjs aprint_naive("\n"); 408 1.1 rjs 409 1.1 rjs if (strcmp(name, "usb3-port") == 0) { 410 1.1 rjs aprint_normal(": USB3 port\n"); 411 1.1 rjs fdtbus_register_phy_controller(self, phandle, &rk_tcphy_usb3_funcs); 412 1.1 rjs } 413 1.1 rjs } 414