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 rk3328_usb2phy_tuning(struct rockchip_usb2phy *rphy) 744 { 745 struct regmap *base = get_reg_base(rphy); 746 unsigned int tmp, orig; 747 int ret; 748 749 if (soc_is_px30s()) { 750 /* Enable otg/host port pre-emphasis during non-chirp phase */ 751 ret = regmap_read(base, 0x8000, &orig); 752 if (ret) 753 return ret; 754 tmp = orig & ~GENMASK(2, 0); 755 tmp |= BIT(2) & GENMASK(2, 0); 756 ret = regmap_write(base, 0x8000, tmp); 757 if (ret) 758 return ret; 759 760 /* Set otg port squelch trigger point configure to 100mv */ 761 ret = regmap_read(base, 0x8004, &orig); 762 if (ret) 763 return ret; 764 tmp = orig & ~GENMASK(7, 5); 765 tmp |= 0x40 & GENMASK(7, 5); 766 ret = regmap_write(base, 0x8004, tmp); 767 if (ret) 768 return ret; 769 770 ret = regmap_read(base, 0x8008, &orig); 771 if (ret) 772 return ret; 773 tmp = orig & ~BIT(0); 774 tmp |= 0x1 & BIT(0); 775 ret = regmap_write(base, 0x8008, tmp); 776 if (ret) 777 return ret; 778 779 /* Enable host port pre-emphasis during non-chirp phase */ 780 ret = regmap_read(base, 0x8400, &orig); 781 if (ret) 782 return ret; 783 tmp = orig & ~GENMASK(2, 0); 784 tmp |= BIT(2) & GENMASK(2, 0); 785 ret = regmap_write(base, 0x8400, tmp); 786 if (ret) 787 return ret; 788 789 /* Set host port squelch trigger point configure to 100mv */ 790 ret = regmap_read(base, 0x8404, &orig); 791 if (ret) 792 return ret; 793 tmp = orig & ~GENMASK(7, 5); 794 tmp |= 0x40 & GENMASK(7, 5); 795 ret = regmap_write(base, 0x8404, tmp); 796 if (ret) 797 return ret; 798 799 ret = regmap_read(base, 0x8408, &orig); 800 if (ret) 801 return ret; 802 tmp = orig & ~BIT(0); 803 tmp |= 0x1 & BIT(0); 804 ret = regmap_write(base, 0x8408, tmp); 805 if (ret) 806 return ret; 807 } 808 809 return 0; 810 } 811 812 static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy) 813 { 814 struct regmap *base = get_reg_base(rphy); 815 int ret; 816 817 /* Deassert SIDDQ to power on analog block */ 818 ret = regmap_write(base, 0x0008, GENMASK(29, 29) | 0x0000); 819 if (ret) 820 return ret; 821 822 /* Do reset after exit IDDQ mode */ 823 ret = rockchip_usb2phy_reset(rphy); 824 if (ret) 825 return ret; 826 827 /* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */ 828 ret = regmap_write(base, 0x0004, GENMASK(27, 24) | 0x0900); 829 if (ret) 830 return ret; 831 832 /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */ 833 ret = regmap_write(base, 0x0008, GENMASK(20, 19) | 0x0010); 834 if (ret) 835 return ret; 836 837 return 0; 838 } 839 840 static struct phy_ops rockchip_usb2phy_ops = { 841 .init = rockchip_usb2phy_init, 842 .exit = rockchip_usb2phy_exit, 843 .power_on = rockchip_usb2phy_power_on, 844 .power_off = rockchip_usb2phy_power_off, 845 .of_xlate = rockchip_usb2phy_of_xlate, 846 }; 847 848 static const struct rockchip_usb2phy_cfg rk1808_phy_cfgs[] = { 849 { 850 .reg = 0x100, 851 .num_ports = 2, 852 .clkout_ctl = { 0x108, 4, 4, 1, 0 }, 853 .port_cfgs = { 854 [USB2PHY_PORT_OTG] = { 855 .phy_sus = { 0x0100, 8, 0, 0, 0x1d1 }, 856 .bvalid_det_en = { 0x0110, 2, 2, 0, 1 }, 857 .bvalid_det_st = { 0x0114, 2, 2, 0, 1 }, 858 .bvalid_det_clr = { 0x0118, 2, 2, 0, 1 }, 859 .iddig_output = { 0x0100, 10, 10, 0, 1 }, 860 .iddig_en = { 0x0100, 9, 9, 0, 1 }, 861 .idfall_det_en = { 0x0110, 5, 5, 0, 1 }, 862 .idfall_det_st = { 0x0114, 5, 5, 0, 1 }, 863 .idfall_det_clr = { 0x0118, 5, 5, 0, 1 }, 864 .idrise_det_en = { 0x0110, 4, 4, 0, 1 }, 865 .idrise_det_st = { 0x0114, 4, 4, 0, 1 }, 866 .idrise_det_clr = { 0x0118, 4, 4, 0, 1 }, 867 .ls_det_en = { 0x0110, 0, 0, 0, 1 }, 868 .ls_det_st = { 0x0114, 0, 0, 0, 1 }, 869 .ls_det_clr = { 0x0118, 0, 0, 0, 1 }, 870 .utmi_avalid = { 0x0120, 10, 10, 0, 1 }, 871 .utmi_bvalid = { 0x0120, 9, 9, 0, 1 }, 872 .utmi_iddig = { 0x0120, 6, 6, 0, 1 }, 873 .utmi_ls = { 0x0120, 5, 4, 0, 1 }, 874 .vbus_det_en = { 0x001c, 15, 15, 1, 0 }, 875 }, 876 [USB2PHY_PORT_HOST] = { 877 .phy_sus = { 0x104, 8, 0, 0, 0x1d1 }, 878 .ls_det_en = { 0x110, 1, 1, 0, 1 }, 879 .ls_det_st = { 0x114, 1, 1, 0, 1 }, 880 .ls_det_clr = { 0x118, 1, 1, 0, 1 }, 881 .utmi_ls = { 0x120, 17, 16, 0, 1 }, 882 .utmi_hstdet = { 0x120, 19, 19, 0, 1 } 883 } 884 }, 885 .chg_det = { 886 .opmode = { 0x0100, 3, 0, 5, 1 }, 887 .cp_det = { 0x0120, 24, 24, 0, 1 }, 888 .dcp_det = { 0x0120, 23, 23, 0, 1 }, 889 .dp_det = { 0x0120, 25, 25, 0, 1 }, 890 .idm_sink_en = { 0x0108, 8, 8, 0, 1 }, 891 .idp_sink_en = { 0x0108, 7, 7, 0, 1 }, 892 .idp_src_en = { 0x0108, 9, 9, 0, 1 }, 893 .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 }, 894 .vdm_src_en = { 0x0108, 12, 12, 0, 1 }, 895 .vdp_src_en = { 0x0108, 11, 11, 0, 1 }, 896 }, 897 }, 898 { /* sentinel */ } 899 }; 900 901 static const struct rockchip_usb2phy_cfg rk312x_phy_cfgs[] = { 902 { 903 .reg = 0x17c, 904 .num_ports = 2, 905 .clkout_ctl = { 0x0190, 15, 15, 1, 0 }, 906 .port_cfgs = { 907 [USB2PHY_PORT_OTG] = { 908 .phy_sus = { 0x017c, 8, 0, 0, 0x1d1 }, 909 .bvalid_det_en = { 0x017c, 14, 14, 0, 1 }, 910 .bvalid_det_st = { 0x017c, 15, 15, 0, 1 }, 911 .bvalid_det_clr = { 0x017c, 15, 15, 0, 1 }, 912 .iddig_output = { 0x017c, 10, 10, 0, 1 }, 913 .iddig_en = { 0x017c, 9, 9, 0, 1 }, 914 .idfall_det_en = { 0x01a0, 2, 2, 0, 1 }, 915 .idfall_det_st = { 0x01a0, 3, 3, 0, 1 }, 916 .idfall_det_clr = { 0x01a0, 3, 3, 0, 1 }, 917 .idrise_det_en = { 0x01a0, 0, 0, 0, 1 }, 918 .idrise_det_st = { 0x01a0, 1, 1, 0, 1 }, 919 .idrise_det_clr = { 0x01a0, 1, 1, 0, 1 }, 920 .ls_det_en = { 0x017c, 12, 12, 0, 1 }, 921 .ls_det_st = { 0x017c, 13, 13, 0, 1 }, 922 .ls_det_clr = { 0x017c, 13, 13, 0, 1 }, 923 .utmi_bvalid = { 0x014c, 5, 5, 0, 1 }, 924 .utmi_iddig = { 0x014c, 8, 8, 0, 1 }, 925 .utmi_ls = { 0x014c, 7, 6, 0, 1 }, 926 }, 927 [USB2PHY_PORT_HOST] = { 928 .phy_sus = { 0x0194, 8, 0, 0, 0x1d1 }, 929 .ls_det_en = { 0x0194, 14, 14, 0, 1 }, 930 .ls_det_st = { 0x0194, 15, 15, 0, 1 }, 931 .ls_det_clr = { 0x0194, 15, 15, 0, 1 } 932 } 933 }, 934 .chg_det = { 935 .opmode = { 0x017c, 3, 0, 5, 1 }, 936 .cp_det = { 0x02c0, 6, 6, 0, 1 }, 937 .dcp_det = { 0x02c0, 5, 5, 0, 1 }, 938 .dp_det = { 0x02c0, 7, 7, 0, 1 }, 939 .idm_sink_en = { 0x0184, 8, 8, 0, 1 }, 940 .idp_sink_en = { 0x0184, 7, 7, 0, 1 }, 941 .idp_src_en = { 0x0184, 9, 9, 0, 1 }, 942 .rdm_pdwn_en = { 0x0184, 10, 10, 0, 1 }, 943 .vdm_src_en = { 0x0184, 12, 12, 0, 1 }, 944 .vdp_src_en = { 0x0184, 11, 11, 0, 1 }, 945 }, 946 }, 947 { /* sentinel */ } 948 }; 949 950 static const struct rockchip_usb2phy_cfg rk322x_phy_cfgs[] = { 951 { 952 .reg = 0x760, 953 .num_ports = 2, 954 .phy_tuning = rk322x_usb2phy_tuning, 955 .clkout_ctl = { 0x0768, 4, 4, 1, 0 }, 956 .port_cfgs = { 957 [USB2PHY_PORT_OTG] = { 958 .phy_sus = { 0x0760, 8, 0, 0, 0x1d1 }, 959 .bvalid_det_en = { 0x0680, 3, 3, 0, 1 }, 960 .bvalid_det_st = { 0x0690, 3, 3, 0, 1 }, 961 .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 }, 962 .iddig_output = { 0x0760, 10, 10, 0, 1 }, 963 .iddig_en = { 0x0760, 9, 9, 0, 1 }, 964 .idfall_det_en = { 0x0680, 6, 6, 0, 1 }, 965 .idfall_det_st = { 0x0690, 6, 6, 0, 1 }, 966 .idfall_det_clr = { 0x06a0, 6, 6, 0, 1 }, 967 .idrise_det_en = { 0x0680, 5, 5, 0, 1 }, 968 .idrise_det_st = { 0x0690, 5, 5, 0, 1 }, 969 .idrise_det_clr = { 0x06a0, 5, 5, 0, 1 }, 970 .ls_det_en = { 0x0680, 2, 2, 0, 1 }, 971 .ls_det_st = { 0x0690, 2, 2, 0, 1 }, 972 .ls_det_clr = { 0x06a0, 2, 2, 0, 1 }, 973 .utmi_bvalid = { 0x0480, 4, 4, 0, 1 }, 974 .utmi_iddig = { 0x0480, 1, 1, 0, 1 }, 975 .utmi_ls = { 0x0480, 3, 2, 0, 1 }, 976 .vbus_det_en = { 0x0788, 15, 15, 1, 0 }, 977 }, 978 [USB2PHY_PORT_HOST] = { 979 .phy_sus = { 0x0764, 8, 0, 0, 0x1d1 }, 980 .ls_det_en = { 0x0680, 4, 4, 0, 1 }, 981 .ls_det_st = { 0x0690, 4, 4, 0, 1 }, 982 .ls_det_clr = { 0x06a0, 4, 4, 0, 1 } 983 } 984 }, 985 .chg_det = { 986 .opmode = { 0x0760, 3, 0, 5, 1 }, 987 .cp_det = { 0x0884, 4, 4, 0, 1 }, 988 .dcp_det = { 0x0884, 3, 3, 0, 1 }, 989 .dp_det = { 0x0884, 5, 5, 0, 1 }, 990 .idm_sink_en = { 0x0768, 8, 8, 0, 1 }, 991 .idp_sink_en = { 0x0768, 7, 7, 0, 1 }, 992 .idp_src_en = { 0x0768, 9, 9, 0, 1 }, 993 .rdm_pdwn_en = { 0x0768, 10, 10, 0, 1 }, 994 .vdm_src_en = { 0x0768, 12, 12, 0, 1 }, 995 .vdp_src_en = { 0x0768, 11, 11, 0, 1 }, 996 }, 997 }, 998 { 999 .reg = 0x800, 1000 .num_ports = 2, 1001 .clkout_ctl = { 0x0808, 4, 4, 1, 0 }, 1002 .port_cfgs = { 1003 [USB2PHY_PORT_OTG] = { 1004 .phy_sus = { 0x804, 8, 0, 0, 0x1d1 }, 1005 .ls_det_en = { 0x0684, 1, 1, 0, 1 }, 1006 .ls_det_st = { 0x0694, 1, 1, 0, 1 }, 1007 .ls_det_clr = { 0x06a4, 1, 1, 0, 1 } 1008 }, 1009 [USB2PHY_PORT_HOST] = { 1010 .phy_sus = { 0x800, 8, 0, 0, 0x1d1 }, 1011 .ls_det_en = { 0x0684, 0, 0, 0, 1 }, 1012 .ls_det_st = { 0x0694, 0, 0, 0, 1 }, 1013 .ls_det_clr = { 0x06a4, 0, 0, 0, 1 } 1014 } 1015 }, 1016 }, 1017 { /* sentinel */ } 1018 }; 1019 1020 static const struct rockchip_usb2phy_cfg rk3308_phy_cfgs[] = { 1021 { 1022 .reg = 0x100, 1023 .num_ports = 2, 1024 .phy_tuning = rk3308_usb2phy_tuning, 1025 .clkout_ctl = { 0x0108, 4, 4, 1, 0 }, 1026 .port_cfgs = { 1027 [USB2PHY_PORT_OTG] = { 1028 .phy_sus = { 0x0100, 8, 0, 0, 0x1d1 }, 1029 .bvalid_det_en = { 0x3020, 2, 2, 0, 1 }, 1030 .bvalid_det_st = { 0x3024, 2, 2, 0, 1 }, 1031 .bvalid_det_clr = { 0x3028, 2, 2, 0, 1 }, 1032 .iddig_output = { 0x0100, 10, 10, 0, 1 }, 1033 .iddig_en = { 0x0100, 9, 9, 0, 1 }, 1034 .idfall_det_en = { 0x3020, 5, 5, 0, 1 }, 1035 .idfall_det_st = { 0x3024, 5, 5, 0, 1 }, 1036 .idfall_det_clr = { 0x3028, 5, 5, 0, 1 }, 1037 .idrise_det_en = { 0x3020, 4, 4, 0, 1 }, 1038 .idrise_det_st = { 0x3024, 4, 4, 0, 1 }, 1039 .idrise_det_clr = { 0x3028, 4, 4, 0, 1 }, 1040 .ls_det_en = { 0x3020, 0, 0, 0, 1 }, 1041 .ls_det_st = { 0x3024, 0, 0, 0, 1 }, 1042 .ls_det_clr = { 0x3028, 0, 0, 0, 1 }, 1043 .utmi_avalid = { 0x0120, 10, 10, 0, 1 }, 1044 .utmi_bvalid = { 0x0120, 9, 9, 0, 1 }, 1045 .utmi_iddig = { 0x0120, 6, 6, 0, 1 }, 1046 .utmi_ls = { 0x0120, 5, 4, 0, 1 }, 1047 .vbus_det_en = { 0x001c, 15, 15, 1, 0 }, 1048 }, 1049 [USB2PHY_PORT_HOST] = { 1050 .phy_sus = { 0x0104, 8, 0, 0, 0x1d1 }, 1051 .ls_det_en = { 0x3020, 1, 1, 0, 1 }, 1052 .ls_det_st = { 0x3024, 1, 1, 0, 1 }, 1053 .ls_det_clr = { 0x3028, 1, 1, 0, 1 }, 1054 .utmi_ls = { 0x120, 17, 16, 0, 1 }, 1055 .utmi_hstdet = { 0x120, 19, 19, 0, 1 } 1056 } 1057 }, 1058 .chg_det = { 1059 .opmode = { 0x0100, 3, 0, 5, 1 }, 1060 .cp_det = { 0x0120, 24, 24, 0, 1 }, 1061 .dcp_det = { 0x0120, 23, 23, 0, 1 }, 1062 .dp_det = { 0x0120, 25, 25, 0, 1 }, 1063 .idm_sink_en = { 0x0108, 8, 8, 0, 1 }, 1064 .idp_sink_en = { 0x0108, 7, 7, 0, 1 }, 1065 .idp_src_en = { 0x0108, 9, 9, 0, 1 }, 1066 .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 }, 1067 .vdm_src_en = { 0x0108, 12, 12, 0, 1 }, 1068 .vdp_src_en = { 0x0108, 11, 11, 0, 1 }, 1069 }, 1070 }, 1071 { /* sentinel */ } 1072 }; 1073 1074 static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = { 1075 { 1076 .reg = 0x100, 1077 .num_ports = 2, 1078 .phy_tuning = rk3328_usb2phy_tuning, 1079 .clkout_ctl = { 0x108, 4, 4, 1, 0 }, 1080 .port_cfgs = { 1081 [USB2PHY_PORT_OTG] = { 1082 .phy_sus = { 0x0100, 8, 0, 0, 0x1d1 }, 1083 .bvalid_det_en = { 0x0110, 2, 2, 0, 1 }, 1084 .bvalid_det_st = { 0x0114, 2, 2, 0, 1 }, 1085 .bvalid_det_clr = { 0x0118, 2, 2, 0, 1 }, 1086 .iddig_output = { 0x0100, 10, 10, 0, 1 }, 1087 .iddig_en = { 0x0100, 9, 9, 0, 1 }, 1088 .idfall_det_en = { 0x0110, 5, 5, 0, 1 }, 1089 .idfall_det_st = { 0x0114, 5, 5, 0, 1 }, 1090 .idfall_det_clr = { 0x0118, 5, 5, 0, 1 }, 1091 .idrise_det_en = { 0x0110, 4, 4, 0, 1 }, 1092 .idrise_det_st = { 0x0114, 4, 4, 0, 1 }, 1093 .idrise_det_clr = { 0x0118, 4, 4, 0, 1 }, 1094 .ls_det_en = { 0x0110, 0, 0, 0, 1 }, 1095 .ls_det_st = { 0x0114, 0, 0, 0, 1 }, 1096 .ls_det_clr = { 0x0118, 0, 0, 0, 1 }, 1097 .utmi_avalid = { 0x0120, 10, 10, 0, 1 }, 1098 .utmi_bvalid = { 0x0120, 9, 9, 0, 1 }, 1099 .utmi_iddig = { 0x0120, 6, 6, 0, 1 }, 1100 .utmi_ls = { 0x0120, 5, 4, 0, 1 }, 1101 .vbus_det_en = { 0x001c, 15, 15, 1, 0 }, 1102 }, 1103 [USB2PHY_PORT_HOST] = { 1104 .phy_sus = { 0x104, 8, 0, 0, 0x1d1 }, 1105 .ls_det_en = { 0x110, 1, 1, 0, 1 }, 1106 .ls_det_st = { 0x114, 1, 1, 0, 1 }, 1107 .ls_det_clr = { 0x118, 1, 1, 0, 1 }, 1108 .utmi_ls = { 0x120, 17, 16, 0, 1 }, 1109 .utmi_hstdet = { 0x120, 19, 19, 0, 1 } 1110 } 1111 }, 1112 .chg_det = { 1113 .opmode = { 0x0100, 3, 0, 5, 1 }, 1114 .cp_det = { 0x0120, 24, 24, 0, 1 }, 1115 .dcp_det = { 0x0120, 23, 23, 0, 1 }, 1116 .dp_det = { 0x0120, 25, 25, 0, 1 }, 1117 .idm_sink_en = { 0x0108, 8, 8, 0, 1 }, 1118 .idp_sink_en = { 0x0108, 7, 7, 0, 1 }, 1119 .idp_src_en = { 0x0108, 9, 9, 0, 1 }, 1120 .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 }, 1121 .vdm_src_en = { 0x0108, 12, 12, 0, 1 }, 1122 .vdp_src_en = { 0x0108, 11, 11, 0, 1 }, 1123 }, 1124 }, 1125 { /* sentinel */ } 1126 }; 1127 1128 static const struct rockchip_usb2phy_cfg rk3368_phy_cfgs[] = { 1129 { 1130 .reg = 0x700, 1131 .num_ports = 2, 1132 .clkout_ctl = { 0x0724, 15, 15, 1, 0 }, 1133 .port_cfgs = { 1134 [USB2PHY_PORT_OTG] = { 1135 .phy_sus = { 0x0700, 8, 0, 0, 0x1d1 }, 1136 .bvalid_det_en = { 0x0680, 3, 3, 0, 1 }, 1137 .bvalid_det_st = { 0x0690, 3, 3, 0, 1 }, 1138 .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 }, 1139 .ls_det_en = { 0x0680, 2, 2, 0, 1 }, 1140 .ls_det_st = { 0x0690, 2, 2, 0, 1 }, 1141 .ls_det_clr = { 0x06a0, 2, 2, 0, 1 }, 1142 .utmi_bvalid = { 0x04bc, 23, 23, 0, 1 }, 1143 .utmi_ls = { 0x04bc, 25, 24, 0, 1 }, 1144 }, 1145 [USB2PHY_PORT_HOST] = { 1146 .phy_sus = { 0x0728, 8, 0, 0, 0x1d1 }, 1147 .ls_det_en = { 0x0680, 4, 4, 0, 1 }, 1148 .ls_det_st = { 0x0690, 4, 4, 0, 1 }, 1149 .ls_det_clr = { 0x06a0, 4, 4, 0, 1 } 1150 } 1151 }, 1152 .chg_det = { 1153 .opmode = { 0x0700, 3, 0, 5, 1 }, 1154 .cp_det = { 0x04b8, 30, 30, 0, 1 }, 1155 .dcp_det = { 0x04b8, 29, 29, 0, 1 }, 1156 .dp_det = { 0x04b8, 31, 31, 0, 1 }, 1157 .idm_sink_en = { 0x0718, 8, 8, 0, 1 }, 1158 .idp_sink_en = { 0x0718, 7, 7, 0, 1 }, 1159 .idp_src_en = { 0x0718, 9, 9, 0, 1 }, 1160 .rdm_pdwn_en = { 0x0718, 10, 10, 0, 1 }, 1161 .vdm_src_en = { 0x0718, 12, 12, 0, 1 }, 1162 .vdp_src_en = { 0x0718, 11, 11, 0, 1 }, 1163 }, 1164 }, 1165 { /* sentinel */ } 1166 }; 1167 1168 static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = { 1169 { 1170 .reg = 0xe450, 1171 .num_ports = 2, 1172 .clkout_ctl = { 0xe450, 4, 4, 1, 0 }, 1173 .port_cfgs = { 1174 [USB2PHY_PORT_OTG] = { 1175 .phy_sus = { 0xe454, 8, 0, 0x052, 0x1d1 }, 1176 .bvalid_det_en = { 0xe3c0, 3, 3, 0, 1 }, 1177 .bvalid_det_st = { 0xe3e0, 3, 3, 0, 1 }, 1178 .bvalid_det_clr = { 0xe3d0, 3, 3, 0, 1 }, 1179 .idfall_det_en = { 0xe3c0, 5, 5, 0, 1 }, 1180 .idfall_det_st = { 0xe3e0, 5, 5, 0, 1 }, 1181 .idfall_det_clr = { 0xe3d0, 5, 5, 0, 1 }, 1182 .idrise_det_en = { 0xe3c0, 4, 4, 0, 1 }, 1183 .idrise_det_st = { 0xe3e0, 4, 4, 0, 1 }, 1184 .idrise_det_clr = { 0xe3d0, 4, 4, 0, 1 }, 1185 .ls_det_en = { 0xe3c0, 2, 2, 0, 1 }, 1186 .ls_det_st = { 0xe3e0, 2, 2, 0, 1 }, 1187 .ls_det_clr = { 0xe3d0, 2, 2, 0, 1 }, 1188 .utmi_avalid = { 0xe2ac, 7, 7, 0, 1 }, 1189 .utmi_bvalid = { 0xe2ac, 12, 12, 0, 1 }, 1190 .utmi_iddig = { 0xe2ac, 8, 8, 0, 1 }, 1191 .utmi_ls = { 0xe2ac, 14, 13, 0, 1 }, 1192 .vbus_det_en = { 0x449c, 15, 15, 1, 0 }, 1193 }, 1194 [USB2PHY_PORT_HOST] = { 1195 .phy_sus = { 0xe458, 1, 0, 0x2, 0x1 }, 1196 .ls_det_en = { 0xe3c0, 6, 6, 0, 1 }, 1197 .ls_det_st = { 0xe3e0, 6, 6, 0, 1 }, 1198 .ls_det_clr = { 0xe3d0, 6, 6, 0, 1 }, 1199 .utmi_ls = { 0xe2ac, 22, 21, 0, 1 }, 1200 .utmi_hstdet = { 0xe2ac, 23, 23, 0, 1 } 1201 } 1202 }, 1203 .chg_det = { 1204 .opmode = { 0xe454, 3, 0, 5, 1 }, 1205 .cp_det = { 0xe2ac, 2, 2, 0, 1 }, 1206 .dcp_det = { 0xe2ac, 1, 1, 0, 1 }, 1207 .dp_det = { 0xe2ac, 0, 0, 0, 1 }, 1208 .idm_sink_en = { 0xe450, 8, 8, 0, 1 }, 1209 .idp_sink_en = { 0xe450, 7, 7, 0, 1 }, 1210 .idp_src_en = { 0xe450, 9, 9, 0, 1 }, 1211 .rdm_pdwn_en = { 0xe450, 10, 10, 0, 1 }, 1212 .vdm_src_en = { 0xe450, 12, 12, 0, 1 }, 1213 .vdp_src_en = { 0xe450, 11, 11, 0, 1 }, 1214 }, 1215 }, 1216 { 1217 .reg = 0xe460, 1218 .num_ports = 2, 1219 .clkout_ctl = { 0xe460, 4, 4, 1, 0 }, 1220 .port_cfgs = { 1221 [USB2PHY_PORT_OTG] = { 1222 .phy_sus = { 0xe464, 8, 0, 0x052, 0x1d1 }, 1223 .bvalid_det_en = { 0xe3c0, 8, 8, 0, 1 }, 1224 .bvalid_det_st = { 0xe3e0, 8, 8, 0, 1 }, 1225 .bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 }, 1226 .idfall_det_en = { 0xe3c0, 10, 10, 0, 1 }, 1227 .idfall_det_st = { 0xe3e0, 10, 10, 0, 1 }, 1228 .idfall_det_clr = { 0xe3d0, 10, 10, 0, 1 }, 1229 .idrise_det_en = { 0xe3c0, 9, 9, 0, 1 }, 1230 .idrise_det_st = { 0xe3e0, 9, 9, 0, 1 }, 1231 .idrise_det_clr = { 0xe3d0, 9, 9, 0, 1 }, 1232 .ls_det_en = { 0xe3c0, 7, 7, 0, 1 }, 1233 .ls_det_st = { 0xe3e0, 7, 7, 0, 1 }, 1234 .ls_det_clr = { 0xe3d0, 7, 7, 0, 1 }, 1235 .utmi_avalid = { 0xe2ac, 10, 10, 0, 1 }, 1236 .utmi_bvalid = { 0xe2ac, 16, 16, 0, 1 }, 1237 .utmi_iddig = { 0xe2ac, 11, 11, 0, 1 }, 1238 .utmi_ls = { 0xe2ac, 18, 17, 0, 1 }, 1239 .vbus_det_en = { 0x451c, 15, 15, 1, 0 }, 1240 }, 1241 [USB2PHY_PORT_HOST] = { 1242 .phy_sus = { 0xe468, 1, 0, 0x2, 0x1 }, 1243 .ls_det_en = { 0xe3c0, 11, 11, 0, 1 }, 1244 .ls_det_st = { 0xe3e0, 11, 11, 0, 1 }, 1245 .ls_det_clr = { 0xe3d0, 11, 11, 0, 1 }, 1246 .utmi_ls = { 0xe2ac, 26, 25, 0, 1 }, 1247 .utmi_hstdet = { 0xe2ac, 27, 27, 0, 1 } 1248 } 1249 }, 1250 .chg_det = { 1251 .opmode = { 0xe464, 3, 0, 5, 1 }, 1252 .cp_det = { 0xe2ac, 5, 5, 0, 1 }, 1253 .dcp_det = { 0xe2ac, 4, 4, 0, 1 }, 1254 .dp_det = { 0xe2ac, 3, 3, 0, 1 }, 1255 .idm_sink_en = { 0xe460, 8, 8, 0, 1 }, 1256 .idp_sink_en = { 0xe460, 7, 7, 0, 1 }, 1257 .idp_src_en = { 0xe460, 9, 9, 0, 1 }, 1258 .rdm_pdwn_en = { 0xe460, 10, 10, 0, 1 }, 1259 .vdm_src_en = { 0xe460, 12, 12, 0, 1 }, 1260 .vdp_src_en = { 0xe460, 11, 11, 0, 1 }, 1261 }, 1262 }, 1263 { /* sentinel */ } 1264 }; 1265 1266 static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = { 1267 { 1268 .reg = 0x100, 1269 .num_ports = 2, 1270 .clkout_ctl = { 0x108, 4, 4, 1, 0 }, 1271 .port_cfgs = { 1272 [USB2PHY_PORT_OTG] = { 1273 .phy_sus = { 0x0ffa0100, 8, 0, 0, 0x1d1 }, 1274 .bvalid_det_en = { 0x0680, 3, 3, 0, 1 }, 1275 .bvalid_det_st = { 0x0690, 3, 3, 0, 1 }, 1276 .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 }, 1277 .ls_det_en = { 0x0680, 2, 2, 0, 1 }, 1278 .ls_det_st = { 0x0690, 2, 2, 0, 1 }, 1279 .ls_det_clr = { 0x06a0, 2, 2, 0, 1 }, 1280 .utmi_bvalid = { 0x0804, 10, 10, 0, 1 }, 1281 .utmi_ls = { 0x0804, 13, 12, 0, 1 }, 1282 }, 1283 [USB2PHY_PORT_HOST] = { 1284 .phy_sus = { 0x0ffa0104, 8, 0, 0, 0x1d1 }, 1285 .ls_det_en = { 0x0680, 4, 4, 0, 1 }, 1286 .ls_det_st = { 0x0690, 4, 4, 0, 1 }, 1287 .ls_det_clr = { 0x06a0, 4, 4, 0, 1 }, 1288 .utmi_ls = { 0x0804, 9, 8, 0, 1 }, 1289 .utmi_hstdet = { 0x0804, 7, 7, 0, 1 } 1290 } 1291 }, 1292 .chg_det = { 1293 .opmode = { 0x0ffa0100, 3, 0, 5, 1 }, 1294 .cp_det = { 0x0804, 1, 1, 0, 1 }, 1295 .dcp_det = { 0x0804, 0, 0, 0, 1 }, 1296 .dp_det = { 0x0804, 2, 2, 0, 1 }, 1297 .idm_sink_en = { 0x0ffa0108, 8, 8, 0, 1 }, 1298 .idp_sink_en = { 0x0ffa0108, 7, 7, 0, 1 }, 1299 .idp_src_en = { 0x0ffa0108, 9, 9, 0, 1 }, 1300 .rdm_pdwn_en = { 0x0ffa0108, 10, 10, 0, 1 }, 1301 .vdm_src_en = { 0x0ffa0108, 12, 12, 0, 1 }, 1302 .vdp_src_en = { 0x0ffa0108, 11, 11, 0, 1 }, 1303 }, 1304 }, 1305 { /* sentinel */ } 1306 }; 1307 1308 static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = { 1309 { 1310 .reg = 0xfe8a0000, 1311 .num_ports = 2, 1312 .clkout_ctl = { 0x0008, 4, 4, 1, 0 }, 1313 .port_cfgs = { 1314 [USB2PHY_PORT_OTG] = { 1315 .phy_sus = { 0x0000, 8, 0, 0x052, 0x1d1 }, 1316 .bvalid_det_en = { 0x0080, 2, 2, 0, 1 }, 1317 .bvalid_det_st = { 0x0084, 2, 2, 0, 1 }, 1318 .bvalid_det_clr = { 0x0088, 2, 2, 0, 1 }, 1319 .iddig_output = { 0x0000, 10, 10, 0, 1 }, 1320 .iddig_en = { 0x0000, 9, 9, 0, 1 }, 1321 .idfall_det_en = { 0x0080, 5, 5, 0, 1 }, 1322 .idfall_det_st = { 0x0084, 5, 5, 0, 1 }, 1323 .idfall_det_clr = { 0x0088, 5, 5, 0, 1 }, 1324 .idrise_det_en = { 0x0080, 4, 4, 0, 1 }, 1325 .idrise_det_st = { 0x0084, 4, 4, 0, 1 }, 1326 .idrise_det_clr = { 0x0088, 4, 4, 0, 1 }, 1327 .ls_det_en = { 0x0080, 0, 0, 0, 1 }, 1328 .ls_det_st = { 0x0084, 0, 0, 0, 1 }, 1329 .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, 1330 .utmi_avalid = { 0x00c0, 10, 10, 0, 1 }, 1331 .utmi_bvalid = { 0x00c0, 9, 9, 0, 1 }, 1332 .utmi_iddig = { 0x00c0, 6, 6, 0, 1 }, 1333 .utmi_ls = { 0x00c0, 5, 4, 0, 1 }, 1334 }, 1335 [USB2PHY_PORT_HOST] = { 1336 .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d1 }, 1337 .ls_det_en = { 0x0080, 1, 1, 0, 1 }, 1338 .ls_det_st = { 0x0084, 1, 1, 0, 1 }, 1339 .ls_det_clr = { 0x0088, 1, 1, 0, 1 }, 1340 .utmi_ls = { 0x00c0, 17, 16, 0, 1 }, 1341 .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 } 1342 } 1343 }, 1344 .chg_det = { 1345 .opmode = { 0x0000, 3, 0, 5, 1 }, 1346 .cp_det = { 0x00c0, 24, 24, 0, 1 }, 1347 .dcp_det = { 0x00c0, 23, 23, 0, 1 }, 1348 .dp_det = { 0x00c0, 25, 25, 0, 1 }, 1349 .idm_sink_en = { 0x0008, 8, 8, 0, 1 }, 1350 .idp_sink_en = { 0x0008, 7, 7, 0, 1 }, 1351 .idp_src_en = { 0x0008, 9, 9, 0, 1 }, 1352 .rdm_pdwn_en = { 0x0008, 10, 10, 0, 1 }, 1353 .vdm_src_en = { 0x0008, 12, 12, 0, 1 }, 1354 .vdp_src_en = { 0x0008, 11, 11, 0, 1 }, 1355 }, 1356 }, 1357 { 1358 .reg = 0xfe8b0000, 1359 .num_ports = 2, 1360 .clkout_ctl = { 0x0008, 4, 4, 1, 0 }, 1361 .port_cfgs = { 1362 [USB2PHY_PORT_OTG] = { 1363 .phy_sus = { 0x0000, 8, 0, 0x1d2, 0x1d1 }, 1364 .ls_det_en = { 0x0080, 0, 0, 0, 1 }, 1365 .ls_det_st = { 0x0084, 0, 0, 0, 1 }, 1366 .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, 1367 .utmi_ls = { 0x00c0, 5, 4, 0, 1 }, 1368 .utmi_hstdet = { 0x00c0, 7, 7, 0, 1 } 1369 }, 1370 [USB2PHY_PORT_HOST] = { 1371 .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d1 }, 1372 .ls_det_en = { 0x0080, 1, 1, 0, 1 }, 1373 .ls_det_st = { 0x0084, 1, 1, 0, 1 }, 1374 .ls_det_clr = { 0x0088, 1, 1, 0, 1 }, 1375 .utmi_ls = { 0x00c0, 17, 16, 0, 1 }, 1376 .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 } 1377 } 1378 }, 1379 }, 1380 { /* sentinel */ } 1381 }; 1382 1383 static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = { 1384 { 1385 .reg = 0x0000, 1386 .num_ports = 1, 1387 .phy_tuning = rk3588_usb2phy_tuning, 1388 .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, 1389 .port_cfgs = { 1390 [USB2PHY_PORT_OTG] = { 1391 .phy_sus = { 0x000c, 11, 11, 0, 1 }, 1392 .ls_det_en = { 0x0080, 0, 0, 0, 1 }, 1393 .ls_det_st = { 0x0084, 0, 0, 0, 1 }, 1394 .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, 1395 .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, 1396 } 1397 }, 1398 .chg_det = { 1399 .opmode = { 0x0008, 2, 2, 1, 0 }, 1400 .cp_det = { 0x00c0, 0, 0, 0, 1 }, 1401 .dcp_det = { 0x00c0, 0, 0, 0, 1 }, 1402 .dp_det = { 0x00c0, 1, 1, 1, 0 }, 1403 .idm_sink_en = { 0x0008, 5, 5, 1, 0 }, 1404 .idp_sink_en = { 0x0008, 5, 5, 0, 1 }, 1405 .idp_src_en = { 0x0008, 14, 14, 0, 1 }, 1406 .rdm_pdwn_en = { 0x0008, 14, 14, 0, 1 }, 1407 .vdm_src_en = { 0x0008, 7, 6, 0, 3 }, 1408 .vdp_src_en = { 0x0008, 7, 6, 0, 3 }, 1409 }, 1410 }, 1411 { 1412 .reg = 0x4000, 1413 .num_ports = 1, 1414 .phy_tuning = rk3588_usb2phy_tuning, 1415 .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, 1416 .port_cfgs = { 1417 /* Select suspend control from controller */ 1418 [USB2PHY_PORT_OTG] = { 1419 .phy_sus = { 0x000c, 11, 11, 0, 0 }, 1420 .ls_det_en = { 0x0080, 0, 0, 0, 1 }, 1421 .ls_det_st = { 0x0084, 0, 0, 0, 1 }, 1422 .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, 1423 .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, 1424 } 1425 }, 1426 }, 1427 { 1428 .reg = 0x8000, 1429 .num_ports = 1, 1430 .phy_tuning = rk3588_usb2phy_tuning, 1431 .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, 1432 .port_cfgs = { 1433 [USB2PHY_PORT_HOST] = { 1434 .phy_sus = { 0x0008, 2, 2, 0, 1 }, 1435 .ls_det_en = { 0x0080, 0, 0, 0, 1 }, 1436 .ls_det_st = { 0x0084, 0, 0, 0, 1 }, 1437 .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, 1438 .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, 1439 } 1440 }, 1441 }, 1442 { 1443 .reg = 0xc000, 1444 .num_ports = 1, 1445 .phy_tuning = rk3588_usb2phy_tuning, 1446 .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, 1447 .port_cfgs = { 1448 [USB2PHY_PORT_HOST] = { 1449 .phy_sus = { 0x0008, 2, 2, 0, 1 }, 1450 .ls_det_en = { 0x0080, 0, 0, 0, 1 }, 1451 .ls_det_st = { 0x0084, 0, 0, 0, 1 }, 1452 .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, 1453 .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, 1454 } 1455 }, 1456 }, 1457 { /* sentinel */ } 1458 }; 1459 1460 static const struct udevice_id rockchip_usb2phy_ids[] = { 1461 { .compatible = "rockchip,rk1808-usb2phy", .data = (ulong)&rk1808_phy_cfgs }, 1462 { .compatible = "rockchip,rk3128-usb2phy", .data = (ulong)&rk312x_phy_cfgs }, 1463 { .compatible = "rockchip,rk322x-usb2phy", .data = (ulong)&rk322x_phy_cfgs }, 1464 { .compatible = "rockchip,rk3308-usb2phy", .data = (ulong)&rk3308_phy_cfgs }, 1465 { .compatible = "rockchip,rk3328-usb2phy", .data = (ulong)&rk3328_phy_cfgs }, 1466 { .compatible = "rockchip,rk3368-usb2phy", .data = (ulong)&rk3368_phy_cfgs }, 1467 { .compatible = "rockchip,rk3399-usb2phy", .data = (ulong)&rk3399_phy_cfgs }, 1468 { .compatible = "rockchip,rk3568-usb2phy", .data = (ulong)&rk3568_phy_cfgs }, 1469 { .compatible = "rockchip,rk3588-usb2phy", .data = (ulong)&rk3588_phy_cfgs }, 1470 { .compatible = "rockchip,rv1108-usb2phy", .data = (ulong)&rv1108_phy_cfgs }, 1471 { } 1472 }; 1473 1474 U_BOOT_DRIVER(rockchip_usb2phy_port) = { 1475 .name = "rockchip_usb2phy_port", 1476 .id = UCLASS_PHY, 1477 .ops = &rockchip_usb2phy_ops, 1478 }; 1479 1480 U_BOOT_DRIVER(rockchip_usb2phy) = { 1481 .name = "rockchip_usb2phy", 1482 .id = UCLASS_PHY, 1483 .of_match = rockchip_usb2phy_ids, 1484 .probe = rockchip_usb2phy_probe, 1485 .bind = rockchip_usb2phy_bind, 1486 .priv_auto_alloc_size = sizeof(struct rockchip_usb2phy), 1487 }; 1488