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