From patchwork Wed Sep 16 00:39:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ray Jui X-Patchwork-Id: 7190071 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 9BC93BEEC1 for ; Wed, 16 Sep 2015 00:40:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A62FF20829 for ; Wed, 16 Sep 2015 00:40:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8797F2081E for ; Wed, 16 Sep 2015 00:40:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753201AbbIPAjR (ORCPT ); Tue, 15 Sep 2015 20:39:17 -0400 Received: from mail-gw2-out.broadcom.com ([216.31.210.63]:13841 "EHLO mail-gw2-out.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753332AbbIPAjO (ORCPT ); Tue, 15 Sep 2015 20:39:14 -0400 X-IronPort-AV: E=Sophos;i="5.17,537,1437462000"; d="scan'208";a="75223944" Received: from irvexchcas08.broadcom.com (HELO IRVEXCHCAS08.corp.ad.broadcom.com) ([10.9.208.57]) by mail-gw2-out.broadcom.com with ESMTP; 15 Sep 2015 18:04:17 -0700 Received: from IRVEXCHSMTP1.corp.ad.broadcom.com (10.9.207.51) by IRVEXCHCAS08.corp.ad.broadcom.com (10.9.208.57) with Microsoft SMTP Server (TLS) id 14.3.235.1; Tue, 15 Sep 2015 17:39:13 -0700 Received: from mail-irva-13.broadcom.com (10.10.10.20) by IRVEXCHSMTP1.corp.ad.broadcom.com (10.9.207.51) with Microsoft SMTP Server id 14.3.235.1; Tue, 15 Sep 2015 17:39:13 -0700 Received: from mail.broadcom.com (unknown [10.136.8.49]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id 8A0D040FE5; Tue, 15 Sep 2015 17:36:34 -0700 (PDT) From: Ray Jui To: Bjorn Helgaas CC: Hauke Mehrtens , , , , , Ray Jui Subject: [PATCH 5/8] PCI: iproc: Improve link detection logic Date: Tue, 15 Sep 2015 17:39:19 -0700 Message-ID: <1442363962-29805-6-git-send-email-rjui@broadcom.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1442363962-29805-1-git-send-email-rjui@broadcom.com> References: <1442363962-29805-1-git-send-email-rjui@broadcom.com> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_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 This patch further improves the iProc PCIe link detection logic by explicitly querying the link status register to ensure link is active It also forces class to PCI_CLASS_BRIDGE_PCI (0x0604) through the host configuration space register Signed-off-by: Ray Jui Reviewed-by: Anup Patel Reviewed-by: Scott Branden --- drivers/pci/host/pcie-iproc.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c index 80e0541..62e8085 100644 --- a/drivers/pci/host/pcie-iproc.c +++ b/drivers/pci/host/pcie-iproc.c @@ -60,6 +60,12 @@ #define SYS_RC_INTX_EN 0x330 #define SYS_RC_INTX_MASK 0xf +#define PCIE_LINK_STATUS_OFFSET 0xf0c +#define PCIE_PHYLINKUP_SHIFT 3 +#define PCIE_PHYLINKUP BIT(PCIE_PHYLINKUP_SHIFT) +#define PCIE_DL_ACTIVE_SHIFT 2 +#define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT) + static inline struct iproc_pcie *iproc_data(struct pci_bus *bus) { struct iproc_pcie *pcie; @@ -138,9 +144,15 @@ static void iproc_pcie_reset(struct iproc_pcie *pcie) static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus) { u8 hdr_type; - u32 link_ctrl; + u32 link_ctrl, class, val; u16 pos, link_status; - int link_is_active = 0; + bool link_is_active = false; + + val = readl(pcie->base + PCIE_LINK_STATUS_OFFSET); + if (!(val & PCIE_PHYLINKUP) || !(val & PCIE_DL_ACTIVE)) { + dev_err(pcie->dev, "PHY or data link is INACTIVE!\n"); + return -ENODEV; + } /* make sure we are not in EP mode */ pci_bus_read_config_byte(bus, 0, PCI_HEADER_TYPE, &hdr_type); @@ -150,14 +162,19 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus) } /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */ - pci_bus_write_config_word(bus, 0, PCI_CLASS_DEVICE, - PCI_CLASS_BRIDGE_PCI); +#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c +#define PCI_CLASS_BRIDGE_MASK 0xffff00 +#define PCI_CLASS_BRIDGE_SHIFT 8 + pci_bus_read_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, &class); + class &= ~PCI_CLASS_BRIDGE_MASK; + class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT); + pci_bus_write_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, class); /* check link status to see if link is active */ pos = pci_bus_find_capability(bus, 0, PCI_CAP_ID_EXP); pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA, &link_status); if (link_status & PCI_EXP_LNKSTA_NLW) - link_is_active = 1; + link_is_active = true; if (!link_is_active) { /* try GEN 1 link speed */ @@ -181,7 +198,7 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus) pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA, &link_status); if (link_status & PCI_EXP_LNKSTA_NLW) - link_is_active = 1; + link_is_active = true; } }