From patchwork Tue Jun 28 08:12:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "dongbo (E)" X-Patchwork-Id: 641404 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3rdzCw2pc5z9s9Z for ; Tue, 28 Jun 2016 18:16:28 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752021AbcF1IQG (ORCPT ); Tue, 28 Jun 2016 04:16:06 -0400 Received: from szxga02-in.huawei.com ([119.145.14.65]:30935 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751980AbcF1IQD (ORCPT ); Tue, 28 Jun 2016 04:16:03 -0400 Received: from 172.24.1.47 (EHLO szxeml426-hub.china.huawei.com) ([172.24.1.47]) by szxrg02-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id DJM14027; Tue, 28 Jun 2016 16:12:40 +0800 (CST) Received: from [127.0.0.1] (10.63.194.120) by szxeml426-hub.china.huawei.com (10.82.67.181) with Microsoft SMTP Server id 14.3.235.1; Tue, 28 Jun 2016 16:12:30 +0800 Subject: [PATCH] Exchange the Assignments of `MEMORYs' and `CFGs/IOs' in Designware PCIe Driver References: <1467100302-221983-1-git-send-email-zhaonenglong@hisilicon.com> To: Pratyush Anand , "jingoohan1@gmail.com" , "bhelgaas@google.com" From: "dongbo (E)" CC: Linuxarm , "linux-kernel@vger.kernel.org" , "linux-pci@vger.kernel.org" , Zhanweitao X-Forwarded-Message-Id: <1467100302-221983-1-git-send-email-zhaonenglong@hisilicon.com> Message-ID: Date: Tue, 28 Jun 2016 16:12:29 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.1.1 MIME-Version: 1.0 In-Reply-To: <1467100302-221983-1-git-send-email-zhaonenglong@hisilicon.com> X-Originating-IP: [10.63.194.120] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090205.5772317B.0045, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 87164758f7d114d05933040204dd315a Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Dong Bo In designware PCIe driver, the iatu0 is used for both CFG and IO accesses. When sending CFGs to peripherals (e.g. lspci), iatu0 frequently switches between CFG and IO alternatively. A MEMORY probably be sent as an IOs by mistake. Considering the following configurations: MEMORY -> BASE_ADDR: 0xb4100000, LIMIT: 0xb4100FFF, TYPE=mem CFG -> BASE_ADDR: 0xb4000000, LIMIT: 0xb4000FFF, TYPE=cfg IO -> BASE_ADDR: 0xFFFFFFFF, LIMIT: 0xFFFFFFFE, TYPE=io Suppose PCIe has just completed a CFG access, to switch back to IO, it set the BASE_ADDR to 0xFFFFFFFF, LIMIT 0xFFFFFFFE and TYPE to io. When another CFG comes, the BASE_ADDR is set to 0xb4000000 to switch to CFG. At this moment, a MEMORY access shows up, since it matches with iatu0 (due to 0xb4000000 <= MEMORY BASE_ADDR <= MEMORY LIMIE <= 0xFFFFFFF), it is treated as an IO access by mistake, then sent to perpheral. This patch fixes the problem by exchanging the assignments of `MEMORYs' and `CFGs/IOs', which assigning MEMEORYs to iatu0, CFGs and IOs to iatu1. Signed-off-by: Dong Bo --- drivers/pci/host/pcie-designware.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) } - dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, + dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, type, cpu_addr, busdev, cfg_size); ret = dw_pcie_cfg_write(va_cfg_base + where, size, val); - dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, + dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, PCIE_ATU_TYPE_IO, pp->io_base, pp->io_bus_addr, pp->io_size); @@ -779,7 +779,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp) * we should not program the ATU here. */ if (!pp->ops->rd_other_conf) - dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, + dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, PCIE_ATU_TYPE_MEM, pp->mem_base, pp->mem_bus_addr, pp->mem_size); -- 1.9.1 . -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index aafd766..1bd88d9 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -599,11 +599,11 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, va_cfg_base = pp->va_cfg1_base; } - dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, + dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, type, cpu_addr, busdev, cfg_size); ret = dw_pcie_cfg_read(va_cfg_base + where, size, val); - dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, + dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, PCIE_ATU_TYPE_IO, pp->io_base, pp->io_bus_addr, pp->io_size); @@ -636,11 +636,11 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, va_cfg_base = pp->va_cfg1_base;