Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phy: phy-mt65xx-usb3: add support for mt2701 platform

Add a new OF device ID for mt2701

Some register settings to avoid RX sensitivity level degradation
which may arise on mt8173 platform are separated from other
platforms.

Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

authored by

Chunfeng Yun and committed by
Kishon Vijay Abraham I
e1d76530 931b119e

+52 -26
+2 -3
drivers/phy/Kconfig
··· 219 219 depends on ARCH_MEDIATEK && OF 220 220 select GENERIC_PHY 221 221 help 222 - Say 'Y' here to add support for Mediatek USB3.0 PHY driver 223 - for mt65xx SoCs. it supports two usb2.0 ports and 224 - one usb3.0 port. 222 + Say 'Y' here to add support for Mediatek USB3.0 PHY driver, 223 + it supports multiple usb2.0 and usb3.0 ports. 225 224 226 225 config PHY_HI6220_USB 227 226 tristate "hi6220 USB PHY support"
+50 -23
drivers/phy/phy-mt65xx-usb3.c
··· 134 134 #define U3P_SR_COEF_DIVISOR 1000 135 135 #define U3P_FM_DET_CYCLE_CNT 1024 136 136 137 + struct mt65xx_phy_pdata { 138 + /* avoid RX sensitivity level degradation only for mt8173 */ 139 + bool avoid_rx_sen_degradation; 140 + }; 141 + 137 142 struct mt65xx_phy_instance { 138 143 struct phy *phy; 139 144 void __iomem *port_base; ··· 150 145 struct device *dev; 151 146 void __iomem *sif_base; /* include sif2, but exclude port's */ 152 147 struct clk *u3phya_ref; /* reference clock of usb3 anolog phy */ 148 + const struct mt65xx_phy_pdata *pdata; 153 149 struct mt65xx_phy_instance **phys; 154 150 int nphys; 155 151 }; ··· 247 241 tmp = readl(port_base + U3P_U2PHYACR4); 248 242 tmp &= ~P2C_U2_GPIO_CTR_MSK; 249 243 writel(tmp, port_base + U3P_U2PHYACR4); 244 + } 250 245 251 - tmp = readl(port_base + U3P_USBPHYACR2); 252 - tmp |= PA2_RG_SIF_U2PLL_FORCE_EN; 253 - writel(tmp, port_base + U3P_USBPHYACR2); 246 + if (u3phy->pdata->avoid_rx_sen_degradation) { 247 + if (!index) { 248 + tmp = readl(port_base + U3P_USBPHYACR2); 249 + tmp |= PA2_RG_SIF_U2PLL_FORCE_EN; 250 + writel(tmp, port_base + U3P_USBPHYACR2); 254 251 255 - tmp = readl(port_base + U3D_U2PHYDCR0); 256 - tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON; 257 - writel(tmp, port_base + U3D_U2PHYDCR0); 258 - } else { 259 - tmp = readl(port_base + U3D_U2PHYDCR0); 260 - tmp |= P2C_RG_SIF_U2PLL_FORCE_ON; 261 - writel(tmp, port_base + U3D_U2PHYDCR0); 252 + tmp = readl(port_base + U3D_U2PHYDCR0); 253 + tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON; 254 + writel(tmp, port_base + U3D_U2PHYDCR0); 255 + } else { 256 + tmp = readl(port_base + U3D_U2PHYDCR0); 257 + tmp |= P2C_RG_SIF_U2PLL_FORCE_ON; 258 + writel(tmp, port_base + U3D_U2PHYDCR0); 262 259 263 - tmp = readl(port_base + U3P_U2PHYDTM0); 264 - tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM; 265 - writel(tmp, port_base + U3P_U2PHYDTM0); 260 + tmp = readl(port_base + U3P_U2PHYDTM0); 261 + tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM; 262 + writel(tmp, port_base + U3P_U2PHYDTM0); 263 + } 266 264 } 267 265 268 266 tmp = readl(port_base + U3P_USBPHYACR6); ··· 328 318 tmp |= XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD; 329 319 writel(tmp, u3phy->sif_base + U3P_XTALCTL3); 330 320 331 - /* [mt8173]switch 100uA current to SSUSB */ 321 + /* switch 100uA current to SSUSB */ 332 322 tmp = readl(port_base + U3P_USBPHYACR5); 333 323 tmp |= PA5_RG_U2_HS_100U_U3_EN; 334 324 writel(tmp, port_base + U3P_USBPHYACR5); ··· 345 335 tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(4); 346 336 writel(tmp, port_base + U3P_USBPHYACR5); 347 337 348 - if (index) { 338 + if (u3phy->pdata->avoid_rx_sen_degradation && index) { 349 339 tmp = readl(port_base + U3D_U2PHYDCR0); 350 340 tmp |= P2C_RG_SIF_U2PLL_FORCE_ON; 351 341 writel(tmp, port_base + U3D_U2PHYDCR0); ··· 396 386 tmp = readl(port_base + U3P_U3_PHYA_REG0); 397 387 tmp &= ~P3A_RG_U3_VUSB10_ON; 398 388 writel(tmp, port_base + U3P_U3_PHYA_REG0); 399 - } else { 389 + } 390 + 391 + if (u3phy->pdata->avoid_rx_sen_degradation && index) { 400 392 tmp = readl(port_base + U3D_U2PHYDCR0); 401 393 tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON; 402 394 writel(tmp, port_base + U3D_U2PHYDCR0); ··· 414 402 u32 index = instance->index; 415 403 u32 tmp; 416 404 417 - if (index) { 405 + if (u3phy->pdata->avoid_rx_sen_degradation && index) { 418 406 tmp = readl(port_base + U3D_U2PHYDCR0); 419 407 tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON; 420 408 writel(tmp, port_base + U3D_U2PHYDCR0); ··· 514 502 .owner = THIS_MODULE, 515 503 }; 516 504 505 + static const struct mt65xx_phy_pdata mt2701_pdata = { 506 + .avoid_rx_sen_degradation = false, 507 + }; 508 + 509 + static const struct mt65xx_phy_pdata mt8173_pdata = { 510 + .avoid_rx_sen_degradation = true, 511 + }; 512 + 513 + static const struct of_device_id mt65xx_u3phy_id_table[] = { 514 + { .compatible = "mediatek,mt2701-u3phy", .data = &mt2701_pdata }, 515 + { .compatible = "mediatek,mt8173-u3phy", .data = &mt8173_pdata }, 516 + { }, 517 + }; 518 + MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table); 519 + 517 520 static int mt65xx_u3phy_probe(struct platform_device *pdev) 518 521 { 522 + const struct of_device_id *match; 519 523 struct device *dev = &pdev->dev; 520 524 struct device_node *np = dev->of_node; 521 525 struct device_node *child_np; ··· 541 513 struct resource res; 542 514 int port, retval; 543 515 516 + match = of_match_node(mt65xx_u3phy_id_table, pdev->dev.of_node); 517 + if (!match) 518 + return -EINVAL; 519 + 544 520 u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL); 545 521 if (!u3phy) 546 522 return -ENOMEM; 547 523 524 + u3phy->pdata = match->data; 548 525 u3phy->nphys = of_get_child_count(np); 549 526 u3phy->phys = devm_kcalloc(dev, u3phy->nphys, 550 527 sizeof(*u3phy->phys), GFP_KERNEL); ··· 619 586 of_node_put(child_np); 620 587 return retval; 621 588 } 622 - 623 - static const struct of_device_id mt65xx_u3phy_id_table[] = { 624 - { .compatible = "mediatek,mt8173-u3phy", }, 625 - { }, 626 - }; 627 - MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table); 628 589 629 590 static struct platform_driver mt65xx_u3phy_driver = { 630 591 .probe = mt65xx_u3phy_probe,