nouveau_vga.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include <linux/vgaarb.h>
  2. #include <linux/vga_switcheroo.h>
  3. #include <drm/drmP.h>
  4. #include <drm/drm_crtc_helper.h>
  5. #include "nouveau_drm.h"
  6. #include "nouveau_acpi.h"
  7. #include "nouveau_fbcon.h"
  8. #include "nouveau_vga.h"
  9. static unsigned int
  10. nouveau_vga_set_decode(void *priv, bool state)
  11. {
  12. struct nouveau_device *device = nouveau_dev(priv);
  13. if (device->chipset >= 0x40)
  14. nv_wr32(device, 0x088054, state);
  15. else
  16. nv_wr32(device, 0x001854, state);
  17. if (state)
  18. return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
  19. VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
  20. else
  21. return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
  22. }
  23. static void
  24. nouveau_switcheroo_set_state(struct pci_dev *pdev,
  25. enum vga_switcheroo_state state)
  26. {
  27. struct drm_device *dev = pci_get_drvdata(pdev);
  28. pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
  29. if (state == VGA_SWITCHEROO_ON) {
  30. printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
  31. dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
  32. nouveau_drm_resume(pdev);
  33. drm_kms_helper_poll_enable(dev);
  34. dev->switch_power_state = DRM_SWITCH_POWER_ON;
  35. } else {
  36. printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
  37. dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
  38. drm_kms_helper_poll_disable(dev);
  39. nouveau_switcheroo_optimus_dsm();
  40. nouveau_drm_suspend(pdev, pmm);
  41. dev->switch_power_state = DRM_SWITCH_POWER_OFF;
  42. }
  43. }
  44. static void
  45. nouveau_switcheroo_reprobe(struct pci_dev *pdev)
  46. {
  47. struct drm_device *dev = pci_get_drvdata(pdev);
  48. nouveau_fbcon_output_poll_changed(dev);
  49. }
  50. static bool
  51. nouveau_switcheroo_can_switch(struct pci_dev *pdev)
  52. {
  53. struct drm_device *dev = pci_get_drvdata(pdev);
  54. bool can_switch;
  55. spin_lock(&dev->count_lock);
  56. can_switch = (dev->open_count == 0);
  57. spin_unlock(&dev->count_lock);
  58. return can_switch;
  59. }
  60. static const struct vga_switcheroo_client_ops
  61. nouveau_switcheroo_ops = {
  62. .set_gpu_state = nouveau_switcheroo_set_state,
  63. .reprobe = nouveau_switcheroo_reprobe,
  64. .can_switch = nouveau_switcheroo_can_switch,
  65. };
  66. void
  67. nouveau_vga_init(struct nouveau_drm *drm)
  68. {
  69. struct drm_device *dev = drm->dev;
  70. vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
  71. vga_switcheroo_register_client(dev->pdev, &nouveau_switcheroo_ops);
  72. }
  73. void
  74. nouveau_vga_fini(struct nouveau_drm *drm)
  75. {
  76. struct drm_device *dev = drm->dev;
  77. vga_switcheroo_unregister_client(dev->pdev);
  78. vga_client_register(dev->pdev, NULL, NULL, NULL);
  79. }
  80. void
  81. nouveau_vga_lastclose(struct drm_device *dev)
  82. {
  83. vga_switcheroo_process_delayed_switch();
  84. }