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