aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2014-02-19 15:22:18 -0500
committerBjorn Helgaas <bhelgaas@google.com>2014-02-19 16:54:45 -0500
commitf95d3ae771916c8c7024fecfb6c420e5dfeced05 (patch)
tree4ded9996fcb51cb63f68b652be0ecb465e44ab78 /drivers/pci
parent38dbfb59d1175ef458d006556061adeaa8751b72 (diff)
PCI: imx6: Wait for retraining
This patch handles the case where the PCIe link is up and running, yet drops into the LTSSM training mode. The link spends short time in the LTSSM training mode, but the current code can misinterpret it as the link being stalled. Waiting for the LTSSM training to complete fixes the issue. Quoting Sascha: This is broken since commit 7f9f40c01cce ('PCI: imx6: Report "link up" only after link training completes'). The designware driver changes the PORT_LOGIC_SPEED_CHANGE bit in dw_pcie_host_init() which causes the link to be retrained. During the next call to dw_pcie_rd_conf() the link is then reported being down and the function returns PCIBIOS_DEVICE_NOT_FOUND resulting in nonfunctioning PCIe. Fixes: 7f9f40c01cce (PCI: imx6: Report "link up" only after link training completes) Tested-by: Troy Kisky <troy.kisky@boundarydevices.com> Tested-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Marek Vasut <marex@denx.de> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Shawn Guo <shawn.guo@linaro.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/host/pci-imx6.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index e8663a8c3406..ee082509b0ba 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -424,20 +424,40 @@ static void imx6_pcie_reset_phy(struct pcie_port *pp)
424 424
425static int imx6_pcie_link_up(struct pcie_port *pp) 425static int imx6_pcie_link_up(struct pcie_port *pp)
426{ 426{
427 u32 rc, ltssm, rx_valid; 427 u32 rc, debug_r0, rx_valid;
428 int count = 5;
428 429
429 /* 430 /*
430 * Test if the PHY reports that the link is up and also that 431 * Test if the PHY reports that the link is up and also that the LTSSM
431 * the link training finished. It might happen that the PHY 432 * training finished. There are three possible states of the link when
432 * reports the link is already up, but the link training bit 433 * this code is called:
433 * is still set, so make sure to check the training is done 434 * 1) The link is DOWN (unlikely)
434 * as well here. 435 * The link didn't come up yet for some reason. This usually means
436 * we have a real problem somewhere. Reset the PHY and exit. This
437 * state calls for inspection of the DEBUG registers.
438 * 2) The link is UP, but still in LTSSM training
439 * Wait for the training to finish, which should take a very short
440 * time. If the training does not finish, we have a problem and we
441 * need to inspect the DEBUG registers. If the training does finish,
442 * the link is up and operating correctly.
443 * 3) The link is UP and no longer in LTSSM training
444 * The link is up and operating correctly.
435 */ 445 */
436 rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1); 446 while (1) {
437 if ((rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) && 447 rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1);
438 !(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING)) 448 if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP))
439 return 1; 449 break;
440 450 if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING))
451 return 1;
452 if (!count--)
453 break;
454 dev_dbg(pp->dev, "Link is up, but still in training\n");
455 /*
456 * Wait a little bit, then re-check if the link finished
457 * the training.
458 */
459 usleep_range(1000, 2000);
460 }
441 /* 461 /*
442 * From L0, initiate MAC entry to gen2 if EP/RC supports gen2. 462 * From L0, initiate MAC entry to gen2 if EP/RC supports gen2.
443 * Wait 2ms (LTSSM timeout is 24ms, PHY lock is ~5us in gen2). 463 * Wait 2ms (LTSSM timeout is 24ms, PHY lock is ~5us in gen2).
@@ -446,15 +466,16 @@ static int imx6_pcie_link_up(struct pcie_port *pp)
446 * to gen2 is stuck 466 * to gen2 is stuck
447 */ 467 */
448 pcie_phy_read(pp->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid); 468 pcie_phy_read(pp->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid);
449 ltssm = readl(pp->dbi_base + PCIE_PHY_DEBUG_R0) & 0x3F; 469 debug_r0 = readl(pp->dbi_base + PCIE_PHY_DEBUG_R0);
450 470
451 if (rx_valid & 0x01) 471 if (rx_valid & 0x01)
452 return 0; 472 return 0;
453 473
454 if (ltssm != 0x0d) 474 if ((debug_r0 & 0x3f) != 0x0d)
455 return 0; 475 return 0;
456 476
457 dev_err(pp->dev, "transition to gen2 is stuck, reset PHY!\n"); 477 dev_err(pp->dev, "transition to gen2 is stuck, reset PHY!\n");
478 dev_dbg(pp->dev, "debug_r0=%08x debug_r1=%08x\n", debug_r0, rc);
458 479
459 imx6_pcie_reset_phy(pp); 480 imx6_pcie_reset_phy(pp);
460 481