aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 572ac309d23c..ad273ad7b591 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -45,6 +45,7 @@
45static struct nouveau_dsm_priv { 45static struct nouveau_dsm_priv {
46 bool dsm_detected; 46 bool dsm_detected;
47 bool optimus_detected; 47 bool optimus_detected;
48 bool optimus_flags_detected;
48 acpi_handle dhandle; 49 acpi_handle dhandle;
49 acpi_handle rom_handle; 50 acpi_handle rom_handle;
50} nouveau_dsm_priv; 51} nouveau_dsm_priv;
@@ -212,7 +213,8 @@ static const struct vga_switcheroo_handler nouveau_dsm_handler = {
212}; 213};
213 214
214static void nouveau_dsm_pci_probe(struct pci_dev *pdev, acpi_handle *dhandle_out, 215static void nouveau_dsm_pci_probe(struct pci_dev *pdev, acpi_handle *dhandle_out,
215 bool *has_mux, bool *has_opt) 216 bool *has_mux, bool *has_opt,
217 bool *has_opt_flags)
216{ 218{
217 acpi_handle dhandle; 219 acpi_handle dhandle;
218 bool supports_mux; 220 bool supports_mux;
@@ -236,6 +238,7 @@ static void nouveau_dsm_pci_probe(struct pci_dev *pdev, acpi_handle *dhandle_out
236 *dhandle_out = dhandle; 238 *dhandle_out = dhandle;
237 *has_mux = supports_mux; 239 *has_mux = supports_mux;
238 *has_opt = !!optimus_funcs; 240 *has_opt = !!optimus_funcs;
241 *has_opt_flags = optimus_funcs & (1 << NOUVEAU_DSM_OPTIMUS_FLAGS);
239 242
240 if (optimus_funcs) { 243 if (optimus_funcs) {
241 uint32_t result; 244 uint32_t result;
@@ -256,6 +259,7 @@ static bool nouveau_dsm_detect(void)
256 acpi_handle dhandle = NULL; 259 acpi_handle dhandle = NULL;
257 bool has_mux = false; 260 bool has_mux = false;
258 bool has_optimus = false; 261 bool has_optimus = false;
262 bool has_optimus_flags = false;
259 int vga_count = 0; 263 int vga_count = 0;
260 bool guid_valid; 264 bool guid_valid;
261 bool ret = false; 265 bool ret = false;
@@ -270,13 +274,15 @@ static bool nouveau_dsm_detect(void)
270 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { 274 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
271 vga_count++; 275 vga_count++;
272 276
273 nouveau_dsm_pci_probe(pdev, &dhandle, &has_mux, &has_optimus); 277 nouveau_dsm_pci_probe(pdev, &dhandle, &has_mux, &has_optimus,
278 &has_optimus_flags);
274 } 279 }
275 280
276 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_3D << 8, pdev)) != NULL) { 281 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_3D << 8, pdev)) != NULL) {
277 vga_count++; 282 vga_count++;
278 283
279 nouveau_dsm_pci_probe(pdev, &dhandle, &has_mux, &has_optimus); 284 nouveau_dsm_pci_probe(pdev, &dhandle, &has_mux, &has_optimus,
285 &has_optimus_flags);
280 } 286 }
281 287
282 /* find the optimus DSM or the old v1 DSM */ 288 /* find the optimus DSM or the old v1 DSM */
@@ -287,6 +293,7 @@ static bool nouveau_dsm_detect(void)
287 printk(KERN_INFO "VGA switcheroo: detected Optimus DSM method %s handle\n", 293 printk(KERN_INFO "VGA switcheroo: detected Optimus DSM method %s handle\n",
288 acpi_method_name); 294 acpi_method_name);
289 nouveau_dsm_priv.optimus_detected = true; 295 nouveau_dsm_priv.optimus_detected = true;
296 nouveau_dsm_priv.optimus_flags_detected = has_optimus_flags;
290 ret = true; 297 ret = true;
291 } else if (vga_count == 2 && has_mux && guid_valid) { 298 } else if (vga_count == 2 && has_mux && guid_valid) {
292 nouveau_dsm_priv.dhandle = dhandle; 299 nouveau_dsm_priv.dhandle = dhandle;
@@ -320,8 +327,9 @@ void nouveau_switcheroo_optimus_dsm(void)
320 if (!nouveau_dsm_priv.optimus_detected) 327 if (!nouveau_dsm_priv.optimus_detected)
321 return; 328 return;
322 329
323 nouveau_optimus_dsm(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_FLAGS, 330 if (nouveau_dsm_priv.optimus_flags_detected)
324 0x3, &result); 331 nouveau_optimus_dsm(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_FLAGS,
332 0x3, &result);
325 333
326 nouveau_optimus_dsm(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_CAPS, 334 nouveau_optimus_dsm(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_CAPS,
327 NOUVEAU_DSM_OPTIMUS_SET_POWERDOWN, &result); 335 NOUVEAU_DSM_OPTIMUS_SET_POWERDOWN, &result);