RE: [PATCH v9 8/8] PCI: imx6: Add compliance tests mode support

From: Hongxing Zhu
Date: Thu Jun 09 2022 - 02:19:01 EST


> -----Original Message-----
> From: Lucas Stach <l.stach@xxxxxxxxxxxxxx>
> Sent: 2022年6月8日 15:49
> To: Hongxing Zhu <hongxing.zhu@xxxxxxx>; bhelgaas@xxxxxxxxxx;
> robh+dt@xxxxxxxxxx; broonie@xxxxxxxxxx; lorenzo.pieralisi@xxxxxxx;
> jingoohan1@xxxxxxxxx; festevam@xxxxxxxxx;
> francesco.dolcini@xxxxxxxxxxx
> Cc: linux-pci@xxxxxxxxxxxxxxx; linux-arm-kernel@xxxxxxxxxxxxxxxxxxx;
> linux-kernel@xxxxxxxxxxxxxxx; kernel@xxxxxxxxxxxxxx; dl-linux-imx
> <linux-imx@xxxxxxx>
> Subject: Re: [PATCH v9 8/8] PCI: imx6: Add compliance tests mode support
>
> Am Freitag, dem 06.05.2022 um 09:47 +0800 schrieb Richard Zhu:
> > Refer to the Chapter 3.2 System Board Signal Quality of PCI Express
> > Architecture PHY Test Specification Revision 2.0.
> >
> > Signal quality tests (for example: jitter, differential eye opening
> > and so on) can be executed with devices in the polling.compliance state.
> >
> > To let the device support polling.compliance state, the clocks and
> > powers shouldn't be turned off when the probe of device driver fails.
> >
> > Based on CLB (Compliance Load Board) Test Fixture and so on test
> > equipments, the PHY link would be down during the compliance tests.
> > Refer to this scenario, add the i.MX PCIe compliance tests mode enable
> > support, and keep the clocks and powers on, and finish the driver
> > probe without error return.
> >
> > Use the "pci_imx6.compliance=1" in kernel command line to enable the
> > compliance tests mode.
> >
> > Signed-off-by: Richard Zhu <hongxing.zhu@xxxxxxx>
> > ---
> > drivers/pci/controller/dwc/pci-imx6.c | 39
> > ++++++++++++++++++---------
> > 1 file changed, 27 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c
> > b/drivers/pci/controller/dwc/pci-imx6.c
> > index f0ffd9011975..f78b59822626 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -146,6 +146,10 @@ struct imx6_pcie {
> > #define PHY_RX_OVRD_IN_LO_RX_DATA_EN BIT(5)
> > #define PHY_RX_OVRD_IN_LO_RX_PLL_EN BIT(3)
> >
> > +static bool imx6_pcie_cmp_mode;
> > +module_param_named(compliance, imx6_pcie_cmp_mode, bool, 0644);
> > +MODULE_PARM_DESC(compliance, "i.MX PCIe compliance test mode
> > +(1=compliance test mode enabled)");
> > +
> > static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, bool
> > exp_val) {
> > struct dw_pcie *pci = imx6_pcie->pci; @@ -826,10 +830,12 @@ static
> > int imx6_pcie_start_link(struct dw_pcie *pci)
> > * started in Gen2 mode, there is a possibility the devices on the
> > * bus will not be detected at all. This happens with PCIe switches.
> > */
> > - tmp = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
> > - tmp &= ~PCI_EXP_LNKCAP_SLS;
> > - tmp |= PCI_EXP_LNKCAP_SLS_2_5GB;
> > - dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, tmp);
> > + if (!imx6_pcie_cmp_mode) {
> > + tmp = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
> > + tmp &= ~PCI_EXP_LNKCAP_SLS;
> > + tmp |= PCI_EXP_LNKCAP_SLS_2_5GB;
> > + dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, tmp);
> > + }
> >
> > /* Start LTSSM. */
> > imx6_pcie_ltssm_enable(dev);
> > @@ -887,14 +893,16 @@ static int imx6_pcie_start_link(struct dw_pcie
> *pci)
> > dev_dbg(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
> > dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG0),
> > dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG1));
> > - imx6_pcie_reset_phy(imx6_pcie);
> > - imx6_pcie_clk_disable(imx6_pcie);
> > - if (imx6_pcie->phy != NULL) {
> > - phy_power_off(imx6_pcie->phy);
> > - phy_exit(imx6_pcie->phy);
> > + if (!imx6_pcie_cmp_mode) {
> > + imx6_pcie_reset_phy(imx6_pcie);
> > + imx6_pcie_clk_disable(imx6_pcie);
> > + if (imx6_pcie->phy != NULL) {
> > + phy_power_off(imx6_pcie->phy);
> > + phy_exit(imx6_pcie->phy);
> > + }
> > + if (imx6_pcie->vpcie)
> > + regulator_disable(imx6_pcie->vpcie);
> > }
> > - if (imx6_pcie->vpcie)
> > - regulator_disable(imx6_pcie->vpcie);
> > return ret;
> > }
> >
> > @@ -1289,8 +1297,15 @@ static int imx6_pcie_probe(struct
> platform_device *pdev)
> > return ret;
> >
> > ret = dw_pcie_host_init(&pci->pp);
> > - if (ret < 0)
> > + if (ret < 0) {
> > + if (imx6_pcie_cmp_mode) {
> > + dev_info(dev, "driver loaded with compliance test mode
> enabled\n");
> > + ret = 0;
> > + } else {
> > + dev_err(dev, "unable to add PCIe port\n");
> > + }
> > return ret;
> > + }
>
> If you drop the error return from imx6_pcie_start_link, like I suggested in patch
> 6/8, you don't need this block as dw_pcie_host_init will succeed even if the
> link is down or in compliance test mode.
Thanks for your review comments.
As what I said in the 6/8 patch, there would be a long latency in the probe and
every resume operation if the probe is finished successfully when link is down.
With this extreme long latency, I'm afraid that user would have a bad
experience and wouldn't accept such kind of long latency in every
suspend/resume operations.

Best Regards
Richard Zhu

>
> Regards,
> Lucas
>
> >
> > if (pci_msi_enabled()) {
> > u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI);
>