aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_irq.c27
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c20
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1
-rw-r--r--drivers/gpu/drm/i915/intel_display.c17
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
-rw-r--r--drivers/gpu/drm/radeon/r100.c14
-rw-r--r--drivers/gpu/drm/radeon/r600.c14
-rw-r--r--drivers/gpu/drm/radeon/r600d.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h12
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c21
-rw-r--r--include/drm/drmP.h3
13 files changed, 133 insertions, 1 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index f85aaf21e783..0a6f0b3bdc78 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -37,6 +37,7 @@
37 37
38#include <linux/interrupt.h> /* For task queue support */ 38#include <linux/interrupt.h> /* For task queue support */
39 39
40#include <linux/vgaarb.h>
40/** 41/**
41 * Get interrupt from bus id. 42 * Get interrupt from bus id.
42 * 43 *
@@ -171,6 +172,26 @@ err:
171} 172}
172EXPORT_SYMBOL(drm_vblank_init); 173EXPORT_SYMBOL(drm_vblank_init);
173 174
175static void drm_irq_vgaarb_nokms(void *cookie, bool state)
176{
177 struct drm_device *dev = cookie;
178
179 if (dev->driver->vgaarb_irq) {
180 dev->driver->vgaarb_irq(dev, state);
181 return;
182 }
183
184 if (!dev->irq_enabled)
185 return;
186
187 if (state)
188 dev->driver->irq_uninstall(dev);
189 else {
190 dev->driver->irq_preinstall(dev);
191 dev->driver->irq_postinstall(dev);
192 }
193}
194
174/** 195/**
175 * Install IRQ handler. 196 * Install IRQ handler.
176 * 197 *
@@ -231,6 +252,9 @@ int drm_irq_install(struct drm_device *dev)
231 return ret; 252 return ret;
232 } 253 }
233 254
255 if (!drm_core_check_feature(dev, DRIVER_MODESET))
256 vga_client_register(dev->pdev, (void *)dev, drm_irq_vgaarb_nokms, NULL);
257
234 /* After installing handler */ 258 /* After installing handler */
235 ret = dev->driver->irq_postinstall(dev); 259 ret = dev->driver->irq_postinstall(dev);
236 if (ret < 0) { 260 if (ret < 0) {
@@ -279,6 +303,9 @@ int drm_irq_uninstall(struct drm_device * dev)
279 303
280 DRM_DEBUG("irq=%d\n", dev->pdev->irq); 304 DRM_DEBUG("irq=%d\n", dev->pdev->irq);
281 305
306 if (!drm_core_check_feature(dev, DRIVER_MODESET))
307 vga_client_register(dev->pdev, NULL, NULL, NULL);
308
282 dev->driver->irq_uninstall(dev); 309 dev->driver->irq_uninstall(dev);
283 310
284 free_irq(dev->pdev->irq, dev); 311 free_irq(dev->pdev->irq, dev);
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 9909505d070a..5a49a1867b35 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -33,6 +33,7 @@
33#include "intel_drv.h" 33#include "intel_drv.h"
34#include "i915_drm.h" 34#include "i915_drm.h"
35#include "i915_drv.h" 35#include "i915_drv.h"
36#include <linux/vgaarb.h>
36 37
37/* Really want an OS-independent resettable timer. Would like to have 38/* Really want an OS-independent resettable timer. Would like to have
38 * this loop run for (eg) 3 sec, but have the timer reset every time 39 * this loop run for (eg) 3 sec, but have the timer reset every time
@@ -1012,6 +1013,19 @@ static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size,
1012 return 0; 1013 return 0;
1013} 1014}
1014 1015
1016/* true = enable decode, false = disable decoder */
1017static unsigned int i915_vga_set_decode(void *cookie, bool state)
1018{
1019 struct drm_device *dev = cookie;
1020
1021 intel_modeset_vga_set_state(dev, state);
1022 if (state)
1023 return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
1024 VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
1025 else
1026 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
1027}
1028
1015static int i915_load_modeset_init(struct drm_device *dev, 1029static int i915_load_modeset_init(struct drm_device *dev,
1016 unsigned long prealloc_size, 1030 unsigned long prealloc_size,
1017 unsigned long agp_size) 1031 unsigned long agp_size)
@@ -1057,6 +1071,11 @@ static int i915_load_modeset_init(struct drm_device *dev,
1057 if (ret) 1071 if (ret)
1058 DRM_INFO("failed to find VBIOS tables\n"); 1072 DRM_INFO("failed to find VBIOS tables\n");
1059 1073
1074 /* if we have > 1 VGA cards, then disable the radeon VGA resources */
1075 ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
1076 if (ret)
1077 goto destroy_ringbuffer;
1078
1060 ret = drm_irq_install(dev); 1079 ret = drm_irq_install(dev);
1061 if (ret) 1080 if (ret)
1062 goto destroy_ringbuffer; 1081 goto destroy_ringbuffer;
@@ -1324,6 +1343,7 @@ int i915_driver_unload(struct drm_device *dev)
1324 1343
1325 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 1344 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
1326 drm_irq_uninstall(dev); 1345 drm_irq_uninstall(dev);
1346 vga_client_register(dev->pdev, NULL, NULL, NULL);
1327 } 1347 }
1328 1348
1329 if (dev->pdev->msi_enabled) 1349 if (dev->pdev->msi_enabled)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 77ed060b4292..a0632f8e76ac 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -766,6 +766,7 @@ static inline void opregion_enable_asle(struct drm_device *dev) { return; }
766/* modesetting */ 766/* modesetting */
767extern void intel_modeset_init(struct drm_device *dev); 767extern void intel_modeset_init(struct drm_device *dev);
768extern void intel_modeset_cleanup(struct drm_device *dev); 768extern void intel_modeset_cleanup(struct drm_device *dev);
769extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
769 770
770/** 771/**
771 * Lock test for when it's just for synchronization of ring access. 772 * Lock test for when it's just for synchronization of ring access.
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e38cd21161c8..3f7963553464 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -30,6 +30,7 @@
30 * fb aperture size and the amount of pre-reserved memory. 30 * fb aperture size and the amount of pre-reserved memory.
31 */ 31 */
32#define INTEL_GMCH_CTRL 0x52 32#define INTEL_GMCH_CTRL 0x52
33#define INTEL_GMCH_VGA_DISABLE (1 << 1)
33#define INTEL_GMCH_ENABLED 0x4 34#define INTEL_GMCH_ENABLED 0x4
34#define INTEL_GMCH_MEM_MASK 0x1 35#define INTEL_GMCH_MEM_MASK 0x1
35#define INTEL_GMCH_MEM_64M 0x1 36#define INTEL_GMCH_MEM_64M 0x1
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 155719ff99d1..0227b1652906 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3917,3 +3917,20 @@ struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
3917 3917
3918 return &intel_output->enc; 3918 return &intel_output->enc;
3919} 3919}
3920
3921/*
3922 * set vga decode state - true == enable VGA decode
3923 */
3924int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
3925{
3926 struct drm_i915_private *dev_priv = dev->dev_private;
3927 u16 gmch_ctrl;
3928
3929 pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &gmch_ctrl);
3930 if (state)
3931 gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
3932 else
3933 gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
3934 pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl);
3935 return 0;
3936}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index b9e47f1e1cc0..3a0004f755d0 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -178,4 +178,5 @@ extern int intel_framebuffer_create(struct drm_device *dev,
178 struct drm_mode_fb_cmd *mode_cmd, 178 struct drm_mode_fb_cmd *mode_cmd,
179 struct drm_framebuffer **fb, 179 struct drm_framebuffer **fb,
180 struct drm_gem_object *obj); 180 struct drm_gem_object *obj);
181
181#endif /* __INTEL_DRV_H__ */ 182#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 737970b43aef..be51c5f7d0f6 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -1955,6 +1955,20 @@ void r100_vram_init_sizes(struct radeon_device *rdev)
1955 rdev->mc.real_vram_size = rdev->mc.aper_size; 1955 rdev->mc.real_vram_size = rdev->mc.aper_size;
1956} 1956}
1957 1957
1958void r100_vga_set_state(struct radeon_device *rdev, bool state)
1959{
1960 uint32_t temp;
1961
1962 temp = RREG32(RADEON_CONFIG_CNTL);
1963 if (state == false) {
1964 temp &= ~(1<<8);
1965 temp |= (1<<9);
1966 } else {
1967 temp &= ~(1<<9);
1968 }
1969 WREG32(RADEON_CONFIG_CNTL, temp);
1970}
1971
1958void r100_vram_info(struct radeon_device *rdev) 1972void r100_vram_info(struct radeon_device *rdev)
1959{ 1973{
1960 r100_vram_get_type(rdev); 1974 r100_vram_get_type(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 5f42fad19190..eab31c1d6df1 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -1499,6 +1499,20 @@ int r600_startup(struct radeon_device *rdev)
1499 return 0; 1499 return 0;
1500} 1500}
1501 1501
1502void r600_vga_set_state(struct radeon_device *rdev, bool state)
1503{
1504 uint32_t temp;
1505
1506 temp = RREG32(CONFIG_CNTL);
1507 if (state == false) {
1508 temp &= ~(1<<0);
1509 temp |= (1<<1);
1510 } else {
1511 temp &= ~(1<<1);
1512 }
1513 WREG32(CONFIG_CNTL, temp);
1514}
1515
1502int r600_resume(struct radeon_device *rdev) 1516int r600_resume(struct radeon_device *rdev)
1503{ 1517{
1504 int r; 1518 int r;
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index 723295f59281..4a9028a85c9b 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -78,6 +78,7 @@
78#define CB_COLOR0_MASK 0x28100 78#define CB_COLOR0_MASK 0x28100
79 79
80#define CONFIG_MEMSIZE 0x5428 80#define CONFIG_MEMSIZE 0x5428
81#define CONFIG_CNTL 0x5424
81#define CP_STAT 0x8680 82#define CP_STAT 0x8680
82#define CP_COHER_BASE 0x85F8 83#define CP_COHER_BASE 0x85F8
83#define CP_DEBUG 0xC1FC 84#define CP_DEBUG 0xC1FC
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 817af8ecff10..c839b608970f 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -596,6 +596,7 @@ struct radeon_asic {
596 int (*suspend)(struct radeon_device *rdev); 596 int (*suspend)(struct radeon_device *rdev);
597 void (*errata)(struct radeon_device *rdev); 597 void (*errata)(struct radeon_device *rdev);
598 void (*vram_info)(struct radeon_device *rdev); 598 void (*vram_info)(struct radeon_device *rdev);
599 void (*vga_set_state)(struct radeon_device *rdev, bool state);
599 int (*gpu_reset)(struct radeon_device *rdev); 600 int (*gpu_reset)(struct radeon_device *rdev);
600 int (*mc_init)(struct radeon_device *rdev); 601 int (*mc_init)(struct radeon_device *rdev);
601 void (*mc_fini)(struct radeon_device *rdev); 602 void (*mc_fini)(struct radeon_device *rdev);
@@ -954,6 +955,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
954#define radeon_cs_parse(p) rdev->asic->cs_parse((p)) 955#define radeon_cs_parse(p) rdev->asic->cs_parse((p))
955#define radeon_errata(rdev) (rdev)->asic->errata((rdev)) 956#define radeon_errata(rdev) (rdev)->asic->errata((rdev))
956#define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev)) 957#define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev))
958#define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state))
957#define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((rdev)) 959#define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((rdev))
958#define radeon_mc_init(rdev) (rdev)->asic->mc_init((rdev)) 960#define radeon_mc_init(rdev) (rdev)->asic->mc_init((rdev))
959#define radeon_mc_fini(rdev) (rdev)->asic->mc_fini((rdev)) 961#define radeon_mc_fini(rdev) (rdev)->asic->mc_fini((rdev))
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 5f2a9e6f12c5..8968f78fa1e3 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -47,6 +47,7 @@ uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg);
47void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 47void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
48void r100_errata(struct radeon_device *rdev); 48void r100_errata(struct radeon_device *rdev);
49void r100_vram_info(struct radeon_device *rdev); 49void r100_vram_info(struct radeon_device *rdev);
50void r100_vga_set_state(struct radeon_device *rdev, bool state);
50int r100_gpu_reset(struct radeon_device *rdev); 51int r100_gpu_reset(struct radeon_device *rdev);
51int r100_mc_init(struct radeon_device *rdev); 52int r100_mc_init(struct radeon_device *rdev);
52void r100_mc_fini(struct radeon_device *rdev); 53void r100_mc_fini(struct radeon_device *rdev);
@@ -89,6 +90,7 @@ static struct radeon_asic r100_asic = {
89 .init = &r100_init, 90 .init = &r100_init,
90 .errata = &r100_errata, 91 .errata = &r100_errata,
91 .vram_info = &r100_vram_info, 92 .vram_info = &r100_vram_info,
93 .vga_set_state = &r100_vga_set_state,
92 .gpu_reset = &r100_gpu_reset, 94 .gpu_reset = &r100_gpu_reset,
93 .mc_init = &r100_mc_init, 95 .mc_init = &r100_mc_init,
94 .mc_fini = &r100_mc_fini, 96 .mc_fini = &r100_mc_fini,
@@ -158,6 +160,7 @@ static struct radeon_asic r300_asic = {
158 .init = &r300_init, 160 .init = &r300_init,
159 .errata = &r300_errata, 161 .errata = &r300_errata,
160 .vram_info = &r300_vram_info, 162 .vram_info = &r300_vram_info,
163 .vga_set_state = &r100_vga_set_state,
161 .gpu_reset = &r300_gpu_reset, 164 .gpu_reset = &r300_gpu_reset,
162 .mc_init = &r300_mc_init, 165 .mc_init = &r300_mc_init,
163 .mc_fini = &r300_mc_fini, 166 .mc_fini = &r300_mc_fini,
@@ -208,6 +211,7 @@ static struct radeon_asic r420_asic = {
208 .resume = &r420_resume, 211 .resume = &r420_resume,
209 .errata = NULL, 212 .errata = NULL,
210 .vram_info = NULL, 213 .vram_info = NULL,
214 .vga_set_state = &r100_vga_set_state,
211 .gpu_reset = &r300_gpu_reset, 215 .gpu_reset = &r300_gpu_reset,
212 .mc_init = NULL, 216 .mc_init = NULL,
213 .mc_fini = NULL, 217 .mc_fini = NULL,
@@ -262,6 +266,7 @@ static struct radeon_asic rs400_asic = {
262 .init = &r300_init, 266 .init = &r300_init,
263 .errata = &rs400_errata, 267 .errata = &rs400_errata,
264 .vram_info = &rs400_vram_info, 268 .vram_info = &rs400_vram_info,
269 .vga_set_state = &r100_vga_set_state,
265 .gpu_reset = &r300_gpu_reset, 270 .gpu_reset = &r300_gpu_reset,
266 .mc_init = &rs400_mc_init, 271 .mc_init = &rs400_mc_init,
267 .mc_fini = &rs400_mc_fini, 272 .mc_fini = &rs400_mc_fini,
@@ -323,6 +328,7 @@ static struct radeon_asic rs600_asic = {
323 .init = &rs600_init, 328 .init = &rs600_init,
324 .errata = &rs600_errata, 329 .errata = &rs600_errata,
325 .vram_info = &rs600_vram_info, 330 .vram_info = &rs600_vram_info,
331 .vga_set_state = &r100_vga_set_state,
326 .gpu_reset = &r300_gpu_reset, 332 .gpu_reset = &r300_gpu_reset,
327 .mc_init = &rs600_mc_init, 333 .mc_init = &rs600_mc_init,
328 .mc_fini = &rs600_mc_fini, 334 .mc_fini = &rs600_mc_fini,
@@ -372,6 +378,7 @@ static struct radeon_asic rs690_asic = {
372 .init = &rs600_init, 378 .init = &rs600_init,
373 .errata = &rs690_errata, 379 .errata = &rs690_errata,
374 .vram_info = &rs690_vram_info, 380 .vram_info = &rs690_vram_info,
381 .vga_set_state = &r100_vga_set_state,
375 .gpu_reset = &r300_gpu_reset, 382 .gpu_reset = &r300_gpu_reset,
376 .mc_init = &rs690_mc_init, 383 .mc_init = &rs690_mc_init,
377 .mc_fini = &rs690_mc_fini, 384 .mc_fini = &rs690_mc_fini,
@@ -428,6 +435,7 @@ static struct radeon_asic rv515_asic = {
428 .init = &rv515_init, 435 .init = &rv515_init,
429 .errata = &rv515_errata, 436 .errata = &rv515_errata,
430 .vram_info = &rv515_vram_info, 437 .vram_info = &rv515_vram_info,
438 .vga_set_state = &r100_vga_set_state,
431 .gpu_reset = &rv515_gpu_reset, 439 .gpu_reset = &rv515_gpu_reset,
432 .mc_init = &rv515_mc_init, 440 .mc_init = &rv515_mc_init,
433 .mc_fini = &rv515_mc_fini, 441 .mc_fini = &rv515_mc_fini,
@@ -477,6 +485,7 @@ static struct radeon_asic r520_asic = {
477 .init = &rv515_init, 485 .init = &rv515_init,
478 .errata = &r520_errata, 486 .errata = &r520_errata,
479 .vram_info = &r520_vram_info, 487 .vram_info = &r520_vram_info,
488 .vga_set_state = &r100_vga_set_state,
480 .gpu_reset = &rv515_gpu_reset, 489 .gpu_reset = &rv515_gpu_reset,
481 .mc_init = &r520_mc_init, 490 .mc_init = &r520_mc_init,
482 .mc_fini = &r520_mc_fini, 491 .mc_fini = &r520_mc_fini,
@@ -520,6 +529,7 @@ int r600_init(struct radeon_device *rdev);
520void r600_fini(struct radeon_device *rdev); 529void r600_fini(struct radeon_device *rdev);
521int r600_suspend(struct radeon_device *rdev); 530int r600_suspend(struct radeon_device *rdev);
522int r600_resume(struct radeon_device *rdev); 531int r600_resume(struct radeon_device *rdev);
532void r600_vga_set_state(struct radeon_device *rdev, bool state);
523int r600_wb_init(struct radeon_device *rdev); 533int r600_wb_init(struct radeon_device *rdev);
524void r600_wb_fini(struct radeon_device *rdev); 534void r600_wb_fini(struct radeon_device *rdev);
525void r600_cp_commit(struct radeon_device *rdev); 535void r600_cp_commit(struct radeon_device *rdev);
@@ -556,6 +566,7 @@ static struct radeon_asic r600_asic = {
556 .resume = &r600_resume, 566 .resume = &r600_resume,
557 .cp_commit = &r600_cp_commit, 567 .cp_commit = &r600_cp_commit,
558 .vram_info = NULL, 568 .vram_info = NULL,
569 .vga_set_state = &r600_vga_set_state,
559 .gpu_reset = &r600_gpu_reset, 570 .gpu_reset = &r600_gpu_reset,
560 .mc_init = NULL, 571 .mc_init = NULL,
561 .mc_fini = NULL, 572 .mc_fini = NULL,
@@ -606,6 +617,7 @@ static struct radeon_asic rv770_asic = {
606 .cp_commit = &r600_cp_commit, 617 .cp_commit = &r600_cp_commit,
607 .vram_info = NULL, 618 .vram_info = NULL,
608 .gpu_reset = &rv770_gpu_reset, 619 .gpu_reset = &rv770_gpu_reset,
620 .vga_set_state = &r600_vga_set_state,
609 .mc_init = NULL, 621 .mc_init = NULL,
610 .mc_fini = NULL, 622 .mc_fini = NULL,
611 .wb_init = &r600_wb_init, 623 .wb_init = &r600_wb_init,
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 8a40c616b534..daf5db780956 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -29,6 +29,7 @@
29#include <drm/drmP.h> 29#include <drm/drmP.h>
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 "radeon_reg.h" 33#include "radeon_reg.h"
33#include "radeon.h" 34#include "radeon.h"
34#include "radeon_asic.h" 35#include "radeon_asic.h"
@@ -480,7 +481,18 @@ void radeon_combios_fini(struct radeon_device *rdev)
480{ 481{
481} 482}
482 483
484/* if we get transitioned to only one device, tak VGA back */
485static unsigned int radeon_vga_set_decode(void *cookie, bool state)
486{
487 struct radeon_device *rdev = cookie;
483 488
489 radeon_vga_set_state(rdev, state);
490 if (state)
491 return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
492 VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
493 else
494 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
495}
484/* 496/*
485 * Radeon device. 497 * Radeon device.
486 */ 498 */
@@ -578,6 +590,13 @@ int radeon_device_init(struct radeon_device *rdev,
578 if (r) { 590 if (r) {
579 return r; 591 return r;
580 } 592 }
593
594 /* if we have > 1 VGA cards, then disable the radeon VGA resources */
595 r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
596 if (r) {
597 return -EINVAL;
598 }
599
581 if (!rdev->new_init_path) { 600 if (!rdev->new_init_path) {
582 /* Setup errata flags */ 601 /* Setup errata flags */
583 radeon_errata(rdev); 602 radeon_errata(rdev);
@@ -586,7 +605,6 @@ int radeon_device_init(struct radeon_device *rdev,
586 /* Initialize surface registers */ 605 /* Initialize surface registers */
587 radeon_surface_init(rdev); 606 radeon_surface_init(rdev);
588 607
589 /* TODO: disable VGA need to use VGA request */
590 /* BIOS*/ 608 /* BIOS*/
591 if (!radeon_get_bios(rdev)) { 609 if (!radeon_get_bios(rdev)) {
592 if (ASIC_IS_AVIVO(rdev)) 610 if (ASIC_IS_AVIVO(rdev))
@@ -697,6 +715,7 @@ void radeon_device_fini(struct radeon_device *rdev)
697 radeon_agp_fini(rdev); 715 radeon_agp_fini(rdev);
698#endif 716#endif
699 radeon_irq_kms_fini(rdev); 717 radeon_irq_kms_fini(rdev);
718 vga_client_register(rdev->pdev, NULL, NULL, NULL);
700 radeon_fence_driver_fini(rdev); 719 radeon_fence_driver_fini(rdev);
701 radeon_clocks_fini(rdev); 720 radeon_clocks_fini(rdev);
702 radeon_object_fini(rdev); 721 radeon_object_fini(rdev);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index eeefb6369e19..c8e64bbadbcf 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -810,6 +810,9 @@ struct drm_driver {
810 int (*gem_init_object) (struct drm_gem_object *obj); 810 int (*gem_init_object) (struct drm_gem_object *obj);
811 void (*gem_free_object) (struct drm_gem_object *obj); 811 void (*gem_free_object) (struct drm_gem_object *obj);
812 812
813 /* vga arb irq handler */
814 void (*vgaarb_irq)(struct drm_device *dev, bool state);
815
813 /* Driver private ops for this object */ 816 /* Driver private ops for this object */
814 struct vm_operations_struct *gem_vm_ops; 817 struct vm_operations_struct *gem_vm_ops;
815 818