aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorPeter Lekensteyn <lekensteyn@gmail.com>2011-12-17 06:53:43 -0500
committerDave Airlie <airlied@redhat.com>2012-01-13 04:09:07 -0500
commit9075e85f46c598e4dfc852b16b256a32e2fb396f (patch)
tree841922a76fb85d8cbcaa7d6f64b5ea6c4d067370 /drivers/gpu
parent3b32a592ea6e49145d4dc610b85dd9042226896d (diff)
nouveau: properly check for _DSM function support
According to the ACPI spec version 4, section 9.14.1, _DSM functions must return a value with the first bit enabled if any DSM functions are supported for the given UUID and revision ID. For a given function index n to be marked supported, bit n must be enabled. Signed-off-by: Peter Lekensteyn <lekensteyn@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 525744d593c1..96756d0d6411 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -18,12 +18,6 @@
18 18
19#include <linux/vga_switcheroo.h> 19#include <linux/vga_switcheroo.h>
20 20
21#define NOUVEAU_DSM_SUPPORTED 0x00
22#define NOUVEAU_DSM_SUPPORTED_FUNCTIONS 0x00
23
24#define NOUVEAU_DSM_ACTIVE 0x01
25#define NOUVEAU_DSM_ACTIVE_QUERY 0x00
26
27#define NOUVEAU_DSM_LED 0x02 21#define NOUVEAU_DSM_LED 0x02
28#define NOUVEAU_DSM_LED_STATE 0x00 22#define NOUVEAU_DSM_LED_STATE 0x00
29#define NOUVEAU_DSM_LED_OFF 0x10 23#define NOUVEAU_DSM_LED_OFF 0x10
@@ -35,6 +29,7 @@
35#define NOUVEAU_DSM_POWER_SPEED 0x01 29#define NOUVEAU_DSM_POWER_SPEED 0x01
36#define NOUVEAU_DSM_POWER_STAMINA 0x02 30#define NOUVEAU_DSM_POWER_STAMINA 0x02
37 31
32#define NOUVEAU_DSM_OPTIMUS_FN 0x1A
38static struct nouveau_dsm_priv { 33static struct nouveau_dsm_priv {
39 bool dsm_detected; 34 bool dsm_detected;
40 bool optimus_detected; 35 bool optimus_detected;
@@ -148,6 +143,23 @@ static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
148 return 0; 143 return 0;
149} 144}
150 145
146/* Returns 1 if a DSM function is usable and 0 otherwise */
147static int nouveau_test_dsm(acpi_handle test_handle,
148 int (*dsm_func)(acpi_handle, int, int, uint32_t *),
149 int sfnc)
150{
151 u32 result = 0;
152
153 /* Function 0 returns a Buffer containing available functions. The args
154 * parameter is ignored for function 0, so just put 0 in it */
155 if (dsm_func(test_handle, 0, 0, &result))
156 return 0;
157
158 /* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. If
159 * the n-th bit is enabled, function n is supported */
160 return result & 1 && result & (1 << sfnc);
161}
162
151static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id) 163static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id)
152{ 164{
153 mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); 165 mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0);
@@ -212,8 +224,7 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
212{ 224{
213 acpi_handle dhandle, nvidia_handle; 225 acpi_handle dhandle, nvidia_handle;
214 acpi_status status; 226 acpi_status status;
215 int ret, retval = 0; 227 int retval = 0;
216 uint32_t result;
217 228
218 dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); 229 dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
219 if (!dhandle) 230 if (!dhandle)
@@ -224,13 +235,11 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
224 return false; 235 return false;
225 } 236 }
226 237
227 ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED, 238 if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER))
228 NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result);
229 if (ret == 0)
230 retval |= NOUVEAU_DSM_HAS_MUX; 239 retval |= NOUVEAU_DSM_HAS_MUX;
231 240
232 ret = nouveau_optimus_dsm(dhandle, 0, 0, &result); 241 if (nouveau_test_dsm(dhandle, nouveau_optimus_dsm,
233 if (ret == 0) 242 NOUVEAU_DSM_OPTIMUS_FN))
234 retval |= NOUVEAU_DSM_HAS_OPT; 243 retval |= NOUVEAU_DSM_HAS_OPT;
235 244
236 if (retval) 245 if (retval)