nouveau_vga.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. if ((nouveau_is_optimus() || nouveau_is_v1_dsm()) && state == VGA_SWITCHEROO_OFF)
  29. return;
  30. if (state == VGA_SWITCHEROO_ON) {
  31. printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
  32. dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
  33. nouveau_pmops_resume(&pdev->dev);
  34. drm_kms_helper_poll_enable(dev);
  35. dev->switch_power_state = DRM_SWITCH_POWER_ON;
  36. } else {
  37. printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
  38. dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
  39. drm_kms_helper_poll_disable(dev);
  40. nouveau_switcheroo_optimus_dsm();
  41. nouveau_pmops_suspend(&pdev->dev);
  42. dev->switch_power_state = DRM_SWITCH_POWER_OFF;
  43. }
  44. }
  45. static void
  46. nouveau_switcheroo_reprobe(struct pci_dev *pdev)
  47. {
  48. struct drm_device *dev = pci_get_drvdata(pdev);
  49. nouveau_fbcon_output_poll_changed(dev);
  50. }
  51. static bool
  52. nouveau_switcheroo_can_switch(struct pci_dev *pdev)
  53. {
  54. struct drm_device *dev = pci_get_drvdata(pdev);
  55. bool can_switch;
  56. spin_lock(&dev->count_lock);
  57. can_switch = (dev->open_count == 0);
  58. spin_unlock(&dev->count_lock);
  59. return can_switch;
  60. }
  61. static const struct vga_switcheroo_client_ops
  62. nouveau_switcheroo_ops = {
  63. .set_gpu_state = nouveau_switcheroo_set_state,
  64. .reprobe = nouveau_switcheroo_reprobe,
  65. .can_switch = nouveau_switcheroo_can_switch,
  66. };
  67. void
  68. nouveau_vga_init(struct nouveau_drm *drm)
  69. {
  70. struct drm_device *dev = drm->dev;
  71. bool runtime = false;
  72. vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
  73. if (nouveau_runtime_pm == 1)
  74. runtime = true;
  75. if ((nouveau_runtime_pm == -1) && (nouveau_is_optimus() || nouveau_is_v1_dsm()))
  76. runtime = true;
  77. vga_switcheroo_register_client(dev->pdev, &nouveau_switcheroo_ops, runtime);
  78. if (runtime && nouveau_is_v1_dsm() && !nouveau_is_optimus())
  79. vga_switcheroo_init_domain_pm_ops(drm->dev->dev, &drm->vga_pm_domain);
  80. }
  81. void
  82. nouveau_vga_fini(struct nouveau_drm *drm)
  83. {
  84. struct drm_device *dev = drm->dev;
  85. vga_switcheroo_unregister_client(dev->pdev);
  86. vga_client_register(dev->pdev, NULL, NULL, NULL);
  87. }
  88. void
  89. nouveau_vga_lastclose(struct drm_device *dev)
  90. {
  91. vga_switcheroo_process_delayed_switch();
  92. }