From owner-dev-commits-src-branches@freebsd.org Tue Sep 7 12:09:42 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 5E1D36624CF; Tue, 7 Sep 2021 12:09:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4H3kbT6jjMz4rb6; Tue, 7 Sep 2021 12:09:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 2486211FE7; Tue, 7 Sep 2021 12:09:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 187C9f0P087228; Tue, 7 Sep 2021 12:09:41 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 187C9f8t087227; Tue, 7 Sep 2021 12:09:41 GMT (envelope-from git) Date: Tue, 7 Sep 2021 12:09:41 GMT Message-Id: <202109071209.187C9f8t087227@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Jessica Clarke Subject: git: 982d709cdc25 - stable/13 - pci_dw: Support multiple memory windows MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jrtc27 X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 982d709cdc25757f0cd39c3f7f4fa7ecc73470a6 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Sep 2021 12:09:42 -0000 The branch stable/13 has been updated by jrtc27: URL: https://cgit.FreeBSD.org/src/commit/?id=982d709cdc25757f0cd39c3f7f4fa7ecc73470a6 commit 982d709cdc25757f0cd39c3f7f4fa7ecc73470a6 Author: Jessica Clarke AuthorDate: 2021-07-21 04:50:24 +0000 Commit: Jessica Clarke CommitDate: 2021-09-07 12:06:47 +0000 pci_dw: Support multiple memory windows Currently we assume there is only one memory and one prefetch memory window, and ignore the latter. However, the SiFive FU740 has two normal memory windows. As part of this, the viewports are rearranged. Previously the viewports were memory, config then optionally I/O. Both to simplify the config index calculation and to ensure it can always be mapped even if we have too many memory windows for the number of viewports, config is moved to being the first viewport. This generalisation now also naturally supports mapping prefetch memory windows. Reviewed by: mmel MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D31028 (cherry picked from commit f8c1701f23b5b99365ffab2a067e4676b905ab57) --- sys/dev/pci/pci_dw.c | 108 +++++++++++++++++++++++++++++---------------------- sys/dev/pci/pci_dw.h | 4 +- 2 files changed, 63 insertions(+), 49 deletions(-) diff --git a/sys/dev/pci/pci_dw.c b/sys/dev/pci/pci_dw.c index f0aae5bf8418..e4211a70a80b 100644 --- a/sys/dev/pci/pci_dw.c +++ b/sys/dev/pci/pci_dw.c @@ -204,7 +204,7 @@ static int pci_dw_setup_hw(struct pci_dw_softc *sc) { uint32_t reg; - int rv; + int rv, i; pci_dw_dbi_protect(sc, false); @@ -222,21 +222,25 @@ pci_dw_setup_hw(struct pci_dw_softc *sc) PCIM_CMD_BUSMASTEREN | PCIM_CMD_SERRESPEN); pci_dw_dbi_protect(sc, true); - /* Setup outbound memory window */ - rv = pci_dw_map_out_atu(sc, 0, IATU_CTRL1_TYPE_MEM, - sc->mem_range.host, sc->mem_range.pci, sc->mem_range.size); - if (rv != 0) - return (rv); + /* Setup outbound memory windows */ + for (i = 0; i < min(sc->num_mem_ranges, sc->num_viewport - 1); ++i) { + rv = pci_dw_map_out_atu(sc, i + 1, IATU_CTRL1_TYPE_MEM, + sc->mem_ranges[i].host, sc->mem_ranges[i].pci, + sc->mem_ranges[i].size); + if (rv != 0) + return (rv); + } - /* If we have enouht viewports ..*/ - if (sc->num_viewport >= 3 && sc->io_range.size != 0) { + /* If we have enough viewports ..*/ + if (sc->num_mem_ranges + 1 < sc->num_viewport && + sc->io_range.size != 0) { /* Setup outbound I/O window */ - rv = pci_dw_map_out_atu(sc, 2, IATU_CTRL1_TYPE_IO, - sc->io_range.host, sc->io_range.pci, sc->io_range.size); + rv = pci_dw_map_out_atu(sc, sc->num_mem_ranges + 1, + IATU_CTRL1_TYPE_IO, sc->io_range.host, sc->io_range.pci, + sc->io_range.size); if (rv != 0) return (rv); } - /* XXX Should we handle also prefetch memory? */ /* Adjust number of lanes */ reg = DBI_RD4(sc, DW_PORT_LINK_CTRL); @@ -304,57 +308,67 @@ static int pci_dw_decode_ranges(struct pci_dw_softc *sc, struct ofw_pci_range *ranges, int nranges) { - int i; + int i, nmem, rv; + nmem = 0; + for (i = 0; i < nranges; i++) { + if ((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) == + OFW_PCI_PHYS_HI_SPACE_MEM32) + ++nmem; + } + + sc->mem_ranges = malloc(nmem * sizeof(*sc->mem_ranges), M_DEVBUF, + M_WAITOK); + sc->num_mem_ranges = nmem; + + nmem = 0; for (i = 0; i < nranges; i++) { if ((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) == OFW_PCI_PHYS_HI_SPACE_IO) { if (sc->io_range.size != 0) { device_printf(sc->dev, "Duplicated IO range found in DT\n"); - return (ENXIO); + rv = ENXIO; + goto out; } + sc->io_range = ranges[i]; + if (sc->io_range.size > UINT32_MAX) { + device_printf(sc->dev, + "ATU IO window size is too large. " + "Up to 4GB windows are supported, " + "trimming window size to 4GB\n"); + sc->io_range.size = UINT32_MAX; + } } - if (((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) == - OFW_PCI_PHYS_HI_SPACE_MEM32)) { - if (ranges[i].pci_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) { - if (sc->pref_mem_range.size != 0) { - device_printf(sc->dev, - "Duplicated memory range found " - "in DT\n"); - return (ENXIO); - } - sc->pref_mem_range = ranges[i]; - } else { - if (sc->mem_range.size != 0) { - device_printf(sc->dev, - "Duplicated memory range found " - "in DT\n"); - return (ENXIO); - } - sc->mem_range = ranges[i]; + if ((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) == + OFW_PCI_PHYS_HI_SPACE_MEM32) { + MPASS(nmem < sc->num_mem_ranges); + sc->mem_ranges[nmem] = ranges[i]; + if (sc->mem_ranges[nmem].size > UINT32_MAX) { + device_printf(sc->dev, + "ATU MEM window size is too large. " + "Up to 4GB windows are supported, " + "trimming window size to 4GB\n"); + sc->mem_ranges[nmem].size = UINT32_MAX; } + ++nmem; } } - if (sc->mem_range.size == 0) { + + MPASS(nmem == sc->num_mem_ranges); + + if (nmem == 0) { device_printf(sc->dev, - " Not all required ranges are found in DT\n"); + "Missing required memory range in DT\n"); return (ENXIO); } - if (sc->io_range.size > UINT32_MAX) { - device_printf(sc->dev, - "ATU IO window size is too large. Up to 4GB windows " - "are supported, trimming window size to 4GB\n"); - sc->io_range.size = UINT32_MAX; - } - if (sc->mem_range.size > UINT32_MAX) { - device_printf(sc->dev, - "ATU MEM window size is too large. Up to 4GB windows " - "are supported, trimming window size to 4GB\n"); - sc->mem_range.size = UINT32_MAX; - } + return (0); + +out: + free(sc->mem_ranges, M_DEVBUF); + return (rv); } /*----------------------------------------------------------------------------- @@ -386,7 +400,7 @@ pci_dw_read_config(device_t dev, u_int bus, u_int slot, type = IATU_CTRL1_TYPE_CFG0; else type = IATU_CTRL1_TYPE_CFG1; - rv = pci_dw_map_out_atu(sc, 1, type, + rv = pci_dw_map_out_atu(sc, 0, type, sc->cfg_pa, addr, sc->cfg_size); if (rv != 0) return (0xFFFFFFFFU); @@ -433,7 +447,7 @@ pci_dw_write_config(device_t dev, u_int bus, u_int slot, type = IATU_CTRL1_TYPE_CFG0; else type = IATU_CTRL1_TYPE_CFG1; - rv = pci_dw_map_out_atu(sc, 1, type, + rv = pci_dw_map_out_atu(sc, 0, type, sc->cfg_pa, addr, sc->cfg_size); if (rv != 0) return ; diff --git a/sys/dev/pci/pci_dw.h b/sys/dev/pci/pci_dw.h index d6248cf87298..c2c9249449bb 100644 --- a/sys/dev/pci/pci_dw.h +++ b/sys/dev/pci/pci_dw.h @@ -92,9 +92,9 @@ struct pci_dw_softc { struct mtx mtx; struct resource *cfg_res; - struct ofw_pci_range mem_range; - struct ofw_pci_range pref_mem_range; struct ofw_pci_range io_range; + struct ofw_pci_range *mem_ranges; + int num_mem_ranges; bool coherent; bus_dma_tag_t dmat;