1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/clk.h> 4 #include <linux/err.h> 5 #include <linux/io.h> 6 #include <linux/module.h> 7 #include <linux/of_device.h> 8 #include <linux/phy/phy.h> 9 #include <linux/platform_device.h> 10 #include <linux/delay.h> 11 #include <linux/regmap.h> 12 #include <linux/mfd/syscon.h> 13 14 /* USB QSCRATCH Hardware registers */ 15 #define QSCRATCH_GENERAL_CFG (0x08) 16 #define HSUSB_PHY_CTRL_REG (0x10) 17 18 /* PHY_CTRL_REG */ 19 #define HSUSB_CTRL_DMSEHV_CLAMP BIT(24) 20 #define HSUSB_CTRL_USB2_SUSPEND BIT(23) 21 #define HSUSB_CTRL_UTMI_CLK_EN BIT(21) 22 #define HSUSB_CTRL_UTMI_OTG_VBUS_VALID BIT(20) 23 #define HSUSB_CTRL_USE_CLKCORE BIT(18) 24 #define HSUSB_CTRL_DPSEHV_CLAMP BIT(17) 25 #define HSUSB_CTRL_COMMONONN BIT(11) 26 #define HSUSB_CTRL_ID_HV_CLAMP BIT(9) 27 #define HSUSB_CTRL_OTGSESSVLD_CLAMP BIT(8) 28 #define HSUSB_CTRL_CLAMP_EN BIT(7) 29 #define HSUSB_CTRL_RETENABLEN BIT(1) 30 #define HSUSB_CTRL_POR BIT(0) 31 32 /* QSCRATCH_GENERAL_CFG */ 33 #define HSUSB_GCFG_XHCI_REV BIT(2) 34 35 /* USB QSCRATCH Hardware registers */ 36 #define SSUSB_PHY_CTRL_REG (0x00) 37 #define SSUSB_PHY_PARAM_CTRL_1 (0x04) 38 #define SSUSB_PHY_PARAM_CTRL_2 (0x08) 39 #define CR_PROTOCOL_DATA_IN_REG (0x0c) 40 #define CR_PROTOCOL_DATA_OUT_REG (0x10) 41 #define CR_PROTOCOL_CAP_ADDR_REG (0x14) 42 #define CR_PROTOCOL_CAP_DATA_REG (0x18) 43 #define CR_PROTOCOL_READ_REG (0x1c) 44 #define CR_PROTOCOL_WRITE_REG (0x20) 45 46 /* PHY_CTRL_REG */ 47 #define SSUSB_CTRL_REF_USE_PAD BIT(28) 48 #define SSUSB_CTRL_TEST_POWERDOWN BIT(27) 49 #define SSUSB_CTRL_LANE0_PWR_PRESENT BIT(24) 50 #define SSUSB_CTRL_SS_PHY_EN BIT(8) 51 #define SSUSB_CTRL_SS_PHY_RESET BIT(7) 52 53 /* SSPHY control registers - Does this need 0x30? */ 54 #define SSPHY_CTRL_RX_OVRD_IN_HI(lane) (0x1006 + 0x100 * (lane)) 55 #define SSPHY_CTRL_TX_OVRD_DRV_LO(lane) (0x1002 + 0x100 * (lane)) 56 57 /* SSPHY SoC version specific values */ 58 #define SSPHY_RX_EQ_VALUE 4 /* Override value for rx_eq */ 59 /* Override value for transmit preemphasis */ 60 #define SSPHY_TX_DEEMPH_3_5DB 23 61 /* Override value for mpll */ 62 #define SSPHY_MPLL_VALUE 0 63 64 /* QSCRATCH PHY_PARAM_CTRL1 fields */ 65 #define PHY_PARAM_CTRL1_TX_FULL_SWING_MASK GENMASK(26, 19) 66 #define PHY_PARAM_CTRL1_TX_DEEMPH_6DB_MASK GENMASK(19, 13) 67 #define PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB_MASK GENMASK(13, 7) 68 #define PHY_PARAM_CTRL1_LOS_BIAS_MASK GENMASK(7, 2) 69 70 #define PHY_PARAM_CTRL1_MASK \ 71 (PHY_PARAM_CTRL1_TX_FULL_SWING_MASK | \ 72 PHY_PARAM_CTRL1_TX_DEEMPH_6DB_MASK | \ 73 PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB_MASK | \ 74 PHY_PARAM_CTRL1_LOS_BIAS_MASK) 75 76 #define PHY_PARAM_CTRL1_TX_FULL_SWING(x) \ 77 (((x) << 20) & PHY_PARAM_CTRL1_TX_FULL_SWING_MASK) 78 #define PHY_PARAM_CTRL1_TX_DEEMPH_6DB(x) \ 79 (((x) << 14) & PHY_PARAM_CTRL1_TX_DEEMPH_6DB_MASK) 80 #define PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB(x) \ 81 (((x) << 8) & PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB_MASK) 82 #define PHY_PARAM_CTRL1_LOS_BIAS(x) \ 83 (((x) << 3) & PHY_PARAM_CTRL1_LOS_BIAS_MASK) 84 85 /* RX OVRD IN HI bits */ 86 #define RX_OVRD_IN_HI_RX_RESET_OVRD BIT(13) 87 #define RX_OVRD_IN_HI_RX_RX_RESET BIT(12) 88 #define RX_OVRD_IN_HI_RX_EQ_OVRD BIT(11) 89 #define RX_OVRD_IN_HI_RX_EQ_MASK GENMASK(10, 7) 90 #define RX_OVRD_IN_HI_RX_EQ(x) ((x) << 8) 91 #define RX_OVRD_IN_HI_RX_EQ_EN_OVRD BIT(7) 92 #define RX_OVRD_IN_HI_RX_EQ_EN BIT(6) 93 #define RX_OVRD_IN_HI_RX_LOS_FILTER_OVRD BIT(5) 94 #define RX_OVRD_IN_HI_RX_LOS_FILTER_MASK GENMASK(4, 2) 95 #define RX_OVRD_IN_HI_RX_RATE_OVRD BIT(2) 96 #define RX_OVRD_IN_HI_RX_RATE_MASK GENMASK(2, 0) 97 98 /* TX OVRD DRV LO register bits */ 99 #define TX_OVRD_DRV_LO_AMPLITUDE_MASK GENMASK(6, 0) 100 #define TX_OVRD_DRV_LO_PREEMPH_MASK GENMASK(13, 6) 101 #define TX_OVRD_DRV_LO_PREEMPH(x) ((x) << 7) 102 #define TX_OVRD_DRV_LO_EN BIT(14) 103 104 /* MPLL bits */ 105 #define SSPHY_MPLL_MASK GENMASK(8, 5) 106 #define SSPHY_MPLL(x) ((x) << 5) 107 108 /* SS CAP register bits */ 109 #define SS_CR_CAP_ADDR_REG BIT(0) 110 #define SS_CR_CAP_DATA_REG BIT(0) 111 #define SS_CR_READ_REG BIT(0) 112 #define SS_CR_WRITE_REG BIT(0) 113 114 struct usb_phy { 115 void __iomem *base; 116 struct device *dev; 117 struct clk *xo_clk; 118 struct clk *ref_clk; 119 u32 rx_eq; 120 u32 tx_deamp_3_5db; 121 u32 mpll; 122 }; 123 124 struct phy_drvdata { 125 struct phy_ops ops; 126 u32 clk_rate; 127 }; 128 129 /** 130 * Write register and read back masked value to confirm it is written 131 * 132 * @base - QCOM DWC3 PHY base virtual address. 133 * @offset - register offset. 134 * @mask - register bitmask specifying what should be updated 135 * @val - value to write. 136 */ 137 static inline void usb_phy_write_readback(struct usb_phy *phy_dwc3, 138 u32 offset, 139 const u32 mask, u32 val) 140 { 141 u32 write_val, tmp = readl(phy_dwc3->base + offset); 142 143 tmp &= ~mask; /* retain other bits */ 144 write_val = tmp | val; 145 146 writel(write_val, phy_dwc3->base + offset); 147 148 /* Read back to see if val was written */ 149 tmp = readl(phy_dwc3->base + offset); 150 tmp &= mask; /* clear other bits */ 151 152 if (tmp != val) 153 dev_err(phy_dwc3->dev, "write: %x to QSCRATCH: %x FAILED\n", val, offset); 154 } 155 156 static int wait_for_latch(void __iomem *addr) 157 { 158 u32 retry = 10; 159 160 while (true) { 161 if (!readl(addr)) 162 break; 163 164 if (--retry == 0) 165 return -ETIMEDOUT; 166 167 usleep_range(10, 20); 168 } 169 170 return 0; 171 } 172 173 /** 174 * Write SSPHY register 175 * 176 * @base - QCOM DWC3 PHY base virtual address. 177 * @addr - SSPHY address to write. 178 * @val - value to write. 179 */ 180 static int usb_ss_write_phycreg(struct usb_phy *phy_dwc3, 181 u32 addr, u32 val) 182 { 183 int ret; 184 185 writel(addr, phy_dwc3->base + CR_PROTOCOL_DATA_IN_REG); 186 writel(SS_CR_CAP_ADDR_REG, 187 phy_dwc3->base + CR_PROTOCOL_CAP_ADDR_REG); 188 189 ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_CAP_ADDR_REG); 190 if (ret) 191 goto err_wait; 192 193 writel(val, phy_dwc3->base + CR_PROTOCOL_DATA_IN_REG); 194 writel(SS_CR_CAP_DATA_REG, 195 phy_dwc3->base + CR_PROTOCOL_CAP_DATA_REG); 196 197 ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_CAP_DATA_REG); 198 if (ret) 199 goto err_wait; 200 201 writel(SS_CR_WRITE_REG, phy_dwc3->base + CR_PROTOCOL_WRITE_REG); 202 203 ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_WRITE_REG); 204 205 err_wait: 206 if (ret) 207 dev_err(phy_dwc3->dev, "timeout waiting for latch\n"); 208 return ret; 209 } 210 211 /** 212 * Read SSPHY register. 213 * 214 * @base - QCOM DWC3 PHY base virtual address. 215 * @addr - SSPHY address to read. 216 */ 217 static int usb_ss_read_phycreg(struct usb_phy *phy_dwc3, 218 u32 addr, u32 *val) 219 { 220 int ret; 221 222 writel(addr, phy_dwc3->base + CR_PROTOCOL_DATA_IN_REG); 223 writel(SS_CR_CAP_ADDR_REG, 224 phy_dwc3->base + CR_PROTOCOL_CAP_ADDR_REG); 225 226 ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_CAP_ADDR_REG); 227 if (ret) 228 goto err_wait; 229 230 /* 231 * Due to hardware bug, first read of SSPHY register might be 232 * incorrect. Hence as workaround, SW should perform SSPHY register 233 * read twice, but use only second read and ignore first read. 234 */ 235 writel(SS_CR_READ_REG, phy_dwc3->base + CR_PROTOCOL_READ_REG); 236 237 ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_READ_REG); 238 if (ret) 239 goto err_wait; 240 241 /* throwaway read */ 242 readl(phy_dwc3->base + CR_PROTOCOL_DATA_OUT_REG); 243 244 writel(SS_CR_READ_REG, phy_dwc3->base + CR_PROTOCOL_READ_REG); 245 246 ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_READ_REG); 247 if (ret) 248 goto err_wait; 249 250 *val = readl(phy_dwc3->base + CR_PROTOCOL_DATA_OUT_REG); 251 252 err_wait: 253 return ret; 254 } 255 256 static int qcom_ipq806x_usb_hs_phy_init(struct phy *phy) 257 { 258 struct usb_phy *phy_dwc3 = phy_get_drvdata(phy); 259 int ret; 260 u32 val; 261 262 ret = clk_prepare_enable(phy_dwc3->xo_clk); 263 if (ret) 264 return ret; 265 266 ret = clk_prepare_enable(phy_dwc3->ref_clk); 267 if (ret) { 268 clk_disable_unprepare(phy_dwc3->xo_clk); 269 return ret; 270 } 271 272 /* 273 * HSPHY Initialization: Enable UTMI clock, select 19.2MHz fsel 274 * enable clamping, and disable RETENTION (power-on default is ENABLED) 275 */ 276 val = HSUSB_CTRL_DPSEHV_CLAMP | HSUSB_CTRL_DMSEHV_CLAMP | 277 HSUSB_CTRL_RETENABLEN | HSUSB_CTRL_COMMONONN | 278 HSUSB_CTRL_OTGSESSVLD_CLAMP | HSUSB_CTRL_ID_HV_CLAMP | 279 HSUSB_CTRL_UTMI_OTG_VBUS_VALID | HSUSB_CTRL_UTMI_CLK_EN | 280 HSUSB_CTRL_CLAMP_EN | 0x70; 281 282 /* use core clock if external reference is not present */ 283 if (!phy_dwc3->xo_clk) 284 val |= HSUSB_CTRL_USE_CLKCORE; 285 286 writel(val, phy_dwc3->base + HSUSB_PHY_CTRL_REG); 287 usleep_range(2000, 2200); 288 289 /* Disable (bypass) VBUS and ID filters */ 290 writel(HSUSB_GCFG_XHCI_REV, phy_dwc3->base + QSCRATCH_GENERAL_CFG); 291 292 return 0; 293 } 294 295 static int qcom_ipq806x_usb_hs_phy_exit(struct phy *phy) 296 { 297 struct usb_phy *phy_dwc3 = phy_get_drvdata(phy); 298 299 clk_disable_unprepare(phy_dwc3->ref_clk); 300 clk_disable_unprepare(phy_dwc3->xo_clk); 301 302 return 0; 303 } 304 305 static int qcom_ipq806x_usb_ss_phy_init(struct phy *phy) 306 { 307 struct usb_phy *phy_dwc3 = phy_get_drvdata(phy); 308 int ret; 309 u32 data; 310 311 ret = clk_prepare_enable(phy_dwc3->xo_clk); 312 if (ret) 313 return ret; 314 315 ret = clk_prepare_enable(phy_dwc3->ref_clk); 316 if (ret) { 317 clk_disable_unprepare(phy_dwc3->xo_clk); 318 return ret; 319 } 320 321 /* reset phy */ 322 data = readl(phy_dwc3->base + SSUSB_PHY_CTRL_REG); 323 writel(data | SSUSB_CTRL_SS_PHY_RESET, 324 phy_dwc3->base + SSUSB_PHY_CTRL_REG); 325 usleep_range(2000, 2200); 326 writel(data, phy_dwc3->base + SSUSB_PHY_CTRL_REG); 327 328 /* clear REF_PAD if we don't have XO clk */ 329 if (!phy_dwc3->xo_clk) 330 data &= ~SSUSB_CTRL_REF_USE_PAD; 331 else 332 data |= SSUSB_CTRL_REF_USE_PAD; 333 334 writel(data, phy_dwc3->base + SSUSB_PHY_CTRL_REG); 335 336 /* wait for ref clk to become stable, this can take up to 30ms */ 337 msleep(30); 338 339 data |= SSUSB_CTRL_SS_PHY_EN | SSUSB_CTRL_LANE0_PWR_PRESENT; 340 writel(data, phy_dwc3->base + SSUSB_PHY_CTRL_REG); 341 342 /* 343 * WORKAROUND: There is SSPHY suspend bug due to which USB enumerates 344 * in HS mode instead of SS mode. Workaround it by asserting 345 * LANE0.TX_ALT_BLOCK.EN_ALT_BUS to enable TX to use alt bus mode 346 */ 347 ret = usb_ss_read_phycreg(phy_dwc3, 0x102D, &data); 348 if (ret) 349 goto err_phy_trans; 350 351 data |= (1 << 7); 352 ret = usb_ss_write_phycreg(phy_dwc3, 0x102D, data); 353 if (ret) 354 goto err_phy_trans; 355 356 ret = usb_ss_read_phycreg(phy_dwc3, 0x1010, &data); 357 if (ret) 358 goto err_phy_trans; 359 360 data &= ~0xff0; 361 data |= 0x20; 362 ret = usb_ss_write_phycreg(phy_dwc3, 0x1010, data); 363 if (ret) 364 goto err_phy_trans; 365 366 /* 367 * Fix RX Equalization setting as follows 368 * LANE0.RX_OVRD_IN_HI. RX_EQ_EN set to 0 369 * LANE0.RX_OVRD_IN_HI.RX_EQ_EN_OVRD set to 1 370 * LANE0.RX_OVRD_IN_HI.RX_EQ set based on SoC version 371 * LANE0.RX_OVRD_IN_HI.RX_EQ_OVRD set to 1 372 */ 373 ret = usb_ss_read_phycreg(phy_dwc3, SSPHY_CTRL_RX_OVRD_IN_HI(0), &data); 374 if (ret) 375 goto err_phy_trans; 376 377 data &= ~RX_OVRD_IN_HI_RX_EQ_EN; 378 data |= RX_OVRD_IN_HI_RX_EQ_EN_OVRD; 379 data &= ~RX_OVRD_IN_HI_RX_EQ_MASK; 380 data |= RX_OVRD_IN_HI_RX_EQ(phy_dwc3->rx_eq); 381 data |= RX_OVRD_IN_HI_RX_EQ_OVRD; 382 ret = usb_ss_write_phycreg(phy_dwc3, 383 SSPHY_CTRL_RX_OVRD_IN_HI(0), data); 384 if (ret) 385 goto err_phy_trans; 386 387 /* 388 * Set EQ and TX launch amplitudes as follows 389 * LANE0.TX_OVRD_DRV_LO.PREEMPH set based on SoC version 390 * LANE0.TX_OVRD_DRV_LO.AMPLITUDE set to 110 391 * LANE0.TX_OVRD_DRV_LO.EN set to 1. 392 */ 393 ret = usb_ss_read_phycreg(phy_dwc3, 394 SSPHY_CTRL_TX_OVRD_DRV_LO(0), &data); 395 if (ret) 396 goto err_phy_trans; 397 398 data &= ~TX_OVRD_DRV_LO_PREEMPH_MASK; 399 data |= TX_OVRD_DRV_LO_PREEMPH(phy_dwc3->tx_deamp_3_5db); 400 data &= ~TX_OVRD_DRV_LO_AMPLITUDE_MASK; 401 data |= 0x6E; 402 data |= TX_OVRD_DRV_LO_EN; 403 ret = usb_ss_write_phycreg(phy_dwc3, 404 SSPHY_CTRL_TX_OVRD_DRV_LO(0), data); 405 if (ret) 406 goto err_phy_trans; 407 408 data = 0; 409 data &= ~SSPHY_MPLL_MASK; 410 data |= SSPHY_MPLL(phy_dwc3->mpll); 411 usb_ss_write_phycreg(phy_dwc3, 0x30, data); 412 413 /* 414 * Set the QSCRATCH PHY_PARAM_CTRL1 parameters as follows 415 * TX_FULL_SWING [26:20] amplitude to 110 416 * TX_DEEMPH_6DB [19:14] to 32 417 * TX_DEEMPH_3_5DB [13:8] set based on SoC version 418 * LOS_BIAS [7:3] to 9 419 */ 420 data = readl(phy_dwc3->base + SSUSB_PHY_PARAM_CTRL_1); 421 422 data &= ~PHY_PARAM_CTRL1_MASK; 423 424 data |= PHY_PARAM_CTRL1_TX_FULL_SWING(0x6e) | 425 PHY_PARAM_CTRL1_TX_DEEMPH_6DB(0x20) | 426 PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB(phy_dwc3->tx_deamp_3_5db) | 427 PHY_PARAM_CTRL1_LOS_BIAS(0x9); 428 429 usb_phy_write_readback(phy_dwc3, SSUSB_PHY_PARAM_CTRL_1, 430 PHY_PARAM_CTRL1_MASK, data); 431 432 err_phy_trans: 433 return ret; 434 } 435 436 static int qcom_ipq806x_usb_ss_phy_exit(struct phy *phy) 437 { 438 struct usb_phy *phy_dwc3 = phy_get_drvdata(phy); 439 440 /* Sequence to put SSPHY in low power state: 441 * 1. Clear REF_PHY_EN in PHY_CTRL_REG 442 * 2. Clear REF_USE_PAD in PHY_CTRL_REG 443 * 3. Set TEST_POWERED_DOWN in PHY_CTRL_REG to enable PHY retention 444 */ 445 usb_phy_write_readback(phy_dwc3, SSUSB_PHY_CTRL_REG, 446 SSUSB_CTRL_SS_PHY_EN, 0x0); 447 usb_phy_write_readback(phy_dwc3, SSUSB_PHY_CTRL_REG, 448 SSUSB_CTRL_REF_USE_PAD, 0x0); 449 usb_phy_write_readback(phy_dwc3, SSUSB_PHY_CTRL_REG, 450 SSUSB_CTRL_TEST_POWERDOWN, 0x0); 451 452 clk_disable_unprepare(phy_dwc3->ref_clk); 453 clk_disable_unprepare(phy_dwc3->xo_clk); 454 455 return 0; 456 } 457 458 static const struct phy_drvdata qcom_ipq806x_usb_hs_drvdata = { 459 .ops = { 460 .init = qcom_ipq806x_usb_hs_phy_init, 461 .exit = qcom_ipq806x_usb_hs_phy_exit, 462 .owner = THIS_MODULE, 463 }, 464 .clk_rate = 60000000, 465 }; 466 467 static const struct phy_drvdata qcom_ipq806x_usb_ss_drvdata = { 468 .ops = { 469 .init = qcom_ipq806x_usb_ss_phy_init, 470 .exit = qcom_ipq806x_usb_ss_phy_exit, 471 .owner = THIS_MODULE, 472 }, 473 .clk_rate = 125000000, 474 }; 475 476 static const struct of_device_id qcom_ipq806x_usb_phy_table[] = { 477 { .compatible = "qcom,ipq806x-usb-phy-hs", 478 .data = &qcom_ipq806x_usb_hs_drvdata }, 479 { .compatible = "qcom,ipq806x-usb-phy-ss", 480 .data = &qcom_ipq806x_usb_ss_drvdata }, 481 { /* Sentinel */ } 482 }; 483 MODULE_DEVICE_TABLE(of, qcom_ipq806x_usb_phy_table); 484 485 static int qcom_ipq806x_usb_phy_probe(struct platform_device *pdev) 486 { 487 struct resource *res; 488 resource_size_t size; 489 struct phy *generic_phy; 490 struct usb_phy *phy_dwc3; 491 const struct phy_drvdata *data; 492 struct phy_provider *phy_provider; 493 494 phy_dwc3 = devm_kzalloc(&pdev->dev, sizeof(*phy_dwc3), GFP_KERNEL); 495 if (!phy_dwc3) 496 return -ENOMEM; 497 498 data = of_device_get_match_data(&pdev->dev); 499 500 phy_dwc3->dev = &pdev->dev; 501 502 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 503 if (!res) 504 return -EINVAL; 505 size = resource_size(res); 506 phy_dwc3->base = devm_ioremap(phy_dwc3->dev, res->start, size); 507 508 if (!phy_dwc3->base) { 509 dev_err(phy_dwc3->dev, "failed to map reg\n"); 510 return -ENOMEM; 511 } 512 513 phy_dwc3->ref_clk = devm_clk_get(phy_dwc3->dev, "ref"); 514 if (IS_ERR(phy_dwc3->ref_clk)) { 515 dev_dbg(phy_dwc3->dev, "cannot get reference clock\n"); 516 return PTR_ERR(phy_dwc3->ref_clk); 517 } 518 519 clk_set_rate(phy_dwc3->ref_clk, data->clk_rate); 520 521 phy_dwc3->xo_clk = devm_clk_get(phy_dwc3->dev, "xo"); 522 if (IS_ERR(phy_dwc3->xo_clk)) { 523 dev_dbg(phy_dwc3->dev, "cannot get TCXO clock\n"); 524 phy_dwc3->xo_clk = NULL; 525 } 526 527 /* Parse device node to probe HSIO settings */ 528 if (device_property_read_u32(&pdev->dev, "qcom,rx-eq", 529 &phy_dwc3->rx_eq)) 530 phy_dwc3->rx_eq = SSPHY_RX_EQ_VALUE; 531 532 if (device_property_read_u32(&pdev->dev, "qcom,tx-deamp_3_5db", 533 &phy_dwc3->tx_deamp_3_5db)) 534 phy_dwc3->tx_deamp_3_5db = SSPHY_TX_DEEMPH_3_5DB; 535 536 if (device_property_read_u32(&pdev->dev, "qcom,mpll", &phy_dwc3->mpll)) 537 phy_dwc3->mpll = SSPHY_MPLL_VALUE; 538 539 generic_phy = devm_phy_create(phy_dwc3->dev, pdev->dev.of_node, &data->ops); 540 541 if (IS_ERR(generic_phy)) 542 return PTR_ERR(generic_phy); 543 544 phy_set_drvdata(generic_phy, phy_dwc3); 545 platform_set_drvdata(pdev, phy_dwc3); 546 547 phy_provider = devm_of_phy_provider_register(phy_dwc3->dev, 548 of_phy_simple_xlate); 549 550 if (IS_ERR(phy_provider)) 551 return PTR_ERR(phy_provider); 552 553 return 0; 554 } 555 556 static struct platform_driver qcom_ipq806x_usb_phy_driver = { 557 .probe = qcom_ipq806x_usb_phy_probe, 558 .driver = { 559 .name = "qcom-ipq806x-usb-phy", 560 .of_match_table = qcom_ipq806x_usb_phy_table, 561 }, 562 }; 563 564 module_platform_driver(qcom_ipq806x_usb_phy_driver); 565 566 MODULE_ALIAS("platform:phy-qcom-ipq806x-usb"); 567 MODULE_LICENSE("GPL v2"); 568 MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>"); 569 MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>"); 570 MODULE_DESCRIPTION("DesignWare USB3 QCOM PHY driver"); 571