From patchwork Mon Aug 8 12:56:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Nowicki X-Patchwork-Id: 9268279 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 71ED960754 for ; Mon, 8 Aug 2016 12:59:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5BB7127FA9 for ; Mon, 8 Aug 2016 12:59:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4CBED2838D; Mon, 8 Aug 2016 12:59:50 +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=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B251327FA9 for ; Mon, 8 Aug 2016 12:59:49 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bWk8K-0003Kn-Nl; Mon, 08 Aug 2016 12:58:20 +0000 Received: from mail-wm0-x236.google.com ([2a00:1450:400c:c09::236]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1bWk7h-00035i-DF for linux-arm-kernel@lists.infradead.org; Mon, 08 Aug 2016 12:57:44 +0000 Received: by mail-wm0-x236.google.com with SMTP id q128so117549170wma.1 for ; Mon, 08 Aug 2016 05:57:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=2c4AQLKIdhxMC+YkTcDTl3btcgSQcl0evHLiOJ3VlwE=; b=xPaNr4HxRMjhAa/6Q3na4qm/1uXaJ/ifkKxMPyRcfuq6EffO4fHG09XltI63b5Vs52 eeL/bpUg9g3cvXFmOXI0H8VLOVsYcTSzKgdoWZ5iYmj2Tn53BcNHLUKBEUQRaTqKO/Fp c9zvto+RGI1w9YomCn4GhaBx0DVRDkwYzAJbUM/HKM+tUc/pzomUrbPiL5mMt4wmk9Fr DMn3Wl3ky3+1euFEZMNPJHuoeq7BV9O048VuhPHKtKvv2YLPLxCHBHMEIlo91POagoOf UxmFvWy9V2yaGZagfFfu/ZlOPzoc1fhj8VVEbv9FDtgDWSwgMwY/UyrxVkJbciB0Ns8O rdMA== 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:in-reply-to :references; bh=2c4AQLKIdhxMC+YkTcDTl3btcgSQcl0evHLiOJ3VlwE=; b=bHLhPGmkpUGf6Z7h1SRMqcQOGSwQe2csEq8cW0OvajaNqpNa0XsnN9PsiEK1BVldMa FErobJDnSMr9eRRA1SJ/Zbbd2ISuoIypRNUGsiBeXDBs6AgyN1HwuGITJthToE5+dRSX eWYA8tT3Vpz9SCxGQCiYzJrw1TADUkq7faurLYHauBC+uULJbPKqiBRH4AEO+Wom/bh6 2nkYDieaSagoE9jalXC6yewsbkh5Ev4LlSyKPxZpflXJpC7xplHzAFArVJpX/BP1c3e1 XgO29VLhl8w5d4/8i/IKa68kUAPSQQc6Wfp2YJ41+OyWONqy+6M+kTq2CZZtlCdrKmSI eVhw== X-Gm-Message-State: AEkooutyB1XVzvC/2z9GO5jGkkCWfK3iLe/pzd+uyUeB2r7o6556dm1V7C5gx8j60Bl2Vw== X-Received: by 10.46.1.224 with SMTP id f93mr25927651lji.44.1470661039264; Mon, 08 Aug 2016 05:57:19 -0700 (PDT) Received: from tn-HP-4.semihalf.local (31-172-191-173.noc.fibertech.net.pl. [31.172.191.173]) by smtp.gmail.com with ESMTPSA id k63sm5708186lfe.48.2016.08.08.05.57.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 08 Aug 2016 05:57:18 -0700 (PDT) From: Tomasz Nowicki To: helgaas@kernel.org, arnd@arndb.de, will.deacon@arm.com, catalin.marinas@arm.com, rafael@kernel.org, Lorenzo.Pieralisi@arm.com Subject: [RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks Date: Mon, 8 Aug 2016 14:56:40 +0200 Message-Id: <1470661002-26213-4-git-send-email-tn@semihalf.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1470661002-26213-1-git-send-email-tn@semihalf.com> References: <1470661002-26213-1-git-send-email-tn@semihalf.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160808_055741_975698_3F8AEA88 X-CRM114-Status: GOOD ( 18.65 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gabriele.paoloni@huawei.com, linaro-acpi@lists.linaro.org, linux-pci@vger.kernel.org, Liviu.Dudau@arm.com, okaya@codeaurora.org, wangyijing@huawei.com, andrea.gallo@linaro.org, jhugo@codeaurora.org, Tomasz Nowicki , ddaney@caviumnetworks.com, robert.richter@caviumnetworks.com, liudongdong3@huawei.com, msalter@redhat.com, jcm@redhat.com, cov@codeaurora.org, mw@semihalf.com, linux-arm-kernel@lists.infradead.org, jchandra@broadcom.com, ard.biesheuvel@linaro.org, dhdang@apm.com, jeremy.linton@arm.com, hanjun.guo@linaro.org MIME-Version: 1.0 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 Some platforms may not be fully compliant with generic set of PCI config accessors. For these cases we implement the way to overwrite accessors set. Algorithm traverses available quirk list (static array), matches against and returns pci_config_window structure with fancy PCI config ops. oem_id, oem_table_id and rev come from MCFG table standard header. It is possible to define custom init call which is responsible for setting up PCI configuration access accordingly to quirk requirements. If custom init call is not defined, use standard pci_acpi_setup_ecam_mapping(). pci_generic_ecam_ops will be used for platforms free from quirks. Signed-off-by: Tomasz Nowicki Signed-off-by: Dongdong Liu Signed-off-by: Christopher Covington --- drivers/pci/host/Makefile | 1 + drivers/pci/host/mcfg-quirks.c | 86 ++++++++++++++++++++++++++++++++++++++++++ drivers/pci/host/mcfg-quirks.h | 20 ++++++++++ include/linux/pci-acpi.h | 2 + 4 files changed, 109 insertions(+) create mode 100644 drivers/pci/host/mcfg-quirks.c create mode 100644 drivers/pci/host/mcfg-quirks.h diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 8843410..500cf78 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -31,3 +31,4 @@ obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o +obj-$(CONFIG_ACPI_MCFG) += mcfg-quirks.o diff --git a/drivers/pci/host/mcfg-quirks.c b/drivers/pci/host/mcfg-quirks.c new file mode 100644 index 0000000..aa9907b --- /dev/null +++ b/drivers/pci/host/mcfg-quirks.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2016 Semihalf + * Author: Tomasz Nowicki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation (the "GPL"). + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 (GPLv2) for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 (GPLv2) along with this source code. + */ + +#include +#include +#include +#include +#include + +#include "mcfg-quirks.h" + +struct pci_cfg_fixup { + char oem_id[ACPI_OEM_ID_SIZE + 1]; + char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; + u32 oem_revision; + struct resource domain_range; + struct resource bus_range; + struct pci_ops *ops; + struct pci_config_window *(*init)(struct acpi_pci_root *root, + struct pci_ops *ops); +}; + +#define MCFG_DOM_RANGE(start, end) DEFINE_RES_NAMED((start), \ + ((end) - (start) + 1), NULL, 0) +#define MCFG_DOM_ANY MCFG_DOM_RANGE(0x0, 0xffff) +#define MCFG_BUS_RANGE(start, end) DEFINE_RES_NAMED((start), \ + ((end) - (start) + 1), \ + NULL, IORESOURCE_BUS) +#define MCFG_BUS_ANY MCFG_BUS_RANGE(0x0, 0xff) + +static struct pci_cfg_fixup mcfg_quirks[] __initconst = { +/* { OEM_ID, OEM_TABLE_ID, REV, DOMAIN, BUS_RANGE, pci_ops, init_hook }, */ +}; + +static bool pci_mcfg_fixup_match(struct pci_cfg_fixup *f, + struct acpi_table_header *mcfg_header) +{ + return (!memcmp(f->oem_id, mcfg_header->oem_id, ACPI_OEM_ID_SIZE) && + !memcmp(f->oem_table_id, mcfg_header->oem_table_id, + ACPI_OEM_TABLE_ID_SIZE) && + f->oem_revision == mcfg_header->oem_revision); +} + +struct pci_config_window *pci_mcfg_match_quirks(struct acpi_pci_root *root) +{ + struct resource dom_res = MCFG_DOM_RANGE(root->segment, root->segment); + struct resource *bus_res = &root->secondary; + struct pci_cfg_fixup *f = mcfg_quirks; + struct acpi_table_header *mcfg_header; + acpi_status status; + int i; + + status = acpi_get_table(ACPI_SIG_MCFG, 0, &mcfg_header); + if (ACPI_FAILURE(status)) + return NULL; + + /* + * First match against PCI topology then use OEM ID, OEM + * table ID, and OEM revision from MCFG table standard header. + */ + for (i = 0; i < ARRAY_SIZE(mcfg_quirks); i++, f++) { + if (resource_contains(&f->domain_range, &dom_res) && + resource_contains(&f->bus_range, bus_res) && + pci_mcfg_fixup_match(f, mcfg_header)) { + dev_info(&root->device->dev, "Applying PCI MCFG quirks for %s %s rev: %d\n", + f->oem_id, f->oem_table_id, f->oem_revision); + return f->init ? f->init(root, f->ops) : + pci_acpi_setup_ecam_mapping(root, f->ops); + } + } + return pci_acpi_setup_ecam_mapping(root, &pci_generic_ecam_ops.pci_ops); +} diff --git a/drivers/pci/host/mcfg-quirks.h b/drivers/pci/host/mcfg-quirks.h new file mode 100644 index 0000000..45cbd16 --- /dev/null +++ b/drivers/pci/host/mcfg-quirks.h @@ -0,0 +1,20 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation (the "GPL"). + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 (GPLv2) for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 (GPLv2) along with this source code. + */ + +#ifndef __MCFG_QUIRKS_H__ +#define __MCFG_QUIRKS_H__ + +/* MCFG quirks initialize call list */ + +#endif /* __MCFG_QUIRKS_H__ */ diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index e9bfe00..28cdce4 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h @@ -25,6 +25,8 @@ static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle); extern phys_addr_t pci_mcfg_lookup(u16 domain, struct resource *bus_res); +extern struct pci_config_window * +pci_mcfg_match_quirks(struct acpi_pci_root *root); extern struct pci_config_window * pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root, struct pci_ops *ops);