From: l.stach@pengutronix.de (Lucas Stach)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 2/2] PCI: imx: Add workaround for e10728, IMX7d PCIe PLL failure
Date: Wed, 01 Aug 2018 12:44:17 +0200 [thread overview]
Message-ID: <1533120257.20186.7.camel@pengutronix.de> (raw)
In-Reply-To: <20180718194424.8844-3-tpiepho@impinj.com>
Am Mittwoch, den 18.07.2018, 12:44 -0700 schrieb Trent Piepho:
> This implements the workound described in the NXP IMX7d erratum e10728.
>
> Initial VCO oscillation may fail under corner conditions such as cold
> temperature.??It causes PCIe PLL to fail to lock in the initialization
> phase, which results in the PCIe link failing to come up.
>
> The workaround is to disable Duty-cycle Corrector (DCC) calibration
> after G_RST.
>
> To do this it is necessary to gain access to the undocumented and
> currently unused PCIe PHY register bank.??A new device tree node of type
> "fsl,imx-pcie-phy" is created for the PHY block and the existing PCIe
> device uses a phandle named "fsl,pcie-phy" to point to it.
>
> > Cc: Shawn Guo <shawnguo@kernel.org>
> > Cc: Sascha Hauer <kernel@pengutronix.de>
> > Cc: Fabio Estevam <fabio.estevam@nxp.com>
> > Cc: Richard Zhu <hongxing.zhu@nxp.com>
> > Cc: Lucas Stach <l.stach@pengutronix.de>
> > Signed-off-by: Trent Piepho <tpiepho@impinj.com>
> ---
> ?drivers/pci/dwc/pci-imx6.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++
> ?1 file changed, 59 insertions(+)
>
> diff --git a/drivers/pci/dwc/pci-imx6.c b/drivers/pci/dwc/pci-imx6.c
> index dcf389b62944..32429afc9380 100644
> --- a/drivers/pci/dwc/pci-imx6.c
> +++ b/drivers/pci/dwc/pci-imx6.c
> @@ -18,6 +18,7 @@
> ?#include <linux/module.h>
> ?#include <linux/of_gpio.h>
> ?#include <linux/of_device.h>
> +#include <linux/of_address.h>
> ?#include <linux/pci.h>
> ?#include <linux/platform_device.h>
> ?#include <linux/regmap.h>
> @@ -58,6 +59,7 @@ struct imx6_pcie {
> > > ? u32 tx_swing_low;
> > > ? int link_gen;
> > > ? struct regulator *vpcie;
> > > + void __iomem *phy_base;
> ?};
> ?
> ?/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
> @@ -98,6 +100,23 @@ struct imx6_pcie {
> ?#define PCIE_PHY_RX_ASIC_OUT 0x100D
> > ?#define PCIE_PHY_RX_ASIC_OUT_VALID (1 << 0)
> ?
> +/* iMX7 PCIe PHY registers */
> > +#define PCIE_PHY_CMN_REG4 0x14
> +/* These are probably the bits that *aren't* DCC_FB_EN */
> > +#define PCIE_PHY_CMN_REG4_DCC_FB_EN 0x29
> +
> > +#define PCIE_PHY_CMN_REG15 ????????0x54
> > +#define PCIE_PHY_CMN_REG15_DLY_4 BIT(2)
> > +#define PCIE_PHY_CMN_REG15_PLL_PD BIT(5)
> > +#define PCIE_PHY_CMN_REG15_OVRD_PLL_PD BIT(7)
> +
> > +#define PCIE_PHY_CMN_REG24 0x90
> > +#define PCIE_PHY_CMN_REG24_RX_EQ BIT(6)
> > +#define PCIE_PHY_CMN_REG24_RX_EQ_SEL BIT(3)
> +
> > +#define PCIE_PHY_CMN_REG26 0x98
> > +#define PCIE_PHY_CMN_REG26_ATT_MODE 0xBC
> +
> ?#define PHY_RX_OVRD_IN_LO 0x1005
> ?#define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5)
> ?#define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3)
> @@ -431,6 +450,26 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
> > ? switch (imx6_pcie->variant) {
> > ? case IMX7D:
> > ? reset_control_deassert(imx6_pcie->pciephy_reset);
> +
> > + /* Workaround for ERR010728, failure of PCI-e PLL VCO to
> > + ?* oscillate, especially when cold.??This turns off "Duty-cycle
> > + ?* Corrector" and other mysterious undocumented things.
> > + ?*/
> > + if (likely(imx6_pcie->phy_base)) {
> > + /* De-assert DCC_FB_EN */
> > + writel(PCIE_PHY_CMN_REG4_DCC_FB_EN,
> > + ???????imx6_pcie->phy_base + PCIE_PHY_CMN_REG4);
> > + /* Assert RX_EQS and RX_EQS_SEL */
> > + writel(PCIE_PHY_CMN_REG24_RX_EQ_SEL
> > + | PCIE_PHY_CMN_REG24_RX_EQ,
> > + ???????imx6_pcie->phy_base + PCIE_PHY_CMN_REG24);
> > + /* Assert ATT_MODE */
> > + writel(PCIE_PHY_CMN_REG26_ATT_MODE,
> > + ???????imx6_pcie->phy_base + PCIE_PHY_CMN_REG26);
> > + } else {
> + dev_err(dev, "PHY base address not set\n");
Please tune this down to the dev_warn level, in case we are running a
new kernel on a older DT. Also the message isn't really helpful to the
user. It would be better to have something like "No access to PHY
registers, can't apply workaround for ERR010728." Maybe even with a
hint to update the DT.
> + }
> +
> > ? imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie);
> > ? break;
> > ? case IMX6SX:
> @@ -698,6 +737,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
> > ? struct device *dev = &pdev->dev;
> > ? struct dw_pcie *pci;
> > ? struct imx6_pcie *imx6_pcie;
> > + struct device_node *np;
> > ? struct resource *dbi_base;
> > ? struct device_node *node = dev->of_node;
> > ? int ret;
> @@ -717,6 +757,25 @@ static int imx6_pcie_probe(struct platform_device *pdev)
> > ? imx6_pcie->variant =
> > ? (enum imx6_pcie_variants)of_device_get_match_data(dev);
> ?
> > + /* Find the PHY if one is defined, only imx7d uses it */
> > + np = of_parse_phandle(node, "fsl,pcie-phy", 0);
> > + if (np) {
> > + struct resource res;
> +
> > + ret = of_address_to_resource(np, 0, &res);
> > + if (ret) {
> > + dev_err(dev, "Unable to map PCIe PHY\n");
> > + return ret;
> > + }
> > + imx6_pcie->phy_base = devm_ioremap_resource(dev, &res);
> > + if (IS_ERR(imx6_pcie->phy_base)) {
> > + dev_err(dev, "Unable to map PCIe PHY\n");
> > + return PTR_ERR(imx6_pcie->phy_base);
> > + }
> > + } else {
> > + imx6_pcie->phy_base = NULL;
> + }
imx6_pcie is zero initialized on allocation, so no need for the else
path setting this to NULL.
Regards,
Lucas
> +
> > ? dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > ? pci->dbi_base = devm_ioremap_resource(dev, dbi_base);
> > ? if (IS_ERR(pci->dbi_base))
next prev parent reply other threads:[~2018-08-01 10:44 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-18 19:44 [PATCH 0/2] Workaround for IMX7d PCI-e PLL lock failure Trent Piepho
2018-07-18 19:44 ` [PATCH 1/2] ARM: dts: imx7d: Add node for PCIe PHY Trent Piepho
2018-07-19 3:24 ` Shawn Guo
2018-08-01 10:39 ` Lucas Stach
2018-08-01 17:33 ` Trent Piepho
2018-08-02 0:43 ` Richard Zhu
2018-08-02 6:55 ` Lucas Stach
2018-07-18 19:44 ` [PATCH 2/2] PCI: imx: Add workaround for e10728, IMX7d PCIe PLL failure Trent Piepho
2018-08-01 10:44 ` Lucas Stach [this message]
2018-08-01 10:47 ` [PATCH 0/2] Workaround for IMX7d PCI-e PLL lock failure Lucas Stach
2018-09-17 10:13 ` Lorenzo Pieralisi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1533120257.20186.7.camel@pengutronix.de \
--to=l.stach@pengutronix.de \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).