diff options
-rw-r--r-- | drivers/gpu/drm/drm_irq.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600d.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 21 | ||||
-rw-r--r-- | include/drm/drmP.h | 3 |
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 | } |
172 | EXPORT_SYMBOL(drm_vblank_init); | 173 | EXPORT_SYMBOL(drm_vblank_init); |
173 | 174 | ||
175 | static 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 */ | ||
1017 | static 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 | |||
1015 | static int i915_load_modeset_init(struct drm_device *dev, | 1029 | static 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 */ |
767 | extern void intel_modeset_init(struct drm_device *dev); | 767 | extern void intel_modeset_init(struct drm_device *dev); |
768 | extern void intel_modeset_cleanup(struct drm_device *dev); | 768 | extern void intel_modeset_cleanup(struct drm_device *dev); |
769 | extern 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 | */ | ||
3924 | int 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 | ||
1958 | void 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 | |||
1958 | void r100_vram_info(struct radeon_device *rdev) | 1972 | void 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 | ||
1502 | void 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 | |||
1502 | int r600_resume(struct radeon_device *rdev) | 1516 | int 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); | |||
47 | void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 47 | void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
48 | void r100_errata(struct radeon_device *rdev); | 48 | void r100_errata(struct radeon_device *rdev); |
49 | void r100_vram_info(struct radeon_device *rdev); | 49 | void r100_vram_info(struct radeon_device *rdev); |
50 | void r100_vga_set_state(struct radeon_device *rdev, bool state); | ||
50 | int r100_gpu_reset(struct radeon_device *rdev); | 51 | int r100_gpu_reset(struct radeon_device *rdev); |
51 | int r100_mc_init(struct radeon_device *rdev); | 52 | int r100_mc_init(struct radeon_device *rdev); |
52 | void r100_mc_fini(struct radeon_device *rdev); | 53 | void 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); | |||
520 | void r600_fini(struct radeon_device *rdev); | 529 | void r600_fini(struct radeon_device *rdev); |
521 | int r600_suspend(struct radeon_device *rdev); | 530 | int r600_suspend(struct radeon_device *rdev); |
522 | int r600_resume(struct radeon_device *rdev); | 531 | int r600_resume(struct radeon_device *rdev); |
532 | void r600_vga_set_state(struct radeon_device *rdev, bool state); | ||
523 | int r600_wb_init(struct radeon_device *rdev); | 533 | int r600_wb_init(struct radeon_device *rdev); |
524 | void r600_wb_fini(struct radeon_device *rdev); | 534 | void r600_wb_fini(struct radeon_device *rdev); |
525 | void r600_cp_commit(struct radeon_device *rdev); | 535 | void 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 */ | ||
485 | static 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 | ||