From patchwork Wed Jul 5 03:08:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Oza Pawandeep X-Patchwork-Id: 9825793 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 01981602F0 for ; Wed, 5 Jul 2017 03:09:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F1E3523F88 for ; Wed, 5 Jul 2017 03:09:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E65E52582C; Wed, 5 Jul 2017 03:09:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,RCVD_IN_DNSWL_HI,RCVD_IN_SORBS_SPAM autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 49FA823F88 for ; Wed, 5 Jul 2017 03:09:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752393AbdGEDJv (ORCPT ); Tue, 4 Jul 2017 23:09:51 -0400 Received: from mail-wm0-f44.google.com ([74.125.82.44]:35712 "EHLO mail-wm0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752368AbdGEDJt (ORCPT ); Tue, 4 Jul 2017 23:09:49 -0400 Received: by mail-wm0-f44.google.com with SMTP id w126so209290508wme.0 for ; Tue, 04 Jul 2017 20:09:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=jQuC8diQPza8KpGzgrtUWMPrRtPFvto9NrGwOIJcgyI=; b=EV4xaz3Be9Anx3D3d24c9lnnraf8nwYdYedXsKdhsGztzqjhap3vbaZYJPc7B4fOEo NoDBqllFeMA2j9dpgMlNqDfc+hmohABs8SVr1ngtlC+uS8TaqklJM+kcqcz5VgMx3BEb rI4lxun7VLGHlMC//ZMboIEeqz7FJi4A27AW4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jQuC8diQPza8KpGzgrtUWMPrRtPFvto9NrGwOIJcgyI=; b=CXVQMx4t+BebCDi6LmJenOzgZZOQcwgWVAf8LMTdyPG00nCpq4tIPCz/7RSxhGDNaj GQMBVbwd+jLF0HEzXB17IPj3xmK57qp0nQJcK11r4x6L5Qur2jI/gAkssscq9APf38TD koGO5CW9m5Bg1Tw6mWMzefjqZF9Rp6ySNG13HE6CZmC55Od5WqZTe8tI/m9zXm6Co+S8 lIfg1jXcJqGPqLlsscp81zwssNNYqYCnLxOlNEvY9qw7Zaec9nPEiMCgREkTUoXVyRG7 xcv0xpwRaE0t2E44I4P8NFDHQUN/Jfl8xPD6P1TnIMNxoIFl1L91awZT5C2rOVHozjg7 Y5nw== X-Gm-Message-State: AKS2vOxpW5Ls25qJ8XE7kAG2P9LxsglY90GaBMe4qWCAG3VaTkmKA8mL 1Fj9j0JYHeGPM3k9EIE= X-Received: by 10.28.149.76 with SMTP id x73mr21738170wmd.119.1499224167609; Tue, 04 Jul 2017 20:09:27 -0700 (PDT) Received: from anjanavk-OptiPlex-7010.dhcp.avagotech.net ([192.19.237.250]) by smtp.gmail.com with ESMTPSA id 46sm29701073wrz.8.2017.07.04.20.09.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 04 Jul 2017 20:09:26 -0700 (PDT) From: Oza Pawandeep To: Bjorn Helgaas , Ray Jui , Scott Branden , Jon Mason , bcm-kernel-feedback-list@broadcom.com, Oza Pawandeep , Andy Gospodarek , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Oza Pawandeep Subject: [PATCH v4 1/2] PCI: iproc: Retry request when CRS returned from EP Date: Wed, 5 Jul 2017 08:38:58 +0530 Message-Id: <1499224139-10746-2-git-send-email-oza.oza@broadcom.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1499224139-10746-1-git-send-email-oza.oza@broadcom.com> References: <1499224139-10746-1-git-send-email-oza.oza@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-Virus-Scanned: ClamAV using ClamSMTP For Configuration Requests only, following reset it is possible for a device to terminate the request but indicate that it is temporarily unable to process the Request, but will be able to process the Request in the future – in this case, the Configuration Request Retry Status 100 (CRS) Completion Status is used. As per PCI spec, CRS Software Visibility only affects config read of the Vendor ID, for config write or any other config read the Root must automatically re-issue configuration request again as a new request. Iproc based PCIe RC (hw) does not retry request on its own. As a result of the fact, PCIe RC driver (sw) should take care of CRS. This patch fixes the problem, and attempts to read config space again in case of PCIe code forwarding the CRS back to CPU. It implements iproc_pcie_config_read which gets called for Stingray, Otherwise it falls back to PCI generic APIs. Signed-off-by: Oza Pawandeep Reviewed-by: Ray Jui Reviewed-by: Scott Branden diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c index 0f39bd2..b0abcd7 100644 --- a/drivers/pci/host/pcie-iproc.c +++ b/drivers/pci/host/pcie-iproc.c @@ -68,6 +68,9 @@ #define APB_ERR_EN_SHIFT 0 #define APB_ERR_EN BIT(APB_ERR_EN_SHIFT) +#define CFG_RETRY_STATUS 0xffff0001 +#define CFG_RETRY_STATUS_TIMEOUT_US 500000 /* 500 milli-seconds. */ + /* derive the enum index of the outbound/inbound mapping registers */ #define MAP_REG(base_reg, index) ((base_reg) + (index) * 2) @@ -448,6 +451,55 @@ static inline void iproc_pcie_apb_err_disable(struct pci_bus *bus, } } +static int iproc_pcie_cfg_retry(void __iomem *cfg_data_p) +{ + int timeout = CFG_RETRY_STATUS_TIMEOUT_US; + unsigned int ret; + + /* + * As per PCI spec, CRS Software Visibility only + * affects config read of the Vendor ID. + * For config write or any other config read the Root must + * automatically re-issue configuration request again as a + * new request. Iproc based PCIe RC (hw) does not retry + * request on its own, so handle it here. + */ + do { + ret = readl(cfg_data_p); + if (ret == CFG_RETRY_STATUS) + udelay(1); + else + return PCIBIOS_SUCCESSFUL; + } while (timeout--); + + return PCIBIOS_DEVICE_NOT_FOUND; +} + +static void __iomem *iproc_pcie_map_ep_cfg_reg(struct iproc_pcie *pcie, + unsigned int busno, + unsigned int slot, + unsigned int fn, + int where) +{ + u16 offset; + u32 val; + + /* EP device access */ + val = (busno << CFG_ADDR_BUS_NUM_SHIFT) | + (slot << CFG_ADDR_DEV_NUM_SHIFT) | + (fn << CFG_ADDR_FUNC_NUM_SHIFT) | + (where & CFG_ADDR_REG_NUM_MASK) | + (1 & CFG_ADDR_CFG_TYPE_MASK); + + iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_ADDR, val); + offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_DATA); + + if (iproc_pcie_reg_is_invalid(offset)) + return NULL; + + return (pcie->base + offset); +} + /** * Note access to the configuration registers are protected at the higher layer * by 'pci_lock' in drivers/pci/access.c @@ -499,13 +551,48 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus, return (pcie->base + offset); } +static int iproc_pcie_config_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + struct iproc_pcie *pcie = iproc_data(bus); + unsigned int slot = PCI_SLOT(devfn); + unsigned int fn = PCI_FUNC(devfn); + unsigned int busno = bus->number; + void __iomem *cfg_data_p; + int ret; + + /* root complex access. */ + if (busno == 0) + return pci_generic_config_read32(bus, devfn, where, size, val); + + cfg_data_p = iproc_pcie_map_ep_cfg_reg(pcie, busno, slot, fn, where); + + if (!cfg_data_p) + return PCIBIOS_DEVICE_NOT_FOUND; + + ret = iproc_pcie_cfg_retry(cfg_data_p); + if (ret) + return ret; + + *val = readl(cfg_data_p); + + if (size <= 2) + *val = (*val >> (8 * (where & 3))) & ((1 << (size * 8)) - 1); + + return PCIBIOS_SUCCESSFUL; +} + static int iproc_pcie_config_read32(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { int ret; + struct iproc_pcie *pcie = iproc_data(bus); iproc_pcie_apb_err_disable(bus, true); - ret = pci_generic_config_read32(bus, devfn, where, size, val); + if (pcie->type == IPROC_PCIE_PAXB_V2) + ret = iproc_pcie_config_read(bus, devfn, where, size, val); + else + ret = pci_generic_config_read32(bus, devfn, where, size, val); iproc_pcie_apb_err_disable(bus, false); return ret;