aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/Makefile2
-rw-r--r--drivers/gpu/drm/radeon/radeon.h8
-rw-r--r--drivers/gpu/drm/radeon/radeon_atpx_handler.c258
-rw-r--r--drivers/gpu/drm/radeon/radeon_bios.c44
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c40
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c3
9 files changed, 357 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index b46f115d1c25..0a4d526e4f44 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -60,7 +60,7 @@ radeon-y += radeon_device.o radeon_kms.o \
60 rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ 60 rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \
61 r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ 61 r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
62 r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ 62 r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \
63 evergreen.o 63 evergreen.o radeon_atpx_handler.o
64 64
65radeon-$(CONFIG_COMPAT) += radeon_ioc32.o 65radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
66 66
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 2434d553bbbc..ad9d55f94398 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -119,6 +119,10 @@ struct radeon_device;
119/* 119/*
120 * BIOS. 120 * BIOS.
121 */ 121 */
122#define ATRM_BIOS_PAGE 4096
123
124bool radeon_atrm_supported(struct pci_dev *pdev);
125int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len);
122bool radeon_get_bios(struct radeon_device *rdev); 126bool radeon_get_bios(struct radeon_device *rdev);
123 127
124 128
@@ -957,6 +961,8 @@ struct radeon_device {
957 int audio_bits_per_sample; 961 int audio_bits_per_sample;
958 uint8_t audio_status_bits; 962 uint8_t audio_status_bits;
959 uint8_t audio_category_code; 963 uint8_t audio_category_code;
964
965 bool powered_down;
960}; 966};
961 967
962int radeon_device_init(struct radeon_device *rdev, 968int radeon_device_init(struct radeon_device *rdev,
@@ -1167,6 +1173,8 @@ extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain);
1167extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo); 1173extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo);
1168extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base); 1174extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base);
1169extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); 1175extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
1176extern int radeon_resume_kms(struct drm_device *dev);
1177extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state);
1170 1178
1171/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ 1179/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
1172struct r100_mc_save { 1180struct r100_mc_save {
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
new file mode 100644
index 000000000000..0ae52f19071d
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -0,0 +1,258 @@
1/*
2 * Copyright (c) 2010 Red Hat Inc.
3 * Author : Dave Airlie <airlied@redhat.com>
4 *
5 * Licensed under GPLv2
6 *
7 * ATPX support for both Intel/ATI
8 */
9
10#include <linux/vga_switcheroo.h>
11#include <acpi/acpi.h>
12#include <acpi/acpi_bus.h>
13#include <linux/pci.h>
14
15#define ATPX_VERSION 0
16#define ATPX_GPU_PWR 2
17#define ATPX_MUX_SELECT 3
18
19#define ATPX_INTEGRATED 0
20#define ATPX_DISCRETE 1
21
22#define ATPX_MUX_IGD 0
23#define ATPX_MUX_DISCRETE 1
24
25static struct radeon_atpx_priv {
26 bool atpx_detected;
27 /* handle for device - and atpx */
28 acpi_handle dhandle;
29 acpi_handle atpx_handle;
30 acpi_handle atrm_handle;
31} radeon_atpx_priv;
32
33/* retrieve the ROM in 4k blocks */
34static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
35 int offset, int len)
36{
37 acpi_status status;
38 union acpi_object atrm_arg_elements[2], *obj;
39 struct acpi_object_list atrm_arg;
40 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
41
42 atrm_arg.count = 2;
43 atrm_arg.pointer = &atrm_arg_elements[0];
44
45 atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
46 atrm_arg_elements[0].integer.value = offset;
47
48 atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
49 atrm_arg_elements[1].integer.value = len;
50
51 status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
52 if (ACPI_FAILURE(status)) {
53 printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
54 return -ENODEV;
55 }
56
57 obj = (union acpi_object *)buffer.pointer;
58 memcpy(bios+offset, obj->buffer.pointer, len);
59 kfree(buffer.pointer);
60 return len;
61}
62
63bool radeon_atrm_supported(struct pci_dev *pdev)
64{
65 /* get the discrete ROM only via ATRM */
66 if (!radeon_atpx_priv.atpx_detected)
67 return false;
68
69 if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
70 return false;
71 return true;
72}
73
74
75int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len)
76{
77 return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len);
78}
79
80static int radeon_atpx_get_version(acpi_handle handle)
81{
82 acpi_status status;
83 union acpi_object atpx_arg_elements[2], *obj;
84 struct acpi_object_list atpx_arg;
85 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
86
87 atpx_arg.count = 2;
88 atpx_arg.pointer = &atpx_arg_elements[0];
89
90 atpx_arg_elements[0].type = ACPI_TYPE_INTEGER;
91 atpx_arg_elements[0].integer.value = ATPX_VERSION;
92
93 atpx_arg_elements[1].type = ACPI_TYPE_INTEGER;
94 atpx_arg_elements[1].integer.value = ATPX_VERSION;
95
96 status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
97 if (ACPI_FAILURE(status)) {
98 printk("%s: failed to call ATPX: %s\n", __func__, acpi_format_exception(status));
99 return -ENOSYS;
100 }
101 obj = (union acpi_object *)buffer.pointer;
102 if (obj && (obj->type == ACPI_TYPE_BUFFER))
103 printk(KERN_INFO "radeon atpx: version is %d\n", *((u8 *)(obj->buffer.pointer) + 2));
104 kfree(buffer.pointer);
105 return 0;
106}
107
108static int radeon_atpx_execute(acpi_handle handle, int cmd_id, u16 value)
109{
110 acpi_status status;
111 union acpi_object atpx_arg_elements[2];
112 struct acpi_object_list atpx_arg;
113 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
114 uint8_t buf[4] = {0};
115
116 if (!handle)
117 return -EINVAL;
118
119 atpx_arg.count = 2;
120 atpx_arg.pointer = &atpx_arg_elements[0];
121
122 atpx_arg_elements[0].type = ACPI_TYPE_INTEGER;
123 atpx_arg_elements[0].integer.value = cmd_id;
124
125 buf[2] = value & 0xff;
126 buf[3] = (value >> 8) & 0xff;
127
128 atpx_arg_elements[1].type = ACPI_TYPE_BUFFER;
129 atpx_arg_elements[1].buffer.length = 4;
130 atpx_arg_elements[1].buffer.pointer = buf;
131
132 status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
133 if (ACPI_FAILURE(status)) {
134 printk("%s: failed to call ATPX: %s\n", __func__, acpi_format_exception(status));
135 return -ENOSYS;
136 }
137 kfree(buffer.pointer);
138
139 return 0;
140}
141
142static int radeon_atpx_set_discrete_state(acpi_handle handle, int state)
143{
144 return radeon_atpx_execute(handle, ATPX_GPU_PWR, state);
145}
146
147static int radeon_atpx_switch_mux(acpi_handle handle, int mux_id)
148{
149 return radeon_atpx_execute(handle, ATPX_MUX_SELECT, mux_id);
150}
151
152
153static int radeon_atpx_switchto(enum vga_switcheroo_client_id id)
154{
155 if (id == VGA_SWITCHEROO_IGD)
156 radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 0);
157 else
158 radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 1);
159 return 0;
160}
161
162static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
163 enum vga_switcheroo_state state)
164{
165 /* on w500 ACPI can't change intel gpu state */
166 if (id == VGA_SWITCHEROO_IGD)
167 return 0;
168
169 radeon_atpx_set_discrete_state(radeon_atpx_priv.atpx_handle, state);
170 return 0;
171}
172
173static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
174{
175 acpi_handle dhandle, atpx_handle, atrm_handle;
176 acpi_status status;
177
178 dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
179 if (!dhandle)
180 return false;
181
182 status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
183 if (ACPI_FAILURE(status))
184 return false;
185
186 status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
187 if (ACPI_FAILURE(status))
188 return false;
189
190 radeon_atpx_priv.dhandle = dhandle;
191 radeon_atpx_priv.atpx_handle = atpx_handle;
192 radeon_atpx_priv.atrm_handle = atrm_handle;
193 return true;
194}
195
196static int radeon_atpx_init(void)
197{
198 /* set up the ATPX handle */
199
200 radeon_atpx_get_version(radeon_atpx_priv.atpx_handle);
201 return 0;
202}
203
204static int radeon_atpx_get_client_id(struct pci_dev *pdev)
205{
206 if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
207 return VGA_SWITCHEROO_IGD;
208 else
209 return VGA_SWITCHEROO_DIS;
210}
211
212static struct vga_switcheroo_handler radeon_atpx_handler = {
213 .switchto = radeon_atpx_switchto,
214 .power_state = radeon_atpx_power_state,
215 .init = radeon_atpx_init,
216 .get_client_id = radeon_atpx_get_client_id,
217};
218
219static bool radeon_atpx_detect(void)
220{
221 char acpi_method_name[255] = { 0 };
222 struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
223 struct pci_dev *pdev = NULL;
224 bool has_atpx = false;
225 int vga_count = 0;
226
227 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
228 vga_count++;
229
230 has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
231 }
232
233 if (has_atpx && vga_count == 2) {
234 acpi_get_name(radeon_atpx_priv.atpx_handle, ACPI_FULL_PATHNAME, &buffer);
235 printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n",
236 acpi_method_name);
237 radeon_atpx_priv.atpx_detected = true;
238 return true;
239 }
240 return false;
241}
242
243void radeon_register_atpx_handler(void)
244{
245 bool r;
246
247 /* detect if we have any ATPX + 2 VGA in the system */
248 r = radeon_atpx_detect();
249 if (!r)
250 return;
251
252 vga_switcheroo_register_handler(&radeon_atpx_handler);
253}
254
255void radeon_unregister_atpx_handler(void)
256{
257 vga_switcheroo_unregister_handler();
258}
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 26856ed8d972..557240460526 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 */
100static 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}
96static bool r700_read_disabled_bios(struct radeon_device *rdev) 129static 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
391bool radeon_get_bios(struct radeon_device *rdev) 425bool 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
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 91a9b966238e..e28e4ed5f720 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -30,6 +30,7 @@
30#include <drm/drm_crtc_helper.h> 30#include <drm/drm_crtc_helper.h>
31#include <drm/radeon_drm.h> 31#include <drm/radeon_drm.h>
32#include <linux/vgaarb.h> 32#include <linux/vgaarb.h>
33#include <linux/vga_switcheroo.h>
33#include "radeon_reg.h" 34#include "radeon_reg.h"
34#include "radeon.h" 35#include "radeon.h"
35#include "radeon_asic.h" 36#include "radeon_asic.h"
@@ -655,6 +656,36 @@ void radeon_check_arguments(struct radeon_device *rdev)
655 } 656 }
656} 657}
657 658
659static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state)
660{
661 struct drm_device *dev = pci_get_drvdata(pdev);
662 struct radeon_device *rdev = dev->dev_private;
663 pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
664 if (state == VGA_SWITCHEROO_ON) {
665 printk(KERN_INFO "radeon: switched on\n");
666 /* don't suspend or resume card normally */
667 rdev->powered_down = false;
668 radeon_resume_kms(dev);
669 } else {
670 printk(KERN_INFO "radeon: switched off\n");
671 radeon_suspend_kms(dev, pmm);
672 /* don't suspend or resume card normally */
673 rdev->powered_down = true;
674 }
675}
676
677static bool radeon_switcheroo_can_switch(struct pci_dev *pdev)
678{
679 struct drm_device *dev = pci_get_drvdata(pdev);
680 bool can_switch;
681
682 spin_lock(&dev->count_lock);
683 can_switch = (dev->open_count == 0);
684 spin_unlock(&dev->count_lock);
685 return can_switch;
686}
687
688
658int radeon_device_init(struct radeon_device *rdev, 689int radeon_device_init(struct radeon_device *rdev,
659 struct drm_device *ddev, 690 struct drm_device *ddev,
660 struct pci_dev *pdev, 691 struct pci_dev *pdev,
@@ -737,6 +768,9 @@ int radeon_device_init(struct radeon_device *rdev,
737 /* this will fail for cards that aren't VGA class devices, just 768 /* this will fail for cards that aren't VGA class devices, just
738 * ignore it */ 769 * ignore it */
739 vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); 770 vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
771 vga_switcheroo_register_client(rdev->pdev,
772 radeon_switcheroo_set_state,
773 radeon_switcheroo_can_switch);
740 774
741 r = radeon_init(rdev); 775 r = radeon_init(rdev);
742 if (r) 776 if (r)
@@ -768,6 +802,7 @@ void radeon_device_fini(struct radeon_device *rdev)
768 rdev->shutdown = true; 802 rdev->shutdown = true;
769 radeon_fini(rdev); 803 radeon_fini(rdev);
770 destroy_workqueue(rdev->wq); 804 destroy_workqueue(rdev->wq);
805 vga_switcheroo_unregister_client(rdev->pdev);
771 vga_client_register(rdev->pdev, NULL, NULL, NULL); 806 vga_client_register(rdev->pdev, NULL, NULL, NULL);
772 iounmap(rdev->rmmio); 807 iounmap(rdev->rmmio);
773 rdev->rmmio = NULL; 808 rdev->rmmio = NULL;
@@ -791,6 +826,8 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
791 } 826 }
792 rdev = dev->dev_private; 827 rdev = dev->dev_private;
793 828
829 if (rdev->powered_down)
830 return 0;
794 /* unpin the front buffers */ 831 /* unpin the front buffers */
795 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 832 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
796 struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); 833 struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb);
@@ -836,6 +873,9 @@ int radeon_resume_kms(struct drm_device *dev)
836{ 873{
837 struct radeon_device *rdev = dev->dev_private; 874 struct radeon_device *rdev = dev->dev_private;
838 875
876 if (rdev->powered_down)
877 return 0;
878
839 acquire_console_sem(); 879 acquire_console_sem();
840 pci_set_power_state(dev->pdev, PCI_D0); 880 pci_set_power_state(dev->pdev, PCI_D0);
841 pci_restore_state(dev->pdev); 881 pci_restore_state(dev->pdev);
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index be99d4e55a34..f6456e02d1fe 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -343,6 +343,7 @@ static int __init radeon_init(void)
343 driver = &kms_driver; 343 driver = &kms_driver;
344 driver->driver_features |= DRIVER_MODESET; 344 driver->driver_features |= DRIVER_MODESET;
345 driver->num_ioctls = radeon_max_kms_ioctl; 345 driver->num_ioctls = radeon_max_kms_ioctl;
346 radeon_register_atpx_handler();
346 } 347 }
347 /* if the vga console setting is enabled still 348 /* if the vga console setting is enabled still
348 * let modprobe override it */ 349 * let modprobe override it */
@@ -352,6 +353,7 @@ static int __init radeon_init(void)
352static void __exit radeon_exit(void) 353static void __exit radeon_exit(void)
353{ 354{
354 drm_exit(driver); 355 drm_exit(driver);
356 radeon_unregister_atpx_handler();
355} 357}
356 358
357module_init(radeon_init); 359module_init(radeon_init);
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index cf911859eac2..4fe16461bb1b 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -462,6 +462,9 @@ extern void r600_blit_swap(struct drm_device *dev,
462 int sx, int sy, int dx, int dy, 462 int sx, int sy, int dx, int dy,
463 int w, int h, int src_pitch, int dst_pitch, int cpp); 463 int w, int h, int src_pitch, int dst_pitch, int cpp);
464 464
465/* atpx handler */
466void radeon_register_atpx_handler(void);
467void radeon_unregister_atpx_handler(void);
465/* Flags for stats.boxes 468/* Flags for stats.boxes
466 */ 469 */
467#define RADEON_BOX_DMA_IDLE 0x1 470#define RADEON_BOX_DMA_IDLE 0x1
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index cda112cc7a6c..8fccbf29235e 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -39,6 +39,8 @@
39 39
40#include "drm_fb_helper.h" 40#include "drm_fb_helper.h"
41 41
42#include <linux/vga_switcheroo.h>
43
42struct radeon_fb_device { 44struct radeon_fb_device {
43 struct drm_fb_helper helper; 45 struct drm_fb_helper helper;
44 struct radeon_framebuffer *rfb; 46 struct radeon_framebuffer *rfb;
@@ -286,6 +288,7 @@ int radeonfb_create(struct drm_device *dev,
286 rfbdev->rdev = rdev; 288 rfbdev->rdev = rdev;
287 289
288 mutex_unlock(&rdev->ddev->struct_mutex); 290 mutex_unlock(&rdev->ddev->struct_mutex);
291 vga_switcheroo_client_fb_set(rdev->ddev->pdev, info);
289 return 0; 292 return 0;
290 293
291out_unref: 294out_unref:
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 3c5002ea3f8f..20ec276e7596 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -30,6 +30,8 @@
30#include "radeon.h" 30#include "radeon.h"
31#include "radeon_drm.h" 31#include "radeon_drm.h"
32 32
33#include <linux/vga_switcheroo.h>
34
33int radeon_driver_unload_kms(struct drm_device *dev) 35int radeon_driver_unload_kms(struct drm_device *dev)
34{ 36{
35 struct radeon_device *rdev = dev->dev_private; 37 struct radeon_device *rdev = dev->dev_private;
@@ -136,6 +138,7 @@ int radeon_driver_firstopen_kms(struct drm_device *dev)
136 138
137void radeon_driver_lastclose_kms(struct drm_device *dev) 139void radeon_driver_lastclose_kms(struct drm_device *dev)
138{ 140{
141 vga_switcheroo_process_delayed_switch();
139} 142}
140 143
141int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) 144int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)