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