1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Rockchip USB3.0/PCIe Gen2/SATA/SGMII combphy driver 4 * 5 * Copyright (C) 2021 Rockchip Electronics Co., Ltd. 6 */ 7 8 #include <common.h> 9 #include <clk.h> 10 #include <dm.h> 11 #include <dm/lists.h> 12 #include <dt-bindings/phy/phy.h> 13 #include <generic-phy.h> 14 #include <syscon.h> 15 #include <asm/io.h> 16 #include <asm/arch/clock.h> 17 #include <regmap.h> 18 #include <reset-uclass.h> 19 20 #define BIT_WRITEABLE_SHIFT 16 21 22 struct rockchip_combphy_priv; 23 24 struct combphy_reg { 25 u32 offset; 26 u16 bitend; 27 u16 bitstart; 28 u16 disable; 29 u16 enable; 30 }; 31 32 struct rockchip_combphy_grfcfg { 33 struct combphy_reg pcie_mode_set; 34 struct combphy_reg usb_mode_set; 35 struct combphy_reg sgmii_mode_set; 36 struct combphy_reg qsgmii_mode_set; 37 struct combphy_reg pipe_rxterm_set; 38 struct combphy_reg pipe_txelec_set; 39 struct combphy_reg pipe_txcomp_set; 40 struct combphy_reg pipe_clk_24m; 41 struct combphy_reg pipe_clk_25m; 42 struct combphy_reg pipe_clk_100m; 43 struct combphy_reg pipe_phymode_sel; 44 struct combphy_reg pipe_rate_sel; 45 struct combphy_reg pipe_rxterm_sel; 46 struct combphy_reg pipe_txelec_sel; 47 struct combphy_reg pipe_txcomp_sel; 48 struct combphy_reg pipe_clk_ext; 49 struct combphy_reg pipe_sel_usb; 50 struct combphy_reg pipe_sel_qsgmii; 51 struct combphy_reg pipe_phy_status; 52 struct combphy_reg con0_for_pcie; 53 struct combphy_reg con1_for_pcie; 54 struct combphy_reg con2_for_pcie; 55 struct combphy_reg con3_for_pcie; 56 struct combphy_reg con0_for_sata; 57 struct combphy_reg con1_for_sata; 58 struct combphy_reg con2_for_sata; 59 struct combphy_reg con3_for_sata; 60 struct combphy_reg pipe_con0_for_sata; 61 struct combphy_reg pipe_con1_for_sata; 62 struct combphy_reg pipe_sgmii_mac_sel; 63 struct combphy_reg pipe_xpcs_phy_ready; 64 struct combphy_reg u3otg0_port_en; 65 struct combphy_reg u3otg1_port_en; 66 }; 67 68 struct rockchip_combphy_cfg { 69 const struct rockchip_combphy_grfcfg *grfcfg; 70 int (*combphy_cfg)(struct rockchip_combphy_priv *priv); 71 }; 72 73 struct rockchip_combphy_priv { 74 u32 mode; 75 void __iomem *mmio; 76 struct udevice *dev; 77 struct regmap *pipe_grf; 78 struct regmap *phy_grf; 79 struct phy *phy; 80 struct reset_ctl phy_rst; 81 struct clk ref_clk; 82 const struct rockchip_combphy_cfg *cfg; 83 }; 84 85 static int param_write(struct regmap *base, 86 const struct combphy_reg *reg, bool en) 87 { 88 u32 val, mask, tmp; 89 90 tmp = en ? reg->enable : reg->disable; 91 mask = GENMASK(reg->bitend, reg->bitstart); 92 val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT); 93 94 return regmap_write(base, reg->offset, val); 95 } 96 97 static int rockchip_combphy_pcie_init(struct rockchip_combphy_priv *priv) 98 { 99 int ret = 0; 100 101 if (priv->cfg->combphy_cfg) { 102 ret = priv->cfg->combphy_cfg(priv); 103 if (ret) { 104 dev_err(priv->dev, "failed to init phy for pcie\n"); 105 return ret; 106 } 107 } 108 109 return ret; 110 } 111 112 static int rockchip_combphy_usb3_init(struct rockchip_combphy_priv *priv) 113 { 114 int ret = 0; 115 116 if (priv->cfg->combphy_cfg) { 117 ret = priv->cfg->combphy_cfg(priv); 118 if (ret) { 119 dev_err(priv->dev, "failed to init phy for usb3\n"); 120 return ret; 121 } 122 } 123 124 return ret; 125 } 126 127 static int rockchip_combphy_sata_init(struct rockchip_combphy_priv *priv) 128 { 129 int ret = 0; 130 131 if (priv->cfg->combphy_cfg) { 132 ret = priv->cfg->combphy_cfg(priv); 133 if (ret) { 134 dev_err(priv->dev, "failed to init phy for sata\n"); 135 return ret; 136 } 137 } 138 139 return ret; 140 } 141 142 static int rockchip_combphy_sgmii_init(struct rockchip_combphy_priv *priv) 143 { 144 int ret = 0; 145 146 if (priv->cfg->combphy_cfg) { 147 ret = priv->cfg->combphy_cfg(priv); 148 if (ret) { 149 dev_err(priv->dev, "failed to init phy for sgmii\n"); 150 return ret; 151 } 152 } 153 154 return ret; 155 } 156 157 static int rockchip_combphy_set_mode(struct rockchip_combphy_priv *priv) 158 { 159 switch (priv->mode) { 160 case PHY_TYPE_PCIE: 161 rockchip_combphy_pcie_init(priv); 162 break; 163 case PHY_TYPE_USB3: 164 rockchip_combphy_usb3_init(priv); 165 break; 166 case PHY_TYPE_SATA: 167 rockchip_combphy_sata_init(priv); 168 break; 169 case PHY_TYPE_SGMII: 170 case PHY_TYPE_QSGMII: 171 return rockchip_combphy_sgmii_init(priv); 172 default: 173 dev_err(priv->dev, "incompatible PHY type\n"); 174 return -EINVAL; 175 } 176 177 return 0; 178 } 179 180 static int rockchip_combphy_init(struct phy *phy) 181 { 182 struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev); 183 int ret; 184 185 ret = clk_enable(&priv->ref_clk); 186 if (ret < 0 && ret != -ENOSYS) 187 return ret; 188 189 ret = rockchip_combphy_set_mode(priv); 190 if (ret) 191 goto err_clk; 192 193 reset_deassert(&priv->phy_rst); 194 195 return 0; 196 197 err_clk: 198 clk_disable(&priv->ref_clk); 199 200 return ret; 201 } 202 203 static int rockchip_combphy_exit(struct phy *phy) 204 { 205 struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev); 206 207 clk_disable(&priv->ref_clk); 208 reset_assert(&priv->phy_rst); 209 210 return 0; 211 } 212 213 static int rockchip_combphy_xlate(struct phy *phy, struct ofnode_phandle_args *args) 214 { 215 struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev); 216 217 if (args->args_count != 1) { 218 pr_err("invalid number of arguments\n"); 219 return -EINVAL; 220 } 221 222 priv->mode = args->args[0]; 223 224 return 0; 225 } 226 227 static const struct phy_ops rochchip_combphy_ops = { 228 .init = rockchip_combphy_init, 229 .exit = rockchip_combphy_exit, 230 .of_xlate = rockchip_combphy_xlate, 231 }; 232 233 static int rockchip_combphy_parse_dt(struct udevice *dev, 234 struct rockchip_combphy_priv *priv) 235 { 236 struct udevice *syscon; 237 int ret; 238 u32 vals[4]; 239 240 ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pipe-grf", &syscon); 241 if (ret) { 242 dev_err(dev, "failed to find peri_ctrl pipe-grf regmap ret= %d\n", ret); 243 return ret; 244 } 245 priv->pipe_grf = syscon_get_regmap(syscon); 246 247 ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pipe-phy-grf", &syscon); 248 if (ret) { 249 dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n"); 250 return ret; 251 } 252 priv->phy_grf = syscon_get_regmap(syscon); 253 254 ret = clk_get_by_index(dev, 0, &priv->ref_clk); 255 if (ret) { 256 dev_err(dev, "failed to find ref clock\n"); 257 return PTR_ERR(&priv->ref_clk); 258 } 259 260 ret = reset_get_by_name(dev, "combphy", &priv->phy_rst); 261 if (ret) { 262 dev_err(dev, "no phy reset control specified\n"); 263 return ret; 264 } 265 266 if (!dev_read_u32_array(dev, "rockchip,pcie1ln-sel-bits", 267 vals, ARRAY_SIZE(vals))) 268 regmap_write(priv->pipe_grf, vals[0], 269 (GENMASK(vals[2], vals[1]) << 16) | vals[3]); 270 271 return 0; 272 } 273 274 static int rockchip_combphy_probe(struct udevice *udev) 275 { 276 struct rockchip_combphy_priv *priv = dev_get_priv(udev); 277 const struct rockchip_combphy_cfg *phy_cfg; 278 279 priv->mmio = (void __iomem *)dev_read_addr(udev); 280 if (IS_ERR(priv->mmio)) 281 return PTR_ERR(priv->mmio); 282 283 phy_cfg = (const struct rockchip_combphy_cfg *)dev_get_driver_data(udev); 284 if (!phy_cfg) { 285 dev_err(udev, "No OF match data provided\n"); 286 return -EINVAL; 287 } 288 289 priv->dev = udev; 290 priv->mode = PHY_TYPE_SATA; 291 priv->cfg = phy_cfg; 292 293 return rockchip_combphy_parse_dt(udev, priv); 294 } 295 296 static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv) 297 { 298 const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 299 u32 val; 300 301 switch (priv->mode) { 302 case PHY_TYPE_PCIE: 303 /* Set SSC downward spread spectrum */ 304 val = readl(priv->mmio + 0x18); 305 val &= ~GENMASK(5, 4); 306 val |= 0x01 << 4; 307 writel(val, priv->mmio + 0x18); 308 309 param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 310 param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 311 param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 312 param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 313 break; 314 case PHY_TYPE_USB3: 315 /* Set SSC downward spread spectrum */ 316 val = readl(priv->mmio + 0x18); 317 val &= ~GENMASK(5, 4); 318 val |= 0x01 << 4; 319 writel(val, priv->mmio + 0x18); 320 321 /* Enable adaptive CTLE for USB3.0 Rx */ 322 val = readl(priv->mmio + 0x200); 323 val &= ~GENMASK(17, 17); 324 val |= 0x01; 325 writel(val, priv->mmio + 0x200); 326 327 param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 328 param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 329 param_write(priv->phy_grf, &cfg->usb_mode_set, true); 330 break; 331 default: 332 dev_err(priv->dev, "incompatible PHY type\n"); 333 return -EINVAL; 334 } 335 336 param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 337 if (priv->mode == PHY_TYPE_PCIE) { 338 /* PLL KVCO tuning fine */ 339 val = readl(priv->mmio + 0x18); 340 val &= ~(0x7 << 10); 341 val |= 0x2 << 10; 342 writel(val, priv->mmio + 0x18); 343 344 /* su_trim[6:4]=111, [10:7]=1001, [2:0]=000 */ 345 val = readl(priv->mmio + 0x108); 346 val &= ~(0x7f7); 347 val |= 0x4f0; 348 writel(val, priv->mmio + 0x108); 349 } 350 351 return 0; 352 } 353 354 static const struct rockchip_combphy_grfcfg rk3528_combphy_grfcfgs = { 355 /* pipe-phy-grf */ 356 .pcie_mode_set = { 0x48000, 5, 0, 0x00, 0x11 }, 357 .usb_mode_set = { 0x48000, 5, 0, 0x00, 0x04 }, 358 .pipe_rxterm_set = { 0x48000, 12, 12, 0x00, 0x01 }, 359 .pipe_txelec_set = { 0x48004, 1, 1, 0x00, 0x01 }, 360 .pipe_txcomp_set = { 0x48004, 4, 4, 0x00, 0x01 }, 361 .pipe_clk_24m = { 0x48004, 14, 13, 0x00, 0x00 }, 362 .pipe_clk_100m = { 0x48004, 14, 13, 0x00, 0x02 }, 363 .pipe_rxterm_sel = { 0x48008, 8, 8, 0x00, 0x01 }, 364 .pipe_txelec_sel = { 0x48008, 12, 12, 0x00, 0x01 }, 365 .pipe_txcomp_sel = { 0x48008, 15, 15, 0x00, 0x01 }, 366 .pipe_clk_ext = { 0x4800c, 9, 8, 0x02, 0x01 }, 367 .pipe_phy_status = { 0x48034, 6, 6, 0x01, 0x00 }, 368 .con0_for_pcie = { 0x48000, 15, 0, 0x00, 0x110 }, 369 .con1_for_pcie = { 0x48004, 15, 0, 0x00, 0x00 }, 370 .con2_for_pcie = { 0x48008, 15, 0, 0x00, 0x101 }, 371 .con3_for_pcie = { 0x4800c, 15, 0, 0x00, 0x0200 }, 372 /* pipe-grf */ 373 .u3otg0_port_en = { 0x40044, 15, 0, 0x0181, 0x1100 }, 374 }; 375 376 static const struct rockchip_combphy_cfg rk3528_combphy_cfgs = { 377 .grfcfg = &rk3528_combphy_grfcfgs, 378 .combphy_cfg = rk3528_combphy_cfg, 379 }; 380 381 static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) 382 { 383 const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 384 u32 val; 385 386 switch (priv->mode) { 387 case PHY_TYPE_PCIE: 388 /* Set SSC downward spread spectrum */ 389 val = readl(priv->mmio + (0x1f << 2)); 390 val &= ~GENMASK(5, 4); 391 val |= 0x01 << 4; 392 writel(val, priv->mmio + 0x7c); 393 394 param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 395 param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 396 param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 397 param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 398 break; 399 case PHY_TYPE_USB3: 400 /* Set SSC downward spread spectrum */ 401 val = readl(priv->mmio + (0x1f << 2)); 402 val &= ~GENMASK(5, 4); 403 val |= 0x01 << 4; 404 writel(val, priv->mmio + 0x7c); 405 406 /* Enable adaptive CTLE for USB3.0 Rx */ 407 val = readl(priv->mmio + (0x0e << 2)); 408 val &= ~GENMASK(0, 0); 409 val |= 0x01; 410 writel(val, priv->mmio + (0x0e << 2)); 411 412 /* Set PLL KVCO fine tuning signals */ 413 val = readl(priv->mmio + (0x20 << 2)); 414 val &= ~(0x7 << 2); 415 val |= 0x2 << 2; 416 writel(val, priv->mmio + (0x20 << 2)); 417 418 /* Set PLL LPF R1 to su_trim[10:7]=1001 */ 419 writel(0x4, priv->mmio + (0xb << 2)); 420 421 /* Set PLL input clock divider 1/2 */ 422 val = readl(priv->mmio + (0x5 << 2)); 423 val &= ~(0x3 << 6); 424 val |= 0x1 << 6; 425 writel(val, priv->mmio + (0x5 << 2)); 426 427 /* Set PLL loop divider */ 428 writel(0x32, priv->mmio + (0x11 << 2)); 429 430 /* Set PLL KVCO to min and set PLL charge pump current to max */ 431 writel(0xf0, priv->mmio + (0xa << 2)); 432 433 param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); 434 param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 435 param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 436 param_write(priv->phy_grf, &cfg->usb_mode_set, true); 437 break; 438 default: 439 pr_err("%s, phy-type %d\n", __func__, priv->mode); 440 return -EINVAL; 441 } 442 443 clk_set_rate(&priv->ref_clk, 100000000); 444 param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 445 446 if (dev_read_bool(priv->dev, "rockchip,enable-ssc")) { 447 val = readl(priv->mmio + (0x7 << 2)); 448 val |= BIT(4); 449 writel(val, priv->mmio + (0x7 << 2)); 450 } 451 452 return 0; 453 } 454 455 static const struct rockchip_combphy_grfcfg rk3562_combphy_grfcfgs = { 456 /* pipe-phy-grf */ 457 .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, 458 .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, 459 .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, 460 .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, 461 .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, 462 .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, 463 .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, 464 .pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 }, 465 .pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 }, 466 .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, 467 .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, 468 .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, 469 .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, 470 .pipe_sel_usb = { 0x000c, 14, 13, 0x00, 0x01 }, 471 .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, 472 .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, 473 .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, 474 .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, 475 .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, 476 /* pipe-grf */ 477 .u3otg0_port_en = { 0x0094, 15, 0, 0x0181, 0x1100 }, 478 }; 479 480 static const struct rockchip_combphy_cfg rk3562_combphy_cfgs = { 481 .grfcfg = &rk3562_combphy_grfcfgs, 482 .combphy_cfg = rk3562_combphy_cfg, 483 }; 484 485 static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) 486 { 487 const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 488 u32 val; 489 490 switch (priv->mode) { 491 case PHY_TYPE_PCIE: 492 /* Set SSC downward spread spectrum */ 493 val = readl(priv->mmio + (0x1f << 2)); 494 val &= ~GENMASK(5, 4); 495 val |= 0x01 << 4; 496 writel(val, priv->mmio + 0x7c); 497 498 param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 499 param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 500 param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 501 param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 502 break; 503 case PHY_TYPE_USB3: 504 /* Set SSC downward spread spectrum */ 505 val = readl(priv->mmio + (0x1f << 2)); 506 val &= ~GENMASK(5, 4); 507 val |= 0x01 << 4; 508 writel(val, priv->mmio + 0x7c); 509 510 /* Enable adaptive CTLE for USB3.0 Rx */ 511 val = readl(priv->mmio + (0x0e << 2)); 512 val &= ~GENMASK(0, 0); 513 val |= 0x01; 514 writel(val, priv->mmio + (0x0e << 2)); 515 516 /* Set PLL KVCO fine tuning signals */ 517 val = readl(priv->mmio + (0x20 << 2)); 518 val &= ~(0x7 << 2); 519 val |= 0x2 << 2; 520 writel(val, priv->mmio + (0x20 << 2)); 521 522 /* Set PLL LPF R1 to su_trim[10:7]=1001 */ 523 writel(0x4, priv->mmio + (0xb << 2)); 524 525 /* Set PLL input clock divider 1/2 */ 526 val = readl(priv->mmio + (0x5 << 2)); 527 val &= ~(0x3 << 6); 528 val |= 0x1 << 6; 529 writel(val, priv->mmio + (0x5 << 2)); 530 531 /* Set PLL loop divider */ 532 writel(0x32, priv->mmio + (0x11 << 2)); 533 534 /* Set PLL KVCO to min and set PLL charge pump current to max */ 535 writel(0xf0, priv->mmio + (0xa << 2)); 536 537 param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); 538 param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 539 param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 540 param_write(priv->phy_grf, &cfg->usb_mode_set, true); 541 break; 542 case PHY_TYPE_SATA: 543 writel(0x41, priv->mmio + 0x38); 544 writel(0x8F, priv->mmio + 0x18); 545 param_write(priv->phy_grf, &cfg->con0_for_sata, true); 546 param_write(priv->phy_grf, &cfg->con1_for_sata, true); 547 param_write(priv->phy_grf, &cfg->con2_for_sata, true); 548 param_write(priv->phy_grf, &cfg->con3_for_sata, true); 549 param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true); 550 break; 551 case PHY_TYPE_SGMII: 552 param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true); 553 param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true); 554 param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true); 555 param_write(priv->phy_grf, &cfg->sgmii_mode_set, true); 556 break; 557 case PHY_TYPE_QSGMII: 558 param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true); 559 param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true); 560 param_write(priv->phy_grf, &cfg->pipe_rate_sel, true); 561 param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true); 562 param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true); 563 break; 564 default: 565 pr_err("%s, phy-type %d\n", __func__, priv->mode); 566 return -EINVAL; 567 } 568 569 /* The default ref clock is 25Mhz */ 570 param_write(priv->phy_grf, &cfg->pipe_clk_25m, true); 571 572 if (dev_read_bool(priv->dev, "rockchip,enable-ssc")) { 573 val = readl(priv->mmio + (0x7 << 2)); 574 val |= BIT(4); 575 writel(val, priv->mmio + (0x7 << 2)); 576 } 577 578 return 0; 579 } 580 581 static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = { 582 /* pipe-phy-grf */ 583 .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, 584 .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, 585 .sgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x01 }, 586 .qsgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x21 }, 587 .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, 588 .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, 589 .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, 590 .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, 591 .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, 592 .pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 }, 593 .pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 }, 594 .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, 595 .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, 596 .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, 597 .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, 598 .pipe_sel_usb = { 0x000c, 14, 13, 0x00, 0x01 }, 599 .pipe_sel_qsgmii = { 0x000c, 15, 13, 0x00, 0x07 }, 600 .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, 601 .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, 602 .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, 603 .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, 604 .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, 605 .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0119 }, 606 .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0040 }, 607 .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c3 }, 608 .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x4407 }, 609 /* pipe-grf */ 610 .pipe_con0_for_sata = { 0x0000, 15, 0, 0x00, 0x2220 }, 611 .pipe_sgmii_mac_sel = { 0x0040, 1, 1, 0x00, 0x01 }, 612 .pipe_xpcs_phy_ready = { 0x0040, 2, 2, 0x00, 0x01 }, 613 .u3otg0_port_en = { 0x0104, 15, 0, 0x0181, 0x1100 }, 614 .u3otg1_port_en = { 0x0144, 15, 0, 0x0181, 0x1100 }, 615 }; 616 617 static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = { 618 .grfcfg = &rk3568_combphy_grfcfgs, 619 .combphy_cfg = rk3568_combphy_cfg, 620 }; 621 622 static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) 623 { 624 const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 625 u32 val; 626 627 switch (priv->mode) { 628 case PHY_TYPE_PCIE: 629 param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 630 param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 631 param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 632 param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 633 break; 634 case PHY_TYPE_USB3: 635 /* Set SSC downward spread spectrum */ 636 val = readl(priv->mmio + (0x1f << 2)); 637 val &= ~GENMASK(5, 4); 638 val |= 0x01 << 4; 639 writel(val, priv->mmio + 0x7c); 640 641 /* Enable adaptive CTLE for USB3.0 Rx */ 642 val = readl(priv->mmio + (0x0e << 2)); 643 val &= ~GENMASK(0, 0); 644 val |= 0x01; 645 writel(val, priv->mmio + (0x0e << 2)); 646 647 /* Set PLL KVCO fine tuning signals */ 648 val = readl(priv->mmio + (0x20 << 2)); 649 val &= ~(0x7 << 2); 650 val |= 0x2 << 2; 651 writel(val, priv->mmio + (0x20 << 2)); 652 653 /* Set PLL LPF R1 to su_trim[10:7]=1001 */ 654 writel(0x4, priv->mmio + (0xb << 2)); 655 656 /* Set PLL input clock divider 1/2 */ 657 val = readl(priv->mmio + (0x5 << 2)); 658 val &= ~(0x3 << 6); 659 val |= 0x1 << 6; 660 writel(val, priv->mmio + (0x5 << 2)); 661 662 /* Set PLL loop divider */ 663 writel(0x32, priv->mmio + (0x11 << 2)); 664 665 /* Set PLL KVCO to min and set PLL charge pump current to max */ 666 writel(0xf0, priv->mmio + (0xa << 2)); 667 668 /* Set Rx squelch input filler bandwidth */ 669 writel(0x0d, priv->mmio + (0x14 << 2)); 670 671 param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 672 param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 673 param_write(priv->phy_grf, &cfg->usb_mode_set, true); 674 break; 675 case PHY_TYPE_SATA: 676 /* Enable adaptive CTLE for SATA Rx */ 677 val = readl(priv->mmio + (0x0e << 2)); 678 val &= ~GENMASK(0, 0); 679 val |= 0x01; 680 writel(val, priv->mmio + (0x0e << 2)); 681 /* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */ 682 writel(0x8F, priv->mmio + (0x06 << 2)); 683 684 param_write(priv->phy_grf, &cfg->con0_for_sata, true); 685 param_write(priv->phy_grf, &cfg->con1_for_sata, true); 686 param_write(priv->phy_grf, &cfg->con2_for_sata, true); 687 param_write(priv->phy_grf, &cfg->con3_for_sata, true); 688 param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true); 689 param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true); 690 break; 691 case PHY_TYPE_SGMII: 692 case PHY_TYPE_QSGMII: 693 default: 694 dev_err(priv->dev, "incompatible PHY type\n"); 695 return -EINVAL; 696 } 697 698 /* 100MHz refclock signal is good */ 699 clk_set_rate(&priv->ref_clk, 100000000); 700 param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 701 if (priv->mode == PHY_TYPE_PCIE) { 702 /* PLL KVCO tuning fine */ 703 val = readl(priv->mmio + (0x20 << 2)); 704 val &= ~GENMASK(4, 2); 705 val |= 0x4 << 2; 706 writel(val, priv->mmio + (0x20 << 2)); 707 708 /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ 709 val = 0x4c; 710 writel(val, priv->mmio + (0x1b << 2)); 711 712 /* Set up su_trim: T3 */ 713 val = 0xb0; 714 writel(val, priv->mmio + (0xa << 2)); 715 val = 0x47; 716 writel(val, priv->mmio + (0xb << 2)); 717 val = 0x57; 718 writel(val, priv->mmio + (0xd << 2)); 719 } 720 721 return 0; 722 } 723 724 static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = { 725 /* pipe-phy-grf */ 726 .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, 727 .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, 728 .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, 729 .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, 730 .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, 731 .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, 732 .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, 733 .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, 734 .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, 735 .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, 736 .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, 737 .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, 738 .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, 739 .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, 740 .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, 741 .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, 742 .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0129 }, 743 .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0000 }, 744 .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c1 }, 745 .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x0407 }, 746 /* pipe-grf */ 747 .pipe_con0_for_sata = { 0x0000, 11, 5, 0x00, 0x22 }, 748 .pipe_con1_for_sata = { 0x0000, 2, 0, 0x00, 0x2 }, 749 }; 750 751 static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = { 752 .grfcfg = &rk3588_combphy_grfcfgs, 753 .combphy_cfg = rk3588_combphy_cfg, 754 }; 755 756 static const struct udevice_id rockchip_combphy_ids[] = { 757 { 758 .compatible = "rockchip,rk3528-naneng-combphy", 759 .data = (ulong)&rk3528_combphy_cfgs 760 }, 761 { 762 .compatible = "rockchip,rk3562-naneng-combphy", 763 .data = (ulong)&rk3562_combphy_cfgs 764 }, 765 { 766 .compatible = "rockchip,rk3568-naneng-combphy", 767 .data = (ulong)&rk3568_combphy_cfgs 768 }, 769 { 770 .compatible = "rockchip,rk3588-naneng-combphy", 771 .data = (ulong)&rk3588_combphy_cfgs 772 }, 773 { } 774 }; 775 776 U_BOOT_DRIVER(rockchip_naneng_combphy) = { 777 .name = "naneng-combphy", 778 .id = UCLASS_PHY, 779 .of_match = rockchip_combphy_ids, 780 .ops = &rochchip_combphy_ops, 781 .probe = rockchip_combphy_probe, 782 .priv_auto_alloc_size = sizeof(struct rockchip_combphy_priv), 783 }; 784