nouveau_vga.c 2.4 KB

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