1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Rockchip PIPE USB3.0 PCIE SATA Combo Phy driver 4 * 5 * Copyright (C) 2021 Rockchip Electronics Co., Ltd. 6 */ 7 8 #include <dt-bindings/phy/phy.h> 9 #include <linux/clk.h> 10 #include <linux/mfd/syscon.h> 11 #include <linux/of_device.h> 12 #include <linux/phy/phy.h> 13 #include <linux/regmap.h> 14 #include <linux/reset.h> 15 #include <linux/units.h> 16 17 #define BIT_WRITEABLE_SHIFT 16 18 #define REF_CLOCK_24MHz (24 * HZ_PER_MHZ) 19 #define REF_CLOCK_25MHz (25 * HZ_PER_MHZ) 20 #define REF_CLOCK_100MHz (100 * HZ_PER_MHZ) 21 22 /* COMBO PHY REG */ 23 #define PHYREG6 0x14 24 #define PHYREG6_PLL_DIV_MASK GENMASK(7, 6) 25 #define PHYREG6_PLL_DIV_SHIFT 6 26 #define PHYREG6_PLL_DIV_2 1 27 28 #define PHYREG7 0x18 29 #define PHYREG7_TX_RTERM_MASK GENMASK(7, 4) 30 #define PHYREG7_TX_RTERM_SHIFT 4 31 #define PHYREG7_TX_RTERM_50OHM 8 32 #define PHYREG7_RX_RTERM_MASK GENMASK(3, 0) 33 #define PHYREG7_RX_RTERM_SHIFT 0 34 #define PHYREG7_RX_RTERM_44OHM 15 35 36 #define PHYREG8 0x1C 37 #define PHYREG8_SSC_EN BIT(4) 38 39 #define PHYREG11 0x28 40 #define PHYREG11_SU_TRIM_0_7 0xF0 41 42 #define PHYREG12 0x2C 43 #define PHYREG12_PLL_LPF_ADJ_VALUE 4 44 45 #define PHYREG13 0x30 46 #define PHYREG13_RESISTER_MASK GENMASK(5, 4) 47 #define PHYREG13_RESISTER_SHIFT 0x4 48 #define PHYREG13_RESISTER_HIGH_Z 3 49 #define PHYREG13_CKRCV_AMP0 BIT(7) 50 51 #define PHYREG14 0x34 52 #define PHYREG14_CKRCV_AMP1 BIT(0) 53 54 #define PHYREG15 0x38 55 #define PHYREG15_CTLE_EN BIT(0) 56 #define PHYREG15_SSC_CNT_MASK GENMASK(7, 6) 57 #define PHYREG15_SSC_CNT_SHIFT 6 58 #define PHYREG15_SSC_CNT_VALUE 1 59 60 #define PHYREG16 0x3C 61 #define PHYREG16_SSC_CNT_VALUE 0x5f 62 63 #define PHYREG18 0x44 64 #define PHYREG18_PLL_LOOP 0x32 65 66 #define PHYREG27 0x6C 67 #define PHYREG27_RX_TRIM_RK3588 0x4C 68 69 #define PHYREG32 0x7C 70 #define PHYREG32_SSC_MASK GENMASK(7, 4) 71 #define PHYREG32_SSC_DIR_SHIFT 4 72 #define PHYREG32_SSC_UPWARD 0 73 #define PHYREG32_SSC_DOWNWARD 1 74 #define PHYREG32_SSC_OFFSET_SHIFT 6 75 #define PHYREG32_SSC_OFFSET_500PPM 1 76 77 #define PHYREG33 0x80 78 #define PHYREG33_PLL_KVCO_MASK GENMASK(4, 2) 79 #define PHYREG33_PLL_KVCO_SHIFT 2 80 #define PHYREG33_PLL_KVCO_VALUE 2 81 82 struct rockchip_combphy_priv; 83 84 struct combphy_reg { 85 u16 offset; 86 u16 bitend; 87 u16 bitstart; 88 u16 disable; 89 u16 enable; 90 }; 91 92 struct rockchip_combphy_grfcfg { 93 struct combphy_reg pcie_mode_set; 94 struct combphy_reg usb_mode_set; 95 struct combphy_reg sgmii_mode_set; 96 struct combphy_reg qsgmii_mode_set; 97 struct combphy_reg pipe_rxterm_set; 98 struct combphy_reg pipe_txelec_set; 99 struct combphy_reg pipe_txcomp_set; 100 struct combphy_reg pipe_clk_25m; 101 struct combphy_reg pipe_clk_100m; 102 struct combphy_reg pipe_phymode_sel; 103 struct combphy_reg pipe_rate_sel; 104 struct combphy_reg pipe_rxterm_sel; 105 struct combphy_reg pipe_txelec_sel; 106 struct combphy_reg pipe_txcomp_sel; 107 struct combphy_reg pipe_clk_ext; 108 struct combphy_reg pipe_sel_usb; 109 struct combphy_reg pipe_sel_qsgmii; 110 struct combphy_reg pipe_phy_status; 111 struct combphy_reg con0_for_pcie; 112 struct combphy_reg con1_for_pcie; 113 struct combphy_reg con2_for_pcie; 114 struct combphy_reg con3_for_pcie; 115 struct combphy_reg con0_for_sata; 116 struct combphy_reg con1_for_sata; 117 struct combphy_reg con2_for_sata; 118 struct combphy_reg con3_for_sata; 119 struct combphy_reg pipe_con0_for_sata; 120 struct combphy_reg pipe_con1_for_sata; 121 struct combphy_reg pipe_xpcs_phy_ready; 122 struct combphy_reg pipe_pcie1l0_sel; 123 struct combphy_reg pipe_pcie1l1_sel; 124 }; 125 126 struct rockchip_combphy_cfg { 127 const struct rockchip_combphy_grfcfg *grfcfg; 128 int (*combphy_cfg)(struct rockchip_combphy_priv *priv); 129 }; 130 131 struct rockchip_combphy_priv { 132 u8 type; 133 void __iomem *mmio; 134 int num_clks; 135 struct clk_bulk_data *clks; 136 struct device *dev; 137 struct regmap *pipe_grf; 138 struct regmap *phy_grf; 139 struct phy *phy; 140 struct reset_control *phy_rst; 141 const struct rockchip_combphy_cfg *cfg; 142 bool enable_ssc; 143 bool ext_refclk; 144 struct clk *refclk; 145 }; 146 147 static void rockchip_combphy_updatel(struct rockchip_combphy_priv *priv, 148 int mask, int val, int reg) 149 { 150 unsigned int temp; 151 152 temp = readl(priv->mmio + reg); 153 temp = (temp & ~(mask)) | val; 154 writel(temp, priv->mmio + reg); 155 } 156 157 static int rockchip_combphy_param_write(struct regmap *base, 158 const struct combphy_reg *reg, bool en) 159 { 160 u32 val, mask, tmp; 161 162 tmp = en ? reg->enable : reg->disable; 163 mask = GENMASK(reg->bitend, reg->bitstart); 164 val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT); 165 166 return regmap_write(base, reg->offset, val); 167 } 168 169 static u32 rockchip_combphy_is_ready(struct rockchip_combphy_priv *priv) 170 { 171 const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 172 u32 mask, val; 173 174 mask = GENMASK(cfg->pipe_phy_status.bitend, 175 cfg->pipe_phy_status.bitstart); 176 177 regmap_read(priv->phy_grf, cfg->pipe_phy_status.offset, &val); 178 val = (val & mask) >> cfg->pipe_phy_status.bitstart; 179 180 return val; 181 } 182 183 static int rockchip_combphy_init(struct phy *phy) 184 { 185 struct rockchip_combphy_priv *priv = phy_get_drvdata(phy); 186 const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 187 u32 val; 188 int ret; 189 190 ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks); 191 if (ret) { 192 dev_err(priv->dev, "failed to enable clks\n"); 193 return ret; 194 } 195 196 switch (priv->type) { 197 case PHY_TYPE_PCIE: 198 case PHY_TYPE_USB3: 199 case PHY_TYPE_SATA: 200 case PHY_TYPE_SGMII: 201 case PHY_TYPE_QSGMII: 202 if (priv->cfg->combphy_cfg) 203 ret = priv->cfg->combphy_cfg(priv); 204 break; 205 default: 206 dev_err(priv->dev, "incompatible PHY type\n"); 207 ret = -EINVAL; 208 break; 209 } 210 211 if (ret) { 212 dev_err(priv->dev, "failed to init phy for phy type %x\n", priv->type); 213 goto err_clk; 214 } 215 216 ret = reset_control_deassert(priv->phy_rst); 217 if (ret) 218 goto err_clk; 219 220 if (priv->type == PHY_TYPE_USB3) { 221 ret = readx_poll_timeout_atomic(rockchip_combphy_is_ready, 222 priv, val, 223 val == cfg->pipe_phy_status.enable, 224 10, 1000); 225 if (ret) 226 dev_warn(priv->dev, "wait phy status ready timeout\n"); 227 } 228 229 return 0; 230 231 err_clk: 232 clk_bulk_disable_unprepare(priv->num_clks, priv->clks); 233 234 return ret; 235 } 236 237 static int rockchip_combphy_exit(struct phy *phy) 238 { 239 struct rockchip_combphy_priv *priv = phy_get_drvdata(phy); 240 241 clk_bulk_disable_unprepare(priv->num_clks, priv->clks); 242 reset_control_assert(priv->phy_rst); 243 244 return 0; 245 } 246 247 static const struct phy_ops rochchip_combphy_ops = { 248 .init = rockchip_combphy_init, 249 .exit = rockchip_combphy_exit, 250 .owner = THIS_MODULE, 251 }; 252 253 static struct phy *rockchip_combphy_xlate(struct device *dev, struct of_phandle_args *args) 254 { 255 struct rockchip_combphy_priv *priv = dev_get_drvdata(dev); 256 257 if (args->args_count != 1) { 258 dev_err(dev, "invalid number of arguments\n"); 259 return ERR_PTR(-EINVAL); 260 } 261 262 if (priv->type != PHY_NONE && priv->type != args->args[0]) 263 dev_warn(dev, "phy type select %d overwriting type %d\n", 264 args->args[0], priv->type); 265 266 priv->type = args->args[0]; 267 268 return priv->phy; 269 } 270 271 static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy_priv *priv) 272 { 273 int i; 274 275 priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks); 276 if (priv->num_clks < 1) 277 return -EINVAL; 278 279 priv->refclk = NULL; 280 for (i = 0; i < priv->num_clks; i++) { 281 if (!strncmp(priv->clks[i].id, "ref", 3)) { 282 priv->refclk = priv->clks[i].clk; 283 break; 284 } 285 } 286 287 if (!priv->refclk) { 288 dev_err(dev, "no refclk found\n"); 289 return -EINVAL; 290 } 291 292 priv->pipe_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-grf"); 293 if (IS_ERR(priv->pipe_grf)) { 294 dev_err(dev, "failed to find peri_ctrl pipe-grf regmap\n"); 295 return PTR_ERR(priv->pipe_grf); 296 } 297 298 priv->phy_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-phy-grf"); 299 if (IS_ERR(priv->phy_grf)) { 300 dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n"); 301 return PTR_ERR(priv->phy_grf); 302 } 303 304 priv->enable_ssc = device_property_present(dev, "rockchip,enable-ssc"); 305 306 priv->ext_refclk = device_property_present(dev, "rockchip,ext-refclk"); 307 308 priv->phy_rst = devm_reset_control_array_get_exclusive(dev); 309 if (IS_ERR(priv->phy_rst)) 310 return dev_err_probe(dev, PTR_ERR(priv->phy_rst), "failed to get phy reset\n"); 311 312 return 0; 313 } 314 315 static int rockchip_combphy_probe(struct platform_device *pdev) 316 { 317 struct phy_provider *phy_provider; 318 struct device *dev = &pdev->dev; 319 struct rockchip_combphy_priv *priv; 320 const struct rockchip_combphy_cfg *phy_cfg; 321 struct resource *res; 322 int ret; 323 324 phy_cfg = of_device_get_match_data(dev); 325 if (!phy_cfg) { 326 dev_err(dev, "no OF match data provided\n"); 327 return -EINVAL; 328 } 329 330 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 331 if (!priv) 332 return -ENOMEM; 333 334 priv->mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 335 if (IS_ERR(priv->mmio)) { 336 ret = PTR_ERR(priv->mmio); 337 return ret; 338 } 339 340 priv->dev = dev; 341 priv->type = PHY_NONE; 342 priv->cfg = phy_cfg; 343 344 ret = rockchip_combphy_parse_dt(dev, priv); 345 if (ret) 346 return ret; 347 348 ret = reset_control_assert(priv->phy_rst); 349 if (ret) { 350 dev_err(dev, "failed to reset phy\n"); 351 return ret; 352 } 353 354 priv->phy = devm_phy_create(dev, NULL, &rochchip_combphy_ops); 355 if (IS_ERR(priv->phy)) { 356 dev_err(dev, "failed to create combphy\n"); 357 return PTR_ERR(priv->phy); 358 } 359 360 dev_set_drvdata(dev, priv); 361 phy_set_drvdata(priv->phy, priv); 362 363 phy_provider = devm_of_phy_provider_register(dev, rockchip_combphy_xlate); 364 365 return PTR_ERR_OR_ZERO(phy_provider); 366 } 367 368 static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) 369 { 370 const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 371 unsigned long rate; 372 u32 val; 373 374 switch (priv->type) { 375 case PHY_TYPE_PCIE: 376 /* Set SSC downward spread spectrum. */ 377 rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, 378 PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, 379 PHYREG32); 380 381 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 382 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 383 rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 384 rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 385 break; 386 387 case PHY_TYPE_USB3: 388 /* Set SSC downward spread spectrum. */ 389 rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, 390 PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, 391 PHYREG32); 392 393 /* Enable adaptive CTLE for USB3.0 Rx. */ 394 val = readl(priv->mmio + PHYREG15); 395 val |= PHYREG15_CTLE_EN; 396 writel(val, priv->mmio + PHYREG15); 397 398 /* Set PLL KVCO fine tuning signals. */ 399 rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, 400 PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT, 401 PHYREG33); 402 403 /* Enable controlling random jitter. */ 404 writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); 405 406 /* Set PLL input clock divider 1/2. */ 407 rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, 408 PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT, 409 PHYREG6); 410 411 writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); 412 writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); 413 414 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); 415 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 416 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 417 rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); 418 break; 419 420 case PHY_TYPE_SATA: 421 /* Enable adaptive CTLE for SATA Rx. */ 422 val = readl(priv->mmio + PHYREG15); 423 val |= PHYREG15_CTLE_EN; 424 writel(val, priv->mmio + PHYREG15); 425 /* 426 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. 427 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) 428 */ 429 val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT; 430 val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT; 431 writel(val, priv->mmio + PHYREG7); 432 433 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); 434 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); 435 rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true); 436 rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true); 437 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true); 438 break; 439 440 case PHY_TYPE_SGMII: 441 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true); 442 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true); 443 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true); 444 rockchip_combphy_param_write(priv->phy_grf, &cfg->sgmii_mode_set, true); 445 break; 446 447 case PHY_TYPE_QSGMII: 448 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true); 449 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true); 450 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_rate_sel, true); 451 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true); 452 rockchip_combphy_param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true); 453 break; 454 455 default: 456 dev_err(priv->dev, "incompatible PHY type\n"); 457 return -EINVAL; 458 } 459 460 rate = clk_get_rate(priv->refclk); 461 462 switch (rate) { 463 case REF_CLOCK_24MHz: 464 if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { 465 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ 466 val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT; 467 rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, 468 val, PHYREG15); 469 470 writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); 471 } 472 break; 473 474 case REF_CLOCK_25MHz: 475 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true); 476 break; 477 478 case REF_CLOCK_100MHz: 479 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 480 if (priv->type == PHY_TYPE_PCIE) { 481 /* PLL KVCO fine tuning. */ 482 val = PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT; 483 rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, 484 val, PHYREG33); 485 486 /* Enable controlling random jitter. */ 487 writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); 488 489 val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT; 490 rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, 491 val, PHYREG6); 492 493 writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); 494 writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); 495 } else if (priv->type == PHY_TYPE_SATA) { 496 /* downward spread spectrum +500ppm */ 497 val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT; 498 val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT; 499 rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); 500 } 501 break; 502 503 default: 504 dev_err(priv->dev, "unsupported rate: %lu\n", rate); 505 return -EINVAL; 506 } 507 508 if (priv->ext_refclk) { 509 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); 510 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { 511 val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; 512 val |= PHYREG13_CKRCV_AMP0; 513 rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); 514 515 val = readl(priv->mmio + PHYREG14); 516 val |= PHYREG14_CKRCV_AMP1; 517 writel(val, priv->mmio + PHYREG14); 518 } 519 } 520 521 if (priv->enable_ssc) { 522 val = readl(priv->mmio + PHYREG8); 523 val |= PHYREG8_SSC_EN; 524 writel(val, priv->mmio + PHYREG8); 525 } 526 527 return 0; 528 } 529 530 static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = { 531 /* pipe-phy-grf */ 532 .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, 533 .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, 534 .sgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x01 }, 535 .qsgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x21 }, 536 .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, 537 .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, 538 .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, 539 .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, 540 .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, 541 .pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 }, 542 .pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 }, 543 .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, 544 .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, 545 .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, 546 .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, 547 .pipe_sel_usb = { 0x000c, 14, 13, 0x00, 0x01 }, 548 .pipe_sel_qsgmii = { 0x000c, 15, 13, 0x00, 0x07 }, 549 .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, 550 .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, 551 .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, 552 .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, 553 .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, 554 .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0119 }, 555 .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0040 }, 556 .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c3 }, 557 .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x4407 }, 558 /* pipe-grf */ 559 .pipe_con0_for_sata = { 0x0000, 15, 0, 0x00, 0x2220 }, 560 .pipe_xpcs_phy_ready = { 0x0040, 2, 2, 0x00, 0x01 }, 561 }; 562 563 static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = { 564 .grfcfg = &rk3568_combphy_grfcfgs, 565 .combphy_cfg = rk3568_combphy_cfg, 566 }; 567 568 static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) 569 { 570 const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 571 unsigned long rate; 572 u32 val; 573 574 switch (priv->type) { 575 case PHY_TYPE_PCIE: 576 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 577 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 578 rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 579 rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 580 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l0_sel, true); 581 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l1_sel, true); 582 break; 583 case PHY_TYPE_USB3: 584 /* Set SSC downward spread spectrum */ 585 rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, 586 PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, 587 PHYREG32); 588 589 /* Enable adaptive CTLE for USB3.0 Rx. */ 590 val = readl(priv->mmio + PHYREG15); 591 val |= PHYREG15_CTLE_EN; 592 writel(val, priv->mmio + PHYREG15); 593 594 /* Set PLL KVCO fine tuning signals. */ 595 rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, 596 PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT, 597 PHYREG33); 598 599 /* Enable controlling random jitter. */ 600 writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); 601 602 /* Set PLL input clock divider 1/2. */ 603 rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, 604 PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT, 605 PHYREG6); 606 607 writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); 608 writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); 609 610 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 611 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 612 rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); 613 break; 614 case PHY_TYPE_SATA: 615 /* Enable adaptive CTLE for SATA Rx. */ 616 val = readl(priv->mmio + PHYREG15); 617 val |= PHYREG15_CTLE_EN; 618 writel(val, priv->mmio + PHYREG15); 619 /* 620 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. 621 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) 622 */ 623 val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT; 624 val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT; 625 writel(val, priv->mmio + PHYREG7); 626 627 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); 628 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); 629 rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true); 630 rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true); 631 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true); 632 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true); 633 break; 634 case PHY_TYPE_SGMII: 635 case PHY_TYPE_QSGMII: 636 default: 637 dev_err(priv->dev, "incompatible PHY type\n"); 638 return -EINVAL; 639 } 640 641 rate = clk_get_rate(priv->refclk); 642 643 switch (rate) { 644 case REF_CLOCK_24MHz: 645 if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { 646 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ 647 val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT; 648 rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, 649 val, PHYREG15); 650 651 writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); 652 } 653 break; 654 655 case REF_CLOCK_25MHz: 656 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true); 657 break; 658 case REF_CLOCK_100MHz: 659 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 660 if (priv->type == PHY_TYPE_PCIE) { 661 /* PLL KVCO fine tuning. */ 662 val = 4 << PHYREG33_PLL_KVCO_SHIFT; 663 rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, 664 val, PHYREG33); 665 666 /* Enable controlling random jitter. */ 667 writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); 668 669 /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ 670 writel(PHYREG27_RX_TRIM_RK3588, priv->mmio + PHYREG27); 671 672 /* Set up su_trim: */ 673 writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); 674 } else if (priv->type == PHY_TYPE_SATA) { 675 /* downward spread spectrum +500ppm */ 676 val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT; 677 val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT; 678 rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); 679 } 680 break; 681 default: 682 dev_err(priv->dev, "Unsupported rate: %lu\n", rate); 683 return -EINVAL; 684 } 685 686 if (priv->ext_refclk) { 687 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); 688 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { 689 val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; 690 val |= PHYREG13_CKRCV_AMP0; 691 rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); 692 693 val = readl(priv->mmio + PHYREG14); 694 val |= PHYREG14_CKRCV_AMP1; 695 writel(val, priv->mmio + PHYREG14); 696 } 697 } 698 699 if (priv->enable_ssc) { 700 val = readl(priv->mmio + PHYREG8); 701 val |= PHYREG8_SSC_EN; 702 writel(val, priv->mmio + PHYREG8); 703 } 704 705 return 0; 706 } 707 708 static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = { 709 /* pipe-phy-grf */ 710 .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, 711 .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, 712 .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, 713 .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, 714 .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, 715 .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, 716 .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, 717 .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, 718 .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, 719 .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, 720 .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, 721 .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, 722 .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, 723 .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, 724 .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, 725 .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, 726 .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0129 }, 727 .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0000 }, 728 .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c1 }, 729 .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x0407 }, 730 /* pipe-grf */ 731 .pipe_con0_for_sata = { 0x0000, 11, 5, 0x00, 0x22 }, 732 .pipe_con1_for_sata = { 0x0000, 2, 0, 0x00, 0x2 }, 733 .pipe_pcie1l0_sel = { 0x0100, 0, 0, 0x01, 0x0 }, 734 .pipe_pcie1l1_sel = { 0x0100, 1, 1, 0x01, 0x0 }, 735 }; 736 737 static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = { 738 .grfcfg = &rk3588_combphy_grfcfgs, 739 .combphy_cfg = rk3588_combphy_cfg, 740 }; 741 742 static const struct of_device_id rockchip_combphy_of_match[] = { 743 { 744 .compatible = "rockchip,rk3568-naneng-combphy", 745 .data = &rk3568_combphy_cfgs, 746 }, 747 { 748 .compatible = "rockchip,rk3588-naneng-combphy", 749 .data = &rk3588_combphy_cfgs, 750 }, 751 { }, 752 }; 753 MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match); 754 755 static struct platform_driver rockchip_combphy_driver = { 756 .probe = rockchip_combphy_probe, 757 .driver = { 758 .name = "rockchip-naneng-combphy", 759 .of_match_table = rockchip_combphy_of_match, 760 }, 761 }; 762 module_platform_driver(rockchip_combphy_driver); 763 764 MODULE_DESCRIPTION("Rockchip NANENG COMBPHY driver"); 765 MODULE_LICENSE("GPL v2"); 766