aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChunfeng Yun <chunfeng.yun@mediatek.com>2016-04-19 20:14:02 -0400
committerKishon Vijay Abraham I <kishon@ti.com>2016-04-30 10:42:27 -0400
commite1d76530d7f8f67d0b2a020a2453bed4e8e27b1a (patch)
tree95061387bfc2287a92ab387f3a121245c37611cd
parent931b119e9432f48e2b384e4d59c33490c5567353 (diff)
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>
-rw-r--r--drivers/phy/Kconfig5
-rw-r--r--drivers/phy/phy-mt65xx-usb3.c77
2 files changed, 54 insertions, 28 deletions
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 447cb7c1a18d..f6ff76ec89dc 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -219,9 +219,8 @@ config PHY_MT65XX_USB3
219 depends on ARCH_MEDIATEK && OF 219 depends on ARCH_MEDIATEK && OF
220 select GENERIC_PHY 220 select GENERIC_PHY
221 help 221 help
222 Say 'Y' here to add support for Mediatek USB3.0 PHY driver 222 Say 'Y' here to add support for Mediatek USB3.0 PHY driver,
223 for mt65xx SoCs. it supports two usb2.0 ports and 223 it supports multiple usb2.0 and usb3.0 ports.
224 one usb3.0 port.
225 224
226config PHY_HI6220_USB 225config PHY_HI6220_USB
227 tristate "hi6220 USB PHY support" 226 tristate "hi6220 USB PHY support"
diff --git a/drivers/phy/phy-mt65xx-usb3.c b/drivers/phy/phy-mt65xx-usb3.c
index c0e7b4b0cf5c..4d85e730ccab 100644
--- a/drivers/phy/phy-mt65xx-usb3.c
+++ b/drivers/phy/phy-mt65xx-usb3.c
@@ -134,6 +134,11 @@
134#define U3P_SR_COEF_DIVISOR 1000 134#define U3P_SR_COEF_DIVISOR 1000
135#define U3P_FM_DET_CYCLE_CNT 1024 135#define U3P_FM_DET_CYCLE_CNT 1024
136 136
137struct mt65xx_phy_pdata {
138 /* avoid RX sensitivity level degradation only for mt8173 */
139 bool avoid_rx_sen_degradation;
140};
141
137struct mt65xx_phy_instance { 142struct mt65xx_phy_instance {
138 struct phy *phy; 143 struct phy *phy;
139 void __iomem *port_base; 144 void __iomem *port_base;
@@ -145,6 +150,7 @@ struct mt65xx_u3phy {
145 struct device *dev; 150 struct device *dev;
146 void __iomem *sif_base; /* include sif2, but exclude port's */ 151 void __iomem *sif_base; /* include sif2, but exclude port's */
147 struct clk *u3phya_ref; /* reference clock of usb3 anolog phy */ 152 struct clk *u3phya_ref; /* reference clock of usb3 anolog phy */
153 const struct mt65xx_phy_pdata *pdata;
148 struct mt65xx_phy_instance **phys; 154 struct mt65xx_phy_instance **phys;
149 int nphys; 155 int nphys;
150}; 156};
@@ -241,22 +247,26 @@ static void phy_instance_init(struct mt65xx_u3phy *u3phy,
241 tmp = readl(port_base + U3P_U2PHYACR4); 247 tmp = readl(port_base + U3P_U2PHYACR4);
242 tmp &= ~P2C_U2_GPIO_CTR_MSK; 248 tmp &= ~P2C_U2_GPIO_CTR_MSK;
243 writel(tmp, port_base + U3P_U2PHYACR4); 249 writel(tmp, port_base + U3P_U2PHYACR4);
250 }
244 251
245 tmp = readl(port_base + U3P_USBPHYACR2); 252 if (u3phy->pdata->avoid_rx_sen_degradation) {
246 tmp |= PA2_RG_SIF_U2PLL_FORCE_EN; 253 if (!index) {
247 writel(tmp, port_base + U3P_USBPHYACR2); 254 tmp = readl(port_base + U3P_USBPHYACR2);
248 255 tmp |= PA2_RG_SIF_U2PLL_FORCE_EN;
249 tmp = readl(port_base + U3D_U2PHYDCR0); 256 writel(tmp, port_base + U3P_USBPHYACR2);
250 tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON; 257
251 writel(tmp, port_base + U3D_U2PHYDCR0); 258 tmp = readl(port_base + U3D_U2PHYDCR0);
252 } else { 259 tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
253 tmp = readl(port_base + U3D_U2PHYDCR0); 260 writel(tmp, port_base + U3D_U2PHYDCR0);
254 tmp |= P2C_RG_SIF_U2PLL_FORCE_ON; 261 } else {
255 writel(tmp, port_base + U3D_U2PHYDCR0); 262 tmp = readl(port_base + U3D_U2PHYDCR0);
256 263 tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
257 tmp = readl(port_base + U3P_U2PHYDTM0); 264 writel(tmp, port_base + U3D_U2PHYDCR0);
258 tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM; 265
259 writel(tmp, port_base + U3P_U2PHYDTM0); 266 tmp = readl(port_base + U3P_U2PHYDTM0);
267 tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM;
268 writel(tmp, port_base + U3P_U2PHYDTM0);
269 }
260 } 270 }
261 271
262 tmp = readl(port_base + U3P_USBPHYACR6); 272 tmp = readl(port_base + U3P_USBPHYACR6);
@@ -318,7 +328,7 @@ static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
318 tmp |= XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD; 328 tmp |= XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD;
319 writel(tmp, u3phy->sif_base + U3P_XTALCTL3); 329 writel(tmp, u3phy->sif_base + U3P_XTALCTL3);
320 330
321 /* [mt8173]switch 100uA current to SSUSB */ 331 /* switch 100uA current to SSUSB */
322 tmp = readl(port_base + U3P_USBPHYACR5); 332 tmp = readl(port_base + U3P_USBPHYACR5);
323 tmp |= PA5_RG_U2_HS_100U_U3_EN; 333 tmp |= PA5_RG_U2_HS_100U_U3_EN;
324 writel(tmp, port_base + U3P_USBPHYACR5); 334 writel(tmp, port_base + U3P_USBPHYACR5);
@@ -335,7 +345,7 @@ static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
335 tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(4); 345 tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(4);
336 writel(tmp, port_base + U3P_USBPHYACR5); 346 writel(tmp, port_base + U3P_USBPHYACR5);
337 347
338 if (index) { 348 if (u3phy->pdata->avoid_rx_sen_degradation && index) {
339 tmp = readl(port_base + U3D_U2PHYDCR0); 349 tmp = readl(port_base + U3D_U2PHYDCR0);
340 tmp |= P2C_RG_SIF_U2PLL_FORCE_ON; 350 tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
341 writel(tmp, port_base + U3D_U2PHYDCR0); 351 writel(tmp, port_base + U3D_U2PHYDCR0);
@@ -386,7 +396,9 @@ static void phy_instance_power_off(struct mt65xx_u3phy *u3phy,
386 tmp = readl(port_base + U3P_U3_PHYA_REG0); 396 tmp = readl(port_base + U3P_U3_PHYA_REG0);
387 tmp &= ~P3A_RG_U3_VUSB10_ON; 397 tmp &= ~P3A_RG_U3_VUSB10_ON;
388 writel(tmp, port_base + U3P_U3_PHYA_REG0); 398 writel(tmp, port_base + U3P_U3_PHYA_REG0);
389 } else { 399 }
400
401 if (u3phy->pdata->avoid_rx_sen_degradation && index) {
390 tmp = readl(port_base + U3D_U2PHYDCR0); 402 tmp = readl(port_base + U3D_U2PHYDCR0);
391 tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON; 403 tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
392 writel(tmp, port_base + U3D_U2PHYDCR0); 404 writel(tmp, port_base + U3D_U2PHYDCR0);
@@ -402,7 +414,7 @@ static void phy_instance_exit(struct mt65xx_u3phy *u3phy,
402 u32 index = instance->index; 414 u32 index = instance->index;
403 u32 tmp; 415 u32 tmp;
404 416
405 if (index) { 417 if (u3phy->pdata->avoid_rx_sen_degradation && index) {
406 tmp = readl(port_base + U3D_U2PHYDCR0); 418 tmp = readl(port_base + U3D_U2PHYDCR0);
407 tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON; 419 tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
408 writel(tmp, port_base + U3D_U2PHYDCR0); 420 writel(tmp, port_base + U3D_U2PHYDCR0);
@@ -502,8 +514,24 @@ static struct phy_ops mt65xx_u3phy_ops = {
502 .owner = THIS_MODULE, 514 .owner = THIS_MODULE,
503}; 515};
504 516
517static const struct mt65xx_phy_pdata mt2701_pdata = {
518 .avoid_rx_sen_degradation = false,
519};
520
521static const struct mt65xx_phy_pdata mt8173_pdata = {
522 .avoid_rx_sen_degradation = true,
523};
524
525static const struct of_device_id mt65xx_u3phy_id_table[] = {
526 { .compatible = "mediatek,mt2701-u3phy", .data = &mt2701_pdata },
527 { .compatible = "mediatek,mt8173-u3phy", .data = &mt8173_pdata },
528 { },
529};
530MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table);
531
505static int mt65xx_u3phy_probe(struct platform_device *pdev) 532static int mt65xx_u3phy_probe(struct platform_device *pdev)
506{ 533{
534 const struct of_device_id *match;
507 struct device *dev = &pdev->dev; 535 struct device *dev = &pdev->dev;
508 struct device_node *np = dev->of_node; 536 struct device_node *np = dev->of_node;
509 struct device_node *child_np; 537 struct device_node *child_np;
@@ -513,10 +541,15 @@ static int mt65xx_u3phy_probe(struct platform_device *pdev)
513 struct resource res; 541 struct resource res;
514 int port, retval; 542 int port, retval;
515 543
544 match = of_match_node(mt65xx_u3phy_id_table, pdev->dev.of_node);
545 if (!match)
546 return -EINVAL;
547
516 u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL); 548 u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
517 if (!u3phy) 549 if (!u3phy)
518 return -ENOMEM; 550 return -ENOMEM;
519 551
552 u3phy->pdata = match->data;
520 u3phy->nphys = of_get_child_count(np); 553 u3phy->nphys = of_get_child_count(np);
521 u3phy->phys = devm_kcalloc(dev, u3phy->nphys, 554 u3phy->phys = devm_kcalloc(dev, u3phy->nphys,
522 sizeof(*u3phy->phys), GFP_KERNEL); 555 sizeof(*u3phy->phys), GFP_KERNEL);
@@ -587,12 +620,6 @@ put_child:
587 return retval; 620 return retval;
588} 621}
589 622
590static const struct of_device_id mt65xx_u3phy_id_table[] = {
591 { .compatible = "mediatek,mt8173-u3phy", },
592 { },
593};
594MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table);
595
596static struct platform_driver mt65xx_u3phy_driver = { 623static struct platform_driver mt65xx_u3phy_driver = {
597 .probe = mt65xx_u3phy_probe, 624 .probe = mt65xx_u3phy_probe,
598 .driver = { 625 .driver = {