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 114static struct ofw_compat_data compat_data[] = { 115 { "rockchip,rk3399-typec-phy", 1 }, 116 { NULL, 0 } 117}; 118 119static struct resource_spec rk_typec_phy_spec[] = { 120 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 121 { -1, 0 } 122}; 123 124struct 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. */ 141static int rk_typec_phy_enable(struct phynode *phynode, bool enable); 142static int rk_typec_phy_get_mode(struct phynode *phy, int *mode); 143static int rk_typec_phy_set_mode(struct phynode *phy, int mode); 144static 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 152DEFINE_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 156enum RK3399_USBPHY { 157 RK3399_TYPEC_PHY_DP = 0, 158 RK3399_TYPEC_PHY_USB3, 159}; 160 161static void 162rk_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 187static int 188rk_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 290static int 291rk_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 309static int 310rk_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 328static int 329rk_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 342static int 343rk_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 451fail: 452 bus_release_resources(dev, rk_typec_phy_spec, &sc->res); 453 454 return (ENXIO); 455} 456 457static 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 465static driver_t rk_typec_phy_driver = { 466 "rk_typec_phy", 467 rk_typec_phy_methods, 468 sizeof(struct rk_typec_phy_softc) 469}; 470 471static devclass_t rk_typec_phy_devclass; 472EARLY_DRIVER_MODULE(rk_typec_phy, simplebus, rk_typec_phy_driver, 473 rk_typec_phy_devclass, 0, 0, BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE); 474MODULE_VERSION(rk_typec_phy, 1); 475