diff options
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_acpi.c | 18 |
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 @@ | |||
45 | static struct nouveau_dsm_priv { | 45 | static 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 | ||
214 | static void nouveau_dsm_pci_probe(struct pci_dev *pdev, acpi_handle *dhandle_out, | 215 | static 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); |