1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2019 Emmanuel Vadot <manu@FreeBSD.Org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 /* 29 * Rockchip PHY TYPEC 30 */ 31 32 #include <sys/cdefs.h> 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/bus.h> 36 #include <sys/rman.h> 37 #include <sys/kernel.h> 38 #include <sys/module.h> 39 #include <sys/gpio.h> 40 #include <machine/bus.h> 41 42 #include <dev/fdt/fdt_common.h> 43 #include <dev/ofw/ofw_bus.h> 44 #include <dev/ofw/ofw_bus_subr.h> 45 #include <dev/ofw/ofw_subr.h> 46 47 #include <dev/extres/clk/clk.h> 48 #include <dev/extres/phy/phy_usb.h> 49 #include <dev/extres/syscon/syscon.h> 50 #include <dev/extres/hwreset/hwreset.h> 51 52 #include "syscon_if.h" 53 54 #define GRF_USB3OTG_BASE(x) (0x2430 + (0x10 * x)) 55 #define GRF_USB3OTG_CON0(x) (GRF_USB3OTG_BASE(x) + 0x0) 56 #define GRF_USB3OTG_CON1(x) (GRF_USB3OTG_BASE(x) + 0x4) 57 #define USB3OTG_CON1_U3_DIS (1 << 0) 58 59 #define GRF_USB3PHY_BASE(x) (0x0e580 + (0xc * (x))) 60 #define GRF_USB3PHY_CON0(x) (GRF_USB3PHY_BASE(x) + 0x0) 61 #define USB3PHY_CON0_USB2_ONLY (1 << 3) 62 #define GRF_USB3PHY_CON1(x) (GRF_USB3PHY_BASE(x) + 0x4) 63 #define GRF_USB3PHY_CON2(x) (GRF_USB3PHY_BASE(x) + 0x8) 64 #define GRF_USB3PHY_STATUS0 0x0e5c0 65 #define GRF_USB3PHY_STATUS1 0x0e5c4 66 67 #define CMN_PLL0_VCOCAL_INIT (0x84 << 2) 68 #define CMN_PLL0_VCOCAL_ITER (0x85 << 2) 69 #define CMN_PLL0_INTDIV (0x94 << 2) 70 #define CMN_PLL0_FRACDIV (0x95 << 2) 71 #define CMN_PLL0_HIGH_THR (0x96 << 2) 72 #define CMN_PLL0_DSM_DIAG (0x97 << 2) 73 #define CMN_PLL0_SS_CTRL1 (0x98 << 2) 74 #define CMN_PLL0_SS_CTRL2 (0x99 << 2) 75 #define CMN_DIAG_PLL0_FBH_OVRD (0x1c0 << 2) 76 #define CMN_DIAG_PLL0_FBL_OVRD (0x1c1 << 2) 77 #define CMN_DIAG_PLL0_OVRD (0x1c2 << 2) 78 #define CMN_DIAG_PLL0_V2I_TUNE (0x1c5 << 2) 79 #define CMN_DIAG_PLL0_CP_TUNE (0x1c6 << 2) 80 #define CMN_DIAG_PLL0_LF_PROG (0x1c7 << 2) 81 #define CMN_DIAG_HSCLK_SEL (0x1e0 << 2) 82 #define CMN_DIAG_HSCLK_SEL_PLL_CONFIG 0x30 83 #define CMN_DIAG_HSCLK_SEL_PLL_MASK 0x33 84 85 #define TX_TXCC_MGNFS_MULT_000(lane) ((0x4050 | ((lane) << 9)) << 2) 86 #define XCVR_DIAG_BIDI_CTRL(lane) ((0x40e8 | ((lane) << 9)) << 2) 87 #define XCVR_DIAG_LANE_FCM_EN_MGN(lane) ((0x40f2 | ((lane) << 9)) << 2) 88 #define TX_PSC_A0(lane) ((0x4100 | ((lane) << 9)) << 2) 89 #define TX_PSC_A1(lane) ((0x4101 | ((lane) << 9)) << 2) 90 #define TX_PSC_A2(lane) ((0x4102 | ((lane) << 9)) << 2) 91 #define TX_PSC_A3(lane) ((0x4103 | ((lane) << 9)) << 2) 92 #define TX_RCVDET_EN_TMR(lane) ((0x4122 | ((lane) << 9)) << 2) 93 #define TX_RCVDET_ST_TMR(lane) ((0x4123 | ((lane) << 9)) << 2) 94 95 #define RX_PSC_A0(lane) ((0x8000 | ((lane) << 9)) << 2) 96 #define RX_PSC_A1(lane) ((0x8001 | ((lane) << 9)) << 2) 97 #define RX_PSC_A2(lane) ((0x8002 | ((lane) << 9)) << 2) 98 #define RX_PSC_A3(lane) ((0x8003 | ((lane) << 9)) << 2) 99 #define RX_PSC_CAL(lane) ((0x8006 | ((lane) << 9)) << 2) 100 #define RX_PSC_RDY(lane) ((0x8007 | ((lane) << 9)) << 2) 101 #define RX_SIGDET_HL_FILT_TMR(lane) ((0x8090 | ((lane) << 9)) << 2) 102 #define RX_REE_CTRL_DATA_MASK(lane) ((0x81bb | ((lane) << 9)) << 2) 103 #define RX_DIAG_SIGDET_TUNE(lane) ((0x81dc | ((lane) << 9)) << 2) 104 105 #define PMA_LANE_CFG (0xc000 << 2) 106 #define PIN_ASSIGN_D_F 0x5100 107 #define DP_MODE_CTL (0xc008 << 2) 108 #define DP_MODE_ENTER_A2 0xc104 109 #define PMA_CMN_CTRL1 (0xc800 << 2) 110 #define PMA_CMN_CTRL1_READY (1 << 0) 111 112 static struct ofw_compat_data compat_data[] = { 113 { "rockchip,rk3399-typec-phy", 1 }, 114 { NULL, 0 } 115 }; 116 117 static struct resource_spec rk_typec_phy_spec[] = { 118 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 119 { -1, 0 } 120 }; 121 122 struct rk_typec_phy_softc { 123 device_t dev; 124 struct resource *res; 125 struct syscon *grf; 126 clk_t tcpdcore; 127 clk_t tcpdphy_ref; 128 hwreset_t rst_uphy; 129 hwreset_t rst_pipe; 130 hwreset_t rst_tcphy; 131 int mode; 132 int phy_ctrl_id; 133 }; 134 135 #define RK_TYPEC_PHY_READ(sc, reg) bus_read_4(sc->res, (reg)) 136 #define RK_TYPEC_PHY_WRITE(sc, reg, val) bus_write_4(sc->res, (reg), (val)) 137 138 /* Phy class and methods. */ 139 static int rk_typec_phy_enable(struct phynode *phynode, bool enable); 140 static int rk_typec_phy_get_mode(struct phynode *phy, int *mode); 141 static int rk_typec_phy_set_mode(struct phynode *phy, int mode); 142 static phynode_method_t rk_typec_phy_phynode_methods[] = { 143 PHYNODEMETHOD(phynode_enable, rk_typec_phy_enable), 144 PHYNODEMETHOD(phynode_usb_get_mode, rk_typec_phy_get_mode), 145 PHYNODEMETHOD(phynode_usb_set_mode, rk_typec_phy_set_mode), 146 147 PHYNODEMETHOD_END 148 }; 149 150 DEFINE_CLASS_1(rk_typec_phy_phynode, rk_typec_phy_phynode_class, 151 rk_typec_phy_phynode_methods, 152 sizeof(struct phynode_usb_sc), phynode_usb_class); 153 154 enum RK3399_USBPHY { 155 RK3399_TYPEC_PHY_DP = 0, 156 RK3399_TYPEC_PHY_USB3, 157 }; 158 159 static void 160 rk_typec_phy_set_usb2_only(struct rk_typec_phy_softc *sc, bool usb2only) 161 { 162 uint32_t reg; 163 164 /* Disable usb3tousb2 only */ 165 reg = SYSCON_READ_4(sc->grf, GRF_USB3PHY_CON0(sc->phy_ctrl_id)); 166 if (usb2only) 167 reg |= USB3PHY_CON0_USB2_ONLY; 168 else 169 reg &= ~USB3PHY_CON0_USB2_ONLY; 170 /* Write Mask */ 171 reg |= (USB3PHY_CON0_USB2_ONLY) << 16; 172 SYSCON_WRITE_4(sc->grf, GRF_USB3PHY_CON0(sc->phy_ctrl_id), reg); 173 174 /* Enable the USB3 Super Speed port */ 175 reg = SYSCON_READ_4(sc->grf, GRF_USB3OTG_CON1(sc->phy_ctrl_id)); 176 if (usb2only) 177 reg |= USB3OTG_CON1_U3_DIS; 178 else 179 reg &= ~USB3OTG_CON1_U3_DIS; 180 /* Write Mask */ 181 reg |= (USB3OTG_CON1_U3_DIS) << 16; 182 SYSCON_WRITE_4(sc->grf, GRF_USB3OTG_CON1(sc->phy_ctrl_id), reg); 183 } 184 185 static int 186 rk_typec_phy_enable(struct phynode *phynode, bool enable) 187 { 188 struct rk_typec_phy_softc *sc; 189 device_t dev; 190 intptr_t phy; 191 uint32_t reg; 192 int err, retry; 193 194 dev = phynode_get_device(phynode); 195 phy = phynode_get_id(phynode); 196 sc = device_get_softc(dev); 197 198 if (phy != RK3399_TYPEC_PHY_USB3) 199 return (ERANGE); 200 201 rk_typec_phy_set_usb2_only(sc, false); 202 203 err = clk_enable(sc->tcpdcore); 204 if (err != 0) { 205 device_printf(dev, "Could not enable clock %s\n", 206 clk_get_name(sc->tcpdcore)); 207 return (ENXIO); 208 } 209 err = clk_enable(sc->tcpdphy_ref); 210 if (err != 0) { 211 device_printf(dev, "Could not enable clock %s\n", 212 clk_get_name(sc->tcpdphy_ref)); 213 clk_disable(sc->tcpdcore); 214 return (ENXIO); 215 } 216 217 hwreset_deassert(sc->rst_tcphy); 218 219 /* 24M configuration, magic values from rockchip */ 220 RK_TYPEC_PHY_WRITE(sc, PMA_CMN_CTRL1, 0x830); 221 for (int i = 0; i < 4; i++) { 222 RK_TYPEC_PHY_WRITE(sc, XCVR_DIAG_LANE_FCM_EN_MGN(i), 0x90); 223 RK_TYPEC_PHY_WRITE(sc, TX_RCVDET_EN_TMR(i), 0x960); 224 RK_TYPEC_PHY_WRITE(sc, TX_RCVDET_ST_TMR(i), 0x30); 225 } 226 reg = RK_TYPEC_PHY_READ(sc, CMN_DIAG_HSCLK_SEL); 227 reg &= ~CMN_DIAG_HSCLK_SEL_PLL_MASK; 228 reg |= CMN_DIAG_HSCLK_SEL_PLL_CONFIG; 229 RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_HSCLK_SEL, reg); 230 231 /* PLL configuration, magic values from rockchip */ 232 RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_VCOCAL_INIT, 0xf0); 233 RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_VCOCAL_ITER, 0x18); 234 RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_INTDIV, 0xd0); 235 RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_FRACDIV, 0x4a4a); 236 RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_HIGH_THR, 0x34); 237 RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_SS_CTRL1, 0x1ee); 238 RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_SS_CTRL2, 0x7f03); 239 RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_DSM_DIAG, 0x20); 240 RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_PLL0_OVRD, 0); 241 RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_PLL0_FBH_OVRD, 0); 242 RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_PLL0_FBL_OVRD, 0); 243 RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_PLL0_V2I_TUNE, 0x7); 244 RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_PLL0_CP_TUNE, 0x45); 245 RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_PLL0_LF_PROG, 0x8); 246 247 /* Configure the TX and RX line, magic values from rockchip */ 248 RK_TYPEC_PHY_WRITE(sc, TX_PSC_A0(0), 0x7799); 249 RK_TYPEC_PHY_WRITE(sc, TX_PSC_A1(0), 0x7798); 250 RK_TYPEC_PHY_WRITE(sc, TX_PSC_A2(0), 0x5098); 251 RK_TYPEC_PHY_WRITE(sc, TX_PSC_A3(0), 0x5098); 252 RK_TYPEC_PHY_WRITE(sc, TX_TXCC_MGNFS_MULT_000(0), 0x0); 253 RK_TYPEC_PHY_WRITE(sc, XCVR_DIAG_BIDI_CTRL(0), 0xbf); 254 255 RK_TYPEC_PHY_WRITE(sc, RX_PSC_A0(1), 0xa6fd); 256 RK_TYPEC_PHY_WRITE(sc, RX_PSC_A1(1), 0xa6fd); 257 RK_TYPEC_PHY_WRITE(sc, RX_PSC_A2(1), 0xa410); 258 RK_TYPEC_PHY_WRITE(sc, RX_PSC_A3(1), 0x2410); 259 RK_TYPEC_PHY_WRITE(sc, RX_PSC_CAL(1), 0x23ff); 260 RK_TYPEC_PHY_WRITE(sc, RX_SIGDET_HL_FILT_TMR(1), 0x13); 261 RK_TYPEC_PHY_WRITE(sc, RX_REE_CTRL_DATA_MASK(1), 0x03e7); 262 RK_TYPEC_PHY_WRITE(sc, RX_DIAG_SIGDET_TUNE(1), 0x1004); 263 RK_TYPEC_PHY_WRITE(sc, RX_PSC_RDY(1), 0x2010); 264 RK_TYPEC_PHY_WRITE(sc, XCVR_DIAG_BIDI_CTRL(1), 0xfb); 265 266 RK_TYPEC_PHY_WRITE(sc, PMA_LANE_CFG, PIN_ASSIGN_D_F); 267 268 RK_TYPEC_PHY_WRITE(sc, DP_MODE_CTL, DP_MODE_ENTER_A2); 269 270 hwreset_deassert(sc->rst_uphy); 271 272 for (retry = 10000; retry > 0; retry--) { 273 reg = RK_TYPEC_PHY_READ(sc, PMA_CMN_CTRL1); 274 if (reg & PMA_CMN_CTRL1_READY) 275 break; 276 DELAY(10); 277 } 278 if (retry == 0) { 279 device_printf(sc->dev, "Timeout waiting for PMA\n"); 280 return (ENXIO); 281 } 282 283 hwreset_deassert(sc->rst_pipe); 284 285 return (0); 286 } 287 288 static int 289 rk_typec_phy_get_mode(struct phynode *phynode, int *mode) 290 { 291 struct rk_typec_phy_softc *sc; 292 intptr_t phy; 293 device_t dev; 294 295 dev = phynode_get_device(phynode); 296 phy = phynode_get_id(phynode); 297 sc = device_get_softc(dev); 298 299 if (phy != RK3399_TYPEC_PHY_USB3) 300 return (ERANGE); 301 302 *mode = sc->mode; 303 304 return (0); 305 } 306 307 static int 308 rk_typec_phy_set_mode(struct phynode *phynode, int mode) 309 { 310 struct rk_typec_phy_softc *sc; 311 intptr_t phy; 312 device_t dev; 313 314 dev = phynode_get_device(phynode); 315 phy = phynode_get_id(phynode); 316 sc = device_get_softc(dev); 317 318 if (phy != RK3399_TYPEC_PHY_USB3) 319 return (ERANGE); 320 321 sc->mode = mode; 322 323 return (0); 324 } 325 326 static int 327 rk_typec_phy_probe(device_t dev) 328 { 329 330 if (!ofw_bus_status_okay(dev)) 331 return (ENXIO); 332 333 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) 334 return (ENXIO); 335 336 device_set_desc(dev, "Rockchip RK3399 PHY TYPEC"); 337 return (BUS_PROBE_DEFAULT); 338 } 339 340 static int 341 rk_typec_phy_attach(device_t dev) 342 { 343 struct rk_typec_phy_softc *sc; 344 struct phynode_init_def phy_init; 345 struct phynode *phynode; 346 phandle_t node, usb3; 347 phandle_t reg_prop[4]; 348 349 sc = device_get_softc(dev); 350 sc->dev = dev; 351 node = ofw_bus_get_node(dev); 352 353 /* 354 * Find out which phy we are. 355 * There is not property for this so we need to know the 356 * address to use the correct GRF registers. 357 */ 358 if (OF_getencprop(node, "reg", reg_prop, sizeof(reg_prop)) <= 0) { 359 device_printf(dev, "Cannot guess phy controller id\n"); 360 return (ENXIO); 361 } 362 switch (reg_prop[1]) { 363 case 0xff7c0000: 364 sc->phy_ctrl_id = 0; 365 break; 366 case 0xff800000: 367 sc->phy_ctrl_id = 1; 368 break; 369 default: 370 device_printf(dev, "Unknown address %x for typec-phy\n", reg_prop[1]); 371 return (ENXIO); 372 } 373 374 if (bus_alloc_resources(dev, rk_typec_phy_spec, &sc->res) != 0) { 375 device_printf(dev, "cannot allocate resources for device\n"); 376 goto fail; 377 } 378 379 if (syscon_get_by_ofw_property(dev, node, 380 "rockchip,grf", &sc->grf) != 0) { 381 device_printf(dev, "Cannot get syscon handle\n"); 382 goto fail; 383 } 384 385 if (clk_get_by_ofw_name(dev, 0, "tcpdcore", &sc->tcpdcore) != 0) { 386 device_printf(dev, "Cannot get tcpdcore clock\n"); 387 goto fail; 388 } 389 if (clk_get_by_ofw_name(dev, 0, "tcpdphy-ref", &sc->tcpdphy_ref) != 0) { 390 device_printf(dev, "Cannot get tcpdphy-ref clock\n"); 391 goto fail; 392 } 393 394 if (hwreset_get_by_ofw_name(dev, 0, "uphy", &sc->rst_uphy) != 0) { 395 device_printf(dev, "Cannot get uphy reset\n"); 396 goto fail; 397 } 398 if (hwreset_get_by_ofw_name(dev, 0, "uphy-pipe", &sc->rst_pipe) != 0) { 399 device_printf(dev, "Cannot get uphy-pipe reset\n"); 400 goto fail; 401 } 402 if (hwreset_get_by_ofw_name(dev, 0, "uphy-tcphy", &sc->rst_tcphy) != 0) { 403 device_printf(dev, "Cannot get uphy-tcphy reset\n"); 404 goto fail; 405 } 406 407 /* 408 * Make sure that the module is asserted 409 * We need to deassert in a certain order when we enable the phy 410 */ 411 hwreset_assert(sc->rst_uphy); 412 hwreset_assert(sc->rst_pipe); 413 hwreset_assert(sc->rst_tcphy); 414 415 /* Set the assigned clocks parent and freq */ 416 if (clk_set_assigned(dev, node) != 0) { 417 device_printf(dev, "clk_set_assigned failed\n"); 418 goto fail; 419 } 420 421 /* Only usb3 port is supported right now */ 422 usb3 = ofw_bus_find_child(node, "usb3-port"); 423 if (usb3 == 0) { 424 device_printf(dev, "Cannot find usb3-port child node\n"); 425 goto fail; 426 } 427 /* If the child isn't enable attach the driver 428 * but do not register the PHY. 429 */ 430 if (!ofw_bus_node_status_okay(usb3)) 431 return (0); 432 433 phy_init.id = RK3399_TYPEC_PHY_USB3; 434 phy_init.ofw_node = usb3; 435 phynode = phynode_create(dev, &rk_typec_phy_phynode_class, &phy_init); 436 if (phynode == NULL) { 437 device_printf(dev, "failed to create phy usb3-port\n"); 438 goto fail; 439 } 440 if (phynode_register(phynode) == NULL) { 441 device_printf(dev, "failed to register phy usb3-port\n"); 442 goto fail; 443 } 444 445 OF_device_register_xref(OF_xref_from_node(usb3), dev); 446 447 return (0); 448 449 fail: 450 bus_release_resources(dev, rk_typec_phy_spec, &sc->res); 451 452 return (ENXIO); 453 } 454 455 static device_method_t rk_typec_phy_methods[] = { 456 /* Device interface */ 457 DEVMETHOD(device_probe, rk_typec_phy_probe), 458 DEVMETHOD(device_attach, rk_typec_phy_attach), 459 460 DEVMETHOD_END 461 }; 462 463 static driver_t rk_typec_phy_driver = { 464 "rk_typec_phy", 465 rk_typec_phy_methods, 466 sizeof(struct rk_typec_phy_softc) 467 }; 468 469 EARLY_DRIVER_MODULE(rk_typec_phy, simplebus, rk_typec_phy_driver, 0, 0, 470 BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE); 471 MODULE_VERSION(rk_typec_phy, 1); 472