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