diff options
| author | Kishon Vijay Abraham I <kishon@ti.com> | 2017-10-09 05:03:38 -0400 |
|---|---|---|
| committer | Kishon Vijay Abraham I <kishon@ti.com> | 2017-10-23 01:49:27 -0400 |
| commit | 2796ceb0c18a5a0ee96f36d4c3b3773df74c560e (patch) | |
| tree | 3e7e79ba7819bd6bff8731ca46620364932385fd /drivers/phy/ti | |
| parent | 7a4db656a6350f8dd46f711bdef3b0e9c6e3f4cb (diff) | |
phy: ti-pipe3: Update pcie phy settings
Update the PCIe phy settings based on new settings available
in AM572x Technical Reference Manual[1] Revision I, revised
April 2017 in Table 26-62 "Preferred PCIe_PHY_RX SCP Register
Settings".
[1] http://www.ti.com/lit/ug/spruhz6i/spruhz6i.pdf
Cc: Vignesh R <vigneshr@ti.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
[nsekhar@ti.com: commit message updates]
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Diffstat (limited to 'drivers/phy/ti')
| -rw-r--r-- | drivers/phy/ti/phy-ti-pipe3.c | 101 |
1 files changed, 100 insertions, 1 deletions
diff --git a/drivers/phy/ti/phy-ti-pipe3.c b/drivers/phy/ti/phy-ti-pipe3.c index 0e564f32749f..68ce4a082b9b 100644 --- a/drivers/phy/ti/phy-ti-pipe3.c +++ b/drivers/phy/ti/phy-ti-pipe3.c | |||
| @@ -68,6 +68,40 @@ | |||
| 68 | #define PCIE_PCS_MASK 0xFF0000 | 68 | #define PCIE_PCS_MASK 0xFF0000 |
| 69 | #define PCIE_PCS_DELAY_COUNT_SHIFT 0x10 | 69 | #define PCIE_PCS_DELAY_COUNT_SHIFT 0x10 |
| 70 | 70 | ||
| 71 | #define PCIEPHYRX_ANA_PROGRAMMABILITY 0x0000000C | ||
| 72 | #define INTERFACE_MASK GENMASK(31, 27) | ||
| 73 | #define INTERFACE_SHIFT 27 | ||
| 74 | #define LOSD_MASK GENMASK(17, 14) | ||
| 75 | #define LOSD_SHIFT 14 | ||
| 76 | #define MEM_PLLDIV GENMASK(6, 5) | ||
| 77 | |||
| 78 | #define PCIEPHYRX_TRIM 0x0000001C | ||
| 79 | #define MEM_DLL_TRIM_SEL GENMASK(31, 30) | ||
| 80 | #define MEM_DLL_TRIM_SHIFT 30 | ||
| 81 | |||
| 82 | #define PCIEPHYRX_DLL 0x00000024 | ||
| 83 | #define MEM_DLL_PHINT_RATE GENMASK(31, 30) | ||
| 84 | |||
| 85 | #define PCIEPHYRX_DIGITAL_MODES 0x00000028 | ||
| 86 | #define MEM_CDR_FASTLOCK BIT(23) | ||
| 87 | #define MEM_CDR_LBW GENMASK(22, 21) | ||
| 88 | #define MEM_CDR_STEPCNT GENMASK(20, 19) | ||
| 89 | #define MEM_CDR_STL_MASK GENMASK(18, 16) | ||
| 90 | #define MEM_CDR_STL_SHIFT 16 | ||
| 91 | #define MEM_CDR_THR_MASK GENMASK(15, 13) | ||
| 92 | #define MEM_CDR_THR_SHIFT 13 | ||
| 93 | #define MEM_CDR_THR_MODE BIT(12) | ||
| 94 | #define MEM_CDR_CDR_2NDO_SDM_MODE BIT(11) | ||
| 95 | #define MEM_OVRD_HS_RATE BIT(26) | ||
| 96 | |||
| 97 | #define PCIEPHYRX_EQUALIZER 0x00000038 | ||
| 98 | #define MEM_EQLEV GENMASK(31, 16) | ||
| 99 | #define MEM_EQFTC GENMASK(15, 11) | ||
| 100 | #define MEM_EQCTL GENMASK(10, 7) | ||
| 101 | #define MEM_EQCTL_SHIFT 7 | ||
| 102 | #define MEM_OVRD_EQLEV BIT(2) | ||
| 103 | #define MEM_OVRD_EQFTC BIT(1) | ||
| 104 | |||
| 71 | /* | 105 | /* |
| 72 | * This is an Empirical value that works, need to confirm the actual | 106 | * This is an Empirical value that works, need to confirm the actual |
| 73 | * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status | 107 | * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status |
| @@ -91,6 +125,8 @@ struct pipe3_dpll_map { | |||
| 91 | 125 | ||
| 92 | struct ti_pipe3 { | 126 | struct ti_pipe3 { |
| 93 | void __iomem *pll_ctrl_base; | 127 | void __iomem *pll_ctrl_base; |
| 128 | void __iomem *phy_rx; | ||
| 129 | void __iomem *phy_tx; | ||
| 94 | struct device *dev; | 130 | struct device *dev; |
| 95 | struct device *control_dev; | 131 | struct device *control_dev; |
| 96 | struct clk *wkupclk; | 132 | struct clk *wkupclk; |
| @@ -261,6 +297,37 @@ static int ti_pipe3_dpll_program(struct ti_pipe3 *phy) | |||
| 261 | return ti_pipe3_dpll_wait_lock(phy); | 297 | return ti_pipe3_dpll_wait_lock(phy); |
| 262 | } | 298 | } |
| 263 | 299 | ||
| 300 | static void ti_pipe3_calibrate(struct ti_pipe3 *phy) | ||
| 301 | { | ||
| 302 | u32 val; | ||
| 303 | |||
| 304 | val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_ANA_PROGRAMMABILITY); | ||
| 305 | val &= ~(INTERFACE_MASK | LOSD_MASK | MEM_PLLDIV); | ||
| 306 | val = (0x1 << INTERFACE_SHIFT | 0xA << LOSD_SHIFT); | ||
| 307 | ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_ANA_PROGRAMMABILITY, val); | ||
| 308 | |||
| 309 | val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_DIGITAL_MODES); | ||
| 310 | val &= ~(MEM_CDR_STEPCNT | MEM_CDR_STL_MASK | MEM_CDR_THR_MASK | | ||
| 311 | MEM_CDR_CDR_2NDO_SDM_MODE | MEM_OVRD_HS_RATE); | ||
| 312 | val |= (MEM_CDR_FASTLOCK | MEM_CDR_LBW | 0x3 << MEM_CDR_STL_SHIFT | | ||
| 313 | 0x1 << MEM_CDR_THR_SHIFT | MEM_CDR_THR_MODE); | ||
| 314 | ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_DIGITAL_MODES, val); | ||
| 315 | |||
| 316 | val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_TRIM); | ||
| 317 | val &= ~MEM_DLL_TRIM_SEL; | ||
| 318 | val |= 0x2 << MEM_DLL_TRIM_SHIFT; | ||
| 319 | ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_TRIM, val); | ||
| 320 | |||
| 321 | val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_DLL); | ||
| 322 | val |= MEM_DLL_PHINT_RATE; | ||
| 323 | ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_DLL, val); | ||
| 324 | |||
| 325 | val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_EQUALIZER); | ||
| 326 | val &= ~(MEM_EQLEV | MEM_EQCTL | MEM_OVRD_EQLEV | MEM_OVRD_EQFTC); | ||
| 327 | val |= MEM_EQFTC | 0x1 << MEM_EQCTL_SHIFT; | ||
| 328 | ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_EQUALIZER, val); | ||
| 329 | } | ||
| 330 | |||
| 264 | static int ti_pipe3_init(struct phy *x) | 331 | static int ti_pipe3_init(struct phy *x) |
| 265 | { | 332 | { |
| 266 | struct ti_pipe3 *phy = phy_get_drvdata(x); | 333 | struct ti_pipe3 *phy = phy_get_drvdata(x); |
| @@ -282,7 +349,12 @@ static int ti_pipe3_init(struct phy *x) | |||
| 282 | val = 0x96 << OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT; | 349 | val = 0x96 << OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT; |
| 283 | ret = regmap_update_bits(phy->pcs_syscon, phy->pcie_pcs_reg, | 350 | ret = regmap_update_bits(phy->pcs_syscon, phy->pcie_pcs_reg, |
| 284 | PCIE_PCS_MASK, val); | 351 | PCIE_PCS_MASK, val); |
| 285 | return ret; | 352 | if (ret) |
| 353 | return ret; | ||
| 354 | |||
| 355 | ti_pipe3_calibrate(phy); | ||
| 356 | |||
| 357 | return 0; | ||
| 286 | } | 358 | } |
| 287 | 359 | ||
| 288 | /* Bring it out of IDLE if it is IDLE */ | 360 | /* Bring it out of IDLE if it is IDLE */ |
| @@ -513,6 +585,29 @@ static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy) | |||
| 513 | return 0; | 585 | return 0; |
| 514 | } | 586 | } |
| 515 | 587 | ||
| 588 | static int ti_pipe3_get_tx_rx_base(struct ti_pipe3 *phy) | ||
| 589 | { | ||
| 590 | struct resource *res; | ||
| 591 | struct device *dev = phy->dev; | ||
| 592 | struct device_node *node = dev->of_node; | ||
| 593 | struct platform_device *pdev = to_platform_device(dev); | ||
| 594 | |||
| 595 | if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) | ||
| 596 | return 0; | ||
| 597 | |||
| 598 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | ||
| 599 | "phy_rx"); | ||
| 600 | phy->phy_rx = devm_ioremap_resource(dev, res); | ||
| 601 | if (IS_ERR(phy->phy_rx)) | ||
| 602 | return PTR_ERR(phy->phy_rx); | ||
| 603 | |||
| 604 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | ||
| 605 | "phy_tx"); | ||
| 606 | phy->phy_tx = devm_ioremap_resource(dev, res); | ||
| 607 | |||
| 608 | return PTR_ERR_OR_ZERO(phy->phy_tx); | ||
| 609 | } | ||
| 610 | |||
| 516 | static int ti_pipe3_get_pll_base(struct ti_pipe3 *phy) | 611 | static int ti_pipe3_get_pll_base(struct ti_pipe3 *phy) |
| 517 | { | 612 | { |
| 518 | struct resource *res; | 613 | struct resource *res; |
| @@ -559,6 +654,10 @@ static int ti_pipe3_probe(struct platform_device *pdev) | |||
| 559 | if (ret) | 654 | if (ret) |
| 560 | return ret; | 655 | return ret; |
| 561 | 656 | ||
| 657 | ret = ti_pipe3_get_tx_rx_base(phy); | ||
| 658 | if (ret) | ||
| 659 | return ret; | ||
| 660 | |||
| 562 | ret = ti_pipe3_get_sysctrl(phy); | 661 | ret = ti_pipe3_get_sysctrl(phy); |
| 563 | if (ret) | 662 | if (ret) |
| 564 | return ret; | 663 | return ret; |
