Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2796ceb0 authored by Kishon Vijay Abraham I's avatar Kishon Vijay Abraham I
Browse files

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: default avatarKishon Vijay Abraham I <kishon@ti.com>
[nsekhar@ti.com: commit message updates]
Signed-off-by: default avatarSekhar Nori <nsekhar@ti.com>

Signed-off-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
parent 7a4db656
Loading
Loading
Loading
Loading
+100 −1
Original line number Diff line number Diff line
@@ -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);
		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;