diff options
author | Dave Airlie <airlied@redhat.com> | 2010-03-01 01:22:38 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-03-01 01:22:38 -0500 |
commit | 1c62233508ef7104f8a78e571fdf5c72d0dc0200 (patch) | |
tree | 31e19cbff5c1080d3015d20b24dd43ee95f4ed8c /drivers/gpu/drm/i915 | |
parent | 6d9c13513661c1991bf5f4e6e1363c721292d819 (diff) | |
parent | 6a9ee8af344e3bd7dbd61e67037096cdf7f83289 (diff) |
Merge branch 'gpu-switcher' of /ssd/git//linux-2.6 into drm-next-stage
* 'gpu-switcher' of /ssd/git//linux-2.6:
vga_switcheroo: initial implementation (v15)
fb: for framebuffer handover don't exit the loop early.
Conflicts:
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/radeon/Makefile
drivers/gpu/drm/radeon/radeon.h
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 35 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_fb.c | 2 |
4 files changed, 41 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 3e658d6a6b7d..8bfc0bbf13e6 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/vgaarb.h> | 37 | #include <linux/vgaarb.h> |
38 | #include <linux/acpi.h> | 38 | #include <linux/acpi.h> |
39 | #include <linux/pnp.h> | 39 | #include <linux/pnp.h> |
40 | #include <linux/vga_switcheroo.h> | ||
40 | 41 | ||
41 | /* Really want an OS-independent resettable timer. Would like to have | 42 | /* Really want an OS-independent resettable timer. Would like to have |
42 | * this loop run for (eg) 3 sec, but have the timer reset every time | 43 | * this loop run for (eg) 3 sec, but have the timer reset every time |
@@ -1381,6 +1382,32 @@ static unsigned int i915_vga_set_decode(void *cookie, bool state) | |||
1381 | return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; | 1382 | return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; |
1382 | } | 1383 | } |
1383 | 1384 | ||
1385 | static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) | ||
1386 | { | ||
1387 | struct drm_device *dev = pci_get_drvdata(pdev); | ||
1388 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; | ||
1389 | if (state == VGA_SWITCHEROO_ON) { | ||
1390 | printk(KERN_INFO "i915: switched off\n"); | ||
1391 | /* i915 resume handler doesn't set to D0 */ | ||
1392 | pci_set_power_state(dev->pdev, PCI_D0); | ||
1393 | i915_resume(dev); | ||
1394 | } else { | ||
1395 | printk(KERN_ERR "i915: switched off\n"); | ||
1396 | i915_suspend(dev, pmm); | ||
1397 | } | ||
1398 | } | ||
1399 | |||
1400 | static bool i915_switcheroo_can_switch(struct pci_dev *pdev) | ||
1401 | { | ||
1402 | struct drm_device *dev = pci_get_drvdata(pdev); | ||
1403 | bool can_switch; | ||
1404 | |||
1405 | spin_lock(&dev->count_lock); | ||
1406 | can_switch = (dev->open_count == 0); | ||
1407 | spin_unlock(&dev->count_lock); | ||
1408 | return can_switch; | ||
1409 | } | ||
1410 | |||
1384 | static int i915_load_modeset_init(struct drm_device *dev, | 1411 | static int i915_load_modeset_init(struct drm_device *dev, |
1385 | unsigned long prealloc_start, | 1412 | unsigned long prealloc_start, |
1386 | unsigned long prealloc_size, | 1413 | unsigned long prealloc_size, |
@@ -1442,6 +1469,12 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1442 | if (ret) | 1469 | if (ret) |
1443 | goto destroy_ringbuffer; | 1470 | goto destroy_ringbuffer; |
1444 | 1471 | ||
1472 | ret = vga_switcheroo_register_client(dev->pdev, | ||
1473 | i915_switcheroo_set_state, | ||
1474 | i915_switcheroo_can_switch); | ||
1475 | if (ret) | ||
1476 | goto destroy_ringbuffer; | ||
1477 | |||
1445 | intel_modeset_init(dev); | 1478 | intel_modeset_init(dev); |
1446 | 1479 | ||
1447 | ret = drm_irq_install(dev); | 1480 | ret = drm_irq_install(dev); |
@@ -1733,6 +1766,7 @@ int i915_driver_unload(struct drm_device *dev) | |||
1733 | dev_priv->child_dev_num = 0; | 1766 | dev_priv->child_dev_num = 0; |
1734 | } | 1767 | } |
1735 | drm_irq_uninstall(dev); | 1768 | drm_irq_uninstall(dev); |
1769 | vga_switcheroo_unregister_client(dev->pdev); | ||
1736 | vga_client_register(dev->pdev, NULL, NULL, NULL); | 1770 | vga_client_register(dev->pdev, NULL, NULL, NULL); |
1737 | } | 1771 | } |
1738 | 1772 | ||
@@ -1802,6 +1836,7 @@ void i915_driver_lastclose(struct drm_device * dev) | |||
1802 | 1836 | ||
1803 | if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { | 1837 | if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { |
1804 | drm_fb_helper_restore(); | 1838 | drm_fb_helper_restore(); |
1839 | vga_switcheroo_process_delayed_switch(); | ||
1805 | return; | 1840 | return; |
1806 | } | 1841 | } |
1807 | 1842 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 85ad020125c8..1b2e95455c05 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -214,7 +214,7 @@ static int i915_drm_freeze(struct drm_device *dev) | |||
214 | return 0; | 214 | return 0; |
215 | } | 215 | } |
216 | 216 | ||
217 | static int i915_suspend(struct drm_device *dev, pm_message_t state) | 217 | int i915_suspend(struct drm_device *dev, pm_message_t state) |
218 | { | 218 | { |
219 | int error; | 219 | int error; |
220 | 220 | ||
@@ -268,7 +268,7 @@ static int i915_drm_thaw(struct drm_device *dev) | |||
268 | return error; | 268 | return error; |
269 | } | 269 | } |
270 | 270 | ||
271 | static int i915_resume(struct drm_device *dev) | 271 | int i915_resume(struct drm_device *dev) |
272 | { | 272 | { |
273 | if (pci_enable_device(dev->pdev)) | 273 | if (pci_enable_device(dev->pdev)) |
274 | return -EIO; | 274 | return -EIO; |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f97592609da4..979439cfb827 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -773,6 +773,8 @@ extern unsigned int i915_fbpercrtc; | |||
773 | extern unsigned int i915_powersave; | 773 | extern unsigned int i915_powersave; |
774 | extern unsigned int i915_lvds_downclock; | 774 | extern unsigned int i915_lvds_downclock; |
775 | 775 | ||
776 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); | ||
777 | extern int i915_resume(struct drm_device *dev); | ||
776 | extern void i915_save_display(struct drm_device *dev); | 778 | extern void i915_save_display(struct drm_device *dev); |
777 | extern void i915_restore_display(struct drm_device *dev); | 779 | extern void i915_restore_display(struct drm_device *dev); |
778 | extern int i915_master_create(struct drm_device *dev, struct drm_master *master); | 780 | extern int i915_master_create(struct drm_device *dev, struct drm_master *master); |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index aaabbcbe5905..8cd791dc5b29 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/fb.h> | 36 | #include <linux/fb.h> |
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/vga_switcheroo.h> | ||
38 | 39 | ||
39 | #include "drmP.h" | 40 | #include "drmP.h" |
40 | #include "drm.h" | 41 | #include "drm.h" |
@@ -235,6 +236,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
235 | obj_priv->gtt_offset, fbo); | 236 | obj_priv->gtt_offset, fbo); |
236 | 237 | ||
237 | mutex_unlock(&dev->struct_mutex); | 238 | mutex_unlock(&dev->struct_mutex); |
239 | vga_switcheroo_client_fb_set(dev->pdev, info); | ||
238 | return 0; | 240 | return 0; |
239 | 241 | ||
240 | out_unpin: | 242 | out_unpin: |