On 2022-02-12 6:46 p.m., Jonathan Gray wrote:
> I will review further when you drop the function.

Alright try this again,

diff b5c3be43fcdaf7cbd7d070c07746b451413f6b4a 
453e49da7f0804392d6d51fb578cfd8255f4fb77
blob - a2d53f752bccb1ab54993ec2a7d5791ec2216e0a
blob + f6353eb5f76e0ae0e21277f82e86b70b36dd401d
--- sys/dev/pci/drm/radeon/radeon_kms.c
+++ sys/dev/pci/drm/radeon/radeon_kms.c
@@ -494,14 +494,13 @@ radeondrm_attach_kms(struct device *parent, struct dev
        struct pci_attach_args  *pa = aux;
        const struct pci_device_id *id_entry;
        int                      is_agp;
-       pcireg_t                 type;
-       int                      i;
-       uint8_t                  rmmio_bar;
        paddr_t                  fb_aper;
-#if !defined(__sparc64__)
        pcireg_t                 addr, mask;
-       int                      s;
-#endif
+       int                      s, error;
+       uint8_t                  i, mm;
+       pcireg_t                 type[6];
+       int                      bar[6];
+       const uint8_t            BAR[6] = {0x10,0x14,0x18,0x1C,0x20,0x24};
 
 #if defined(__sparc64__) || defined(__macppc__)
        extern int fbnode;
@@ -542,75 +541,115 @@ radeondrm_attach_kms(struct device *parent, struct dev
 #endif
 #endif
 
-#define RADEON_PCI_MEM         0x10
+       /* Start PCI BAR mappings */
+       bar[0] = pci_mapreg_probe(rdev->pc, rdev->pa_tag, BAR[0], &type[0]);
+       bar[1] = pci_mapreg_probe(rdev->pc, rdev->pa_tag, BAR[1], &type[1]);
+       bar[2] = pci_mapreg_probe(rdev->pc, rdev->pa_tag, BAR[2], &type[2]);
+       bar[3] = pci_mapreg_probe(rdev->pc, rdev->pa_tag, BAR[3], &type[3]);
+       bar[4] = pci_mapreg_probe(rdev->pc, rdev->pa_tag, BAR[4], &type[4]);
+       bar[5] = pci_mapreg_probe(rdev->pc, rdev->pa_tag, BAR[5], &type[5]);
 
-       type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM);
-       if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM ||
-           pci_mapreg_info(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM,
-           type, &rdev->fb_aper_offset, &rdev->fb_aper_size, NULL)) {
-               printf(": can't get frambuffer info\n");
+       /* Framebuffer offset is saved at BAR0 */
+       if (!bar[0] || PCI_MAPREG_TYPE(type[0]) != PCI_MAPREG_TYPE_MEM) {
+               printf(": BAR0 (framebuffer) is not memory mapped.\n");
+               radeon_fatal_error = 1;
                return;
        }
-#if !defined(__sparc64__)
+
+       error = pci_mapreg_info(rdev->pc, rdev->pa_tag, BAR[0],
+           type[0], &rdev->fb_aper_offset, &rdev->fb_aper_size, NULL);
+       if (error) {
+               printf(": Cannot get FB parameters from BAR0 (%d).\n", error);
+               radeon_fatal_error = 1;
+               return;
+       }
+
        if (rdev->fb_aper_offset == 0) {
                bus_size_t start, end;
                bus_addr_t base;
 
+               KASSERT(pa->pa_memex != NULL);
+
                start = max(PCI_MEM_START, pa->pa_memex->ex_start);
                end = min(PCI_MEM_END, pa->pa_memex->ex_end);
-               if (pa->pa_memex == NULL ||
-                   extent_alloc_subregion(pa->pa_memex, start, end,
-                   rdev->fb_aper_size, rdev->fb_aper_size, 0, 0, 0, &base)) {
-                       printf(": can't reserve framebuffer space\n");
+
+               error = extent_alloc_subregion(pa->pa_memex, start, end,
+                   rdev->fb_aper_size, rdev->fb_aper_size, 0, 0, 0, &base);
+               if (error) {
+                       printf(": Cannot allocate framebuffer (%d).\n", error);
+                       radeon_fatal_error = 1;
                        return;
                }
-               pci_conf_write(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM, base);
-               if (PCI_MAPREG_MEM_TYPE(type) == PCI_MAPREG_MEM_TYPE_64BIT)
-                       pci_conf_write(pa->pa_pc, pa->pa_tag,
-                           RADEON_PCI_MEM + 4, (uint64_t)base >> 32);
+
+               /* Set FB aperature to 32bit space for MI purposes */
+               switch (PCI_MAPREG_MEM_TYPE(type[0])) {
+               default:
+                       printf(": Unhandled BAR0 memory type.\n");
+                       radeon_fatal_error = 1;
+                       return;
+               case PCI_MAPREG_MEM_TYPE_64BIT:
+                       pci_conf_write(pa->pa_pc, pa->pa_tag, BAR[1], 0);
+                       /* FALLTHROUGH */
+               case PCI_MAPREG_MEM_TYPE_32BIT:
+                       pci_conf_write(pa->pa_pc, pa->pa_tag, BAR[0], base);
+               }
                rdev->fb_aper_offset = base;
        }
-#endif
 
-       for (i = PCI_MAPREG_START; i < PCI_MAPREG_END; i += 4) {
-               type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, i);
-               if (type == PCI_MAPREG_TYPE_IO) {
-                       pci_mapreg_map(pa, i, type, 0, NULL,
+       /* Search BARs for IO registers (if supported/available) usually BAR1 */
+       for (i = 0; i < 6; i++) {
+               if (bar[i] && PCI_MAPREG_TYPE(type[i]) == PCI_MAPREG_TYPE_IO) {
+                       error = pci_mapreg_map(pa, BAR[i], type[i], 0, NULL,
                            &rdev->rio_mem, NULL, &rdev->rio_mem_size, 0);
+                       /* Non-fatal failure, for alternative access use mmio */
+#ifdef DEBUG
+                       if (error)
+                               printf(": IO map unavailable (%d). ", error);
+#endif
                        break;
                }
-               if (type == PCI_MAPREG_MEM_TYPE_64BIT)
-                       i += 4;
        }
 
+       /* Radeons older than Bonaire have MMIO BAR here */
+       mm = 2;
+
+       /* New ICs add a doorbell and moved the MMIO BAR register to BAR5 */
        if (rdev->family >= CHIP_BONAIRE) {
-               type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, 0x18);
-               if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM ||
-                   pci_mapreg_map(pa, 0x18, type, BUS_SPACE_MAP_LINEAR, NULL,
-                   &rdev->doorbell.bsh, &rdev->doorbell.base,
-                   &rdev->doorbell.size, 0)) {
-                       printf(": can't map doorbell space\n");
+               mm = 5;
+               if (!bar[2] || PCI_MAPREG_TYPE(type[2]) != PCI_MAPREG_TYPE_MEM) 
{
+                       printf(": Unable to memory map BAR2 Doorbell.\n");
+                       radeon_fatal_error = 1;
                        return;
                }
-               rdev->doorbell.ptr = bus_space_vaddr(rdev->memt,
-                   rdev->doorbell.bsh);
+               
+               error = pci_mapreg_map(pa, BAR[2], type[2],
+                   BUS_SPACE_MAP_LINEAR, NULL, &rdev->doorbell.bsh,
+                   &rdev->doorbell.base, &rdev->doorbell.size, 0);     
+               if (error) {
+                       printf(": Cannot map doorbell at BAR2 (%d).\n", error);
+                       radeon_fatal_error = 1;
+                       return;
+               }
+               rdev->doorbell.ptr =
+                   bus_space_vaddr(rdev->memt, rdev->doorbell.bsh);
        }
 
-       if (rdev->family >= CHIP_BONAIRE)
-               rmmio_bar = 0x24;
-       else
-               rmmio_bar = 0x18;
-
-       type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, rmmio_bar);
-       if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM ||
-           pci_mapreg_map(pa, rmmio_bar, type, BUS_SPACE_MAP_LINEAR, NULL,
-           &rdev->rmmio_bsh, &rdev->rmmio_base, &rdev->rmmio_size, 0)) {
-               printf(": can't map rmmio space\n");
+       if (!bar[mm] || PCI_MAPREG_TYPE(type[mm]) != PCI_MAPREG_TYPE_MEM) {
+               printf(": BAR%d (MMIO) is not memory mapped\n", mm);
+               radeon_fatal_error = 1;
                return;
        }
+       error = pci_mapreg_map(pa, BAR[mm], type[mm], BUS_SPACE_MAP_LINEAR,
+           NULL, &rdev->rmmio_bsh, &rdev->rmmio_base, &rdev->rmmio_size, 0);
+       if (error) {
+               printf(": unable to map MMIO registers (%d)\n", error);
+               radeon_fatal_error = 1;
+               return;
+       }
+
        rdev->rmmio = bus_space_vaddr(rdev->memt, rdev->rmmio_bsh);
+       /* Finished PCI BAR mapping */
 
-#if !defined(__sparc64__)
        /*
         * Make sure we have a base address for the ROM such that we
         * can map it later.
@@ -633,7 +672,6 @@ radeondrm_attach_kms(struct device *parent, struct dev
                    size, 0, 0, 0, &base) == 0)
                        pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, 
base);
        }
-#endif
 
 #ifdef notyet
        mtx_init(&rdev->swi_lock, IPL_TTY);
@@ -665,6 +703,11 @@ radeondrm_attach_kms(struct device *parent, struct dev
 
        dev = drm_attach_pci(&kms_driver, pa, is_agp, rdev->primary,
            self, NULL);
+       if (dev == NULL) {
+               printf("%s: drm_attach_pci failed\n", rdev->self.dv_xname);
+               radeon_fatal_error = 1;
+               return;
+       }
        rdev->ddev = dev;
        rdev->pdev = dev->pdev;
 


-- 
Ted Bullock <[email protected]>

Reply via email to