summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_bios.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-04 07:49:37 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-04 07:49:37 -0800
commit03a2c4d76c9e99b80d74ab8a4f344e135a5ae44b (patch)
tree7fd7940a4f87dc1ace1c1bdeb1fb0d90ac3beb13 /drivers/gpu/drm/radeon/radeon_bios.c
parenta27341cd5fcb7cf2d2d4726e9f324009f7162c00 (diff)
parentd424b925f7092b9d95e0a8556872349abe79d9b6 (diff)
Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (151 commits) vga_switcheroo: disable default y by new rules. drm/nouveau: fix *staging* driver build with switcheroo off. drm/radeon: fix typo in Makefile vga_switcheroo: fix build on platforms with no ACPI drm/radeon: Fix printf type warning in 64bit system. drm/radeon/kms: bump the KMS version number for square tiling support. vga_switcheroo: initial implementation (v15) drm/radeon/kms: do not disable audio engine twice Revert "drm/radeon/kms: disable HDMI audio for now on rv710/rv730" drm/radeon/kms: do not preset audio stuff and start timer when not using audio drm/radeon: r100/r200 ums: block ability for userspace app to trash 0 page and beyond drm/ttm: fix function prototype to match implementation drm/radeon: use ALIGN instead of open coding it drm/radeon/kms: initialize set_surface_reg reg for rs600 asic drm/i915: Use a dmi quirk to skip a broken SDVO TV output. drm/i915: enable/disable LVDS port at DPMS time drm/i915: check for multiple write domains in pin_and_relocate drm/i915: clean-up i915_gem_flush_gpu_write_domain drm/i915: reuse i915_gpu_idle helper drm/i915: ensure lru ordering of fence_list ... Fixed trivial conflicts in drivers/gpu/vga/Kconfig
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_bios.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_bios.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 906921740c6..55724046052 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -30,6 +30,7 @@
#include "radeon.h"
#include "atom.h"
+#include <linux/vga_switcheroo.h>
/*
* BIOS.
*/
@@ -62,7 +63,7 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev)
iounmap(bios);
return false;
}
- memcpy(rdev->bios, bios, size);
+ memcpy_fromio(rdev->bios, bios, size);
iounmap(bios);
return true;
}
@@ -93,6 +94,38 @@ static bool radeon_read_bios(struct radeon_device *rdev)
return true;
}
+/* ATRM is used to get the BIOS on the discrete cards in
+ * dual-gpu systems.
+ */
+static bool radeon_atrm_get_bios(struct radeon_device *rdev)
+{
+ int ret;
+ int size = 64 * 1024;
+ int i;
+
+ if (!radeon_atrm_supported(rdev->pdev))
+ return false;
+
+ rdev->bios = kmalloc(size, GFP_KERNEL);
+ if (!rdev->bios) {
+ DRM_ERROR("Unable to allocate bios\n");
+ return false;
+ }
+
+ for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
+ ret = radeon_atrm_get_bios_chunk(rdev->bios,
+ (i * ATRM_BIOS_PAGE),
+ ATRM_BIOS_PAGE);
+ if (ret <= 0)
+ break;
+ }
+
+ if (i == 0 || rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) {
+ kfree(rdev->bios);
+ return false;
+ }
+ return true;
+}
static bool r700_read_disabled_bios(struct radeon_device *rdev)
{
uint32_t viph_control;
@@ -388,16 +421,16 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev)
return legacy_read_disabled_bios(rdev);
}
+
bool radeon_get_bios(struct radeon_device *rdev)
{
bool r;
uint16_t tmp;
- if (rdev->flags & RADEON_IS_IGP) {
+ r = radeon_atrm_get_bios(rdev);
+ if (r == false)
r = igp_read_bios_from_vram(rdev);
- if (r == false)
- r = radeon_read_bios(rdev);
- } else
+ if (r == false)
r = radeon_read_bios(rdev);
if (r == false) {
r = radeon_read_disabled_bios(rdev);
@@ -408,6 +441,13 @@ bool radeon_get_bios(struct radeon_device *rdev)
return false;
}
if (rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) {
+ printk("BIOS signature incorrect %x %x\n", rdev->bios[0], rdev->bios[1]);
+ goto free_bios;
+ }
+
+ tmp = RBIOS16(0x18);
+ if (RBIOS8(tmp + 0x14) != 0x0) {
+ DRM_INFO("Not an x86 BIOS ROM, not using.\n");
goto free_bios;
}