|
@@ -33,12 +33,50 @@
|
|
|
/*
|
|
|
* BIOS.
|
|
|
*/
|
|
|
+
|
|
|
+/* If you boot an IGP board with a discrete card as the primary,
|
|
|
+ * the IGP rom is not accessible via the rom bar as the IGP rom is
|
|
|
+ * part of the system bios. On boot, the system bios puts a
|
|
|
+ * copy of the igp rom at the start of vram if a discrete card is
|
|
|
+ * present.
|
|
|
+ */
|
|
|
+static bool igp_read_bios_from_vram(struct radeon_device *rdev)
|
|
|
+{
|
|
|
+ uint8_t __iomem *bios;
|
|
|
+ resource_size_t vram_base;
|
|
|
+ resource_size_t size = 256 * 1024; /* ??? */
|
|
|
+
|
|
|
+ rdev->bios = NULL;
|
|
|
+ vram_base = drm_get_resource_start(rdev->ddev, 0);
|
|
|
+ bios = ioremap(vram_base, size);
|
|
|
+ if (!bios) {
|
|
|
+ DRM_ERROR("Unable to mmap vram\n");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
|
|
|
+ iounmap(bios);
|
|
|
+ DRM_ERROR("bad rom signature\n");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ rdev->bios = kmalloc(size, GFP_KERNEL);
|
|
|
+ if (rdev->bios == NULL) {
|
|
|
+ iounmap(bios);
|
|
|
+ DRM_ERROR("kmalloc failed\n");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ memcpy(rdev->bios, bios, size);
|
|
|
+ iounmap(bios);
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
static bool radeon_read_bios(struct radeon_device *rdev)
|
|
|
{
|
|
|
uint8_t __iomem *bios;
|
|
|
size_t size;
|
|
|
|
|
|
rdev->bios = NULL;
|
|
|
+ /* XXX: some cards may return 0 for rom size? ddx has a workaround */
|
|
|
bios = pci_map_rom(rdev->pdev, &size);
|
|
|
if (!bios) {
|
|
|
return false;
|
|
@@ -341,7 +379,9 @@ static bool legacy_read_disabled_bios(struct radeon_device *rdev)
|
|
|
|
|
|
static bool radeon_read_disabled_bios(struct radeon_device *rdev)
|
|
|
{
|
|
|
- if (rdev->family >= CHIP_RV770)
|
|
|
+ if (rdev->flags & RADEON_IS_IGP)
|
|
|
+ return igp_read_bios_from_vram(rdev);
|
|
|
+ else if (rdev->family >= CHIP_RV770)
|
|
|
return r700_read_disabled_bios(rdev);
|
|
|
else if (rdev->family >= CHIP_R600)
|
|
|
return r600_read_disabled_bios(rdev);
|
|
@@ -356,7 +396,12 @@ bool radeon_get_bios(struct radeon_device *rdev)
|
|
|
bool r;
|
|
|
uint16_t tmp;
|
|
|
|
|
|
- r = radeon_read_bios(rdev);
|
|
|
+ if (rdev->flags & RADEON_IS_IGP) {
|
|
|
+ r = igp_read_bios_from_vram(rdev);
|
|
|
+ if (r == false)
|
|
|
+ r = radeon_read_bios(rdev);
|
|
|
+ } else
|
|
|
+ r = radeon_read_bios(rdev);
|
|
|
if (r == false) {
|
|
|
r = radeon_read_disabled_bios(rdev);
|
|
|
}
|