mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 20:51:44 +00:00
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>
This commit is contained in:
parent
7a4db656a6
commit
2796ceb0c1
@ -68,6 +68,40 @@
|
||||
#define PCIE_PCS_MASK 0xFF0000
|
||||
#define PCIE_PCS_DELAY_COUNT_SHIFT 0x10
|
||||
|
||||
#define PCIEPHYRX_ANA_PROGRAMMABILITY 0x0000000C
|
||||
#define INTERFACE_MASK GENMASK(31, 27)
|
||||
#define INTERFACE_SHIFT 27
|
||||
#define LOSD_MASK GENMASK(17, 14)
|
||||
#define LOSD_SHIFT 14
|
||||
#define MEM_PLLDIV GENMASK(6, 5)
|
||||
|
||||
#define PCIEPHYRX_TRIM 0x0000001C
|
||||
#define MEM_DLL_TRIM_SEL GENMASK(31, 30)
|
||||
#define MEM_DLL_TRIM_SHIFT 30
|
||||
|
||||
#define PCIEPHYRX_DLL 0x00000024
|
||||
#define MEM_DLL_PHINT_RATE GENMASK(31, 30)
|
||||
|
||||
#define PCIEPHYRX_DIGITAL_MODES 0x00000028
|
||||
#define MEM_CDR_FASTLOCK BIT(23)
|
||||
#define MEM_CDR_LBW GENMASK(22, 21)
|
||||
#define MEM_CDR_STEPCNT GENMASK(20, 19)
|
||||
#define MEM_CDR_STL_MASK GENMASK(18, 16)
|
||||
#define MEM_CDR_STL_SHIFT 16
|
||||
#define MEM_CDR_THR_MASK GENMASK(15, 13)
|
||||
#define MEM_CDR_THR_SHIFT 13
|
||||
#define MEM_CDR_THR_MODE BIT(12)
|
||||
#define MEM_CDR_CDR_2NDO_SDM_MODE BIT(11)
|
||||
#define MEM_OVRD_HS_RATE BIT(26)
|
||||
|
||||
#define PCIEPHYRX_EQUALIZER 0x00000038
|
||||
#define MEM_EQLEV GENMASK(31, 16)
|
||||
#define MEM_EQFTC GENMASK(15, 11)
|
||||
#define MEM_EQCTL GENMASK(10, 7)
|
||||
#define MEM_EQCTL_SHIFT 7
|
||||
#define MEM_OVRD_EQLEV BIT(2)
|
||||
#define MEM_OVRD_EQFTC BIT(1)
|
||||
|
||||
/*
|
||||
* This is an Empirical value that works, need to confirm the actual
|
||||
* value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status
|
||||
@ -91,6 +125,8 @@ struct pipe3_dpll_map {
|
||||
|
||||
struct ti_pipe3 {
|
||||
void __iomem *pll_ctrl_base;
|
||||
void __iomem *phy_rx;
|
||||
void __iomem *phy_tx;
|
||||
struct device *dev;
|
||||
struct device *control_dev;
|
||||
struct clk *wkupclk;
|
||||
@ -261,6 +297,37 @@ static int ti_pipe3_dpll_program(struct ti_pipe3 *phy)
|
||||
return ti_pipe3_dpll_wait_lock(phy);
|
||||
}
|
||||
|
||||
static void ti_pipe3_calibrate(struct ti_pipe3 *phy)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_ANA_PROGRAMMABILITY);
|
||||
val &= ~(INTERFACE_MASK | LOSD_MASK | MEM_PLLDIV);
|
||||
val = (0x1 << INTERFACE_SHIFT | 0xA << LOSD_SHIFT);
|
||||
ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_ANA_PROGRAMMABILITY, val);
|
||||
|
||||
val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_DIGITAL_MODES);
|
||||
val &= ~(MEM_CDR_STEPCNT | MEM_CDR_STL_MASK | MEM_CDR_THR_MASK |
|
||||
MEM_CDR_CDR_2NDO_SDM_MODE | MEM_OVRD_HS_RATE);
|
||||
val |= (MEM_CDR_FASTLOCK | MEM_CDR_LBW | 0x3 << MEM_CDR_STL_SHIFT |
|
||||
0x1 << MEM_CDR_THR_SHIFT | MEM_CDR_THR_MODE);
|
||||
ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_DIGITAL_MODES, val);
|
||||
|
||||
val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_TRIM);
|
||||
val &= ~MEM_DLL_TRIM_SEL;
|
||||
val |= 0x2 << MEM_DLL_TRIM_SHIFT;
|
||||
ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_TRIM, val);
|
||||
|
||||
val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_DLL);
|
||||
val |= MEM_DLL_PHINT_RATE;
|
||||
ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_DLL, val);
|
||||
|
||||
val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_EQUALIZER);
|
||||
val &= ~(MEM_EQLEV | MEM_EQCTL | MEM_OVRD_EQLEV | MEM_OVRD_EQFTC);
|
||||
val |= MEM_EQFTC | 0x1 << MEM_EQCTL_SHIFT;
|
||||
ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_EQUALIZER, val);
|
||||
}
|
||||
|
||||
static int ti_pipe3_init(struct phy *x)
|
||||
{
|
||||
struct ti_pipe3 *phy = phy_get_drvdata(x);
|
||||
@ -282,7 +349,12 @@ static int ti_pipe3_init(struct phy *x)
|
||||
val = 0x96 << OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT;
|
||||
ret = regmap_update_bits(phy->pcs_syscon, phy->pcie_pcs_reg,
|
||||
PCIE_PCS_MASK, val);
|
||||
return ret;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ti_pipe3_calibrate(phy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Bring it out of IDLE if it is IDLE */
|
||||
@ -513,6 +585,29 @@ static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ti_pipe3_get_tx_rx_base(struct ti_pipe3 *phy)
|
||||
{
|
||||
struct resource *res;
|
||||
struct device *dev = phy->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie"))
|
||||
return 0;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"phy_rx");
|
||||
phy->phy_rx = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(phy->phy_rx))
|
||||
return PTR_ERR(phy->phy_rx);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"phy_tx");
|
||||
phy->phy_tx = devm_ioremap_resource(dev, res);
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy->phy_tx);
|
||||
}
|
||||
|
||||
static int ti_pipe3_get_pll_base(struct ti_pipe3 *phy)
|
||||
{
|
||||
struct resource *res;
|
||||
@ -559,6 +654,10 @@ static int ti_pipe3_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ti_pipe3_get_tx_rx_base(phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ti_pipe3_get_sysctrl(phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user