diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_bios.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_bios.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 96e37a6e7ce4..34a9b9119518 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
@@ -33,12 +33,50 @@ | |||
33 | /* | 33 | /* |
34 | * BIOS. | 34 | * BIOS. |
35 | */ | 35 | */ |
36 | |||
37 | /* If you boot an IGP board with a discrete card as the primary, | ||
38 | * the IGP rom is not accessible via the rom bar as the IGP rom is | ||
39 | * part of the system bios. On boot, the system bios puts a | ||
40 | * copy of the igp rom at the start of vram if a discrete card is | ||
41 | * present. | ||
42 | */ | ||
43 | static bool igp_read_bios_from_vram(struct radeon_device *rdev) | ||
44 | { | ||
45 | uint8_t __iomem *bios; | ||
46 | resource_size_t vram_base; | ||
47 | resource_size_t size = 256 * 1024; /* ??? */ | ||
48 | |||
49 | rdev->bios = NULL; | ||
50 | vram_base = drm_get_resource_start(rdev->ddev, 0); | ||
51 | bios = ioremap(vram_base, size); | ||
52 | if (!bios) { | ||
53 | DRM_ERROR("Unable to mmap vram\n"); | ||
54 | return false; | ||
55 | } | ||
56 | |||
57 | if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { | ||
58 | iounmap(bios); | ||
59 | DRM_ERROR("bad rom signature\n"); | ||
60 | return false; | ||
61 | } | ||
62 | rdev->bios = kmalloc(size, GFP_KERNEL); | ||
63 | if (rdev->bios == NULL) { | ||
64 | iounmap(bios); | ||
65 | DRM_ERROR("kmalloc failed\n"); | ||
66 | return false; | ||
67 | } | ||
68 | memcpy(rdev->bios, bios, size); | ||
69 | iounmap(bios); | ||
70 | return true; | ||
71 | } | ||
72 | |||
36 | static bool radeon_read_bios(struct radeon_device *rdev) | 73 | static bool radeon_read_bios(struct radeon_device *rdev) |
37 | { | 74 | { |
38 | uint8_t __iomem *bios; | 75 | uint8_t __iomem *bios; |
39 | size_t size; | 76 | size_t size; |
40 | 77 | ||
41 | rdev->bios = NULL; | 78 | rdev->bios = NULL; |
79 | /* XXX: some cards may return 0 for rom size? ddx has a workaround */ | ||
42 | bios = pci_map_rom(rdev->pdev, &size); | 80 | bios = pci_map_rom(rdev->pdev, &size); |
43 | if (!bios) { | 81 | if (!bios) { |
44 | return false; | 82 | return false; |
@@ -341,7 +379,9 @@ static bool legacy_read_disabled_bios(struct radeon_device *rdev) | |||
341 | 379 | ||
342 | static bool radeon_read_disabled_bios(struct radeon_device *rdev) | 380 | static bool radeon_read_disabled_bios(struct radeon_device *rdev) |
343 | { | 381 | { |
344 | if (rdev->family >= CHIP_RV770) | 382 | if (rdev->flags & RADEON_IS_IGP) |
383 | return igp_read_bios_from_vram(rdev); | ||
384 | else if (rdev->family >= CHIP_RV770) | ||
345 | return r700_read_disabled_bios(rdev); | 385 | return r700_read_disabled_bios(rdev); |
346 | else if (rdev->family >= CHIP_R600) | 386 | else if (rdev->family >= CHIP_R600) |
347 | return r600_read_disabled_bios(rdev); | 387 | return r600_read_disabled_bios(rdev); |
@@ -356,7 +396,12 @@ bool radeon_get_bios(struct radeon_device *rdev) | |||
356 | bool r; | 396 | bool r; |
357 | uint16_t tmp; | 397 | uint16_t tmp; |
358 | 398 | ||
359 | r = radeon_read_bios(rdev); | 399 | if (rdev->flags & RADEON_IS_IGP) { |
400 | r = igp_read_bios_from_vram(rdev); | ||
401 | if (r == false) | ||
402 | r = radeon_read_bios(rdev); | ||
403 | } else | ||
404 | r = radeon_read_bios(rdev); | ||
360 | if (r == false) { | 405 | if (r == false) { |
361 | r = radeon_read_disabled_bios(rdev); | 406 | r = radeon_read_disabled_bios(rdev); |
362 | } | 407 | } |