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