From owner-dev-commits-src-branches@freebsd.org Tue Sep 7 12:09:44 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 EEABC66261C; Tue, 7 Sep 2021 12:09:44 +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 4H3kbX1cDvz4rm1; Tue, 7 Sep 2021 12:09:44 +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 66D3911FE8; Tue, 7 Sep 2021 12:09:43 +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 187C9hrb087276; Tue, 7 Sep 2021 12:09:43 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 187C9h0n087275; Tue, 7 Sep 2021 12:09:43 GMT (envelope-from git) Date: Tue, 7 Sep 2021 12:09:43 GMT Message-Id: <202109071209.187C9h0n087275@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: 0889033d2820 - stable/13 - pci_dw: Detect number of outbound regions automatically 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: 0889033d28204b73af9008571160c35a7beabe8b 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:45 -0000 The branch stable/13 has been updated by jrtc27: URL: https://cgit.FreeBSD.org/src/commit/?id=0889033d28204b73af9008571160c35a7beabe8b commit 0889033d28204b73af9008571160c35a7beabe8b Author: Jessica Clarke AuthorDate: 2021-07-21 04:51:20 +0000 Commit: Jessica Clarke CommitDate: 2021-09-07 12:06:48 +0000 pci_dw: Detect number of outbound regions automatically Currently we use the num-viewports property to decide how many outbound regions there are we can use, defaulting to 2. However, Linux has stopped using that and so it no longer appears in new device trees, such as for the SiFive FU740. Instead, it's possible to just probe the hardware directly. Reviewed by: mmel MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D31030 (cherry picked from commit 4707bb0430e6ca3935ef8196e30830b3cdaf3514) --- sys/dev/pci/pci_dw.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++------ sys/dev/pci/pci_dw.h | 2 +- 2 files changed, 78 insertions(+), 10 deletions(-) diff --git a/sys/dev/pci/pci_dw.c b/sys/dev/pci/pci_dw.c index 525c5fcf9cd5..870782e37c09 100644 --- a/sys/dev/pci/pci_dw.c +++ b/sys/dev/pci/pci_dw.c @@ -179,6 +179,71 @@ pci_dw_detect_atu_unroll(struct pci_dw_softc *sc) return (DBI_RD4(sc, DW_IATU_VIEWPORT) == 0xFFFFFFFFU); } +static int +pci_dw_detect_out_atu_regions_unroll(struct pci_dw_softc *sc) +{ + int num_regions, i; + uint32_t reg; + + num_regions = sc->iatu_ur_size / DW_IATU_UR_STEP; + + for (i = 0; i < num_regions; ++i) { + IATU_UR_WR4(sc, DW_IATU_UR_REG(i, LWR_TARGET_ADDR), + 0x12340000); + reg = IATU_UR_RD4(sc, DW_IATU_UR_REG(i, LWR_TARGET_ADDR)); + if (reg != 0x12340000) + break; + } + + sc->num_out_regions = i; + + return (0); +} + +static int +pci_dw_detect_out_atu_regions_legacy(struct pci_dw_softc *sc) +{ + int num_viewports, i; + uint32_t reg; + + /* Find out how many viewports there are in total */ + DBI_WR4(sc, DW_IATU_VIEWPORT, IATU_REGION_INDEX(~0U)); + reg = DBI_RD4(sc, DW_IATU_VIEWPORT); + if (reg > IATU_REGION_INDEX(~0U)) { + device_printf(sc->dev, + "Cannot detect number of output iATU regions; read %#x\n", + reg); + return (ENXIO); + } + + num_viewports = reg + 1; + + /* + * Find out how many of them are outbound by seeing whether a dummy + * page-aligned address sticks. + */ + for (i = 0; i < num_viewports; ++i) { + DBI_WR4(sc, DW_IATU_VIEWPORT, IATU_REGION_INDEX(i)); + DBI_WR4(sc, DW_IATU_LWR_TARGET_ADDR, 0x12340000); + reg = DBI_RD4(sc, DW_IATU_LWR_TARGET_ADDR); + if (reg != 0x12340000) + break; + } + + sc->num_out_regions = i; + + return (0); +} + +static int +pci_dw_detect_out_atu_regions(struct pci_dw_softc *sc) +{ + if (sc->iatu_ur_res) + return (pci_dw_detect_out_atu_regions_unroll(sc)); + else + return (pci_dw_detect_out_atu_regions_legacy(sc)); +} + static int pci_dw_map_out_atu_unroll(struct pci_dw_softc *sc, int idx, int type, uint64_t pa, uint64_t pci_addr, uint32_t size) @@ -285,7 +350,7 @@ pci_dw_setup_hw(struct pci_dw_softc *sc) pci_dw_dbi_protect(sc, true); /* Setup outbound memory windows */ - for (i = 0; i < min(sc->num_mem_ranges, sc->num_viewport - 1); ++i) { + for (i = 0; i < min(sc->num_mem_ranges, sc->num_out_regions - 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); @@ -293,8 +358,8 @@ pci_dw_setup_hw(struct pci_dw_softc *sc) return (rv); } - /* If we have enough viewports ..*/ - if (sc->num_mem_ranges + 1 < sc->num_viewport && + /* If we have enough regions ... */ + if (sc->num_mem_ranges + 1 < sc->num_out_regions && sc->io_range.size != 0) { /* Setup outbound I/O window */ rv = pci_dw_map_out_atu(sc, sc->num_mem_ranges + 1, @@ -660,13 +725,8 @@ pci_dw_init(device_t dev) if (!sc->coherent) sc->coherent = OF_hasprop(sc->node, "dma-coherent"); - rv = OF_getencprop(sc->node, "num-viewport", &sc->num_viewport, - sizeof(sc->num_viewport)); - if (rv != sizeof(sc->num_viewport)) - sc->num_viewport = 2; - rv = OF_getencprop(sc->node, "num-lanes", &sc->num_lanes, - sizeof(sc->num_viewport)); + sizeof(sc->num_lanes)); if (rv != sizeof(sc->num_lanes)) sc->num_lanes = 1; if (sc->num_lanes != 1 && sc->num_lanes != 2 && @@ -753,6 +813,14 @@ pci_dw_init(device_t dev) } } + rv = pci_dw_detect_out_atu_regions(sc); + if (rv != 0) + goto out; + + if (bootverbose) + device_printf(sc->dev, "Detected outbound iATU regions: %d\n", + sc->num_out_regions); + rv = pci_dw_setup_hw(sc); if (rv != 0) goto out; diff --git a/sys/dev/pci/pci_dw.h b/sys/dev/pci/pci_dw.h index 51c4169f74d2..6f2248344f44 100644 --- a/sys/dev/pci/pci_dw.h +++ b/sys/dev/pci/pci_dw.h @@ -115,7 +115,7 @@ struct pci_dw_softc { bus_dma_tag_t dmat; int num_lanes; - int num_viewport; + int num_out_regions; struct resource *iatu_ur_res; /* NB: May be dbi_res */ bus_addr_t iatu_ur_offset; bus_size_t iatu_ur_size;