From patchwork Thu Aug 6 04:11:12 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gavin Shan X-Patchwork-Id: 6955521 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 B3536C05AC for ; Thu, 6 Aug 2015 04:13:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A8A07206BC for ; Thu, 6 Aug 2015 04:13:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8CF1C206B7 for ; Thu, 6 Aug 2015 04:13:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753957AbbHFEN2 (ORCPT ); Thu, 6 Aug 2015 00:13:28 -0400 Received: from e23smtp05.au.ibm.com ([202.81.31.147]:59248 "EHLO e23smtp05.au.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753764AbbHFENU (ORCPT ); Thu, 6 Aug 2015 00:13:20 -0400 Received: from /spool/local by e23smtp05.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 6 Aug 2015 14:13:18 +1000 Received: from d23dlp03.au.ibm.com (202.81.31.214) by e23smtp05.au.ibm.com (202.81.31.211) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 6 Aug 2015 14:13:15 +1000 X-Helo: d23dlp03.au.ibm.com X-MailFrom: gwshan@linux.vnet.ibm.com X-RcptTo: linux-pci@vger.kernel.org Received: from d23relay09.au.ibm.com (d23relay09.au.ibm.com [9.185.63.181]) by d23dlp03.au.ibm.com (Postfix) with ESMTP id B2CFA357805B; Thu, 6 Aug 2015 14:13:14 +1000 (EST) Received: from d23av01.au.ibm.com (d23av01.au.ibm.com [9.190.234.96]) by d23relay09.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t764D6Z951904718; Thu, 6 Aug 2015 14:13:14 +1000 Received: from d23av01.au.ibm.com (localhost [127.0.0.1]) by d23av01.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t764CbLP001259; Thu, 6 Aug 2015 14:12:42 +1000 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.192.253.14]) by d23av01.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t764CbMP000638; Thu, 6 Aug 2015 14:12:37 +1000 Received: from bran.ozlabs.ibm.com (unknown [9.192.254.114]) by ozlabs.au.ibm.com (Postfix) with ESMTP id 8DD8DA03DD; Thu, 6 Aug 2015 14:11:52 +1000 (AEST) Received: from gwshan (shangw.ozlabs.ibm.com [10.61.2.199]) by bran.ozlabs.ibm.com (Postfix) with ESMTP id 81C40E38F9; Thu, 6 Aug 2015 14:11:52 +1000 (AEST) Received: by gwshan (Postfix, from userid 1000) id 678AF94222F; Thu, 6 Aug 2015 14:11:52 +1000 (AEST) From: Gavin Shan To: linuxppc-dev@lists.ozlabs.org Cc: linux-pci@vger.kernel.org, devicetree@vger.kernel.org, benh@kernel.crashing.org, mpe@ellerman.id.au, bhelgaas@google.com, grant.likely@linaro.org, robherring2@gmail.com, panto@antoniou-consulting.com, aik@ozlabs.ru, Gavin Shan Subject: [PATCH v6 07/42] powerpc/powernv: Improve IO and M32 mapping Date: Thu, 6 Aug 2015 14:11:12 +1000 Message-Id: <1438834307-26960-8-git-send-email-gwshan@linux.vnet.ibm.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1438834307-26960-1-git-send-email-gwshan@linux.vnet.ibm.com> References: <1438834307-26960-1-git-send-email-gwshan@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15080604-0017-0000-0000-000001B1AD10 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 There're 3 windows (IO, M32 and M64) for PHB, root port and upstream port of the PCIE switch behind root port. In order to support PCI hotplug, we extend the start/end address of those 3 windows of root port or upstream port to the start/end address of the 3 PHB's windows. The current implementation, assigning IO or M32 segment based on the bridge's windows, isn't reliable. The patch fixes above issue by calculating PE's consumed IO or M32 segments from its contained devices, no PCI bridge windows involved if the PE doesn't contain all the subordinate PCI buses. Otherwise, the PCI bridge windows still contribute to PE's consumed IO or M32 segments. Signed-off-by: Gavin Shan --- arch/powerpc/platforms/powernv/pci-ioda.c | 136 +++++++++++++++++------------- 1 file changed, 79 insertions(+), 57 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 488a53e..713f4b4 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2844,75 +2844,97 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) } #endif /* CONFIG_PCI_IOV */ -/* - * This function is supposed to be called on basis of PE from top - * to bottom style. So the the I/O or MMIO segment assigned to - * parent PE could be overrided by its child PEs if necessary. - */ -static void pnv_ioda_setup_pe_seg(struct pci_controller *hose, - struct pnv_ioda_pe *pe) +static int pnv_ioda_setup_one_res(struct pci_controller *hose, + struct pnv_ioda_pe *pe, + struct resource *res) { struct pnv_phb *phb = hose->private_data; struct pci_bus_region region; - struct resource *res; - int i, index; - unsigned int segsize; + unsigned int index, segsize; unsigned long *segmap, *pe_segmap; uint16_t win; int64_t rc; - /* - * NOTE: We only care PCI bus based PE for now. For PCI - * device based PE, for example SRIOV sensitive VF should - * be figured out later. - */ - BUG_ON(!(pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL))); + /* Check if we need map the resource */ + if (!res->parent || !res->flags || res->start > res->end) + return 0; - pci_bus_for_each_resource(pe->pbus, res, i) { - if (!res || !res->flags || - res->start > res->end) - continue; + if (res->flags & IORESOURCE_IO) { + region.start = res->start - phb->ioda.io_pci_base; + region.end = res->end - phb->ioda.io_pci_base; + segsize = phb->ioda.io_segsize; + segmap = phb->ioda.io_segmap; + pe_segmap = pe->io_segmap; + win = OPAL_IO_WINDOW_TYPE; + } else if ((res->flags & IORESOURCE_MEM) && + !pnv_pci_is_mem_pref_64(res->flags)) { + region.start = res->start - + hose->mem_offset[0] - + phb->ioda.m32_pci_base; + region.end = res->end - + hose->mem_offset[0] - + phb->ioda.m32_pci_base; + segsize = phb->ioda.m32_segsize; + segmap = phb->ioda.m32_segmap; + pe_segmap = pe->m32_segmap; + win = OPAL_M32_WINDOW_TYPE; + } else { + return 0; + } - if (res->flags & IORESOURCE_IO) { - region.start = res->start - phb->ioda.io_pci_base; - region.end = res->end - phb->ioda.io_pci_base; - segsize = phb->ioda.io_segsize; - segmap = phb->ioda.io_segmap; - pe_segmap = pe->io_segmap; - win = OPAL_IO_WINDOW_TYPE; - } else if ((res->flags & IORESOURCE_MEM) && - !pnv_pci_is_mem_pref_64(res->flags)) { - region.start = res->start - - hose->mem_offset[0] - - phb->ioda.m32_pci_base; - region.end = res->end - - hose->mem_offset[0] - - phb->ioda.m32_pci_base; - segsize = phb->ioda.m32_segsize; - segmap = phb->ioda.m32_segmap; - pe_segmap = pe->m32_segmap; - win = OPAL_M32_WINDOW_TYPE; - } else { - continue; + region.start = _ALIGN_DOWN(region.start, segsize); + region.end = _ALIGN_UP(region.end, segsize); + index = region.start / segsize; + while (index < phb->ioda.total_pe && + region.start < region.end) { + rc = opal_pci_map_pe_mmio_window(phb->opal_id, + pe->pe_number, win, 0, index); + if (rc != OPAL_SUCCESS) { + pr_warn("%s: Error %lld mapping (%d) seg#%d to PHB#%d-PE#%d\n", + __func__, rc, win, index, + pe->phb->hose->global_number, + pe->pe_number); + return -EIO; } - index = region.start / phb->ioda.io_segsize; - while (index < phb->ioda.total_pe && - region.start <= region.end) { - set_bit(index, segmap); - set_bit(index, pe_segmap); - rc = opal_pci_map_pe_mmio_window(phb->opal_id, - pe->pe_number, win, 0, index); - if (rc != OPAL_SUCCESS) { - pr_warn("%s: Error %lld mapping (%d) seg#%d to PHB#%d-PE#%d\n", - __func__, rc, win, index, - pe->phb->hose->global_number, - pe->pe_number); - break; - } + set_bit(index, segmap); + set_bit(index, pe_segmap); + region.start += segsize; + index++; + } + + return 0; +} + +static void pnv_ioda_setup_pe_seg(struct pci_controller *hose, + struct pnv_ioda_pe *pe) +{ + struct pci_dev *pdev; + struct resource *res; + int i; + + /* This function only works for bus dependent PE */ + BUG_ON(!(pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL))); + + list_for_each_entry(pdev, &pe->pbus->devices, bus_list) { + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { + res = &pdev->resource[i]; + if (pnv_ioda_setup_one_res(hose, pe, res)) + return; + } + + /* If the PE contains all subordinate PCI buses, the + * resources of the child bridges should be mapped + * to the PE as well. + */ + if (!(pe->flags & PNV_IODA_PE_BUS_ALL) || + (pdev->class >> 8) != PCI_CLASS_BRIDGE_PCI) + continue; - region.start += segsize; - index++; + for (i = 0; i <= PCI_BRIDGE_RESOURCE_NUM; i++) { + res = &pdev->resource[PCI_BRIDGE_RESOURCES + i]; + if (pnv_ioda_setup_one_res(hose, pe, res)) + return; } } }