aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-03-01 01:22:38 -0500
committerDave Airlie <airlied@redhat.com>2010-03-01 01:22:38 -0500
commit1c62233508ef7104f8a78e571fdf5c72d0dc0200 (patch)
tree31e19cbff5c1080d3015d20b24dd43ee95f4ed8c /drivers/gpu/drm/i915
parent6d9c13513661c1991bf5f4e6e1363c721292d819 (diff)
parent6a9ee8af344e3bd7dbd61e67037096cdf7f83289 (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.c35
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c4
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c2
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
1385static 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
1400static 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
1384static int i915_load_modeset_init(struct drm_device *dev, 1411static 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
217static int i915_suspend(struct drm_device *dev, pm_message_t state) 217int 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
271static int i915_resume(struct drm_device *dev) 271int 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;
773extern unsigned int i915_powersave; 773extern unsigned int i915_powersave;
774extern unsigned int i915_lvds_downclock; 774extern unsigned int i915_lvds_downclock;
775 775
776extern int i915_suspend(struct drm_device *dev, pm_message_t state);
777extern int i915_resume(struct drm_device *dev);
776extern void i915_save_display(struct drm_device *dev); 778extern void i915_save_display(struct drm_device *dev);
777extern void i915_restore_display(struct drm_device *dev); 779extern void i915_restore_display(struct drm_device *dev);
778extern int i915_master_create(struct drm_device *dev, struct drm_master *master); 780extern 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
240out_unpin: 242out_unpin: