From patchwork Mon Apr 27 06:37:34 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gavin Shan X-Patchwork-Id: 6278011 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 BF8F8BF4A6 for ; Mon, 27 Apr 2015 06:39:08 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C16402041C for ; Mon, 27 Apr 2015 06:39:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B5F302041A for ; Mon, 27 Apr 2015 06:39:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752259AbbD0GjB (ORCPT ); Mon, 27 Apr 2015 02:39:01 -0400 Received: from e23smtp08.au.ibm.com ([202.81.31.141]:58661 "EHLO e23smtp08.au.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752649AbbD0Gi6 (ORCPT ); Mon, 27 Apr 2015 02:38:58 -0400 Received: from /spool/local by e23smtp08.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 27 Apr 2015 16:38:56 +1000 Received: from d23dlp01.au.ibm.com (202.81.31.203) by e23smtp08.au.ibm.com (202.81.31.205) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 27 Apr 2015 16:38:54 +1000 Received: from d23relay09.au.ibm.com (d23relay09.au.ibm.com [9.185.63.181]) by d23dlp01.au.ibm.com (Postfix) with ESMTP id 973BD2CE8040 for ; Mon, 27 Apr 2015 16:38:53 +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 t3R6cj9M9568318 for ; Mon, 27 Apr 2015 16:38:53 +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 t3R6cJw1008923 for ; Mon, 27 Apr 2015 16:38:20 +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 t3R6cJMe008391; Mon, 27 Apr 2015 16:38:19 +1000 Received: from bran.ozlabs.ibm.com (haven.au.ibm.com [9.192.253.15]) by ozlabs.au.ibm.com (Postfix) with ESMTP id 61A58A0266; Mon, 27 Apr 2015 16:37:56 +1000 (AEST) Received: from gwshan (shangw.ozlabs.ibm.com [10.61.2.199]) by bran.ozlabs.ibm.com (Postfix) with ESMTP id 1DB1816AA01; Mon, 27 Apr 2015 16:37:56 +1000 (AEST) Received: by gwshan (Postfix, from userid 1000) id F148F941D0F; Mon, 27 Apr 2015 16:37:55 +1000 (AEST) From: Gavin Shan To: linuxppc-dev@lists.ozlabs.org Cc: linux-pci@vger.kernel.org, benh@kernel.crashing.org, bhelgaas@google.com, Gavin Shan Subject: [PATCH v3 02/21] powerpc/powernv: Enable M64 on P7IOC Date: Mon, 27 Apr 2015 16:37:34 +1000 Message-Id: <1430116673-22500-3-git-send-email-gwshan@linux.vnet.ibm.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1430116673-22500-1-git-send-email-gwshan@linux.vnet.ibm.com> References: <1430116673-22500-1-git-send-email-gwshan@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15042706-0029-0000-0000-00000176F252 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_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 The patch enables M64 window on P7IOC, which has been enabled on PHB3. Comparing to PHB3, there are 16 M64 BARs and each of them are divided to 8 segments. So each PHB can support 128 M64 segments. Also, P7IOC has M64DT, which helps mapping one particular M64 segment# to arbitrary PE#. However, we just provide 128 M64 (16 BARs) segments and fixed mapping between PE# and M64 segment# in order to keep same logic to support M64 for PHB3 and P7IOC. In turn, we just need different phb->init_m64() hooks for P7IOC and PHB3. Signed-off-by: Gavin Shan --- arch/powerpc/platforms/powernv/pci-ioda.c | 115 ++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index f8bc950..646962f 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -165,6 +165,67 @@ static void pnv_ioda_free_pe(struct pnv_phb *phb, int pe) clear_bit(pe, phb->ioda.pe_alloc); } +static int pnv_ioda1_init_m64(struct pnv_phb *phb) +{ + struct resource *r; + int seg; + s64 rc; + + /* Each PHB supports 16 separate M64 BARs, each of which are + * divided into 8 segments. So there are number of M64 segments + * as total PE#, which is 128. + */ + for (seg = 0; seg < phb->ioda.total_pe; seg += 8) { + unsigned long base; + + base = phb->ioda.m64_base + seg * phb->ioda.m64_segsize; + rc = opal_pci_set_phb_mem_window(phb->opal_id, + OPAL_M64_WINDOW_TYPE, + seg / 8, + base, + 0, /* unused */ + 8 * phb->ioda.m64_segsize); + if (rc != OPAL_SUCCESS) { + pr_warn(" Failure %lld configuring M64 BAR#%d on PHB#%d\n", + rc, seg / 8, phb->hose->global_number); + goto fail; + } + + rc = opal_pci_phb_mmio_enable(phb->opal_id, + OPAL_M64_WINDOW_TYPE, + seg / 8, + OPAL_ENABLE_M64_SPLIT); + if (rc != OPAL_SUCCESS) { + pr_warn(" Failure %lld enabling M64 BAR#%d on PHB#%d\n", + rc, seg / 8, phb->hose->global_number); + goto fail; + } + } + + /* Strip of the segment used by the reserved PE, which + * is expected to be 0 or last supported PE# + */ + r = &phb->hose->mem_resources[1]; + if (phb->ioda.reserved_pe == 0) + r->start += phb->ioda.m64_segsize; + else if (phb->ioda.reserved_pe == (phb->ioda.total_pe - 1)) + r->end -= phb->ioda.m64_segsize; + else + pr_warn(" Cannot strip M64 segment for reserved PE#%d\n", + phb->ioda.reserved_pe); + + return 0; + +fail: + for ( ; seg >= 0; seg -= 8) + opal_pci_phb_mmio_enable(phb->opal_id, + OPAL_M64_WINDOW_TYPE, + seg / 8, + OPAL_DISABLE_M64); + + return -EIO; +} + /* The default M64 BAR is shared by all PEs */ static int pnv_ioda2_init_m64(struct pnv_phb *phb) { @@ -222,7 +283,7 @@ fail: return -EIO; } -static void pnv_ioda2_reserve_m64_pe(struct pnv_phb *phb) +static void pnv_ioda_reserve_m64_pe(struct pnv_phb *phb) { resource_size_t sgsz = phb->ioda.m64_segsize; struct pci_dev *pdev; @@ -248,8 +309,8 @@ static void pnv_ioda2_reserve_m64_pe(struct pnv_phb *phb) } } -static int pnv_ioda2_pick_m64_pe(struct pnv_phb *phb, - struct pci_bus *bus, int all) +static int pnv_ioda_pick_m64_pe(struct pnv_phb *phb, + struct pci_bus *bus, int all) { resource_size_t segsz = phb->ioda.m64_segsize; struct pci_dev *pdev; @@ -346,6 +407,28 @@ done: pe->master = master_pe; list_add_tail(&pe->list, &master_pe->slaves); } + + /* P7IOC supports M64DT, which helps mapping M64 segment + * to one particular PE#. Unfortunately, PHB3 has fixed + * mapping between M64 segment and PE#. In order for same + * logic for P7IOC and PHB3, we enforce fixed mapping + * between M64 segment and PE# on P7IOC. + */ + if (phb->type == PNV_PHB_IODA1) { + int64_t rc; + + rc = opal_pci_map_pe_mmio_window(phb->opal_id, + pe->pe_number, + OPAL_M64_WINDOW_TYPE, + pe->pe_number / 8, + pe->pe_number % 8); + if (rc != OPAL_SUCCESS) + pr_warn("%s: Failure %lld mapping " + "M64 for PHB#%d-PE#%d\n", + __func__, rc, + phb->hose->global_number, + pe->pe_number); + } } kfree(pe_alloc); @@ -360,12 +443,6 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb) const u32 *r; u64 pci_addr; - /* FIXME: Support M64 for P7IOC */ - if (phb->type != PNV_PHB_IODA2) { - pr_info(" Not support M64 window\n"); - return; - } - if (!firmware_has_feature(FW_FEATURE_OPALv3)) { pr_info(" Firmware too old to support M64 window\n"); return; @@ -394,9 +471,23 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb) /* Use last M64 BAR to cover M64 window */ phb->ioda.m64_bar_idx = 15; - phb->init_m64 = pnv_ioda2_init_m64; - phb->reserve_m64_pe = pnv_ioda2_reserve_m64_pe; - phb->pick_m64_pe = pnv_ioda2_pick_m64_pe; + phb->reserve_m64_pe = pnv_ioda_reserve_m64_pe; + phb->pick_m64_pe = pnv_ioda_pick_m64_pe; + switch (phb->type) { + case PNV_PHB_IODA1: + phb->init_m64 = pnv_ioda1_init_m64; + break; + case PNV_PHB_IODA2: + phb->init_m64 = pnv_ioda2_init_m64; + break; + default: + phb->init_m64 = NULL; + phb->reserve_m64_pe = NULL; + phb->pick_m64_pe = NULL; + phb->ioda.m64_size = 0; + phb->ioda.m64_segsize = 0; + phb->ioda.m64_base = 0; + } } static void pnv_ioda_freeze_pe(struct pnv_phb *phb, int pe_no)