1 /* 2 * Copyright 2017 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <dm/lists.h> 10 #include <generic-phy.h> 11 #include <linux/ioport.h> 12 #include <power/regulator.h> 13 #include <regmap.h> 14 #include <syscon.h> 15 #include <asm/io.h> 16 #include <asm/arch/clock.h> 17 #include <asm/arch/cpu.h> 18 #include <reset-uclass.h> 19 20 #include "../usb/gadget/dwc2_udc_otg_priv.h" 21 22 #define U2PHY_BIT_WRITEABLE_SHIFT 16 23 #define CHG_DCD_MAX_RETRIES 6 24 #define CHG_PRI_MAX_RETRIES 2 25 #define CHG_DCD_POLL_TIME 100 /* millisecond */ 26 #define CHG_PRIMARY_DET_TIME 40 /* millisecond */ 27 #define CHG_SECONDARY_DET_TIME 40 /* millisecond */ 28 29 struct rockchip_usb2phy; 30 31 enum power_supply_type { 32 POWER_SUPPLY_TYPE_UNKNOWN = 0, 33 POWER_SUPPLY_TYPE_USB, /* Standard Downstream Port */ 34 POWER_SUPPLY_TYPE_USB_DCP, /* Dedicated Charging Port */ 35 POWER_SUPPLY_TYPE_USB_CDP, /* Charging Downstream Port */ 36 POWER_SUPPLY_TYPE_USB_FLOATING, /* DCP without shorting D+/D- */ 37 }; 38 39 enum rockchip_usb2phy_port_id { 40 USB2PHY_PORT_OTG, 41 USB2PHY_PORT_HOST, 42 USB2PHY_NUM_PORTS, 43 }; 44 45 struct usb2phy_reg { 46 u32 offset; 47 u32 bitend; 48 u32 bitstart; 49 u32 disable; 50 u32 enable; 51 }; 52 53 /** 54 * struct rockchip_chg_det_reg: usb charger detect registers 55 * @cp_det: charging port detected successfully. 56 * @dcp_det: dedicated charging port detected successfully. 57 * @dp_det: assert data pin connect successfully. 58 * @idm_sink_en: open dm sink curren. 59 * @idp_sink_en: open dp sink current. 60 * @idp_src_en: open dm source current. 61 * @rdm_pdwn_en: open dm pull down resistor. 62 * @vdm_src_en: open dm voltage source. 63 * @vdp_src_en: open dp voltage source. 64 * @opmode: utmi operational mode. 65 */ 66 struct rockchip_chg_det_reg { 67 struct usb2phy_reg cp_det; 68 struct usb2phy_reg dcp_det; 69 struct usb2phy_reg dp_det; 70 struct usb2phy_reg idm_sink_en; 71 struct usb2phy_reg idp_sink_en; 72 struct usb2phy_reg idp_src_en; 73 struct usb2phy_reg rdm_pdwn_en; 74 struct usb2phy_reg vdm_src_en; 75 struct usb2phy_reg vdp_src_en; 76 struct usb2phy_reg opmode; 77 }; 78 79 /** 80 * struct rockchip_usb2phy_port_cfg: usb-phy port configuration. 81 * @phy_sus: phy suspend register. 82 * @bvalid_det_en: vbus valid rise detection enable register. 83 * @bvalid_det_st: vbus valid rise detection status register. 84 * @bvalid_det_clr: vbus valid rise detection clear register. 85 * @ls_det_en: linestate detection enable register. 86 * @ls_det_st: linestate detection state register. 87 * @ls_det_clr: linestate detection clear register. 88 * @iddig_output: iddig output from grf. 89 * @iddig_en: utmi iddig select between grf and phy, 90 * 0: from phy; 1: from grf 91 * @idfall_det_en: id fall detection enable register. 92 * @idfall_det_st: id fall detection state register. 93 * @idfall_det_clr: id fall detection clear register. 94 * @idrise_det_en: id rise detection enable register. 95 * @idrise_det_st: id rise detection state register. 96 * @idrise_det_clr: id rise detection clear register. 97 * @utmi_avalid: utmi vbus avalid status register. 98 * @utmi_bvalid: utmi vbus bvalid status register. 99 * @utmi_iddig: otg port id pin status register. 100 * @utmi_ls: utmi linestate state register. 101 * @utmi_hstdet: utmi host disconnect register. 102 * @vbus_det_en: vbus detect function power down register. 103 */ 104 struct rockchip_usb2phy_port_cfg { 105 struct usb2phy_reg phy_sus; 106 struct usb2phy_reg bvalid_det_en; 107 struct usb2phy_reg bvalid_det_st; 108 struct usb2phy_reg bvalid_det_clr; 109 struct usb2phy_reg ls_det_en; 110 struct usb2phy_reg ls_det_st; 111 struct usb2phy_reg ls_det_clr; 112 struct usb2phy_reg iddig_output; 113 struct usb2phy_reg iddig_en; 114 struct usb2phy_reg idfall_det_en; 115 struct usb2phy_reg idfall_det_st; 116 struct usb2phy_reg idfall_det_clr; 117 struct usb2phy_reg idrise_det_en; 118 struct usb2phy_reg idrise_det_st; 119 struct usb2phy_reg idrise_det_clr; 120 struct usb2phy_reg utmi_avalid; 121 struct usb2phy_reg utmi_bvalid; 122 struct usb2phy_reg utmi_iddig; 123 struct usb2phy_reg utmi_ls; 124 struct usb2phy_reg utmi_hstdet; 125 struct usb2phy_reg vbus_det_en; 126 }; 127 128 /** 129 * struct rockchip_usb2phy_cfg: usb-phy configuration. 130 * @reg: the address offset of grf for usb-phy config. 131 * @num_ports: specify how many ports that the phy has. 132 * @phy_tuning: phy default parameters tunning. 133 * @clkout_ctl: keep on/turn off output clk of phy. 134 * @chg_det: charger detection registers. 135 */ 136 struct rockchip_usb2phy_cfg { 137 u32 reg; 138 u32 num_ports; 139 int (*phy_tuning)(struct rockchip_usb2phy *); 140 struct usb2phy_reg clkout_ctl; 141 const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS]; 142 const struct rockchip_chg_det_reg chg_det; 143 }; 144 145 /** 146 * @dcd_retries: The retry count used to track Data contact 147 * detection process. 148 * @primary_retries: The retry count used to do usb bc detection 149 * primary stage. 150 * @grf: General Register Files register base. 151 * @usbgrf_base : USB General Register Files register base. 152 * @phy_rst: phy reset control. 153 * @phy_cfg: phy register configuration, assigned by driver data. 154 */ 155 struct rockchip_usb2phy { 156 u8 dcd_retries; 157 u8 primary_retries; 158 struct regmap *grf_base; 159 struct regmap *usbgrf_base; 160 struct udevice *vbus_supply[USB2PHY_NUM_PORTS]; 161 struct reset_ctl phy_rst; 162 const struct rockchip_usb2phy_cfg *phy_cfg; 163 }; 164 165 static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy) 166 { 167 return !rphy->usbgrf_base ? rphy->grf_base : rphy->usbgrf_base; 168 } 169 170 static inline int property_enable(struct regmap *base, 171 const struct usb2phy_reg *reg, bool en) 172 { 173 u32 val, mask, tmp; 174 175 tmp = en ? reg->enable : reg->disable; 176 mask = GENMASK(reg->bitend, reg->bitstart); 177 val = (tmp << reg->bitstart) | (mask << U2PHY_BIT_WRITEABLE_SHIFT); 178 179 return regmap_write(base, reg->offset, val); 180 } 181 182 static inline bool property_enabled(struct regmap *base, 183 const struct usb2phy_reg *reg) 184 { 185 u32 tmp, orig; 186 u32 mask = GENMASK(reg->bitend, reg->bitstart); 187 188 regmap_read(base, reg->offset, &orig); 189 190 tmp = (orig & mask) >> reg->bitstart; 191 192 return tmp == reg->enable; 193 } 194 195 static const char *chg_to_string(enum power_supply_type chg_type) 196 { 197 switch (chg_type) { 198 case POWER_SUPPLY_TYPE_USB: 199 return "USB_SDP_CHARGER"; 200 case POWER_SUPPLY_TYPE_USB_DCP: 201 return "USB_DCP_CHARGER"; 202 case POWER_SUPPLY_TYPE_USB_CDP: 203 return "USB_CDP_CHARGER"; 204 case POWER_SUPPLY_TYPE_USB_FLOATING: 205 return "USB_FLOATING_CHARGER"; 206 default: 207 return "INVALID_CHARGER"; 208 } 209 } 210 211 static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy, 212 bool en) 213 { 214 struct regmap *base = get_reg_base(rphy); 215 216 property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en); 217 property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en); 218 } 219 220 static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy, 221 bool en) 222 { 223 struct regmap *base = get_reg_base(rphy); 224 225 property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en); 226 property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en); 227 } 228 229 static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy, 230 bool en) 231 { 232 struct regmap *base = get_reg_base(rphy); 233 234 property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en); 235 property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en); 236 } 237 238 static bool rockchip_chg_primary_det_retry(struct rockchip_usb2phy *rphy) 239 { 240 bool vout = false; 241 struct regmap *base = get_reg_base(rphy); 242 243 while (rphy->primary_retries--) { 244 /* voltage source on DP, probe on DM */ 245 rockchip_chg_enable_primary_det(rphy, true); 246 mdelay(CHG_PRIMARY_DET_TIME); 247 vout = property_enabled(base, &rphy->phy_cfg->chg_det.cp_det); 248 if (vout) 249 break; 250 } 251 252 rockchip_chg_enable_primary_det(rphy, false); 253 return vout; 254 } 255 256 int rockchip_chg_get_type(void) 257 { 258 const struct rockchip_usb2phy_port_cfg *port_cfg; 259 enum power_supply_type chg_type; 260 struct rockchip_usb2phy *rphy; 261 struct udevice *udev; 262 struct regmap *base; 263 bool is_dcd, vout; 264 int ret; 265 266 ret = uclass_get_device_by_name(UCLASS_PHY, "usb2-phy", &udev); 267 if (ret == -ENODEV) { 268 pr_err("%s: get u2phy node failed: %d\n", __func__, ret); 269 return ret; 270 } 271 272 rphy = dev_get_priv(udev); 273 base = get_reg_base(rphy); 274 port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG]; 275 276 /* Check USB-Vbus status first */ 277 if (!property_enabled(base, &port_cfg->utmi_bvalid)) { 278 pr_info("%s: no charger found\n", __func__); 279 return POWER_SUPPLY_TYPE_UNKNOWN; 280 } 281 282 /* Suspend USB-PHY and put the controller in non-driving mode */ 283 property_enable(base, &port_cfg->phy_sus, true); 284 property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); 285 286 rphy->dcd_retries = CHG_DCD_MAX_RETRIES; 287 rphy->primary_retries = CHG_PRI_MAX_RETRIES; 288 289 /* stage 1, start DCD processing stage */ 290 rockchip_chg_enable_dcd(rphy, true); 291 292 while (rphy->dcd_retries--) { 293 mdelay(CHG_DCD_POLL_TIME); 294 295 /* get data contact detection status */ 296 is_dcd = property_enabled(base, &rphy->phy_cfg->chg_det.dp_det); 297 298 if (is_dcd || !rphy->dcd_retries) { 299 /* 300 * stage 2, turn off DCD circuitry, then 301 * voltage source on DP, probe on DM. 302 */ 303 rockchip_chg_enable_dcd(rphy, false); 304 rockchip_chg_enable_primary_det(rphy, true); 305 break; 306 } 307 } 308 309 mdelay(CHG_PRIMARY_DET_TIME); 310 vout = property_enabled(base, &rphy->phy_cfg->chg_det.cp_det); 311 rockchip_chg_enable_primary_det(rphy, false); 312 if (vout) { 313 /* stage 3, voltage source on DM, probe on DP */ 314 rockchip_chg_enable_secondary_det(rphy, true); 315 } else { 316 if (!rphy->dcd_retries) { 317 /* floating charger found */ 318 chg_type = POWER_SUPPLY_TYPE_USB_FLOATING; 319 goto out; 320 } else { 321 /* 322 * Retry some times to make sure that it's 323 * really a USB SDP charger. 324 */ 325 vout = rockchip_chg_primary_det_retry(rphy); 326 if (vout) { 327 /* stage 3, voltage source on DM, probe on DP */ 328 rockchip_chg_enable_secondary_det(rphy, true); 329 } else { 330 /* USB SDP charger found */ 331 chg_type = POWER_SUPPLY_TYPE_USB; 332 goto out; 333 } 334 } 335 } 336 337 mdelay(CHG_SECONDARY_DET_TIME); 338 vout = property_enabled(base, &rphy->phy_cfg->chg_det.dcp_det); 339 /* stage 4, turn off voltage source */ 340 rockchip_chg_enable_secondary_det(rphy, false); 341 if (vout) 342 chg_type = POWER_SUPPLY_TYPE_USB_DCP; 343 else 344 chg_type = POWER_SUPPLY_TYPE_USB_CDP; 345 346 out: 347 /* Resume USB-PHY and put the controller in normal mode */ 348 property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); 349 property_enable(base, &port_cfg->phy_sus, false); 350 351 debug("charger is %s\n", chg_to_string(chg_type)); 352 353 return chg_type; 354 } 355 356 int rockchip_u2phy_vbus_detect(void) 357 { 358 int chg_type; 359 360 chg_type = rockchip_chg_get_type(); 361 362 return (chg_type == POWER_SUPPLY_TYPE_USB || 363 chg_type == POWER_SUPPLY_TYPE_USB_CDP) ? 1 : 0; 364 } 365 366 void otg_phy_init(struct dwc2_udc *dev) 367 { 368 const struct rockchip_usb2phy_port_cfg *port_cfg; 369 struct rockchip_usb2phy *rphy; 370 struct udevice *udev; 371 struct regmap *base; 372 int ret; 373 374 ret = uclass_get_device_by_name(UCLASS_PHY, "usb2-phy", &udev); 375 if (ret == -ENODEV) { 376 pr_err("%s: get u2phy node failed: %d\n", __func__, ret); 377 return; 378 } 379 380 rphy = dev_get_priv(udev); 381 base = get_reg_base(rphy); 382 port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG]; 383 384 /* Set the USB-PHY COMMONONN to 1'b0 to ensure USB's clocks */ 385 property_enable(base, &rphy->phy_cfg->clkout_ctl, false); 386 387 /* Reset USB-PHY */ 388 property_enable(base, &port_cfg->phy_sus, true); 389 udelay(20); 390 property_enable(base, &port_cfg->phy_sus, false); 391 mdelay(2); 392 } 393 394 static struct udevice *rockchip_usb2phy_check_vbus(struct phy *phy) 395 { 396 struct udevice *parent = phy->dev->parent; 397 struct rockchip_usb2phy *rphy = dev_get_priv(parent); 398 const struct rockchip_usb2phy_port_cfg *port_cfg; 399 struct regmap *base = get_reg_base(rphy); 400 struct udevice *vbus = NULL; 401 bool iddig = true; 402 403 if (phy->id == USB2PHY_PORT_HOST) { 404 vbus = rphy->vbus_supply[USB2PHY_PORT_HOST]; 405 } else if (phy->id == USB2PHY_PORT_OTG) { 406 port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG]; 407 if (port_cfg->utmi_iddig.offset) { 408 iddig = property_enabled(base, &port_cfg->utmi_iddig); 409 if (!iddig) 410 vbus = rphy->vbus_supply[USB2PHY_PORT_OTG]; 411 } 412 } 413 414 return vbus; 415 } 416 417 static int rockchip_usb2phy_reset(struct rockchip_usb2phy *rphy) 418 { 419 int ret; 420 421 if (rphy->phy_rst.dev) { 422 ret = reset_assert(&rphy->phy_rst); 423 if (ret < 0) { 424 pr_err("u2phy assert reset failed: %d", ret); 425 return ret; 426 } 427 428 udelay(20); 429 430 ret = reset_deassert(&rphy->phy_rst); 431 if (ret < 0) { 432 pr_err("u2phy deassert reset failed: %d", ret); 433 return ret; 434 } 435 436 udelay(100); 437 } 438 439 return 0; 440 } 441 442 static int rockchip_usb2phy_init(struct phy *phy) 443 { 444 struct udevice *parent = phy->dev->parent; 445 struct rockchip_usb2phy *rphy = dev_get_priv(parent); 446 const struct rockchip_usb2phy_port_cfg *port_cfg; 447 struct regmap *base = get_reg_base(rphy); 448 449 if (phy->id == USB2PHY_PORT_OTG) { 450 port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG]; 451 } else if (phy->id == USB2PHY_PORT_HOST) { 452 port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST]; 453 } else { 454 dev_err(phy->dev, "phy id %lu not support", phy->id); 455 return -EINVAL; 456 } 457 458 property_enable(base, &port_cfg->phy_sus, false); 459 460 /* waiting for the utmi_clk to become stable */ 461 udelay(2000); 462 463 return 0; 464 } 465 466 static int rockchip_usb2phy_exit(struct phy *phy) 467 { 468 struct udevice *parent = phy->dev->parent; 469 struct rockchip_usb2phy *rphy = dev_get_priv(parent); 470 const struct rockchip_usb2phy_port_cfg *port_cfg; 471 struct regmap *base = get_reg_base(rphy); 472 473 if (phy->id == USB2PHY_PORT_OTG) { 474 port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG]; 475 } else if (phy->id == USB2PHY_PORT_HOST) { 476 port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST]; 477 } else { 478 dev_err(phy->dev, "phy id %lu not support", phy->id); 479 return -EINVAL; 480 } 481 482 property_enable(base, &port_cfg->phy_sus, true); 483 484 return 0; 485 } 486 487 static int rockchip_usb2phy_power_on(struct phy *phy) 488 { 489 struct udevice *vbus = NULL; 490 int ret; 491 492 vbus = rockchip_usb2phy_check_vbus(phy); 493 if (vbus) { 494 ret = regulator_set_enable(vbus, true); 495 if (ret) { 496 pr_err("%s: Failed to set VBus supply\n", __func__); 497 return ret; 498 } 499 } 500 501 return 0; 502 } 503 504 static int rockchip_usb2phy_power_off(struct phy *phy) 505 { 506 struct udevice *vbus = NULL; 507 int ret; 508 509 vbus = rockchip_usb2phy_check_vbus(phy); 510 if (vbus) { 511 ret = regulator_set_enable(vbus, false); 512 if (ret) { 513 pr_err("%s: Failed to set VBus supply\n", __func__); 514 return ret; 515 } 516 } 517 518 return 0; 519 } 520 521 static int rockchip_usb2phy_of_xlate(struct phy *phy, 522 struct ofnode_phandle_args *args) 523 { 524 const char *dev_name = phy->dev->name; 525 struct udevice *parent = phy->dev->parent; 526 struct rockchip_usb2phy *rphy = dev_get_priv(parent); 527 528 if (!strcasecmp(dev_name, "host-port")) { 529 phy->id = USB2PHY_PORT_HOST; 530 device_get_supply_regulator(phy->dev, "phy-supply", 531 &rphy->vbus_supply[USB2PHY_PORT_HOST]); 532 } else if (!strcasecmp(dev_name, "otg-port")) { 533 phy->id = USB2PHY_PORT_OTG; 534 device_get_supply_regulator(phy->dev, "phy-supply", 535 &rphy->vbus_supply[USB2PHY_PORT_OTG]); 536 } else { 537 pr_err("%s: invalid dev name\n", __func__); 538 return -EINVAL; 539 } 540 541 return 0; 542 } 543 544 static int rockchip_usb2phy_bind(struct udevice *dev) 545 { 546 struct udevice *child; 547 ofnode subnode; 548 const char *node_name; 549 int ret; 550 551 dev_for_each_subnode(subnode, dev) { 552 if (!ofnode_valid(subnode)) { 553 debug("%s: %s subnode not found", __func__, dev->name); 554 return -ENXIO; 555 } 556 557 node_name = ofnode_get_name(subnode); 558 debug("%s: subnode %s\n", __func__, node_name); 559 560 ret = device_bind_driver_to_node(dev, "rockchip_usb2phy_port", 561 node_name, subnode, &child); 562 if (ret) { 563 pr_err("%s: '%s' cannot bind 'rockchip_usb2phy_port'\n", 564 __func__, node_name); 565 return ret; 566 } 567 } 568 569 return 0; 570 } 571 572 static int rockchip_usb2phy_probe(struct udevice *dev) 573 { 574 const struct rockchip_usb2phy_cfg *phy_cfgs; 575 struct rockchip_usb2phy *rphy = dev_get_priv(dev); 576 struct udevice *parent = dev->parent; 577 struct udevice *syscon; 578 struct resource res; 579 u32 reg, index; 580 int ret; 581 582 if (!strncmp(parent->name, "root_driver", 11) && 583 dev_read_bool(dev, "rockchip,grf")) { 584 ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, 585 "rockchip,grf", &syscon); 586 if (ret) { 587 dev_err(dev, "get syscon grf failed\n"); 588 return ret; 589 } 590 591 rphy->grf_base = syscon_get_regmap(syscon); 592 } else { 593 rphy->grf_base = syscon_get_regmap(parent); 594 } 595 596 if (rphy->grf_base <= 0) { 597 dev_err(dev, "get syscon grf regmap failed\n"); 598 return -EINVAL; 599 } 600 601 if (dev_read_bool(dev, "rockchip,usbgrf")) { 602 ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, 603 "rockchip,usbgrf", &syscon); 604 if (ret) { 605 dev_err(dev, "get syscon usbgrf failed\n"); 606 return ret; 607 } 608 609 rphy->usbgrf_base = syscon_get_regmap(syscon); 610 if (rphy->usbgrf_base <= 0) { 611 dev_err(dev, "get syscon usbgrf regmap failed\n"); 612 return -EINVAL; 613 } 614 } else { 615 rphy->usbgrf_base = NULL; 616 } 617 618 if (!strncmp(parent->name, "root_driver", 11)) { 619 ret = dev_read_resource(dev, 0, &res); 620 reg = res.start; 621 } else { 622 ret = ofnode_read_u32(dev_ofnode(dev), "reg", ®); 623 } 624 625 if (ret) { 626 dev_err(dev, "could not read reg\n"); 627 return -EINVAL; 628 } 629 630 ret = reset_get_by_name(dev, "phy", &rphy->phy_rst); 631 if (ret) 632 dev_dbg(dev, "no u2phy reset control specified\n"); 633 634 phy_cfgs = 635 (const struct rockchip_usb2phy_cfg *)dev_get_driver_data(dev); 636 if (!phy_cfgs) { 637 dev_err(dev, "unable to get phy_cfgs\n"); 638 return -EINVAL; 639 } 640 641 /* find out a proper config which can be matched with dt. */ 642 index = 0; 643 do { 644 if (phy_cfgs[index].reg == reg) { 645 rphy->phy_cfg = &phy_cfgs[index]; 646 break; 647 } 648 ++index; 649 } while (phy_cfgs[index].reg); 650 651 if (!rphy->phy_cfg) { 652 dev_err(dev, "no phy-config can be matched\n"); 653 return -EINVAL; 654 } 655 656 if (rphy->phy_cfg->phy_tuning) 657 rphy->phy_cfg->phy_tuning(rphy); 658 659 return 0; 660 } 661 662 static int rk322x_usb2phy_tuning(struct rockchip_usb2phy *rphy) 663 { 664 struct regmap *base = get_reg_base(rphy); 665 int ret = 0; 666 667 /* Open pre-emphasize in non-chirp state for PHY0 otg port */ 668 if (rphy->phy_cfg->reg == 0x760) 669 ret = regmap_write(base, 0x76c, 0x00070004); 670 671 return ret; 672 } 673 674 static int rk3308_usb2phy_tuning(struct rockchip_usb2phy *rphy) 675 { 676 struct regmap *base = get_reg_base(rphy); 677 unsigned int tmp, orig; 678 int ret; 679 680 if (soc_is_rk3308bs()) { 681 /* Enable otg/host port pre-emphasis during non-chirp phase */ 682 ret = regmap_read(base, 0, &orig); 683 if (ret) 684 return ret; 685 tmp = orig & ~GENMASK(2, 0); 686 tmp |= BIT(2) & GENMASK(2, 0); 687 ret = regmap_write(base, 0, tmp); 688 if (ret) 689 return ret; 690 691 /* Set otg port squelch trigger point configure to 100mv */ 692 ret = regmap_read(base, 0x004, &orig); 693 if (ret) 694 return ret; 695 tmp = orig & ~GENMASK(7, 5); 696 tmp |= 0x40 & GENMASK(7, 5); 697 ret = regmap_write(base, 0x004, tmp); 698 if (ret) 699 return ret; 700 701 ret = regmap_read(base, 0x008, &orig); 702 if (ret) 703 return ret; 704 tmp = orig & ~BIT(0); 705 tmp |= 0x1 & BIT(0); 706 ret = regmap_write(base, 0x008, tmp); 707 if (ret) 708 return ret; 709 710 /* Enable host port pre-emphasis during non-chirp phase */ 711 ret = regmap_read(base, 0x400, &orig); 712 if (ret) 713 return ret; 714 tmp = orig & ~GENMASK(2, 0); 715 tmp |= BIT(2) & GENMASK(2, 0); 716 ret = regmap_write(base, 0x400, tmp); 717 if (ret) 718 return ret; 719 720 /* Set host port squelch trigger point configure to 100mv */ 721 ret = regmap_read(base, 0x404, &orig); 722 if (ret) 723 return ret; 724 tmp = orig & ~GENMASK(7, 5); 725 tmp |= 0x40 & GENMASK(7, 5); 726 ret = regmap_write(base, 0x404, tmp); 727 if (ret) 728 return ret; 729 730 ret = regmap_read(base, 0x408, &orig); 731 if (ret) 732 return ret; 733 tmp = orig & ~BIT(0); 734 tmp |= 0x1 & BIT(0); 735 ret = regmap_write(base, 0x408, tmp); 736 if (ret) 737 return ret; 738 } 739 740 return 0; 741 } 742 743 static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy) 744 { 745 struct regmap *base = get_reg_base(rphy); 746 int ret; 747 748 /* Deassert SIDDQ to power on analog block */ 749 ret = regmap_write(base, 0x0008, GENMASK(29, 29) | 0x0000); 750 if (ret) 751 return ret; 752 753 /* Do reset after exit IDDQ mode */ 754 ret = rockchip_usb2phy_reset(rphy); 755 if (ret) 756 return ret; 757 758 /* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */ 759 ret = regmap_write(base, 0x0004, GENMASK(27, 24) | 0x0900); 760 if (ret) 761 return ret; 762 763 /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */ 764 ret = regmap_write(base, 0x0008, GENMASK(20, 19) | 0x0010); 765 if (ret) 766 return ret; 767 768 return 0; 769 } 770 771 static struct phy_ops rockchip_usb2phy_ops = { 772 .init = rockchip_usb2phy_init, 773 .exit = rockchip_usb2phy_exit, 774 .power_on = rockchip_usb2phy_power_on, 775 .power_off = rockchip_usb2phy_power_off, 776 .of_xlate = rockchip_usb2phy_of_xlate, 777 }; 778 779 static const struct rockchip_usb2phy_cfg rk1808_phy_cfgs[] = { 780 { 781 .reg = 0x100, 782 .num_ports = 2, 783 .clkout_ctl = { 0x108, 4, 4, 1, 0 }, 784 .port_cfgs = { 785 [USB2PHY_PORT_OTG] = { 786 .phy_sus = { 0x0100, 8, 0, 0, 0x1d1 }, 787 .bvalid_det_en = { 0x0110, 2, 2, 0, 1 }, 788 .bvalid_det_st = { 0x0114, 2, 2, 0, 1 }, 789 .bvalid_det_clr = { 0x0118, 2, 2, 0, 1 }, 790 .iddig_output = { 0x0100, 10, 10, 0, 1 }, 791 .iddig_en = { 0x0100, 9, 9, 0, 1 }, 792 .idfall_det_en = { 0x0110, 5, 5, 0, 1 }, 793 .idfall_det_st = { 0x0114, 5, 5, 0, 1 }, 794 .idfall_det_clr = { 0x0118, 5, 5, 0, 1 }, 795 .idrise_det_en = { 0x0110, 4, 4, 0, 1 }, 796 .idrise_det_st = { 0x0114, 4, 4, 0, 1 }, 797 .idrise_det_clr = { 0x0118, 4, 4, 0, 1 }, 798 .ls_det_en = { 0x0110, 0, 0, 0, 1 }, 799 .ls_det_st = { 0x0114, 0, 0, 0, 1 }, 800 .ls_det_clr = { 0x0118, 0, 0, 0, 1 }, 801 .utmi_avalid = { 0x0120, 10, 10, 0, 1 }, 802 .utmi_bvalid = { 0x0120, 9, 9, 0, 1 }, 803 .utmi_iddig = { 0x0120, 6, 6, 0, 1 }, 804 .utmi_ls = { 0x0120, 5, 4, 0, 1 }, 805 .vbus_det_en = { 0x001c, 15, 15, 1, 0 }, 806 }, 807 [USB2PHY_PORT_HOST] = { 808 .phy_sus = { 0x104, 8, 0, 0, 0x1d1 }, 809 .ls_det_en = { 0x110, 1, 1, 0, 1 }, 810 .ls_det_st = { 0x114, 1, 1, 0, 1 }, 811 .ls_det_clr = { 0x118, 1, 1, 0, 1 }, 812 .utmi_ls = { 0x120, 17, 16, 0, 1 }, 813 .utmi_hstdet = { 0x120, 19, 19, 0, 1 } 814 } 815 }, 816 .chg_det = { 817 .opmode = { 0x0100, 3, 0, 5, 1 }, 818 .cp_det = { 0x0120, 24, 24, 0, 1 }, 819 .dcp_det = { 0x0120, 23, 23, 0, 1 }, 820 .dp_det = { 0x0120, 25, 25, 0, 1 }, 821 .idm_sink_en = { 0x0108, 8, 8, 0, 1 }, 822 .idp_sink_en = { 0x0108, 7, 7, 0, 1 }, 823 .idp_src_en = { 0x0108, 9, 9, 0, 1 }, 824 .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 }, 825 .vdm_src_en = { 0x0108, 12, 12, 0, 1 }, 826 .vdp_src_en = { 0x0108, 11, 11, 0, 1 }, 827 }, 828 }, 829 { /* sentinel */ } 830 }; 831 832 static const struct rockchip_usb2phy_cfg rk312x_phy_cfgs[] = { 833 { 834 .reg = 0x17c, 835 .num_ports = 2, 836 .clkout_ctl = { 0x0190, 15, 15, 1, 0 }, 837 .port_cfgs = { 838 [USB2PHY_PORT_OTG] = { 839 .phy_sus = { 0x017c, 8, 0, 0, 0x1d1 }, 840 .bvalid_det_en = { 0x017c, 14, 14, 0, 1 }, 841 .bvalid_det_st = { 0x017c, 15, 15, 0, 1 }, 842 .bvalid_det_clr = { 0x017c, 15, 15, 0, 1 }, 843 .iddig_output = { 0x017c, 10, 10, 0, 1 }, 844 .iddig_en = { 0x017c, 9, 9, 0, 1 }, 845 .idfall_det_en = { 0x01a0, 2, 2, 0, 1 }, 846 .idfall_det_st = { 0x01a0, 3, 3, 0, 1 }, 847 .idfall_det_clr = { 0x01a0, 3, 3, 0, 1 }, 848 .idrise_det_en = { 0x01a0, 0, 0, 0, 1 }, 849 .idrise_det_st = { 0x01a0, 1, 1, 0, 1 }, 850 .idrise_det_clr = { 0x01a0, 1, 1, 0, 1 }, 851 .ls_det_en = { 0x017c, 12, 12, 0, 1 }, 852 .ls_det_st = { 0x017c, 13, 13, 0, 1 }, 853 .ls_det_clr = { 0x017c, 13, 13, 0, 1 }, 854 .utmi_bvalid = { 0x014c, 5, 5, 0, 1 }, 855 .utmi_iddig = { 0x014c, 8, 8, 0, 1 }, 856 .utmi_ls = { 0x014c, 7, 6, 0, 1 }, 857 }, 858 [USB2PHY_PORT_HOST] = { 859 .phy_sus = { 0x0194, 8, 0, 0, 0x1d1 }, 860 .ls_det_en = { 0x0194, 14, 14, 0, 1 }, 861 .ls_det_st = { 0x0194, 15, 15, 0, 1 }, 862 .ls_det_clr = { 0x0194, 15, 15, 0, 1 } 863 } 864 }, 865 .chg_det = { 866 .opmode = { 0x017c, 3, 0, 5, 1 }, 867 .cp_det = { 0x02c0, 6, 6, 0, 1 }, 868 .dcp_det = { 0x02c0, 5, 5, 0, 1 }, 869 .dp_det = { 0x02c0, 7, 7, 0, 1 }, 870 .idm_sink_en = { 0x0184, 8, 8, 0, 1 }, 871 .idp_sink_en = { 0x0184, 7, 7, 0, 1 }, 872 .idp_src_en = { 0x0184, 9, 9, 0, 1 }, 873 .rdm_pdwn_en = { 0x0184, 10, 10, 0, 1 }, 874 .vdm_src_en = { 0x0184, 12, 12, 0, 1 }, 875 .vdp_src_en = { 0x0184, 11, 11, 0, 1 }, 876 }, 877 }, 878 { /* sentinel */ } 879 }; 880 881 static const struct rockchip_usb2phy_cfg rk322x_phy_cfgs[] = { 882 { 883 .reg = 0x760, 884 .num_ports = 2, 885 .phy_tuning = rk322x_usb2phy_tuning, 886 .clkout_ctl = { 0x0768, 4, 4, 1, 0 }, 887 .port_cfgs = { 888 [USB2PHY_PORT_OTG] = { 889 .phy_sus = { 0x0760, 8, 0, 0, 0x1d1 }, 890 .bvalid_det_en = { 0x0680, 3, 3, 0, 1 }, 891 .bvalid_det_st = { 0x0690, 3, 3, 0, 1 }, 892 .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 }, 893 .iddig_output = { 0x0760, 10, 10, 0, 1 }, 894 .iddig_en = { 0x0760, 9, 9, 0, 1 }, 895 .idfall_det_en = { 0x0680, 6, 6, 0, 1 }, 896 .idfall_det_st = { 0x0690, 6, 6, 0, 1 }, 897 .idfall_det_clr = { 0x06a0, 6, 6, 0, 1 }, 898 .idrise_det_en = { 0x0680, 5, 5, 0, 1 }, 899 .idrise_det_st = { 0x0690, 5, 5, 0, 1 }, 900 .idrise_det_clr = { 0x06a0, 5, 5, 0, 1 }, 901 .ls_det_en = { 0x0680, 2, 2, 0, 1 }, 902 .ls_det_st = { 0x0690, 2, 2, 0, 1 }, 903 .ls_det_clr = { 0x06a0, 2, 2, 0, 1 }, 904 .utmi_bvalid = { 0x0480, 4, 4, 0, 1 }, 905 .utmi_iddig = { 0x0480, 1, 1, 0, 1 }, 906 .utmi_ls = { 0x0480, 3, 2, 0, 1 }, 907 .vbus_det_en = { 0x0788, 15, 15, 1, 0 }, 908 }, 909 [USB2PHY_PORT_HOST] = { 910 .phy_sus = { 0x0764, 8, 0, 0, 0x1d1 }, 911 .ls_det_en = { 0x0680, 4, 4, 0, 1 }, 912 .ls_det_st = { 0x0690, 4, 4, 0, 1 }, 913 .ls_det_clr = { 0x06a0, 4, 4, 0, 1 } 914 } 915 }, 916 .chg_det = { 917 .opmode = { 0x0760, 3, 0, 5, 1 }, 918 .cp_det = { 0x0884, 4, 4, 0, 1 }, 919 .dcp_det = { 0x0884, 3, 3, 0, 1 }, 920 .dp_det = { 0x0884, 5, 5, 0, 1 }, 921 .idm_sink_en = { 0x0768, 8, 8, 0, 1 }, 922 .idp_sink_en = { 0x0768, 7, 7, 0, 1 }, 923 .idp_src_en = { 0x0768, 9, 9, 0, 1 }, 924 .rdm_pdwn_en = { 0x0768, 10, 10, 0, 1 }, 925 .vdm_src_en = { 0x0768, 12, 12, 0, 1 }, 926 .vdp_src_en = { 0x0768, 11, 11, 0, 1 }, 927 }, 928 }, 929 { 930 .reg = 0x800, 931 .num_ports = 2, 932 .clkout_ctl = { 0x0808, 4, 4, 1, 0 }, 933 .port_cfgs = { 934 [USB2PHY_PORT_OTG] = { 935 .phy_sus = { 0x804, 8, 0, 0, 0x1d1 }, 936 .ls_det_en = { 0x0684, 1, 1, 0, 1 }, 937 .ls_det_st = { 0x0694, 1, 1, 0, 1 }, 938 .ls_det_clr = { 0x06a4, 1, 1, 0, 1 } 939 }, 940 [USB2PHY_PORT_HOST] = { 941 .phy_sus = { 0x800, 8, 0, 0, 0x1d1 }, 942 .ls_det_en = { 0x0684, 0, 0, 0, 1 }, 943 .ls_det_st = { 0x0694, 0, 0, 0, 1 }, 944 .ls_det_clr = { 0x06a4, 0, 0, 0, 1 } 945 } 946 }, 947 }, 948 { /* sentinel */ } 949 }; 950 951 static const struct rockchip_usb2phy_cfg rk3308_phy_cfgs[] = { 952 { 953 .reg = 0x100, 954 .num_ports = 2, 955 .phy_tuning = rk3308_usb2phy_tuning, 956 .clkout_ctl = { 0x0108, 4, 4, 1, 0 }, 957 .port_cfgs = { 958 [USB2PHY_PORT_OTG] = { 959 .phy_sus = { 0x0100, 8, 0, 0, 0x1d1 }, 960 .bvalid_det_en = { 0x3020, 2, 2, 0, 1 }, 961 .bvalid_det_st = { 0x3024, 2, 2, 0, 1 }, 962 .bvalid_det_clr = { 0x3028, 2, 2, 0, 1 }, 963 .iddig_output = { 0x0100, 10, 10, 0, 1 }, 964 .iddig_en = { 0x0100, 9, 9, 0, 1 }, 965 .idfall_det_en = { 0x3020, 5, 5, 0, 1 }, 966 .idfall_det_st = { 0x3024, 5, 5, 0, 1 }, 967 .idfall_det_clr = { 0x3028, 5, 5, 0, 1 }, 968 .idrise_det_en = { 0x3020, 4, 4, 0, 1 }, 969 .idrise_det_st = { 0x3024, 4, 4, 0, 1 }, 970 .idrise_det_clr = { 0x3028, 4, 4, 0, 1 }, 971 .ls_det_en = { 0x3020, 0, 0, 0, 1 }, 972 .ls_det_st = { 0x3024, 0, 0, 0, 1 }, 973 .ls_det_clr = { 0x3028, 0, 0, 0, 1 }, 974 .utmi_avalid = { 0x0120, 10, 10, 0, 1 }, 975 .utmi_bvalid = { 0x0120, 9, 9, 0, 1 }, 976 .utmi_iddig = { 0x0120, 6, 6, 0, 1 }, 977 .utmi_ls = { 0x0120, 5, 4, 0, 1 }, 978 .vbus_det_en = { 0x001c, 15, 15, 1, 0 }, 979 }, 980 [USB2PHY_PORT_HOST] = { 981 .phy_sus = { 0x0104, 8, 0, 0, 0x1d1 }, 982 .ls_det_en = { 0x3020, 1, 1, 0, 1 }, 983 .ls_det_st = { 0x3024, 1, 1, 0, 1 }, 984 .ls_det_clr = { 0x3028, 1, 1, 0, 1 }, 985 .utmi_ls = { 0x120, 17, 16, 0, 1 }, 986 .utmi_hstdet = { 0x120, 19, 19, 0, 1 } 987 } 988 }, 989 .chg_det = { 990 .opmode = { 0x0100, 3, 0, 5, 1 }, 991 .cp_det = { 0x0120, 24, 24, 0, 1 }, 992 .dcp_det = { 0x0120, 23, 23, 0, 1 }, 993 .dp_det = { 0x0120, 25, 25, 0, 1 }, 994 .idm_sink_en = { 0x0108, 8, 8, 0, 1 }, 995 .idp_sink_en = { 0x0108, 7, 7, 0, 1 }, 996 .idp_src_en = { 0x0108, 9, 9, 0, 1 }, 997 .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 }, 998 .vdm_src_en = { 0x0108, 12, 12, 0, 1 }, 999 .vdp_src_en = { 0x0108, 11, 11, 0, 1 }, 1000 }, 1001 }, 1002 { /* sentinel */ } 1003 }; 1004 1005 static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = { 1006 { 1007 .reg = 0x100, 1008 .num_ports = 2, 1009 .clkout_ctl = { 0x108, 4, 4, 1, 0 }, 1010 .port_cfgs = { 1011 [USB2PHY_PORT_OTG] = { 1012 .phy_sus = { 0x0100, 8, 0, 0, 0x1d1 }, 1013 .bvalid_det_en = { 0x0110, 2, 2, 0, 1 }, 1014 .bvalid_det_st = { 0x0114, 2, 2, 0, 1 }, 1015 .bvalid_det_clr = { 0x0118, 2, 2, 0, 1 }, 1016 .iddig_output = { 0x0100, 10, 10, 0, 1 }, 1017 .iddig_en = { 0x0100, 9, 9, 0, 1 }, 1018 .idfall_det_en = { 0x0110, 5, 5, 0, 1 }, 1019 .idfall_det_st = { 0x0114, 5, 5, 0, 1 }, 1020 .idfall_det_clr = { 0x0118, 5, 5, 0, 1 }, 1021 .idrise_det_en = { 0x0110, 4, 4, 0, 1 }, 1022 .idrise_det_st = { 0x0114, 4, 4, 0, 1 }, 1023 .idrise_det_clr = { 0x0118, 4, 4, 0, 1 }, 1024 .ls_det_en = { 0x0110, 0, 0, 0, 1 }, 1025 .ls_det_st = { 0x0114, 0, 0, 0, 1 }, 1026 .ls_det_clr = { 0x0118, 0, 0, 0, 1 }, 1027 .utmi_avalid = { 0x0120, 10, 10, 0, 1 }, 1028 .utmi_bvalid = { 0x0120, 9, 9, 0, 1 }, 1029 .utmi_iddig = { 0x0120, 6, 6, 0, 1 }, 1030 .utmi_ls = { 0x0120, 5, 4, 0, 1 }, 1031 .vbus_det_en = { 0x001c, 15, 15, 1, 0 }, 1032 }, 1033 [USB2PHY_PORT_HOST] = { 1034 .phy_sus = { 0x104, 8, 0, 0, 0x1d1 }, 1035 .ls_det_en = { 0x110, 1, 1, 0, 1 }, 1036 .ls_det_st = { 0x114, 1, 1, 0, 1 }, 1037 .ls_det_clr = { 0x118, 1, 1, 0, 1 }, 1038 .utmi_ls = { 0x120, 17, 16, 0, 1 }, 1039 .utmi_hstdet = { 0x120, 19, 19, 0, 1 } 1040 } 1041 }, 1042 .chg_det = { 1043 .opmode = { 0x0100, 3, 0, 5, 1 }, 1044 .cp_det = { 0x0120, 24, 24, 0, 1 }, 1045 .dcp_det = { 0x0120, 23, 23, 0, 1 }, 1046 .dp_det = { 0x0120, 25, 25, 0, 1 }, 1047 .idm_sink_en = { 0x0108, 8, 8, 0, 1 }, 1048 .idp_sink_en = { 0x0108, 7, 7, 0, 1 }, 1049 .idp_src_en = { 0x0108, 9, 9, 0, 1 }, 1050 .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 }, 1051 .vdm_src_en = { 0x0108, 12, 12, 0, 1 }, 1052 .vdp_src_en = { 0x0108, 11, 11, 0, 1 }, 1053 }, 1054 }, 1055 { /* sentinel */ } 1056 }; 1057 1058 static const struct rockchip_usb2phy_cfg rk3368_phy_cfgs[] = { 1059 { 1060 .reg = 0x700, 1061 .num_ports = 2, 1062 .clkout_ctl = { 0x0724, 15, 15, 1, 0 }, 1063 .port_cfgs = { 1064 [USB2PHY_PORT_OTG] = { 1065 .phy_sus = { 0x0700, 8, 0, 0, 0x1d1 }, 1066 .bvalid_det_en = { 0x0680, 3, 3, 0, 1 }, 1067 .bvalid_det_st = { 0x0690, 3, 3, 0, 1 }, 1068 .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 }, 1069 .ls_det_en = { 0x0680, 2, 2, 0, 1 }, 1070 .ls_det_st = { 0x0690, 2, 2, 0, 1 }, 1071 .ls_det_clr = { 0x06a0, 2, 2, 0, 1 }, 1072 .utmi_bvalid = { 0x04bc, 23, 23, 0, 1 }, 1073 .utmi_ls = { 0x04bc, 25, 24, 0, 1 }, 1074 }, 1075 [USB2PHY_PORT_HOST] = { 1076 .phy_sus = { 0x0728, 8, 0, 0, 0x1d1 }, 1077 .ls_det_en = { 0x0680, 4, 4, 0, 1 }, 1078 .ls_det_st = { 0x0690, 4, 4, 0, 1 }, 1079 .ls_det_clr = { 0x06a0, 4, 4, 0, 1 } 1080 } 1081 }, 1082 .chg_det = { 1083 .opmode = { 0x0700, 3, 0, 5, 1 }, 1084 .cp_det = { 0x04b8, 30, 30, 0, 1 }, 1085 .dcp_det = { 0x04b8, 29, 29, 0, 1 }, 1086 .dp_det = { 0x04b8, 31, 31, 0, 1 }, 1087 .idm_sink_en = { 0x0718, 8, 8, 0, 1 }, 1088 .idp_sink_en = { 0x0718, 7, 7, 0, 1 }, 1089 .idp_src_en = { 0x0718, 9, 9, 0, 1 }, 1090 .rdm_pdwn_en = { 0x0718, 10, 10, 0, 1 }, 1091 .vdm_src_en = { 0x0718, 12, 12, 0, 1 }, 1092 .vdp_src_en = { 0x0718, 11, 11, 0, 1 }, 1093 }, 1094 }, 1095 { /* sentinel */ } 1096 }; 1097 1098 static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = { 1099 { 1100 .reg = 0xe450, 1101 .num_ports = 2, 1102 .clkout_ctl = { 0xe450, 4, 4, 1, 0 }, 1103 .port_cfgs = { 1104 [USB2PHY_PORT_OTG] = { 1105 .phy_sus = { 0xe454, 8, 0, 0x052, 0x1d1 }, 1106 .bvalid_det_en = { 0xe3c0, 3, 3, 0, 1 }, 1107 .bvalid_det_st = { 0xe3e0, 3, 3, 0, 1 }, 1108 .bvalid_det_clr = { 0xe3d0, 3, 3, 0, 1 }, 1109 .idfall_det_en = { 0xe3c0, 5, 5, 0, 1 }, 1110 .idfall_det_st = { 0xe3e0, 5, 5, 0, 1 }, 1111 .idfall_det_clr = { 0xe3d0, 5, 5, 0, 1 }, 1112 .idrise_det_en = { 0xe3c0, 4, 4, 0, 1 }, 1113 .idrise_det_st = { 0xe3e0, 4, 4, 0, 1 }, 1114 .idrise_det_clr = { 0xe3d0, 4, 4, 0, 1 }, 1115 .ls_det_en = { 0xe3c0, 2, 2, 0, 1 }, 1116 .ls_det_st = { 0xe3e0, 2, 2, 0, 1 }, 1117 .ls_det_clr = { 0xe3d0, 2, 2, 0, 1 }, 1118 .utmi_avalid = { 0xe2ac, 7, 7, 0, 1 }, 1119 .utmi_bvalid = { 0xe2ac, 12, 12, 0, 1 }, 1120 .utmi_iddig = { 0xe2ac, 8, 8, 0, 1 }, 1121 .utmi_ls = { 0xe2ac, 14, 13, 0, 1 }, 1122 .vbus_det_en = { 0x449c, 15, 15, 1, 0 }, 1123 }, 1124 [USB2PHY_PORT_HOST] = { 1125 .phy_sus = { 0xe458, 1, 0, 0x2, 0x1 }, 1126 .ls_det_en = { 0xe3c0, 6, 6, 0, 1 }, 1127 .ls_det_st = { 0xe3e0, 6, 6, 0, 1 }, 1128 .ls_det_clr = { 0xe3d0, 6, 6, 0, 1 }, 1129 .utmi_ls = { 0xe2ac, 22, 21, 0, 1 }, 1130 .utmi_hstdet = { 0xe2ac, 23, 23, 0, 1 } 1131 } 1132 }, 1133 .chg_det = { 1134 .opmode = { 0xe454, 3, 0, 5, 1 }, 1135 .cp_det = { 0xe2ac, 2, 2, 0, 1 }, 1136 .dcp_det = { 0xe2ac, 1, 1, 0, 1 }, 1137 .dp_det = { 0xe2ac, 0, 0, 0, 1 }, 1138 .idm_sink_en = { 0xe450, 8, 8, 0, 1 }, 1139 .idp_sink_en = { 0xe450, 7, 7, 0, 1 }, 1140 .idp_src_en = { 0xe450, 9, 9, 0, 1 }, 1141 .rdm_pdwn_en = { 0xe450, 10, 10, 0, 1 }, 1142 .vdm_src_en = { 0xe450, 12, 12, 0, 1 }, 1143 .vdp_src_en = { 0xe450, 11, 11, 0, 1 }, 1144 }, 1145 }, 1146 { 1147 .reg = 0xe460, 1148 .num_ports = 2, 1149 .clkout_ctl = { 0xe460, 4, 4, 1, 0 }, 1150 .port_cfgs = { 1151 [USB2PHY_PORT_OTG] = { 1152 .phy_sus = { 0xe464, 8, 0, 0x052, 0x1d1 }, 1153 .bvalid_det_en = { 0xe3c0, 8, 8, 0, 1 }, 1154 .bvalid_det_st = { 0xe3e0, 8, 8, 0, 1 }, 1155 .bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 }, 1156 .idfall_det_en = { 0xe3c0, 10, 10, 0, 1 }, 1157 .idfall_det_st = { 0xe3e0, 10, 10, 0, 1 }, 1158 .idfall_det_clr = { 0xe3d0, 10, 10, 0, 1 }, 1159 .idrise_det_en = { 0xe3c0, 9, 9, 0, 1 }, 1160 .idrise_det_st = { 0xe3e0, 9, 9, 0, 1 }, 1161 .idrise_det_clr = { 0xe3d0, 9, 9, 0, 1 }, 1162 .ls_det_en = { 0xe3c0, 7, 7, 0, 1 }, 1163 .ls_det_st = { 0xe3e0, 7, 7, 0, 1 }, 1164 .ls_det_clr = { 0xe3d0, 7, 7, 0, 1 }, 1165 .utmi_avalid = { 0xe2ac, 10, 10, 0, 1 }, 1166 .utmi_bvalid = { 0xe2ac, 16, 16, 0, 1 }, 1167 .utmi_iddig = { 0xe2ac, 11, 11, 0, 1 }, 1168 .utmi_ls = { 0xe2ac, 18, 17, 0, 1 }, 1169 .vbus_det_en = { 0x451c, 15, 15, 1, 0 }, 1170 }, 1171 [USB2PHY_PORT_HOST] = { 1172 .phy_sus = { 0xe468, 1, 0, 0x2, 0x1 }, 1173 .ls_det_en = { 0xe3c0, 11, 11, 0, 1 }, 1174 .ls_det_st = { 0xe3e0, 11, 11, 0, 1 }, 1175 .ls_det_clr = { 0xe3d0, 11, 11, 0, 1 }, 1176 .utmi_ls = { 0xe2ac, 26, 25, 0, 1 }, 1177 .utmi_hstdet = { 0xe2ac, 27, 27, 0, 1 } 1178 } 1179 }, 1180 .chg_det = { 1181 .opmode = { 0xe464, 3, 0, 5, 1 }, 1182 .cp_det = { 0xe2ac, 5, 5, 0, 1 }, 1183 .dcp_det = { 0xe2ac, 4, 4, 0, 1 }, 1184 .dp_det = { 0xe2ac, 3, 3, 0, 1 }, 1185 .idm_sink_en = { 0xe460, 8, 8, 0, 1 }, 1186 .idp_sink_en = { 0xe460, 7, 7, 0, 1 }, 1187 .idp_src_en = { 0xe460, 9, 9, 0, 1 }, 1188 .rdm_pdwn_en = { 0xe460, 10, 10, 0, 1 }, 1189 .vdm_src_en = { 0xe460, 12, 12, 0, 1 }, 1190 .vdp_src_en = { 0xe460, 11, 11, 0, 1 }, 1191 }, 1192 }, 1193 { /* sentinel */ } 1194 }; 1195 1196 static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = { 1197 { 1198 .reg = 0x100, 1199 .num_ports = 2, 1200 .clkout_ctl = { 0x108, 4, 4, 1, 0 }, 1201 .port_cfgs = { 1202 [USB2PHY_PORT_OTG] = { 1203 .phy_sus = { 0x0ffa0100, 8, 0, 0, 0x1d1 }, 1204 .bvalid_det_en = { 0x0680, 3, 3, 0, 1 }, 1205 .bvalid_det_st = { 0x0690, 3, 3, 0, 1 }, 1206 .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 }, 1207 .ls_det_en = { 0x0680, 2, 2, 0, 1 }, 1208 .ls_det_st = { 0x0690, 2, 2, 0, 1 }, 1209 .ls_det_clr = { 0x06a0, 2, 2, 0, 1 }, 1210 .utmi_bvalid = { 0x0804, 10, 10, 0, 1 }, 1211 .utmi_ls = { 0x0804, 13, 12, 0, 1 }, 1212 }, 1213 [USB2PHY_PORT_HOST] = { 1214 .phy_sus = { 0x0ffa0104, 8, 0, 0, 0x1d1 }, 1215 .ls_det_en = { 0x0680, 4, 4, 0, 1 }, 1216 .ls_det_st = { 0x0690, 4, 4, 0, 1 }, 1217 .ls_det_clr = { 0x06a0, 4, 4, 0, 1 }, 1218 .utmi_ls = { 0x0804, 9, 8, 0, 1 }, 1219 .utmi_hstdet = { 0x0804, 7, 7, 0, 1 } 1220 } 1221 }, 1222 .chg_det = { 1223 .opmode = { 0x0ffa0100, 3, 0, 5, 1 }, 1224 .cp_det = { 0x0804, 1, 1, 0, 1 }, 1225 .dcp_det = { 0x0804, 0, 0, 0, 1 }, 1226 .dp_det = { 0x0804, 2, 2, 0, 1 }, 1227 .idm_sink_en = { 0x0ffa0108, 8, 8, 0, 1 }, 1228 .idp_sink_en = { 0x0ffa0108, 7, 7, 0, 1 }, 1229 .idp_src_en = { 0x0ffa0108, 9, 9, 0, 1 }, 1230 .rdm_pdwn_en = { 0x0ffa0108, 10, 10, 0, 1 }, 1231 .vdm_src_en = { 0x0ffa0108, 12, 12, 0, 1 }, 1232 .vdp_src_en = { 0x0ffa0108, 11, 11, 0, 1 }, 1233 }, 1234 }, 1235 { /* sentinel */ } 1236 }; 1237 1238 static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = { 1239 { 1240 .reg = 0xfe8a0000, 1241 .num_ports = 2, 1242 .clkout_ctl = { 0x0008, 4, 4, 1, 0 }, 1243 .port_cfgs = { 1244 [USB2PHY_PORT_OTG] = { 1245 .phy_sus = { 0x0000, 8, 0, 0x052, 0x1d1 }, 1246 .bvalid_det_en = { 0x0080, 2, 2, 0, 1 }, 1247 .bvalid_det_st = { 0x0084, 2, 2, 0, 1 }, 1248 .bvalid_det_clr = { 0x0088, 2, 2, 0, 1 }, 1249 .iddig_output = { 0x0000, 10, 10, 0, 1 }, 1250 .iddig_en = { 0x0000, 9, 9, 0, 1 }, 1251 .idfall_det_en = { 0x0080, 5, 5, 0, 1 }, 1252 .idfall_det_st = { 0x0084, 5, 5, 0, 1 }, 1253 .idfall_det_clr = { 0x0088, 5, 5, 0, 1 }, 1254 .idrise_det_en = { 0x0080, 4, 4, 0, 1 }, 1255 .idrise_det_st = { 0x0084, 4, 4, 0, 1 }, 1256 .idrise_det_clr = { 0x0088, 4, 4, 0, 1 }, 1257 .ls_det_en = { 0x0080, 0, 0, 0, 1 }, 1258 .ls_det_st = { 0x0084, 0, 0, 0, 1 }, 1259 .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, 1260 .utmi_avalid = { 0x00c0, 10, 10, 0, 1 }, 1261 .utmi_bvalid = { 0x00c0, 9, 9, 0, 1 }, 1262 .utmi_iddig = { 0x00c0, 6, 6, 0, 1 }, 1263 .utmi_ls = { 0x00c0, 5, 4, 0, 1 }, 1264 }, 1265 [USB2PHY_PORT_HOST] = { 1266 .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d1 }, 1267 .ls_det_en = { 0x0080, 1, 1, 0, 1 }, 1268 .ls_det_st = { 0x0084, 1, 1, 0, 1 }, 1269 .ls_det_clr = { 0x0088, 1, 1, 0, 1 }, 1270 .utmi_ls = { 0x00c0, 17, 16, 0, 1 }, 1271 .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 } 1272 } 1273 }, 1274 .chg_det = { 1275 .opmode = { 0x0000, 3, 0, 5, 1 }, 1276 .cp_det = { 0x00c0, 24, 24, 0, 1 }, 1277 .dcp_det = { 0x00c0, 23, 23, 0, 1 }, 1278 .dp_det = { 0x00c0, 25, 25, 0, 1 }, 1279 .idm_sink_en = { 0x0008, 8, 8, 0, 1 }, 1280 .idp_sink_en = { 0x0008, 7, 7, 0, 1 }, 1281 .idp_src_en = { 0x0008, 9, 9, 0, 1 }, 1282 .rdm_pdwn_en = { 0x0008, 10, 10, 0, 1 }, 1283 .vdm_src_en = { 0x0008, 12, 12, 0, 1 }, 1284 .vdp_src_en = { 0x0008, 11, 11, 0, 1 }, 1285 }, 1286 }, 1287 { 1288 .reg = 0xfe8b0000, 1289 .num_ports = 2, 1290 .clkout_ctl = { 0x0008, 4, 4, 1, 0 }, 1291 .port_cfgs = { 1292 [USB2PHY_PORT_OTG] = { 1293 .phy_sus = { 0x0000, 8, 0, 0x1d2, 0x1d1 }, 1294 .ls_det_en = { 0x0080, 0, 0, 0, 1 }, 1295 .ls_det_st = { 0x0084, 0, 0, 0, 1 }, 1296 .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, 1297 .utmi_ls = { 0x00c0, 5, 4, 0, 1 }, 1298 .utmi_hstdet = { 0x00c0, 7, 7, 0, 1 } 1299 }, 1300 [USB2PHY_PORT_HOST] = { 1301 .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d1 }, 1302 .ls_det_en = { 0x0080, 1, 1, 0, 1 }, 1303 .ls_det_st = { 0x0084, 1, 1, 0, 1 }, 1304 .ls_det_clr = { 0x0088, 1, 1, 0, 1 }, 1305 .utmi_ls = { 0x00c0, 17, 16, 0, 1 }, 1306 .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 } 1307 } 1308 }, 1309 }, 1310 { /* sentinel */ } 1311 }; 1312 1313 static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = { 1314 { 1315 .reg = 0x0000, 1316 .num_ports = 1, 1317 .phy_tuning = rk3588_usb2phy_tuning, 1318 .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, 1319 .port_cfgs = { 1320 [USB2PHY_PORT_OTG] = { 1321 .phy_sus = { 0x000c, 11, 11, 0, 1 }, 1322 .ls_det_en = { 0x0080, 0, 0, 0, 1 }, 1323 .ls_det_st = { 0x0084, 0, 0, 0, 1 }, 1324 .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, 1325 .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, 1326 } 1327 }, 1328 .chg_det = { 1329 .opmode = { 0x0008, 2, 2, 1, 0 }, 1330 .cp_det = { 0x00c0, 0, 0, 0, 1 }, 1331 .dcp_det = { 0x00c0, 0, 0, 0, 1 }, 1332 .dp_det = { 0x00c0, 1, 1, 1, 0 }, 1333 .idm_sink_en = { 0x0008, 5, 5, 1, 0 }, 1334 .idp_sink_en = { 0x0008, 5, 5, 0, 1 }, 1335 .idp_src_en = { 0x0008, 14, 14, 0, 1 }, 1336 .rdm_pdwn_en = { 0x0008, 14, 14, 0, 1 }, 1337 .vdm_src_en = { 0x0008, 7, 6, 0, 3 }, 1338 .vdp_src_en = { 0x0008, 7, 6, 0, 3 }, 1339 }, 1340 }, 1341 { 1342 .reg = 0x4000, 1343 .num_ports = 1, 1344 .phy_tuning = rk3588_usb2phy_tuning, 1345 .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, 1346 .port_cfgs = { 1347 /* Select suspend control from controller */ 1348 [USB2PHY_PORT_OTG] = { 1349 .phy_sus = { 0x000c, 11, 11, 0, 0 }, 1350 .ls_det_en = { 0x0080, 0, 0, 0, 1 }, 1351 .ls_det_st = { 0x0084, 0, 0, 0, 1 }, 1352 .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, 1353 .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, 1354 } 1355 }, 1356 }, 1357 { 1358 .reg = 0x8000, 1359 .num_ports = 1, 1360 .phy_tuning = rk3588_usb2phy_tuning, 1361 .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, 1362 .port_cfgs = { 1363 [USB2PHY_PORT_HOST] = { 1364 .phy_sus = { 0x0008, 2, 2, 0, 1 }, 1365 .ls_det_en = { 0x0080, 0, 0, 0, 1 }, 1366 .ls_det_st = { 0x0084, 0, 0, 0, 1 }, 1367 .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, 1368 .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, 1369 } 1370 }, 1371 }, 1372 { 1373 .reg = 0xc000, 1374 .num_ports = 1, 1375 .phy_tuning = rk3588_usb2phy_tuning, 1376 .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, 1377 .port_cfgs = { 1378 [USB2PHY_PORT_HOST] = { 1379 .phy_sus = { 0x0008, 2, 2, 0, 1 }, 1380 .ls_det_en = { 0x0080, 0, 0, 0, 1 }, 1381 .ls_det_st = { 0x0084, 0, 0, 0, 1 }, 1382 .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, 1383 .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, 1384 } 1385 }, 1386 }, 1387 { /* sentinel */ } 1388 }; 1389 1390 static const struct udevice_id rockchip_usb2phy_ids[] = { 1391 { .compatible = "rockchip,rk1808-usb2phy", .data = (ulong)&rk1808_phy_cfgs }, 1392 { .compatible = "rockchip,rk3128-usb2phy", .data = (ulong)&rk312x_phy_cfgs }, 1393 { .compatible = "rockchip,rk322x-usb2phy", .data = (ulong)&rk322x_phy_cfgs }, 1394 { .compatible = "rockchip,rk3308-usb2phy", .data = (ulong)&rk3308_phy_cfgs }, 1395 { .compatible = "rockchip,rk3328-usb2phy", .data = (ulong)&rk3328_phy_cfgs }, 1396 { .compatible = "rockchip,rk3368-usb2phy", .data = (ulong)&rk3368_phy_cfgs }, 1397 { .compatible = "rockchip,rk3399-usb2phy", .data = (ulong)&rk3399_phy_cfgs }, 1398 { .compatible = "rockchip,rk3568-usb2phy", .data = (ulong)&rk3568_phy_cfgs }, 1399 { .compatible = "rockchip,rk3588-usb2phy", .data = (ulong)&rk3588_phy_cfgs }, 1400 { .compatible = "rockchip,rv1108-usb2phy", .data = (ulong)&rv1108_phy_cfgs }, 1401 { } 1402 }; 1403 1404 U_BOOT_DRIVER(rockchip_usb2phy_port) = { 1405 .name = "rockchip_usb2phy_port", 1406 .id = UCLASS_PHY, 1407 .ops = &rockchip_usb2phy_ops, 1408 }; 1409 1410 U_BOOT_DRIVER(rockchip_usb2phy) = { 1411 .name = "rockchip_usb2phy", 1412 .id = UCLASS_PHY, 1413 .of_match = rockchip_usb2phy_ids, 1414 .probe = rockchip_usb2phy_probe, 1415 .bind = rockchip_usb2phy_bind, 1416 .priv_auto_alloc_size = sizeof(struct rockchip_usb2phy), 1417 }; 1418