From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C1EDC433EF for ; Thu, 11 Nov 2021 15:38:01 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F0DC76109D for ; Thu, 11 Nov 2021 15:38:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org F0DC76109D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.denx.de Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1955B83A5D; Thu, 11 Nov 2021 16:37:13 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="dGmwn8r+"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A3A8683A37; Thu, 11 Nov 2021 16:36:30 +0100 (CET) Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 4715883A5B for ; Thu, 11 Nov 2021 16:36:04 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=kabel@kernel.org Received: by mail.kernel.org (Postfix) with ESMTPSA id EDACF61179; Thu, 11 Nov 2021 15:36:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1636644963; bh=qt4CbWZOCSA4H6RwqJ/LZSaK98rxMhtpI/Y+zTJ/qOw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dGmwn8r+OWAGeQwLo9E2uYpOVMOBNrTuOBAoOzpiCyFKeTkzOHWqCo8dRVZOWh2DI acVqbPEDJO/+5RJ3NfAPwKNE87X/4pTLKn3Svr18JlzASZ6llAYAK0Cz6hb8FMMYic UoCSBLbmaR5GDwy3yiQXqt1r6BkvSqOZp2RTgPRgNipGrHZevueirIKMmdr6ivZ6Mt zlMA1zl3RPPf07x4Lx4OvNPXXUcHyomr3udjBnKyrvhIs0FtmnlOO/GEsoC/9J40PH Q8Qd2WYTBe25EKMeXOhnS9d00VhBBut+Yu9aS2fMoZtOXLgsGMu5Y3qCRq+mNKZ+l9 r8CBEd9O6WMJg== From: =?UTF-8?q?Marek=20Beh=C3=BAn?= To: Stefan Roese Cc: u-boot@lists.denx.de, =?UTF-8?q?Pali=20Roh=C3=A1r?= , =?UTF-8?q?Marek=20Beh=C3=BAn?= Subject: [PATCH u-boot-marvell 09/10] arm: a37xx: pci: Do not allow setting ROM BAR on PCI Bridge Date: Thu, 11 Nov 2021 16:35:48 +0100 Message-Id: <20211111153549.29111-10-kabel@kernel.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211111153549.29111-1-kabel@kernel.org> References: <20211111153549.29111-1-kabel@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean From: Pali Rohár PCI Bridge which represents aardvark PCIe Root Port has Expansion ROM Base Address register at offset 0x30 but its meaning is different than PCI's Expansion ROM BAR register. Only address format of register is same. In reality, this device does not have any configurable PCI BARs. So ensure that write operation into BARs (including Expansion ROM BAR) is noop and registers always contain zero address which indicates that bars are unsupported. Fixes: cb056005dc67 ("arm: a37xx: pci: Add support for accessing PCI Bridge on root bus") Signed-off-by: Pali Rohár Signed-off-by: Marek Behún --- drivers/pci/pci-aardvark.c | 54 +++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c index 8abbc3ffe8..a92f00d0af 100644 --- a/drivers/pci/pci-aardvark.c +++ b/drivers/pci/pci-aardvark.c @@ -202,7 +202,7 @@ struct pcie_advk { int sec_busno; struct udevice *dev; struct gpio_desc reset_gpio; - u32 cfgcache[(0x34 - 0x10) / 4]; + u32 cfgcache[(0x3c - 0x10) / 4]; bool cfgcrssve; }; @@ -389,20 +389,19 @@ static int pcie_advk_read_config(const struct udevice *bus, pci_dev_t bdf, } /* - * The configuration space of the PCI Bridge on primary (local) bus is + * The configuration space of the PCI Bridge on primary (first) bus is * not accessible via PIO transfers like all other PCIe devices. PCI * Bridge config registers are available directly in Aardvark memory - * space starting at offset zero. Moreover PCI Bridge registers in the - * range 0x10 - 0x34 are not available and register 0x38 (Expansion ROM - * Base Address) is at offset 0x30. - * We therefore read configuration space content of the primary PCI - * Bridge from our virtual cache. + * space starting at offset zero. The PCI Bridge config space is of + * Type 0, but the BAR registers (including ROM BAR) don't have the same + * meaning as in the PCIe specification. Therefore do not access BAR + * registers and non-common registers (those which have different + * meaning for Type 0 and Type 1 config space) of the primary PCI Bridge + * and instead read their content from driver virtual cfgcache[]. */ if (busno == pcie->first_busno) { - if (offset >= 0x10 && offset < 0x34) + if ((offset >= 0x10 && offset < 0x34) || (offset >= 0x38 && offset < 0x3c)) data = pcie->cfgcache[(offset - 0x10) / 4]; - else if ((offset & ~3) == PCI_ROM_ADDRESS1) - data = advk_readl(pcie, PCIE_CORE_EXP_ROM_BAR_REG); else data = advk_readl(pcie, offset & ~3); @@ -576,23 +575,22 @@ static int pcie_advk_write_config(struct udevice *bus, pci_dev_t bdf, } /* - * As explained in pcie_advk_read_config(), for the configuration - * space of the primary PCI Bridge, we write the content into virtual - * cache. + * As explained in pcie_advk_read_config(), PCI Bridge config registers + * are available directly in Aardvark memory space starting at offset + * zero. Type 1 specific registers are not available, so we write their + * content only into driver virtual cfgcache[]. */ if (busno == pcie->first_busno) { - if (offset >= 0x10 && offset < 0x34) { + if ((offset >= 0x10 && offset < 0x34) || + (offset >= 0x38 && offset < 0x3c)) { data = pcie->cfgcache[(offset - 0x10) / 4]; data = pci_conv_size_to_32(data, value, offset, size); /* This PCI bridge does not have configurable bars */ if ((offset & ~3) == PCI_BASE_ADDRESS_0 || - (offset & ~3) == PCI_BASE_ADDRESS_1) + (offset & ~3) == PCI_BASE_ADDRESS_1 || + (offset & ~3) == PCI_ROM_ADDRESS1) data = 0x0; pcie->cfgcache[(offset - 0x10) / 4] = data; - } else if ((offset & ~3) == PCI_ROM_ADDRESS1) { - data = advk_readl(pcie, PCIE_CORE_EXP_ROM_BAR_REG); - data = pci_conv_size_to_32(data, value, offset, size); - advk_writel(pcie, data, PCIE_CORE_EXP_ROM_BAR_REG); } else { data = advk_readl(pcie, offset & ~3); data = pci_conv_size_to_32(data, value, offset, size); @@ -830,12 +828,20 @@ static int pcie_advk_setup_hw(struct pcie_advk *pcie) * * Note that this Aardvark PCI Bridge does not have a compliant Type 1 * Configuration Space and it even cannot be accessed via Aardvark's - * PCI config space access method. Something like config space is + * PCI config space access method. Aardvark PCI Bridge Config space is * available in internal Aardvark registers starting at offset 0x0 - * and is reported as Type 0. In range 0x10 - 0x34 it has totally - * different registers. So our driver reports Header Type as Type 1 and - * for the above mentioned range redirects access to the virtual - * cfgcache[] buffer, which avoids changing internal Aardvark registers. + * and has format of Type 0 config space. + * + * Moreover Type 0 BAR registers (ranges 0x10 - 0x28 and 0x30 - 0x34) + * have the same format in Marvell's specification as in PCIe + * specification, but their meaning is totally different (and not even + * the same meaning as explained in the corresponding comment in the + * pci_mvebu driver; aardvark is still different). + * + * So our driver converts Type 0 config space to Type 1 and reports + * Header Type as Type 1. Access to BAR registers and to non-existent + * Type 1 registers is redirected to the virtual cfgcache[] buffer, + * which avoids changing unrelated registers. */ reg = advk_readl(pcie, PCIE_CORE_DEV_REV_REG); reg &= ~0xffffff00; -- 2.32.0