From patchwork Wed Feb 19 20:22:18 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Troy Kisky X-Patchwork-Id: 3682931 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D46189F2EC for ; Wed, 19 Feb 2014 20:23:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E93CD201FE for ; Wed, 19 Feb 2014 20:23:13 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D8D3E201ED for ; Wed, 19 Feb 2014 20:23:12 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WGDfT-0002iR-4y; Wed, 19 Feb 2014 20:22:55 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WGDfN-000784-14; Wed, 19 Feb 2014 20:22:49 +0000 Received: from mail-pb0-f44.google.com ([209.85.160.44]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WGDfK-00075b-31 for linux-arm-kernel@lists.infradead.org; Wed, 19 Feb 2014 20:22:47 +0000 Received: by mail-pb0-f44.google.com with SMTP id rq2so874264pbb.31 for ; Wed, 19 Feb 2014 12:22:20 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=crv/fYegYSmz5PSyazMg0+B0YqrfWaqJLpxtz1kwCCA=; b=O1L4gpWbWfYk75it3c3BzvrYMWO6SFItHuz17rHrmRxB6g+B4XMeJxm+dfYX5E30To tLmbtBzkqOk5Jnjisb9pt3vWlb43vyfNWmVZtHxskIkHUV4MQdsKczBSGy1mEBLfuMRT t2l93ggR17SzmckcKF10SGAInGL7RosnB4mPya/0s+DaAlcHrD+35/chY0UojGL8HDH5 5SKeohjbQiiCV0SWgkxasJLkfRfYXyyusBQ2OJMhAW7ok724/O8AOYwAVT0LnDvM6VGK UPfsiuCqLm1mg8dR6r1yVz+COi7Fl+d6V9rqpagEDWanZjOI/wFWapJHk15r6P2UUq7c nC+g== X-Gm-Message-State: ALoCoQl8IUZFGyJFO6IULZ+S7/UeMNifp4ooq9W8pL7t8ohqWbeamQZx4zlTNArqK/fyileW3Hdi X-Received: by 10.66.142.107 with SMTP id rv11mr42237972pab.17.1392841340613; Wed, 19 Feb 2014 12:22:20 -0800 (PST) Received: from officeserver-2 ([63.226.49.26]) by mx.google.com with ESMTPSA id ix2sm363780pbc.45.2014.02.19.12.22.18 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 19 Feb 2014 12:22:19 -0800 (PST) Received: from tkisky by officeserver-2 with local (Exim 4.80) (envelope-from ) id 1WGDez-0003Wm-9L; Wed, 19 Feb 2014 13:22:25 -0700 From: Troy Kisky To: bhelgaas@google.com, s.hauer@pengutronix.de, marex@denx.de Subject: [PATCH 1/1] pci-imx6.c: wait for retraining Date: Wed, 19 Feb 2014 13:22:18 -0700 Message-Id: <1392841338-13527-1-git-send-email-troy.kisky@boundarydevices.com> X-Mailer: git-send-email 1.8.1.2 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140219_152246_202792_F08DD740 X-CRM114-Status: GOOD ( 19.18 ) X-Spam-Score: -2.6 (--) Cc: r65037@freescale.com, linux-pci@vger.kernel.org, Troy Kisky , kernel@pengutronix.de, shawn.guo@linaro.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Marek Vasut 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 e6daf4a5e1b813bc7f85507ec83b8c2452c121e6 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." Signed-off-by: Marek Vasut Tested-by: Troy Kisky Tested-by: Sascha Hauer Acked-by: Shawn Guo Signed-off-by: Troy Kisky --- drivers/pci/host/pci-imx6.c | 47 ++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index e8663a8..ee08250 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) static int imx6_pcie_link_up(struct pcie_port *pp) { - u32 rc, ltssm, rx_valid; + u32 rc, debug_r0, rx_valid; + int count = 5; /* - * Test if the PHY reports that the link is up and also that - * the link training finished. It might happen that the PHY - * reports the link is already up, but the link training bit - * is still set, so make sure to check the training is done - * as well here. + * Test if the PHY reports that the link is up and also that the LTSSM + * training finished. There are three possible states of the link when + * this code is called: + * 1) The link is DOWN (unlikely) + * The link didn't come up yet for some reason. This usually means + * we have a real problem somewhere. Reset the PHY and exit. This + * state calls for inspection of the DEBUG registers. + * 2) The link is UP, but still in LTSSM training + * Wait for the training to finish, which should take a very short + * time. If the training does not finish, we have a problem and we + * need to inspect the DEBUG registers. If the training does finish, + * the link is up and operating correctly. + * 3) The link is UP and no longer in LTSSM training + * The link is up and operating correctly. */ - rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1); - if ((rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) && - !(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING)) - return 1; - + while (1) { + rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1); + if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP)) + break; + if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING)) + return 1; + if (!count--) + break; + dev_dbg(pp->dev, "Link is up, but still in training\n"); + /* + * Wait a little bit, then re-check if the link finished + * the training. + */ + usleep_range(1000, 2000); + } /* * From L0, initiate MAC entry to gen2 if EP/RC supports gen2. * 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) * to gen2 is stuck */ pcie_phy_read(pp->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid); - ltssm = readl(pp->dbi_base + PCIE_PHY_DEBUG_R0) & 0x3F; + debug_r0 = readl(pp->dbi_base + PCIE_PHY_DEBUG_R0); if (rx_valid & 0x01) return 0; - if (ltssm != 0x0d) + if ((debug_r0 & 0x3f) != 0x0d) return 0; dev_err(pp->dev, "transition to gen2 is stuck, reset PHY!\n"); + dev_dbg(pp->dev, "debug_r0=%08x debug_r1=%08x\n", debug_r0, rc); imx6_pcie_reset_phy(pp);