From patchwork Wed Feb 14 17:25:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: igall@marvell.com X-Patchwork-Id: 873441 X-Patchwork-Delegate: sr@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3zhRGS0hkkz9t3M for ; Thu, 15 Feb 2018 04:29:02 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 4D143C220AA; Wed, 14 Feb 2018 17:28:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id E6D82C22061; Wed, 14 Feb 2018 17:28:24 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 1109EC22061; Wed, 14 Feb 2018 17:27:59 +0000 (UTC) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by lists.denx.de (Postfix) with ESMTPS id B1191C21E76 for ; Wed, 14 Feb 2018 17:27:55 +0000 (UTC) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w1EHPjSQ006257; Wed, 14 Feb 2018 09:27:49 -0800 Received: from sc-exch02.marvell.com ([199.233.58.182]) by mx0b-0016f401.pphosted.com with ESMTP id 2g24f31cr9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 14 Feb 2018 09:27:48 -0800 Received: from IL-EXCH03.marvell.com (10.5.102.220) by SC-EXCH02.marvell.com (10.93.176.82) with Microsoft SMTP Server (TLS) id 15.0.1210.3; Wed, 14 Feb 2018 09:27:46 -0800 Received: from SC-EXCH02.marvell.com (10.93.176.82) by IL-EXCH03.marvell.com (10.5.102.220) with Microsoft SMTP Server (TLS) id 15.0.1210.3; Wed, 14 Feb 2018 19:27:43 +0200 Received: from maili.marvell.com (10.93.176.43) by SC-EXCH02.marvell.com (10.93.176.82) with Microsoft SMTP Server id 15.0.1210.3 via Frontend Transport; Wed, 14 Feb 2018 09:27:43 -0800 Received: from igall-OptiPlex-990.pt.marvell.com (unknown [10.5.24.64]) by maili.marvell.com (Postfix) with ESMTP id 706E53F703F; Wed, 14 Feb 2018 09:27:41 -0800 (PST) From: To: Date: Wed, 14 Feb 2018 19:25:23 +0200 Message-ID: <1518629123-7889-1-git-send-email-igall@marvell.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-02-14_07:, , signatures=0 X-Proofpoint-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1802140205 Cc: nadavh@marvell.com, neta@marvell.com, sr@denx.de, Igal Liberman Subject: [U-Boot] [PATCH] dm: pcie: designware: add correct ATU handling X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" From: Igal Liberman Currently, ATU (address translation unit) implementation doesn't support translate addresses > 32 bits. This patch allows to configure ATU correctly for different memory accesses (memory, configuration and IO). The same approach is used in Linux Kernel. Signed-off-by: Igal Liberman --- drivers/pci/pcie_dw_mvebu.c | 91 +++++++++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c index a198855..a0032b7 100644 --- a/drivers/pci/pcie_dw_mvebu.c +++ b/drivers/pci/pcie_dw_mvebu.c @@ -111,6 +111,10 @@ struct pcie_dw_mvebu { void *cfg_base; fdt_size_t cfg_size; int first_busno; + + /* IO and MEM PCI regions */ + struct pci_region io; + struct pci_region mem; }; static int pcie_dw_get_link_speed(const void *regs_base) @@ -126,6 +130,34 @@ static int pcie_dw_get_link_width(const void *regs_base) } /** + * pcie_dw_prog_outbound_atu() - Configure ATU for outbound accesses + * + * @pcie: Pointer to the PCI controller state + * @index: ATU region index + * @type: ATU accsess type + * @cpu_addr: the physical address for the translation entry + * @pci_addr: the pcie bus address for the translation entry + * @size: the size of the translation entry + */ +static void pcie_dw_prog_outbound_atu(struct pcie_dw_mvebu *pcie, int index, + int type, u64 cpu_addr, u64 pci_addr, + u32 size) +{ + writel(PCIE_ATU_REGION_OUTBOUND | index, + pcie->ctrl_base + PCIE_ATU_VIEWPORT); + writel(lower_32_bits(cpu_addr), pcie->ctrl_base + PCIE_ATU_LOWER_BASE); + writel(upper_32_bits(cpu_addr), pcie->ctrl_base + PCIE_ATU_UPPER_BASE); + writel(lower_32_bits(cpu_addr + size - 1), + pcie->ctrl_base + PCIE_ATU_LIMIT); + writel(lower_32_bits(pci_addr), + pcie->ctrl_base + PCIE_ATU_LOWER_TARGET); + writel(upper_32_bits(pci_addr), + pcie->ctrl_base + PCIE_ATU_UPPER_TARGET); + writel(type, pcie->ctrl_base + PCIE_ATU_CR1); + writel(PCIE_ATU_ENABLE, pcie->ctrl_base + PCIE_ATU_CR2); +} + +/** * set_cfg_address() - Configure the PCIe controller config space access * * @pcie: Pointer to the PCI controller state @@ -143,27 +175,29 @@ static uintptr_t set_cfg_address(struct pcie_dw_mvebu *pcie, pci_dev_t d, uint where) { uintptr_t va_address; + u32 atu_type; /* * Region #0 is used for Outbound CFG space access. * Direction = Outbound * Region Index = 0 */ - writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT); if (PCI_BUS(d) == (pcie->first_busno + 1)) /* For local bus, change TLP Type field to 4. */ - writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1); + atu_type = PCIE_ATU_TYPE_CFG0; else /* Otherwise, change TLP Type field to 5. */ - writel(PCIE_ATU_TYPE_CFG1, pcie->ctrl_base + PCIE_ATU_CR1); + atu_type = PCIE_ATU_TYPE_CFG1; if (PCI_BUS(d) == pcie->first_busno) { /* Accessing root port configuration space. */ va_address = (uintptr_t)pcie->ctrl_base; } else { d = PCI_MASK_BUS(d) | (PCI_BUS(d) - pcie->first_busno); - writel(d << 8, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET); + pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX0, + atu_type, (u64)pcie->cfg_base, + d << 8, pcie->cfg_size); va_address = (uintptr_t)pcie->cfg_base; } @@ -231,6 +265,10 @@ static int pcie_dw_mvebu_read_config(struct udevice *bus, pci_dev_t bdf, debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); *valuep = pci_conv_32_to_size(value, offset, size); + pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX0, + PCIE_ATU_TYPE_IO, pcie->io.phys_start, + pcie->io.bus_start, pcie->io.size); + return 0; } @@ -272,6 +310,10 @@ static int pcie_dw_mvebu_write_config(struct udevice *bus, pci_dev_t bdf, value = pci_conv_size_to_32(old, value, offset, size); writel(value, va_address); + pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX0, + PCIE_ATU_TYPE_IO, pcie->io.phys_start, + pcie->io.bus_start, pcie->io.size); + return 0; } @@ -388,34 +430,6 @@ static int pcie_dw_mvebu_pcie_link_up(const void *regs_base, u32 cap_speed) } /** - * pcie_dw_regions_setup() - iATU region setup - * - * @pcie: Pointer to the PCI controller state - * - * Configure the iATU regions in the PCIe controller for outbound access. - */ -static void pcie_dw_regions_setup(struct pcie_dw_mvebu *pcie) -{ - /* - * Region #0 is used for Outbound CFG space access. - * Direction = Outbound - * Region Index = 0 - */ - writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT); - - writel((u32)(uintptr_t)pcie->cfg_base, pcie->ctrl_base - + PCIE_ATU_LOWER_BASE); - writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_BASE); - writel((u32)(uintptr_t)pcie->cfg_base + pcie->cfg_size, - pcie->ctrl_base + PCIE_ATU_LIMIT); - - writel(0, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET); - writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_TARGET); - writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1); - writel(PCIE_ATU_ENABLE, pcie->ctrl_base + PCIE_ATU_CR2); -} - -/** * pcie_dw_set_host_bars() - Configure the host BARs * * @regs_base: A pointer to the PCIe controller registers @@ -495,7 +509,18 @@ static int pcie_dw_mvebu_probe(struct udevice *dev) hose->first_busno); } - pcie_dw_regions_setup(pcie); + /* Store the IO and MEM windows settings for future use by the ATU */ + pcie->io.phys_start = hose->regions[0].phys_start; /* IO base */ + pcie->io.bus_start = hose->regions[0].bus_start; /* IO_bus_addr */ + pcie->io.size = hose->regions[0].size; /* IO size */ + + pcie->mem.phys_start = hose->regions[1].phys_start; /* MEM base */ + pcie->mem.bus_start = hose->regions[1].bus_start; /* MEM_bus_addr */ + pcie->mem.size = hose->regions[1].size; /* MEM size */ + + pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX1, + PCIE_ATU_TYPE_MEM, pcie->mem.phys_start, + pcie->mem.bus_start, pcie->mem.size); /* Set the CLASS_REV of RC CFG header to PCI_CLASS_BRIDGE_PCI */ clrsetbits_le32(pcie->ctrl_base + PCI_CLASS_REVISION,