From patchwork Thu Aug 24 05:04:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Oza Pawandeep X-Patchwork-Id: 9919039 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 B6D7D60353 for ; Thu, 24 Aug 2017 05:05:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A88AE28B38 for ; Thu, 24 Aug 2017 05:05:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9D60628B40; Thu, 24 Aug 2017 05:05:52 +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=-2.6 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 220F728B38 for ; Thu, 24 Aug 2017 05:05:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=GZzlTflf1NQRbdUiVMtXuZYBZSJ3hvMQqepdylBozGs=; b=GpolnooXFW4d0/ tl+tyvD18KM6HnkGVGV8Tq+jmkH+KWKVQ6gjdJ0Vf7vPoUV7h72J5N/DuUIAnPtxja9/ibXzlwE6y lqbkz2pkNUaBjDzNFEFUfUQU+aRC2FuvRCQT4ytEu8pINHm95GK3RKOrEax8gG9slTIJwQxeB5F4j ZpyDqWOwdvH8crOTUSk6LokWjsenok+vI/hDiqktxyNkx+LcFgF5xczXRiYkj2CzrUNKxwnDWM11K rKykVXKWSEZQK3bepP+wVwuCK+DDmkHrKYp8NKdVSC+ruZdhnBOHayLw92YkUD2Lpa8TJOVigDVg7 NHbTqp3G5gdZN7EnhW7g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dkkKx-00026Y-9y; Thu, 24 Aug 2017 05:05:47 +0000 Received: from mail-wm0-x231.google.com ([2a00:1450:400c:c09::231]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dkkKI-0000IM-Bn for linux-arm-kernel@lists.infradead.org; Thu, 24 Aug 2017 05:05:14 +0000 Received: by mail-wm0-x231.google.com with SMTP id a70so4081251wmd.1 for ; Wed, 23 Aug 2017 22:04:45 -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=uTLZFckPUE5Jocj2eC6mpTClJfhW6nJu+6sVZ08ZC7w=; b=TjFkKrTzO1vQotYgqMszgvIXEx5hrD94tTaUMNXTKqSmbj2Lq3Z9Io90vbKwB5P9n9 1Y3NApR8Hw+qhMX7noaCqFMU7x72PA6VzMmD1FP7Xds/E8m8dc6tloqHVh0IE1iQrVsD MXMdh7GL4YMY/dXeW2GHKacBISyxHws2sIaTg= 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=uTLZFckPUE5Jocj2eC6mpTClJfhW6nJu+6sVZ08ZC7w=; b=OhfHitbY+ebs8+5aUwzBMPAPxFXpYpqgssq8ko19urTvmz7f1dYTXWgRzdOuaRsHOH Lrhsguq32fm/jubJhUXtFhA69VI/XmGAUW3NsAS41AmUZUAHI3YnMblUlLbLT8r27fdG axO+LCbkTa1X+lA34mZ2Zhk/FL35D82xGSa37UbxwUt5s67LhCQoY2ECST+5cUllyQIH 52VYa83NWhb/gOy9DsgUp0GIbvaYBzQGVMYjvL3pazX8LAsEVK0bFDYnADDVWIXvNh0a qj5mFSDj7a/0LnsOS6diobtbjmkt1qqV4vGIjdjxvNrejYx00NOs+D6wExTVyBeoVlkE HnBQ== X-Gm-Message-State: AHYfb5gZZaf7VxmC/x/D0gMzNR48aKBOcoxiIASmb8dAX30FhInuhl1N bS6IOcNV35jTwLPs X-Received: by 10.28.45.20 with SMTP id t20mr3493486wmt.5.1503551084371; Wed, 23 Aug 2017 22:04:44 -0700 (PDT) Received: from anjanavk-OptiPlex-7010.dhcp.avagotech.net ([192.19.237.250]) by smtp.gmail.com with ESMTPSA id n67sm3602691wmi.43.2017.08.23.22.04.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 23 Aug 2017 22:04:43 -0700 (PDT) From: Oza Pawandeep To: Bjorn Helgaas , , Rob Herring , Mark Rutland , Ray Jui , Scott Branden , Jon Mason , bcm-kernel-feedback-list@broadcom.com, Oza Pawandeep , Andy Gospodarek , linux-pci@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Oza Pawandeep Subject: [PATCH v8 2/3] PCI: iproc: retry request when CRS returned from EP Date: Thu, 24 Aug 2017 10:34:25 +0530 Message-Id: <1503551066-23212-3-git-send-email-oza.oza@broadcom.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1503551066-23212-1-git-send-email-oza.oza@broadcom.com> References: <1503551066-23212-1-git-send-email-oza.oza@broadcom.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170823_220506_898074_490C0B6F X-CRM114-Status: GOOD ( 18.65 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP PCIe spec r3.1, sec 2.3.2 If CRS software visibility is not enabled, the RC must reissue the config request as a new request. - If CRS software visibility is enabled, - for a config read of Vendor ID, the RC must return 0x0001 data - for all other config reads/writes, the RC must reissue the request iproc PCIe Controller spec: 4.7.3.3. Retry Status On Configuration Cycle Endpoints are allowed to generate retry status on configuration cycles. In this case, the RC needs to re-issue the request. The IP does not handle this because the number of configuration cycles needed will probably be less than the total number of non-posted operations needed. When a retry status is received on the User RX interface for a configuration request that was sent on the User TX interface, it will be indicated with a completion with the CMPL_STATUS field set to 2=CRS, and the user will have to find the address and data values and send a new transaction on the User TX interface. When the internal configuration space returns a retry status during a configuration cycle (user_cscfg = 1) on the Command/Status interface, the pcie_cscrs will assert with the pcie_csack signal to indicate the CRS status. When the CRS Software Visibility Enable register in the Root Control register is enabled, the IP will return the data value to 0x0001 for the Vendor ID value and 0xffff (all 1’s) for the rest of the data in the request for reads of offset 0 that return with CRS status. This is true for both the User RX Interface and for the Command/Status interface. When CRS Software Visibility is enabled, the CMPL_STATUS field of the completion on the User RX Interface will not be 2=CRS and the pcie_cscrs signal will not assert on the Command/Status interface. Per PCIe r3.1, sec 2.3.2, config requests that receive completions with Configuration Request Retry Status (CRS) should be reissued by the hardware except reads of the Vendor ID when CRS Software Visibility is enabled. This hardware never reissues configuration requests when it receives CRS completions. Note that, neither PCIe host bridge nor PCIe core re-issues the request for any configuration offset. For config reads, this hardware returns CFG_RETRY_STATUS data when it receives a CRS completion for a config read, regardless of the address of the read or the CRS Software Visibility Enable bit. This patch implements iproc_pcie_config_read which gets called for Stingray, if it receives a CRS completion, it retries reading it again. In case of timeout, it returns 0xffffffff. For other iproc based SOC, it falls back to PCI generic APIs. Signed-off-by: Oza Pawandeep diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c index 61d9be6..37f4adf 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) @@ -473,6 +476,64 @@ static void __iomem *iproc_pcie_map_ep_cfg_reg(struct iproc_pcie *pcie, return (pcie->base + offset); } +static unsigned int iproc_pcie_cfg_retry(void __iomem *cfg_data_p) +{ + int timeout = CFG_RETRY_STATUS_TIMEOUT_US; + unsigned int data; + + /* + * As per PCIe spec r3.1, sec 2.3.2, 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. + * + * For config reads, this hardware returns CFG_RETRY_STATUS data when + * it receives a CRS completion for a config read, regardless of the + * address of the read or the CRS Software Visibility Enable bit. As a + * partial workaround for this, we retry in software any read that + * returns CFG_RETRY_STATUS. + */ + data = readl(cfg_data_p); + while (data == CFG_RETRY_STATUS && timeout--) { + udelay(1); + data = readl(cfg_data_p); + } + + if (data == CFG_RETRY_STATUS) + data = 0xffffffff; + + return data; +} + +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; + unsigned int data; + + /* 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; + + data = iproc_pcie_cfg_retry(cfg_data_p); + + *val = data; + if (size <= 2) + *val = (data >> (8 * (where & 3))) & ((1 << (size * 8)) - 1); + + return PCIBIOS_SUCCESSFUL; +} + /** * Note access to the configuration registers are protected at the higher layer * by 'pci_lock' in drivers/pci/access.c @@ -567,8 +628,13 @@ 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); + 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); ret = pci_generic_config_read32(bus, devfn, where, size, val); iproc_pcie_apb_err_disable(bus, false);