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]>