diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-02-25 00:03:39 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-02-25 00:03:39 +0000 |
commit | 5cc7487bc8ea512cb8454b73dd32e9f96bd3b28a (patch) | |
tree | 249032c1523fc374c3cfabf3eb348e4fcad48496 /sys/dev/pci | |
parent | 1f8c3984d7dfd8074a7700eaf0bf1e6ba99eb3fd (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.c | 39 |
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 |