The branch main has been updated by mmel:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=92c66dc5f8723083530efbbc5cfa4068105f472c

commit 92c66dc5f8723083530efbbc5cfa4068105f472c
Author:     Michal Meloun <[email protected]>
AuthorDate: 2024-10-07 16:50:10 +0000
Commit:     Michal Meloun <[email protected]>
CommitDate: 2026-02-22 17:53:27 +0000

    pci_dw: improve pci_dw
    
    Add support for 64-bit ranges.
    Process 'bus-range' property.
    Add some debug prints.
    
    MFC after:      3 weeks
---
 sys/dev/pci/pci_dw.c | 78 ++++++++++++++++++++++++++++++++++++++++------------
 sys/dev/pci/pci_dw.h |  3 ++
 2 files changed, 63 insertions(+), 18 deletions(-)

diff --git a/sys/dev/pci/pci_dw.c b/sys/dev/pci/pci_dw.c
index dcc9c0c5e369..7c9448a5593e 100644
--- a/sys/dev/pci/pci_dw.c
+++ b/sys/dev/pci/pci_dw.c
@@ -55,10 +55,10 @@
 #include "pcib_if.h"
 #include "pci_dw_if.h"
 
-#ifdef DEBUG
-#define        debugf(fmt, args...) do { printf(fmt,##args); } while (0)
+#if 0
+#define        dprintf(fmt, args...) do { printf(fmt,##args); } while (0)
 #else
-#define        debugf(fmt, args...)
+#define        dprintf(fmt, args...)
 #endif
 
 #define        DBI_WR1(sc, reg, val)   pci_dw_dbi_wr1((sc)->dev, reg, val)
@@ -92,7 +92,7 @@ pci_dw_dbi_read(device_t dev, u_int reg, int width)
 
        sc = device_get_softc(dev);
        MPASS(sc->dbi_res != NULL);
-
+       dprintf("%s: reg: 0x%04X, width: %d\n", __func__, reg, width);
        switch (width) {
        case 4:
                return (bus_read_4(sc->dbi_res, reg));
@@ -113,6 +113,8 @@ pci_dw_dbi_write(device_t dev, u_int reg, uint32_t val, int 
width)
 
        sc = device_get_softc(dev);
        MPASS(sc->dbi_res != NULL);
+       dprintf("%s: reg: 0x%04X, val: 0x%08X, width: %d\n", __func__,
+           reg, val, width);
 
        switch (width) {
        case 4:
@@ -162,7 +164,7 @@ pci_dw_check_dev(struct pci_dw_softc *sc, u_int bus, u_int 
slot, u_int func,
                return (true);
        }
 
-       /* we have only 1 device with 1 function root port */
+       /* we have only 1 device with 1 function on root port */
        if (slot > 0 || func > 0)
                return (false);
        return (true);
@@ -434,9 +436,14 @@ pci_dw_decode_ranges(struct pci_dw_softc *sc, struct 
ofw_pci_range *ranges,
 
        nmem = 0;
        for (i = 0; i < nranges; i++) {
-               if ((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) ==
-                   OFW_PCI_PHYS_HI_SPACE_MEM32)
+               switch (ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) {
+               case OFW_PCI_PHYS_HI_SPACE_MEM32:
+               case OFW_PCI_PHYS_HI_SPACE_MEM64:
                        ++nmem;
+                       break;
+               default:
+                       break;
+               }
        }
 
        sc->mem_ranges = malloc(nmem * sizeof(*sc->mem_ranges), M_DEVBUF,
@@ -445,8 +452,9 @@ pci_dw_decode_ranges(struct pci_dw_softc *sc, struct 
ofw_pci_range *ranges,
 
        nmem = 0;
        for (i = 0; i < nranges; i++) {
-               if ((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK)  ==
-                   OFW_PCI_PHYS_HI_SPACE_IO) {
+               switch (ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) {
+
+               case OFW_PCI_PHYS_HI_SPACE_IO:
                        if (sc->io_range.size != 0) {
                                device_printf(sc->dev,
                                    "Duplicated IO range found in DT\n");
@@ -462,9 +470,10 @@ pci_dw_decode_ranges(struct pci_dw_softc *sc, struct 
ofw_pci_range *ranges,
                                    "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) {
+                       break;
+
+               case OFW_PCI_PHYS_HI_SPACE_MEM32:
+               case OFW_PCI_PHYS_HI_SPACE_MEM64:
                        MPASS(nmem < sc->num_mem_ranges);
                        sc->mem_ranges[nmem] = ranges[i];
                        if (sc->mem_ranges[nmem].size > UINT32_MAX) {
@@ -475,6 +484,13 @@ pci_dw_decode_ranges(struct pci_dw_softc *sc, struct 
ofw_pci_range *ranges,
                                sc->mem_ranges[nmem].size = UINT32_MAX;
                        }
                        ++nmem;
+                       break;
+
+               default:
+                       device_printf(sc->dev,
+                                   "%s: Unsupported range type (0x%X)\n",
+                                   __func__, ranges[i].pci_hi &
+                                   OFW_PCI_PHYS_HI_SPACEMASK);
                }
        }
 
@@ -703,6 +719,7 @@ pci_dw_init(device_t dev)
        struct pci_dw_softc *sc;
        int rv, rid;
        bool unroll_mode;
+       u_int32_t br[2];
 
        sc = device_get_softc(dev);
        sc->dev = dev;
@@ -710,11 +727,30 @@ pci_dw_init(device_t dev)
 
        mtx_init(&sc->mtx, "pci_dw_mtx", NULL, MTX_DEF);
 
-       /* XXXn Should not be this configurable ? */
-       sc->bus_start = 0;
-       sc->bus_end = 255;
-       sc->root_bus = 0;
-       sc->sub_bus = 1;
+       if (OF_hasprop(sc->node, "bus-range")) {
+               rv = OF_getencprop(sc->node, "bus-range", br, sizeof(br));
+               if (rv < 0) {
+                       device_printf(dev,
+                           "Cannot read 'bus-range' property: %d\n", rv);
+                       rv = ENXIO;
+                       goto out;
+               }
+               if (rv != 8) {
+                       device_printf(dev,
+                           "Malformed 'bus-range' property: %d\n", rv);
+                       rv = ENXIO;
+                       goto out;
+               }
+               sc->bus_start = br[0];
+               sc->bus_end = br[1];
+       } else {
+               sc->bus_start = 0;
+               sc->bus_end = 255;
+       }
+       sc->root_bus = sc->bus_start;
+       sc->sub_bus = sc->bus_start + 1;
+       dprintf("%s: bus range[%d..%d], root bus %d, sub bus: %d\n", __func__,
+           sc->bus_end, sc->bus_start, sc->root_bus, sc->sub_bus);
 
        /* Read FDT properties */
        if (!sc->coherent)
@@ -724,6 +760,8 @@ pci_dw_init(device_t dev)
            sizeof(sc->num_lanes));
        if (rv != sizeof(sc->num_lanes))
                sc->num_lanes = 1;
+       dprintf("%s: num lanes: %d\n", __func__, sc->num_lanes);
+
        if (sc->num_lanes != 1 && sc->num_lanes != 2 &&
            sc->num_lanes != 4 && sc->num_lanes != 8) {
                device_printf(dev,
@@ -769,7 +807,6 @@ pci_dw_init(device_t dev)
            &sc->dmat);
        if (rv != 0)
                goto out;
-
        rv = ofw_pcib_init(dev);
        if (rv != 0)
                goto out;
@@ -778,6 +815,9 @@ pci_dw_init(device_t dev)
        if (rv != 0)
                goto out;
 
+       dprintf("%s: version: 0x%08X, version type:0x%08X\n", __func__,
+           DBI_RD4(sc, DW_MISC_VERSION), DBI_RD4(sc, DW_MISC_VERSION_TYPE));
+
        unroll_mode = pci_dw_detect_atu_unroll(sc);
        if (bootverbose)
                device_printf(dev, "Using iATU %s mode\n",
@@ -786,6 +826,7 @@ pci_dw_init(device_t dev)
                rid = 0;
                rv = ofw_bus_find_string_index(sc->node, "reg-names", "atu", 
&rid);
                if (rv == 0) {
+                       dprintf("%s: Have 'atu' regs\n", __func__);
                        sc->iatu_ur_res = bus_alloc_resource_any(dev,
                            SYS_RES_MEMORY, &rid, RF_ACTIVE);
                        if (sc->iatu_ur_res == NULL) {
@@ -798,6 +839,7 @@ pci_dw_init(device_t dev)
                        sc->iatu_ur_offset = 0;
                        sc->iatu_ur_size = rman_get_size(sc->iatu_ur_res);
                } else if (rv == ENOENT) {
+                       dprintf("%s: Using 'dbi' regs for atu\n", __func__);
                        sc->iatu_ur_res = sc->dbi_res;
                        sc->iatu_ur_offset = DW_DEFAULT_IATU_UR_DBI_OFFSET;
                        sc->iatu_ur_size = DW_DEFAULT_IATU_UR_DBI_SIZE;
diff --git a/sys/dev/pci/pci_dw.h b/sys/dev/pci/pci_dw.h
index 388eae86e40f..5b6f62ad6c84 100644
--- a/sys/dev/pci/pci_dw.h
+++ b/sys/dev/pci/pci_dw.h
@@ -61,6 +61,9 @@
 #define        DW_MISC_CONTROL_1               0x8BC
 #define         DBI_RO_WR_EN                           (1 << 0)
 
+#define DW_MISC_VERSION                        0x8F8
+#define DW_MISC_VERSION_TYPE           0x8FC
+
 /* Legacy (pre-4.80) iATU mode */
 #define        DW_IATU_VIEWPORT                        0x900
 #define         IATU_REGION_INBOUND                    (1U << 31)

Reply via email to