From patchwork Thu Aug 5 21:11:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Linton X-Patchwork-Id: 492275 Delivered-To: patch@linaro.org Received: by 2002:a05:6638:396:0:0:0:0 with SMTP id y22csp664636jap; Thu, 5 Aug 2021 14:12:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxZMl+XK5tvjffmmiJyDycOo6o5KNy3ur3FEfiSqkB9C4Jaru4/z1jafI74XW8cVCmXlLhR X-Received: by 2002:a50:cdcb:: with SMTP id h11mr9167111edj.366.1628197935605; Thu, 05 Aug 2021 14:12:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1628197935; cv=none; d=google.com; s=arc-20160816; b=CbrNP1adYhkO80KxidjaSY4Dsv8S1PpNJv+QWnmbIDRX5JKCekcaMIFg75ir6pLPll X5fOK4NJ/2RrsgdaWNeD+mirK8iRFjqmMue6EE+cRyWb9s+Ssv7ew1KcSbNZKPnJsyim bKjuDOTutZWMW22z3IRwh2uEMIgpMThsZfmaHkxF+jXV6ApWRD3LSyjGpANkD9Vdzkub 7npjSRQxSJAJhlNSJ+153V5yFdInyB1+g1zUmao55U0qCdXAKwoD34Njrz3qxW462mS4 kE9aBWsbY3TsatsP+1qrf3tbNl/DuSSSHoQmQMJY/PKnsPI3wtnTdFh1CLmNEM9v+ATq x0pA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=/q8kx/DN8N9GocOhfKRU5+lTG9OgaItTwPBwFTpbttU=; b=BogEL8IUuaWTq4bUgo9/BB2w/JaRf9xPF/b6ErQ4AK24u5KTe08QJ9LFIHer4rJL4t NQT96yWz7sVMJfSs78V5RY+zRjzAV9M/v+VFlxpRSVethbUeQZhm2xIfPobBeUvWJz4E tN1Iy9INrLCI15XXHSOcmTE7BTkZs3a2eizquSNEbrpUlfHH7k8tXJu5pt+BQ1Jkeffx +X/K4jWBFw9sRfOqjRwl65elCK4MCrMbrJVL09atgL8N9QF9LSzS4NjrDw6KQcD5uhGO yqLOhcnqJrJ8gt+tnYNmpC2bjNG7BpLOd00wUzKeoep9Uy9vIFnDmPvyCVeQMcmDpQK3 jNeQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-acpi-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-acpi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ee27si7087336edb.168.2021.08.05.14.12.15; Thu, 05 Aug 2021 14:12:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-acpi-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-acpi-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-acpi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241870AbhHEVMX (ORCPT + 4 others); Thu, 5 Aug 2021 17:12:23 -0400 Received: from foss.arm.com ([217.140.110.172]:52408 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241842AbhHEVMX (ORCPT ); Thu, 5 Aug 2021 17:12:23 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 70D3112FC; Thu, 5 Aug 2021 14:12:08 -0700 (PDT) Received: from u200856.usa.arm.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id C821E3F719; Thu, 5 Aug 2021 14:12:07 -0700 (PDT) From: Jeremy Linton To: linux-pci@vger.kernel.org Cc: lorenzo.pieralisi@arm.com, nsaenz@kernel.org, bhelgaas@google.com, rjw@rjwysocki.net, lenb@kernel.org, robh@kernel.org, kw@linux.com, f.fainelli@gmail.com, bcm-kernel-feedback-list@broadcom.com, linux-acpi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rpi-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Jeremy Linton Subject: [PATCH 2/3] PCI: brcmstb: Add ACPI config space quirk Date: Thu, 5 Aug 2021 16:11:59 -0500 Message-Id: <20210805211200.491275-3-jeremy.linton@arm.com> X-Mailer: git-send-email 2.26.3 In-Reply-To: <20210805211200.491275-1-jeremy.linton@arm.com> References: <20210805211200.491275-1-jeremy.linton@arm.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org The PFTF CM4 is an ACPI platform that is following the PCIe SMCCC standard because its PCIe config space isn't ECAM compliant and is split into two parts. One part for the root port registers and a moveable window which points at a given device's 4K config space. Thus it doesn't have a MCFG (and really any MCFG provided would be nonsense anyway). As Linux doesn't support the PCIe SMCCC standard we key off a Linux specific host bridge _DSD to add custom ECAM ops and cfgres. The cfg op selects between those two regions, as well as disallowing problematic accesses, particularly if the link is down because there isn't an attached device. Signed-off-by: Jeremy Linton --- drivers/pci/controller/Makefile | 1 + drivers/pci/controller/pcie-brcmstb-acpi.c | 77 ++++++++++++++++++++++ include/linux/pci-ecam.h | 1 + 3 files changed, 79 insertions(+) create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c -- 2.31.1 diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile index aaf30b3dcc14..65aa6fd3ed89 100644 --- a/drivers/pci/controller/Makefile +++ b/drivers/pci/controller/Makefile @@ -57,5 +57,6 @@ ifdef CONFIG_PCI_QUIRKS obj-$(CONFIG_ARM64) += pci-thunder-ecam.o obj-$(CONFIG_ARM64) += pci-thunder-pem.o obj-$(CONFIG_ARM64) += pci-xgene.o +obj-$(CONFIG_ARM64) += pcie-brcmstb-acpi.o endif endif diff --git a/drivers/pci/controller/pcie-brcmstb-acpi.c b/drivers/pci/controller/pcie-brcmstb-acpi.c new file mode 100644 index 000000000000..76944876155f --- /dev/null +++ b/drivers/pci/controller/pcie-brcmstb-acpi.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * ACPI quirks for Brcm2711 PCIe host controller + * As used on the Raspberry Pi Compute Module 4 + * + * Copyright (C) 2021 Arm Ltd. + */ + +#include +#include +#include +#include +#include "../pci.h" +#include "pcie-brcmstb.h" + +static int brcm_acpi_init(struct pci_config_window *cfg) +{ + /* + * This platform doesn't technically have anything that could be called + * ECAM. Its config region has root port specific registers between + * standard PCIe defined config registers. Thus the region setup by the + * generic ECAM code needs to be adjusted. The HW can access bus 0-ff + * but the footprint isn't a nice power of 2 (40k). For purposes of + * mapping the config region we are just going to squash the standard + * and nonstandard registers together rather than mapping them + * separately. This code simply honors the quirk provided base+size + * instead. + */ + iounmap(cfg->win); + cfg->win = pci_remap_cfgspace(cfg->res.start, resource_size(&cfg->res)); + if (!cfg->win) + goto err_exit; + + /* MSI is nonstandard as well */ + pci_no_msi(); + + return 0; +err_exit: + dev_err(cfg->parent, "PCI: Failed to remap config\n"); + return -ENOMEM; +} + +static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus, unsigned int devfn, + int where) +{ + struct pci_config_window *cfg = bus->sysdata; + void __iomem *base = cfg->win; + int idx; + u32 up; + + /* Accesses to the RC go right to the RC registers if slot==0 */ + if (pci_is_root_bus(bus)) + return PCI_SLOT(devfn) ? NULL : base + where; + + /* Assure link up before sending request */ + up = readl(base + PCIE_MISC_PCIE_STATUS); + if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK)) + return NULL; + + if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK)) + return NULL; + + /* For devices, write to the config space index register */ + idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0); + writel(idx, base + PCIE_EXT_CFG_INDEX); + return base + PCIE_EXT_CFG_DATA + where; +} + +const struct pci_ecam_ops bcm2711_pcie_ops = { + .init = brcm_acpi_init, + .bus_shift = 1, + .pci_ops = { + .map_bus = brcm_pcie_map_conf2, + .read = pci_generic_config_read, + .write = pci_generic_config_write, + } +}; diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h index adea5a4771cf..a5de0285bb7f 100644 --- a/include/linux/pci-ecam.h +++ b/include/linux/pci-ecam.h @@ -87,6 +87,7 @@ extern const struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 * extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */ extern const struct pci_ecam_ops al_pcie_ops; /* Amazon Annapurna Labs PCIe */ extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */ +extern const struct pci_ecam_ops bcm2711_pcie_ops; /* Bcm2711 PCIe */ #endif #if IS_ENABLED(CONFIG_PCI_HOST_COMMON)