1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2020 Rockchip Electronics Co., Ltd 4 * 5 * Based on drivers/phy/rockchip/phy-rockchip-typec.c in Linux Kernel. 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <dm/lists.h> 11 #include <dm/of_access.h> 12 #include <generic-phy.h> 13 #include <power/regulator.h> 14 #include <regmap.h> 15 #include <reset.h> 16 #include <syscon.h> 17 #include <asm-generic/io.h> 18 #include <asm/arch/clock.h> 19 #include <linux/iopoll.h> 20 #include <linux/usb/rockchip_phy_typec.h> 21 22 #define CMN_PLL0_VCOCAL_OVRD (0x83 << 2) 23 #define CMN_PLL0_VCOCAL_INIT (0x84 << 2) 24 #define CMN_PLL0_VCOCAL_ITER (0x85 << 2) 25 #define CMN_PLL0_LOCK_REFCNT_START (0x90 << 2) 26 #define CMN_PLL0_LOCK_PLLCNT_START (0x92 << 2) 27 #define CMN_PLL0_LOCK_PLLCNT_THR (0x93 << 2) 28 #define CMN_PLL0_INTDIV (0x94 << 2) 29 #define CMN_PLL0_FRACDIV (0x95 << 2) 30 #define CMN_PLL0_HIGH_THR (0x96 << 2) 31 #define CMN_PLL0_DSM_DIAG (0x97 << 2) 32 #define CMN_PLL0_SS_CTRL1 (0x98 << 2) 33 #define CMN_PLL0_SS_CTRL2 (0x99 << 2) 34 #define CMN_DIAG_PLL0_FBH_OVRD (0x1c0 << 2) 35 #define CMN_DIAG_PLL0_FBL_OVRD (0x1c1 << 2) 36 #define CMN_DIAG_PLL0_OVRD (0x1c2 << 2) 37 #define CMN_DIAG_PLL0_V2I_TUNE (0x1c5 << 2) 38 #define CMN_DIAG_PLL0_CP_TUNE (0x1c6 << 2) 39 #define CMN_DIAG_PLL0_LF_PROG (0x1c7 << 2) 40 #define CMN_DIAG_HSCLK_SEL (0x1e0 << 2) 41 42 #define TX_TXCC_MGNFS_MULT_000(n) ((0x4050 | ((n) << 9)) << 2) 43 #define XCVR_DIAG_PLLDRC_CTRL(n) ((0x40e0 | ((n) << 9)) << 2) 44 #define XCVR_DIAG_BIDI_CTRL(n) ((0x40e8 | ((n) << 9)) << 2) 45 #define XCVR_DIAG_LANE_FCM_EN_MGN(n) ((0x40f2 | ((n) << 9)) << 2) 46 #define TX_PSC_A0(n) ((0x4100 | ((n) << 9)) << 2) 47 #define TX_PSC_A1(n) ((0x4101 | ((n) << 9)) << 2) 48 #define TX_PSC_A2(n) ((0x4102 | ((n) << 9)) << 2) 49 #define TX_PSC_A3(n) ((0x4103 | ((n) << 9)) << 2) 50 #define TX_RCVDET_CTRL(n) ((0x4120 | ((n) << 9)) << 2) 51 #define TX_RCVDET_EN_TMR(n) ((0x4122 | ((n) << 9)) << 2) 52 #define TX_RCVDET_ST_TMR(n) ((0x4123 | ((n) << 9)) << 2) 53 #define TX_DIAG_TX_DRV(n) ((0x41e1 | ((n) << 9)) << 2) 54 #define TX_DIAG_BGREF_PREDRV_DELAY (0x41e7 << 2) 55 56 #define RX_PSC_A0(n) ((0x8000 | ((n) << 9)) << 2) 57 #define RX_PSC_A1(n) ((0x8001 | ((n) << 9)) << 2) 58 #define RX_PSC_A2(n) ((0x8002 | ((n) << 9)) << 2) 59 #define RX_PSC_A3(n) ((0x8003 | ((n) << 9)) << 2) 60 #define RX_PSC_CAL(n) ((0x8006 | ((n) << 9)) << 2) 61 #define RX_PSC_RDY(n) ((0x8007 | ((n) << 9)) << 2) 62 #define RX_SIGDET_HL_FILT_TMR(n) ((0x8090 | ((n) << 9)) << 2) 63 #define RX_REE_CTRL_DATA_MASK(n) ((0x81bb | ((n) << 9)) << 2) 64 #define RX_DIAG_SIGDET_TUNE(n) ((0x81dc | ((n) << 9)) << 2) 65 #define RX_DIAG_SC2C_DELAY (0x81e1 << 2) 66 67 #define PHY_ISO_CMN_CTRL (0xc010 << 2) 68 #define PMA_CMN_CTRL1 (0xc800 << 2) 69 #define PHY_PMA_ISO_CMN_CTRL (0xc810 << 2) 70 #define PHY_ISOLATION_CTRL (0xc81f << 2) 71 #define PHY_PMA_ISO_XCVR_CTRL(n) ((0xcc11 | ((n) << 6)) << 2) 72 #define PHY_PMA_ISO_LINK_MODE(n) ((0xcc12 | ((n) << 6)) << 2) 73 #define PHY_PMA_ISO_PWRST_CTRL(n) ((0xcc13 | ((n) << 6)) << 2) 74 #define PHY_PMA_ISO_TX_DATA_LO(n) ((0xcc14 | ((n) << 6)) << 2) 75 #define PHY_PMA_ISO_TX_DATA_HI(n) ((0xcc15 | ((n) << 6)) << 2) 76 #define PHY_PMA_ISO_RX_DATA_LO(n) ((0xcc16 | ((n) << 6)) << 2) 77 #define PHY_PMA_ISO_RX_DATA_HI(n) ((0xcc17 | ((n) << 6)) << 2) 78 79 /* 80 * Selects which PLL clock will be driven on the analog high speed 81 * clock 0: PLL 0 div 1 82 * clock 1: PLL 1 div 2 83 */ 84 #define CLK_PLL1_DIV1 0x20 85 #define CLK_PLL1_DIV2 0x30 86 #define CLK_PLL_MASK 0x33 87 88 #define CMN_READY BIT(0) 89 #define PHY_MODE_SET_TIMEOUT 100000 90 #define MODE_DISCONNECT 0 91 #define MODE_UFP_USB BIT(0) 92 #define MODE_DFP_USB BIT(1) 93 #define POWER_ON_TRIES 5 94 95 struct phy_reg { 96 u16 value; 97 u32 addr; 98 }; 99 100 static const struct phy_reg usb3_pll_cfg[] = { 101 { 0xf0, CMN_PLL0_VCOCAL_INIT }, 102 { 0x18, CMN_PLL0_VCOCAL_ITER }, 103 { 0xd0, CMN_PLL0_INTDIV }, 104 { 0x4a4a, CMN_PLL0_FRACDIV }, 105 { 0x34, CMN_PLL0_HIGH_THR }, 106 { 0x1ee, CMN_PLL0_SS_CTRL1 }, 107 { 0x7f03, CMN_PLL0_SS_CTRL2 }, 108 { 0x20, CMN_PLL0_DSM_DIAG }, 109 { 0, CMN_DIAG_PLL0_OVRD }, 110 { 0, CMN_DIAG_PLL0_FBH_OVRD }, 111 { 0, CMN_DIAG_PLL0_FBL_OVRD }, 112 { 0x7, CMN_DIAG_PLL0_V2I_TUNE }, 113 { 0x45, CMN_DIAG_PLL0_CP_TUNE }, 114 { 0x8, CMN_DIAG_PLL0_LF_PROG }, 115 }; 116 117 static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy) 118 { 119 u32 i, rdata; 120 121 /* 122 * cmn_ref_clk_sel = 3, select the 24Mhz for clk parent 123 * cmn_psm_clk_dig_div = 2, set the clk division to 2 124 */ 125 writel(0x830, tcphy->base + PMA_CMN_CTRL1); 126 for (i = 0; i < 4; i++) { 127 /* 128 * The following PHY configuration assumes a 24 MHz reference 129 * clock. 130 */ 131 writel(0x90, tcphy->base + XCVR_DIAG_LANE_FCM_EN_MGN(i)); 132 writel(0x960, tcphy->base + TX_RCVDET_EN_TMR(i)); 133 writel(0x30, tcphy->base + TX_RCVDET_ST_TMR(i)); 134 } 135 136 rdata = readl(tcphy->base + CMN_DIAG_HSCLK_SEL); 137 rdata &= ~CLK_PLL_MASK; 138 rdata |= CLK_PLL1_DIV2; 139 writel(rdata, tcphy->base + CMN_DIAG_HSCLK_SEL); 140 } 141 142 static void tcphy_cfg_usb3_pll(struct rockchip_typec_phy *tcphy) 143 { 144 u32 i; 145 146 /* load the configuration of PLL0 */ 147 for (i = 0; i < ARRAY_SIZE(usb3_pll_cfg); i++) 148 writel(usb3_pll_cfg[i].value, 149 tcphy->base + usb3_pll_cfg[i].addr); 150 } 151 152 static void tcphy_tx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane) 153 { 154 writel(0x7799, tcphy->base + TX_PSC_A0(lane)); 155 writel(0x7798, tcphy->base + TX_PSC_A1(lane)); 156 writel(0x5098, tcphy->base + TX_PSC_A2(lane)); 157 writel(0x5098, tcphy->base + TX_PSC_A3(lane)); 158 writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_000(lane)); 159 writel(0xbf, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane)); 160 } 161 162 static void tcphy_rx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane) 163 { 164 writel(0xa6fd, tcphy->base + RX_PSC_A0(lane)); 165 writel(0xa6fd, tcphy->base + RX_PSC_A1(lane)); 166 writel(0xa410, tcphy->base + RX_PSC_A2(lane)); 167 writel(0x2410, tcphy->base + RX_PSC_A3(lane)); 168 writel(0x23ff, tcphy->base + RX_PSC_CAL(lane)); 169 writel(0x13, tcphy->base + RX_SIGDET_HL_FILT_TMR(lane)); 170 writel(0x03e7, tcphy->base + RX_REE_CTRL_DATA_MASK(lane)); 171 writel(0x1004, tcphy->base + RX_DIAG_SIGDET_TUNE(lane)); 172 writel(0x2010, tcphy->base + RX_PSC_RDY(lane)); 173 writel(0xfb, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane)); 174 } 175 176 static inline int property_enable(struct rockchip_typec_phy *tcphy, 177 const struct usb3phy_reg *reg, bool en) 178 { 179 u32 mask = 1 << reg->write_enable; 180 u32 val = en << reg->enable_bit; 181 182 return writel((val | mask), (tcphy->grf_regs + reg->offset)); 183 } 184 185 static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy, 186 bool value) 187 { 188 struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs; 189 190 property_enable(tcphy, &cfg->usb3tousb2_en, value); 191 property_enable(tcphy, &cfg->usb3host_disable, value); 192 property_enable(tcphy, &cfg->usb3host_port, !value); 193 194 return 0; 195 } 196 197 static int tcphy_phy_init(struct rockchip_typec_phy *tcphy) 198 { 199 struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs; 200 int ret; 201 u32 val; 202 203 reset_deassert(&tcphy->tcphy_rst); 204 205 property_enable(tcphy, &cfg->typec_conn_dir, tcphy->flip); 206 207 tcphy_cfg_24m(tcphy); 208 209 tcphy_cfg_usb3_pll(tcphy); 210 if (tcphy->flip) { 211 tcphy_tx_usb3_cfg_lane(tcphy, 3); 212 tcphy_rx_usb3_cfg_lane(tcphy, 2); 213 } else { 214 tcphy_tx_usb3_cfg_lane(tcphy, 0); 215 tcphy_rx_usb3_cfg_lane(tcphy, 1); 216 } 217 218 reset_deassert(&tcphy->uphy_rst); 219 220 ret = readx_poll_timeout(readl, tcphy->base + PMA_CMN_CTRL1, 221 val, val & CMN_READY, PHY_MODE_SET_TIMEOUT); 222 if (ret < 0) { 223 dev_err(tcphy->dev, "wait pma ready timeout\n"); 224 ret = -ETIMEDOUT; 225 goto err_wait_pma; 226 } 227 228 reset_deassert(&tcphy->pipe_rst); 229 230 return 0; 231 232 err_wait_pma: 233 reset_assert(&tcphy->uphy_rst); 234 reset_assert(&tcphy->tcphy_rst); 235 return ret; 236 } 237 238 static void tcphy_phy_deinit(struct rockchip_typec_phy *tcphy) 239 { 240 reset_assert(&tcphy->tcphy_rst); 241 reset_assert(&tcphy->uphy_rst); 242 reset_assert(&tcphy->pipe_rst); 243 } 244 245 static int tcphy_get_mode(struct rockchip_typec_phy *tcphy) 246 { 247 u8 mode = MODE_DFP_USB | MODE_UFP_USB; 248 249 tcphy->flip = 0; 250 251 return mode; 252 } 253 254 static int _rockchip_usb3_phy_power_on(struct rockchip_typec_phy *tcphy) 255 { 256 struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs; 257 const struct usb3phy_reg *reg = &cfg->pipe_status; 258 int timeout, new_mode, ret = 0; 259 u32 val; 260 261 mutex_lock(&tcphy->lock); 262 263 new_mode = tcphy_get_mode(tcphy); 264 265 if (tcphy->mode == new_mode) 266 goto unlock_ret; 267 268 if (tcphy->mode == MODE_DISCONNECT) { 269 ret = tcphy_phy_init(tcphy); 270 if (ret) 271 goto unlock_ret; 272 } 273 274 /* wait TCPHY for pipe ready */ 275 for (timeout = 0; timeout < 100; timeout++) { 276 val = readl(tcphy->grf_regs + reg->offset); 277 if (!(val & BIT(reg->enable_bit))) { 278 tcphy->mode |= new_mode & (MODE_DFP_USB | MODE_UFP_USB); 279 280 /* enable usb3 host */ 281 tcphy_cfg_usb3_to_usb2_only(tcphy, false); 282 goto unlock_ret; 283 } 284 udelay(20); 285 } 286 287 if (tcphy->mode == MODE_DISCONNECT) 288 tcphy_phy_deinit(tcphy); 289 290 ret = -ETIMEDOUT; 291 292 unlock_ret: 293 mutex_unlock(&tcphy->lock); 294 return ret; 295 } 296 297 static int rockchip_usb3_phy_power_on(struct phy *phy) 298 { 299 struct udevice *parent = dev_get_parent(phy->dev); 300 struct rockchip_typec_phy *tcphy = dev_get_priv(parent); 301 int ret; 302 int tries; 303 304 for (tries = 0; tries < POWER_ON_TRIES; tries++) { 305 ret = _rockchip_usb3_phy_power_on(tcphy); 306 if (!ret) 307 break; 308 } 309 310 if (tries && !ret) 311 dev_err(tcphy->dev, "Needed %d loops to turn on\n", tries); 312 313 return ret; 314 } 315 316 static int rockchip_usb3_phy_power_off(struct phy *phy) 317 { 318 struct udevice *parent = dev_get_parent(phy->dev); 319 struct rockchip_typec_phy *tcphy = dev_get_priv(parent); 320 321 mutex_lock(&tcphy->lock); 322 323 if (tcphy->mode == MODE_DISCONNECT) 324 goto unlock; 325 326 tcphy->mode = MODE_DISCONNECT; 327 tcphy_phy_deinit(tcphy); 328 329 unlock: 330 mutex_unlock(&tcphy->lock); 331 return 0; 332 } 333 334 static const struct phy_ops rockchip_usb3_phy_ops = { 335 .power_on = rockchip_usb3_phy_power_on, 336 .power_off = rockchip_usb3_phy_power_off, 337 }; 338 339 int rockchip_u3phy_uboot_init(const char *name) 340 { 341 struct udevice *udev; 342 struct rockchip_typec_phy *tcphy; 343 int tries; 344 int ret; 345 346 ret = uclass_get_device_by_name(UCLASS_PHY, name, &udev); 347 if (ret) { 348 pr_err("%s: get usb3-phy failed: %d\n", __func__, ret); 349 return ret; 350 } 351 352 /* Initialize OTG PHY */ 353 tcphy = dev_get_priv(udev); 354 for (tries = 0; tries < POWER_ON_TRIES; tries++) { 355 ret = _rockchip_usb3_phy_power_on(tcphy); 356 if (!ret) 357 break; 358 } 359 360 if (tries && !ret) 361 pr_err("%s: needed %d loops to turn on\n", __func__, tries); 362 363 return ret; 364 } 365 366 static int tcphy_get_param(struct udevice *dev, 367 struct usb3phy_reg *reg, 368 const char *name) 369 { 370 u32 buffer[3]; 371 int ret; 372 373 ret = dev_read_u32_array(dev, name, buffer, 3); 374 if (ret) { 375 pr_err("%s: Can not parse %s\n", __func__, name); 376 return ret; 377 } 378 379 reg->offset = buffer[0]; 380 reg->enable_bit = buffer[1]; 381 reg->write_enable = buffer[2]; 382 383 return 0; 384 } 385 386 static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy, 387 struct udevice *dev) 388 { 389 struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs; 390 int ret; 391 392 ret = tcphy_get_param(dev, &cfg->typec_conn_dir, 393 "rockchip,typec-conn-dir"); 394 if (ret) 395 return ret; 396 397 ret = tcphy_get_param(dev, &cfg->usb3tousb2_en, 398 "rockchip,usb3tousb2-en"); 399 if (ret) 400 return ret; 401 402 ret = tcphy_get_param(dev, &cfg->usb3host_disable, 403 "rockchip,usb3-host-disable"); 404 if (ret) 405 return ret; 406 407 ret = tcphy_get_param(dev, &cfg->usb3host_port, 408 "rockchip,usb3-host-port"); 409 if (ret) 410 return ret; 411 412 ret = tcphy_get_param(dev, &cfg->external_psm, 413 "rockchip,external-psm"); 414 if (ret) 415 return ret; 416 417 ret = tcphy_get_param(dev, &cfg->pipe_status, 418 "rockchip,pipe-status"); 419 if (ret) 420 return ret; 421 422 tcphy->grf_regs = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 423 if (IS_ERR(tcphy->grf_regs)) { 424 dev_err(dev, "could not find grf dt node\n"); 425 return PTR_ERR(tcphy->grf_regs); 426 } 427 428 ret = reset_get_by_name(dev, "uphy", &tcphy->uphy_rst); 429 if (ret) { 430 dev_err(dev, "no uphy_rst reset control found\n"); 431 return ret; 432 } 433 434 ret = reset_get_by_name(dev, "uphy-pipe", &tcphy->pipe_rst); 435 if (ret) { 436 dev_err(dev, "no pipe_rst reset control found\n"); 437 return ret; 438 } 439 440 ret = reset_get_by_name(dev, "uphy-pipe", &tcphy->tcphy_rst); 441 if (ret) { 442 dev_err(dev, "no tcphy_rst reset control found\n"); 443 return ret; 444 } 445 446 return 0; 447 } 448 449 static void typec_phy_pre_init(struct rockchip_typec_phy *tcphy) 450 { 451 struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs; 452 453 reset_assert(&tcphy->tcphy_rst); 454 reset_assert(&tcphy->uphy_rst); 455 reset_assert(&tcphy->pipe_rst); 456 457 /* select external psm clock */ 458 property_enable(tcphy, &cfg->external_psm, 1); 459 property_enable(tcphy, &cfg->usb3tousb2_en, 0); 460 461 tcphy->mode = MODE_DISCONNECT; 462 } 463 464 static int rockchip_typec_phy_bind(struct udevice *parent) 465 { 466 struct udevice *dev; 467 ofnode node; 468 const char *name; 469 int ret; 470 471 dev_for_each_subnode(node, parent) { 472 if (!ofnode_valid(node)) { 473 debug("%s: %s subnode not found", __func__, parent->name); 474 return -ENXIO; 475 } 476 477 name = ofnode_get_name(node); 478 debug("%s: subnode %s\n", __func__, name); 479 480 if (!strcasecmp(name, "usb3-port")) { 481 ret = device_bind_driver_to_node(parent, "rockchip_typec_phy_port", 482 name, node, &dev); 483 if (ret) { 484 pr_err("%s: '%s' cannot bind 'rockchip_typec_phy_port'\n", 485 __func__, name); 486 return ret; 487 } 488 } 489 } 490 491 return 0; 492 } 493 494 static int rockchip_typec_phy_probe(struct udevice *udev) 495 { 496 struct rockchip_typec_phy *tcphy = dev_get_priv(udev); 497 int ret; 498 499 tcphy->base = (void __iomem *)dev_read_addr(udev); 500 if (IS_ERR(tcphy->base)) 501 return PTR_ERR(tcphy->base); 502 503 ret = tcphy_parse_dt(tcphy, udev); 504 if (ret) 505 return ret; 506 507 tcphy->dev = udev; 508 mutex_init(&tcphy->lock); 509 510 typec_phy_pre_init(tcphy); 511 512 printf("Rockchip Type-C PHY is initialized\n"); 513 return 0; 514 } 515 516 static const struct udevice_id rockchip_typec_phy_dt_ids[] = { 517 { .compatible = "rockchip,rk3399-typec-phy" }, 518 {} 519 }; 520 521 U_BOOT_DRIVER(rockchip_typec_phy_port) = { 522 .name = "rockchip_typec_phy_port", 523 .id = UCLASS_PHY, 524 .ops = &rockchip_usb3_phy_ops, 525 }; 526 527 U_BOOT_DRIVER(rockchip_typec_phy) = { 528 .name = "rockchip_typec_phy", 529 .id = UCLASS_PHY, 530 .of_match = rockchip_typec_phy_dt_ids, 531 .probe = rockchip_typec_phy_probe, 532 .bind = rockchip_typec_phy_bind, 533 .priv_auto_alloc_size = sizeof(struct rockchip_typec_phy), 534 }; 535