From patchwork Wed Apr 7 06:43:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Roese X-Patchwork-Id: 1463185 X-Patchwork-Delegate: daniel.schwierzeck@googlemail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=denx.de header.i=@denx.de header.a=rsa-sha256 header.s=phobos-20191101 header.b=PXmuTAgz; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FFZc75f87z9sWY for ; Wed, 7 Apr 2021 16:43:51 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 3E79A8039D; Wed, 7 Apr 2021 08:43:48 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1617777828; bh=o979egc6739Iss6GmEQb0odtq0P8le3e5z6NU56+kOc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=PXmuTAgzmgQtGaIK215/077Lneyr01lEvWpKrCI/BnOQkCEwllVvYAMjLv/3DK3dw Y2jJTFQcwp5Gk6SiBEPpCQmtHaMzVoa0aZpHbr0wMlPDFNnCprDs2vxGGKy2vW6lYg EzlbcuZsJfiQs51BMg1pZRUG8ZxkvIF/yEoLINsesgPTNZENnx57Db1zItf2yJ/QR0 Qf2j4Lhcl2hf6AC6Y6gt+6A+d3RYBhhB5f9s0llH1OWKvaDjwqZBQXRN3eqUTISI7Q Mit2C6HcNJIsElMO920f5CxnF6scuUXr+Trj8BRXiHQcJsUu7iDU0LlN7lPGaVA7sH qYfDzUHbro3Rg== Received: by phobos.denx.de (Postfix, from userid 109) id 9C0CC80433; Wed, 7 Apr 2021 08:43:46 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from mout-u-107.mailbox.org (mout-u-107.mailbox.org [IPv6:2001:67c:2050:1::465:107]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 6766E801FC for ; Wed, 7 Apr 2021 08:43:43 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: phobos.denx.de; spf=none smtp.mailfrom=sr@denx.de Received: from smtp2.mailbox.org (smtp2.mailbox.org [IPv6:2001:67c:2050:105:465:1:2:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-u-107.mailbox.org (Postfix) with ESMTPS id 4FFZbz1FzFzQjbM; Wed, 7 Apr 2021 08:43:43 +0200 (CEST) Received: from smtp2.mailbox.org ([80.241.60.241]) by spamfilter04.heinlein-hosting.de (spamfilter04.heinlein-hosting.de [80.241.56.122]) (amavisd-new, port 10030) with ESMTP id BSy2VenlJ79d; Wed, 7 Apr 2021 08:43:36 +0200 (CEST) From: Stefan Roese To: u-boot@lists.denx.de Cc: Aaron Williams , Chandrakala Chavva , Daniel Schwierzeck Subject: [PATCH v2 49/50] mips: octeon: Add Octeon PCIe host controller driver Date: Wed, 7 Apr 2021 08:43:35 +0200 Message-Id: <20210407064335.525254-1-sr@denx.de> In-Reply-To: <20201211160612.1498780-50-sr@denx.de> References: <20201211160612.1498780-50-sr@denx.de> MIME-Version: 1.0 X-MBO-SPAM-Probability: X-Rspamd-Score: -0.04 / 15.00 / 15.00 X-Rspamd-Queue-Id: 1A6251801 X-Rspamd-UID: caa76a 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.102.4 at phobos.denx.de X-Virus-Status: Clean This patch adds the PCIe host controller driver for MIPS Octeon II/III. The driver mainly consist of the PCI config functions, as all of the complex serdes related port / lane setup, is done in the serdes / pcie code available in the "arch/mips/mach-octeon" directory. Signed-off-by: Stefan Roese Cc: Aaron Williams Cc: Chandrakala Chavva Cc: Daniel Schwierzeck --- I'm sending only this patch from the serdes / QLM series with the PCIe support, as it's the only one that has some changes. To not "pollute" the list with this huge series without need. Please let me know if I should post the complete series again to the list or provide a gitlab branch. v2: - Rebased on top of latest master - Changed priv_auto_alloc_size to priv_auto drivers/pci/Kconfig | 6 ++ drivers/pci/Makefile | 1 + drivers/pci/pcie_octeon.c | 159 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 drivers/pci/pcie_octeon.c diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index ba41787f64dc..0b2daeac23b6 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -158,6 +158,12 @@ config PCI_OCTEONTX These controllers provide PCI configuration access to all on-board peripherals so it should only be disabled for testing purposes +config PCIE_OCTEON + bool "MIPS Octeon PCIe support" + depends on ARCH_OCTEON + help + Enable support for the MIPS Octeon SoC family PCIe controllers. + config PCI_XILINX bool "Xilinx AXI Bridge for PCI Express" depends on DM_PCI diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 5ed94bc95c27..dc04d1c7d675 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -51,3 +51,4 @@ obj-$(CONFIG_PCIE_ROCKCHIP) += pcie_rockchip.o obj-$(CONFIG_PCIE_DW_ROCKCHIP) += pcie_dw_rockchip.o obj-$(CONFIG_PCI_BRCMSTB) += pcie_brcmstb.o obj-$(CONFIG_PCI_OCTEONTX) += pci_octeontx.o +obj-$(CONFIG_PCIE_OCTEON) += pcie_octeon.o diff --git a/drivers/pci/pcie_octeon.c b/drivers/pci/pcie_octeon.c new file mode 100644 index 000000000000..3b28bd81439f --- /dev/null +++ b/drivers/pci/pcie_octeon.c @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Stefan Roese + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct octeon_pcie { + void *base; + int first_busno; + u32 port; + struct udevice *dev; + int pcie_port; +}; + +static bool octeon_bdf_invalid(pci_dev_t bdf, int first_busno) +{ + /* + * In PCIe only a single device (0) can exist on the local bus. + * Beyound the local bus, there might be a switch and everything + * is possible. + */ + if ((PCI_BUS(bdf) == first_busno) && (PCI_DEV(bdf) > 0)) + return true; + + return false; +} + +static int pcie_octeon_write_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct octeon_pcie *pcie = dev_get_priv(bus); + struct pci_controller *hose = dev_get_uclass_priv(bus); + int busno; + int port; + + debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ", + PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); + debug("(addr,size,val)=(0x%04x, %d, 0x%08lx)\n", offset, size, value); + + port = pcie->pcie_port; + busno = PCI_BUS(bdf) - hose->first_busno + 1; + + switch (size) { + case PCI_SIZE_8: + cvmx_pcie_config_write8(port, busno, PCI_DEV(bdf), + PCI_FUNC(bdf), offset, value); + break; + case PCI_SIZE_16: + cvmx_pcie_config_write16(port, busno, PCI_DEV(bdf), + PCI_FUNC(bdf), offset, value); + break; + case PCI_SIZE_32: + cvmx_pcie_config_write32(port, busno, PCI_DEV(bdf), + PCI_FUNC(bdf), offset, value); + break; + default: + printf("Invalid size\n"); + }; + + return 0; +} + +static int pcie_octeon_read_config(const struct udevice *bus, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + struct octeon_pcie *pcie = dev_get_priv(bus); + struct pci_controller *hose = dev_get_uclass_priv(bus); + int busno; + int port; + + port = pcie->pcie_port; + busno = PCI_BUS(bdf) - hose->first_busno + 1; + if (octeon_bdf_invalid(bdf, pcie->first_busno)) { + *valuep = pci_get_ff(size); + return 0; + } + + switch (size) { + case PCI_SIZE_8: + *valuep = cvmx_pcie_config_read8(port, busno, PCI_DEV(bdf), + PCI_FUNC(bdf), offset); + break; + case PCI_SIZE_16: + *valuep = cvmx_pcie_config_read16(port, busno, PCI_DEV(bdf), + PCI_FUNC(bdf), offset); + break; + case PCI_SIZE_32: + *valuep = cvmx_pcie_config_read32(port, busno, PCI_DEV(bdf), + PCI_FUNC(bdf), offset); + break; + default: + printf("Invalid size\n"); + }; + + debug("%02x.%02x.%02x: u%d %x -> %lx\n", + PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), size, offset, *valuep); + + return 0; +} + +static int pcie_octeon_probe(struct udevice *dev) +{ + struct octeon_pcie *pcie = dev_get_priv(dev); + int node = cvmx_get_node_num(); + int pcie_port; + int ret = 0; + + /* Get port number, lane number and memory target / attr */ + if (ofnode_read_u32(dev_ofnode(dev), "marvell,pcie-port", + &pcie->port)) { + ret = -ENODEV; + goto err; + } + + pcie->first_busno = dev_seq(dev); + pcie_port = ((node << 4) | pcie->port); + ret = cvmx_pcie_rc_initialize(pcie_port); + if (ret != 0) + return ret; + + return 0; + +err: + return ret; +} + +static const struct dm_pci_ops pcie_octeon_ops = { + .read_config = pcie_octeon_read_config, + .write_config = pcie_octeon_write_config, +}; + +static const struct udevice_id pcie_octeon_ids[] = { + { .compatible = "marvell,pcie-host-octeon" }, + { } +}; + +U_BOOT_DRIVER(pcie_octeon) = { + .name = "pcie_octeon", + .id = UCLASS_PCI, + .of_match = pcie_octeon_ids, + .ops = &pcie_octeon_ops, + .probe = pcie_octeon_probe, + .priv_auto = sizeof(struct octeon_pcie), + .flags = DM_FLAG_PRE_RELOC, +};