diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_bios.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_bios.c | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 906921740c60..8ad71f701316 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include "radeon.h" | 30 | #include "radeon.h" |
31 | #include "atom.h" | 31 | #include "atom.h" |
32 | 32 | ||
33 | #include <linux/vga_switcheroo.h> | ||
34 | #include <linux/slab.h> | ||
33 | /* | 35 | /* |
34 | * BIOS. | 36 | * BIOS. |
35 | */ | 37 | */ |
@@ -62,7 +64,7 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev) | |||
62 | iounmap(bios); | 64 | iounmap(bios); |
63 | return false; | 65 | return false; |
64 | } | 66 | } |
65 | memcpy(rdev->bios, bios, size); | 67 | memcpy_fromio(rdev->bios, bios, size); |
66 | iounmap(bios); | 68 | iounmap(bios); |
67 | return true; | 69 | return true; |
68 | } | 70 | } |
@@ -93,6 +95,38 @@ static bool radeon_read_bios(struct radeon_device *rdev) | |||
93 | return true; | 95 | return true; |
94 | } | 96 | } |
95 | 97 | ||
98 | /* ATRM is used to get the BIOS on the discrete cards in | ||
99 | * dual-gpu systems. | ||
100 | */ | ||
101 | static bool radeon_atrm_get_bios(struct radeon_device *rdev) | ||
102 | { | ||
103 | int ret; | ||
104 | int size = 64 * 1024; | ||
105 | int i; | ||
106 | |||
107 | if (!radeon_atrm_supported(rdev->pdev)) | ||
108 | return false; | ||
109 | |||
110 | rdev->bios = kmalloc(size, GFP_KERNEL); | ||
111 | if (!rdev->bios) { | ||
112 | DRM_ERROR("Unable to allocate bios\n"); | ||
113 | return false; | ||
114 | } | ||
115 | |||
116 | for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { | ||
117 | ret = radeon_atrm_get_bios_chunk(rdev->bios, | ||
118 | (i * ATRM_BIOS_PAGE), | ||
119 | ATRM_BIOS_PAGE); | ||
120 | if (ret <= 0) | ||
121 | break; | ||
122 | } | ||
123 | |||
124 | if (i == 0 || rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) { | ||
125 | kfree(rdev->bios); | ||
126 | return false; | ||
127 | } | ||
128 | return true; | ||
129 | } | ||
96 | static bool r700_read_disabled_bios(struct radeon_device *rdev) | 130 | static bool r700_read_disabled_bios(struct radeon_device *rdev) |
97 | { | 131 | { |
98 | uint32_t viph_control; | 132 | uint32_t viph_control; |
@@ -388,16 +422,16 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev) | |||
388 | return legacy_read_disabled_bios(rdev); | 422 | return legacy_read_disabled_bios(rdev); |
389 | } | 423 | } |
390 | 424 | ||
425 | |||
391 | bool radeon_get_bios(struct radeon_device *rdev) | 426 | bool radeon_get_bios(struct radeon_device *rdev) |
392 | { | 427 | { |
393 | bool r; | 428 | bool r; |
394 | uint16_t tmp; | 429 | uint16_t tmp; |
395 | 430 | ||
396 | if (rdev->flags & RADEON_IS_IGP) { | 431 | r = radeon_atrm_get_bios(rdev); |
432 | if (r == false) | ||
397 | r = igp_read_bios_from_vram(rdev); | 433 | r = igp_read_bios_from_vram(rdev); |
398 | if (r == false) | 434 | if (r == false) |
399 | r = radeon_read_bios(rdev); | ||
400 | } else | ||
401 | r = radeon_read_bios(rdev); | 435 | r = radeon_read_bios(rdev); |
402 | if (r == false) { | 436 | if (r == false) { |
403 | r = radeon_read_disabled_bios(rdev); | 437 | r = radeon_read_disabled_bios(rdev); |
@@ -408,6 +442,13 @@ bool radeon_get_bios(struct radeon_device *rdev) | |||
408 | return false; | 442 | return false; |
409 | } | 443 | } |
410 | if (rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) { | 444 | if (rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) { |
445 | printk("BIOS signature incorrect %x %x\n", rdev->bios[0], rdev->bios[1]); | ||
446 | goto free_bios; | ||
447 | } | ||
448 | |||
449 | tmp = RBIOS16(0x18); | ||
450 | if (RBIOS8(tmp + 0x14) != 0x0) { | ||
451 | DRM_INFO("Not an x86 BIOS ROM, not using.\n"); | ||
411 | goto free_bios; | 452 | goto free_bios; |
412 | } | 453 | } |
413 | 454 | ||