diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_bios.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_bios.c | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 96e37a6e7ce4..906921740c60 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
@@ -33,12 +33,47 @@ | |||
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 | return false; | ||
54 | } | ||
55 | |||
56 | if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { | ||
57 | iounmap(bios); | ||
58 | return false; | ||
59 | } | ||
60 | rdev->bios = kmalloc(size, GFP_KERNEL); | ||
61 | if (rdev->bios == NULL) { | ||
62 | iounmap(bios); | ||
63 | return false; | ||
64 | } | ||
65 | memcpy(rdev->bios, bios, size); | ||
66 | iounmap(bios); | ||
67 | return true; | ||
68 | } | ||
69 | |||
36 | static bool radeon_read_bios(struct radeon_device *rdev) | 70 | static bool radeon_read_bios(struct radeon_device *rdev) |
37 | { | 71 | { |
38 | uint8_t __iomem *bios; | 72 | uint8_t __iomem *bios; |
39 | size_t size; | 73 | size_t size; |
40 | 74 | ||
41 | rdev->bios = NULL; | 75 | rdev->bios = NULL; |
76 | /* XXX: some cards may return 0 for rom size? ddx has a workaround */ | ||
42 | bios = pci_map_rom(rdev->pdev, &size); | 77 | bios = pci_map_rom(rdev->pdev, &size); |
43 | if (!bios) { | 78 | if (!bios) { |
44 | return false; | 79 | return false; |
@@ -341,7 +376,9 @@ static bool legacy_read_disabled_bios(struct radeon_device *rdev) | |||
341 | 376 | ||
342 | static bool radeon_read_disabled_bios(struct radeon_device *rdev) | 377 | static bool radeon_read_disabled_bios(struct radeon_device *rdev) |
343 | { | 378 | { |
344 | if (rdev->family >= CHIP_RV770) | 379 | if (rdev->flags & RADEON_IS_IGP) |
380 | return igp_read_bios_from_vram(rdev); | ||
381 | else if (rdev->family >= CHIP_RV770) | ||
345 | return r700_read_disabled_bios(rdev); | 382 | return r700_read_disabled_bios(rdev); |
346 | else if (rdev->family >= CHIP_R600) | 383 | else if (rdev->family >= CHIP_R600) |
347 | return r600_read_disabled_bios(rdev); | 384 | return r600_read_disabled_bios(rdev); |
@@ -356,7 +393,12 @@ bool radeon_get_bios(struct radeon_device *rdev) | |||
356 | bool r; | 393 | bool r; |
357 | uint16_t tmp; | 394 | uint16_t tmp; |
358 | 395 | ||
359 | r = radeon_read_bios(rdev); | 396 | if (rdev->flags & RADEON_IS_IGP) { |
397 | r = igp_read_bios_from_vram(rdev); | ||
398 | if (r == false) | ||
399 | r = radeon_read_bios(rdev); | ||
400 | } else | ||
401 | r = radeon_read_bios(rdev); | ||
360 | if (r == false) { | 402 | if (r == false) { |
361 | r = radeon_read_disabled_bios(rdev); | 403 | r = radeon_read_disabled_bios(rdev); |
362 | } | 404 | } |