summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2014-02-25 00:03:39 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2014-02-25 00:03:39 +0000
commit5cc7487bc8ea512cb8454b73dd32e9f96bd3b28a (patch)
tree249032c1523fc374c3cfabf3eb348e4fcad48496 /sys/dev/pci
parent1f8c3984d7dfd8074a7700eaf0bf1e6ba99eb3fd (diff)
Some broken BIOSen don't assign an address to the ROM BAR. Fix this up, as we
typically need to be able to map the ROM to get connector information and/or to POST the card. ok deraadt@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/drm/radeon/radeon_kms.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/sys/dev/pci/drm/radeon/radeon_kms.c b/sys/dev/pci/drm/radeon/radeon_kms.c
index b6af637acf8..5d895ec56ad 100644
--- a/sys/dev/pci/drm/radeon/radeon_kms.c
+++ b/sys/dev/pci/drm/radeon/radeon_kms.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: radeon_kms.c,v 1.23 2014/02/23 09:36:52 kettenis Exp $ */
+/* $OpenBSD: radeon_kms.c,v 1.24 2014/02/25 00:03:38 kettenis Exp $ */
/*
* Copyright 2008 Advanced Micro Devices, Inc.
* Copyright 2008 Red Hat Inc.
@@ -33,6 +33,14 @@
#include "radeon_asic.h"
#include <dev/pci/drm/drm_pciids.h>
+#ifndef PCI_MEM_START
+#define PCI_MEM_START 0
+#endif
+
+#ifndef PCI_MEM_END
+#define PCI_MEM_END 0xffffffff
+#endif
+
/* can't include radeon_drv.h due to duplicated defines in radeon_reg.h */
#include "vga.h"
@@ -453,6 +461,10 @@ radeondrm_attach_kms(struct device *parent, struct device *self, void *aux)
int is_agp;
pcireg_t type;
uint8_t iobar;
+#if !defined(__sparc64__)
+ pcireg_t addr, mask;
+ int s;
+#endif
#if defined(__sparc64__) || defined(__macppc__)
extern int fbnode;
@@ -515,6 +527,31 @@ radeondrm_attach_kms(struct device *parent, struct device *self, void *aux)
return;
}
+#if !defined(__sparc64__)
+ /*
+ * Make sure we have a base address for the ROM such that we
+ * can map it later.
+ */
+ s = splhigh();
+ addr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
+ pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, ~PCI_ROM_ENABLE);
+ mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
+ pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, addr);
+ splx(s);
+
+ if (addr == 0 && PCI_ROM_SIZE(mask) != 0 && pa->pa_memex) {
+ bus_size_t size, start, end;
+ bus_addr_t base;
+
+ size = PCI_ROM_SIZE(mask);
+ start = max(PCI_MEM_START, pa->pa_memex->ex_start);
+ end = min(PCI_MEM_END, pa->pa_memex->ex_end);
+ if (extent_alloc_subregion(pa->pa_memex, start, end, size,
+ 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);
#endif