* properly check for _DSM function support and Optimus support for vga_switcheroo
@ 2011-12-17 12:14 Lekensteyn
[not found] ` <CALBR5ZxR9iuvT57bDZ8yW9ZkZjuoUhBTYw4HBsmsiwoRi4gSkw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 9+ messages in thread
From: Lekensteyn @ 2011-12-17 12:14 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
[-- Attachment #1.1: Type: text/plain, Size: 892 bytes --]
Hello guys,
I've prepared a patch based on my findings for the bbswitch module
(https://github.com/Lekensteyn/acpi-stuff/tree/master/bbswitch). This adds
a proper
check whether a _DSM function is supported or not and make OFF / ON for
vga_switcheroo work for nVidia Optimus models. The patch is based against
the
mainline kernel.
It has been tested on my Clevo B7130 laptop running kernel 3.2 which has a
GT425M
dGPU:
# cat /sys/kernel/debug/vgaswitcheroo/switch
0:IGD:+:Pwr:0000:00:02.0
1:DIS: :Pwr:0000:01:00.0
# tee /sys/kernel/debug/vgaswitcheroo/switch <<<OFF
OFF
# cat /sys/kernel/debug/vgaswitcheroo/switch
0:IGD:+:Pwr:0000:00:02.0
1:DIS: :Off:0000:01:00.0
# tee /sys/kernel/debug/vgaswitcheroo/switch <<<ON
ON
# cat /sys/kernel/debug/vgaswitcheroo/switch
0:IGD:+:Pwr:0000:00:02.0
1:DIS: :Pwr:0000:01:00.0
The iGPU/dGPU LEDS on the keyboard also change as a result.
Regards,
Peter
[-- Attachment #1.2: Type: text/html, Size: 1084 bytes --]
[-- Attachment #2: nouveau-switcheroo-optimus.patch --]
[-- Type: text/x-diff, Size: 8640 bytes --]
From b6e1b5b316ae17ccb7def0a8b38e69ad4c99c55d Mon Sep 17 00:00:00 2001
From: Peter Lekensteyn <lekensteyn@gmail.com>
Date: Sat, 17 Dec 2011 12:53:43 +0100
Subject: [PATCH 1/2] 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>
---
drivers/gpu/drm/nouveau/nouveau_acpi.c | 35 ++++++++++++++++++++-----------
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 525744d..96756d0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -18,12 +18,6 @@
#include <linux/vga_switcheroo.h>
-#define NOUVEAU_DSM_SUPPORTED 0x00
-#define NOUVEAU_DSM_SUPPORTED_FUNCTIONS 0x00
-
-#define NOUVEAU_DSM_ACTIVE 0x01
-#define NOUVEAU_DSM_ACTIVE_QUERY 0x00
-
#define NOUVEAU_DSM_LED 0x02
#define NOUVEAU_DSM_LED_STATE 0x00
#define NOUVEAU_DSM_LED_OFF 0x10
@@ -35,6 +29,7 @@
#define NOUVEAU_DSM_POWER_SPEED 0x01
#define NOUVEAU_DSM_POWER_STAMINA 0x02
+#define NOUVEAU_DSM_OPTIMUS_FN 0x1A
static struct nouveau_dsm_priv {
bool dsm_detected;
bool optimus_detected;
@@ -148,6 +143,23 @@ static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
return 0;
}
+/* Returns 1 if a DSM function is usable and 0 otherwise */
+static int nouveau_test_dsm(acpi_handle test_handle,
+ int (*dsm_func)(acpi_handle, int, int, uint32_t *),
+ int sfnc)
+{
+ u32 result = 0;
+
+ /* Function 0 returns a Buffer containing available functions. The args
+ * parameter is ignored for function 0, so just put 0 in it */
+ if (dsm_func(test_handle, 0, 0, &result))
+ return 0;
+
+ /* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. If
+ * the n-th bit is enabled, function n is supported */
+ return result & 1 && result & (1 << sfnc);
+}
+
static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id)
{
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)
{
acpi_handle dhandle, nvidia_handle;
acpi_status status;
- int ret, retval = 0;
- uint32_t result;
+ int retval = 0;
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
if (!dhandle)
@@ -224,13 +235,11 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
return false;
}
- ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED,
- NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result);
- if (ret == 0)
+ if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER))
retval |= NOUVEAU_DSM_HAS_MUX;
- ret = nouveau_optimus_dsm(dhandle, 0, 0, &result);
- if (ret == 0)
+ if (nouveau_test_dsm(dhandle, nouveau_optimus_dsm,
+ NOUVEAU_DSM_OPTIMUS_FN))
retval |= NOUVEAU_DSM_HAS_OPT;
if (retval)
--
1.7.5.4
From 58c5de8578e387ce0dbd8a77f9cbc36b2f5823a1 Mon Sep 17 00:00:00 2001
From: Peter Lekensteyn <lekensteyn@gmail.com>
Date: Sat, 17 Dec 2011 12:54:04 +0100
Subject: [PATCH 2/2] nouveau: Support Optimus models for vga_switcheroo
Newer nVidia cards with Optimus do not support/use the DSM switching functions.
Instead, it require a DSM function to be called prior to bringing a device into
D3 state. No other _DSM calls are necessary before/after enabling/disabling a
device. Switching between discrete and integrated GPU is not supported by
this Optimus _DSM call, therefore return on the switching method.
Signed-off-by: Peter Lekensteyn <lekensteyn@gmail.com>
---
drivers/gpu/drm/nouveau/nouveau_acpi.c | 44 +++++++++++++++++++++++++++---
drivers/gpu/drm/nouveau/nouveau_drv.h | 1 +
drivers/gpu/drm/nouveau/nouveau_state.c | 1 +
3 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 96756d0..7814a76 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -30,6 +30,8 @@
#define NOUVEAU_DSM_POWER_STAMINA 0x02
#define NOUVEAU_DSM_OPTIMUS_FN 0x1A
+#define NOUVEAU_DSM_OPTIMUS_ARGS 0x03000001
+
static struct nouveau_dsm_priv {
bool dsm_detected;
bool optimus_detected;
@@ -56,7 +58,8 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *
struct acpi_object_list input;
union acpi_object params[4];
union acpi_object *obj;
- int err;
+ int i, err;
+ char args_buff[4];
input.count = 4;
input.pointer = params;
@@ -68,7 +71,11 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *
params[2].type = ACPI_TYPE_INTEGER;
params[2].integer.value = func;
params[3].type = ACPI_TYPE_BUFFER;
- params[3].buffer.length = 0;
+ params[3].buffer.length = 4;
+ /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */
+ for (i = 0; i < 4; i++)
+ args_buff[i] = (arg >> i * 8) & 0xFF;
+ params[3].buffer.pointer = args_buff;
err = acpi_evaluate_object(handle, "_DSM", &input, &output);
if (err) {
@@ -180,6 +187,10 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero
static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id)
{
+ /* perhaps the _DSM functions are mutually exclusive, but prepare for
+ * the future */
+ if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected)
+ return 0;
if (id == VGA_SWITCHEROO_IGD)
return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA);
else
@@ -192,6 +203,11 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id,
if (id == VGA_SWITCHEROO_IGD)
return 0;
+ /* Optimus laptops have the card already disabled in
+ * nouveau_switcheroo_set_state */
+ if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected)
+ return 0;
+
return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state);
}
@@ -278,15 +294,22 @@ static bool nouveau_dsm_detect(void)
}
if (vga_count == 2 && has_dsm && guid_valid) {
- acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer);
+ acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME,
+ &buffer);
printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n",
- acpi_method_name);
+ acpi_method_name);
nouveau_dsm_priv.dsm_detected = true;
ret = true;
}
- if (has_optimus == 1)
+ if (has_optimus == 1) {
+ acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME,
+ &buffer);
+ printk(KERN_INFO "VGA switcheroo: detected Optimus DSM method %s handle\n",
+ acpi_method_name);
nouveau_dsm_priv.optimus_detected = true;
+ ret = true;
+ }
return ret;
}
@@ -302,6 +325,17 @@ void nouveau_register_dsm_handler(void)
vga_switcheroo_register_handler(&nouveau_dsm_handler);
}
+/* Must be called for Optimus models before the card can be turned off */
+void nouveau_switcheroo_optimus_dsm(void)
+{
+ u32 result = 0;
+ if (!nouveau_dsm_priv.optimus_detected)
+ return;
+
+ nouveau_optimus_dsm(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_FN,
+ NOUVEAU_DSM_OPTIMUS_ARGS, &result);
+}
+
void nouveau_unregister_dsm_handler(void)
{
vga_switcheroo_unregister_handler();
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 4c0be3a..061577c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1041,6 +1041,7 @@ extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
#if defined(CONFIG_ACPI)
void nouveau_register_dsm_handler(void);
void nouveau_unregister_dsm_handler(void);
+void nouveau_switcheroo_optimus_dsm(void);
int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
int nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index d8831ab..ef270cf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -525,6 +525,7 @@ static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
drm_kms_helper_poll_disable(dev);
+ nouveau_switcheroo_optimus_dsm();
nouveau_pci_suspend(pdev, pmm);
dev->switch_power_state = DRM_SWITCH_POWER_OFF;
}
--
1.7.5.4
[-- Attachment #3: Type: text/plain, Size: 181 bytes --]
_______________________________________________
Nouveau mailing list
Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 9+ messages in thread
* properly check for _DSM function support and Optimus support for vga_switcheroo
[not found] ` <CALBR5ZxR9iuvT57bDZ8yW9ZkZjuoUhBTYw4HBsmsiwoRi4gSkw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2011-12-17 22:50 ` Lekensteyn
[not found] ` <CALBR5ZyE2ZRX7eFBhooB22e9BRf0f3H2xqtvXB2iwe8nvKKnvw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 9+ messages in thread
From: Lekensteyn @ 2011-12-17 22:50 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
[-- Attachment #1.1: Type: text/plain, Size: 966 bytes --]
Hello guys,
I've prepared a patch based on my findings for the bbswitch module
(https://github.com/Lekensteyn/acpi-stuff/tree/master/bbswitch). This adds
a proper
check whether a _DSM function is supported or not and make OFF / ON for
vga_switcheroo work for nVidia Optimus models. The patch is based against
the
mainline kernel.
It has been tested on my Clevo B7130 laptop running kernel 3.2 which has a
GT425M
dGPU:
# cat /sys/kernel/debug/vgaswitcheroo/switch
0:IGD:+:Pwr:0000:00:02.0
1:DIS: :Pwr:0000:01:00.0
# tee /sys/kernel/debug/vgaswitcheroo/switch <<<OFF
OFF
# cat /sys/kernel/debug/vgaswitcheroo/switch
0:IGD:+:Pwr:0000:00:02.0
1:DIS: :Off:0000:01:00.0
# tee /sys/kernel/debug/vgaswitcheroo/switch <<<ON
ON
# cat /sys/kernel/debug/vgaswitcheroo/switch
0:IGD:+:Pwr:0000:00:02.0
1:DIS: :Pwr:0000:01:00.0
The iGPU/dGPU LEDS on the keyboard also change as a result.
A second patch to make the device stay off after suspend is in progress.
Regards,
Peter
[-- Attachment #1.2: Type: text/html, Size: 1225 bytes --]
[-- Attachment #2: nouveau-switcheroo-optimus.patch --]
[-- Type: text/x-diff, Size: 8640 bytes --]
From b6e1b5b316ae17ccb7def0a8b38e69ad4c99c55d Mon Sep 17 00:00:00 2001
From: Peter Lekensteyn <lekensteyn@gmail.com>
Date: Sat, 17 Dec 2011 12:53:43 +0100
Subject: [PATCH 1/2] 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>
---
drivers/gpu/drm/nouveau/nouveau_acpi.c | 35 ++++++++++++++++++++-----------
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 525744d..96756d0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -18,12 +18,6 @@
#include <linux/vga_switcheroo.h>
-#define NOUVEAU_DSM_SUPPORTED 0x00
-#define NOUVEAU_DSM_SUPPORTED_FUNCTIONS 0x00
-
-#define NOUVEAU_DSM_ACTIVE 0x01
-#define NOUVEAU_DSM_ACTIVE_QUERY 0x00
-
#define NOUVEAU_DSM_LED 0x02
#define NOUVEAU_DSM_LED_STATE 0x00
#define NOUVEAU_DSM_LED_OFF 0x10
@@ -35,6 +29,7 @@
#define NOUVEAU_DSM_POWER_SPEED 0x01
#define NOUVEAU_DSM_POWER_STAMINA 0x02
+#define NOUVEAU_DSM_OPTIMUS_FN 0x1A
static struct nouveau_dsm_priv {
bool dsm_detected;
bool optimus_detected;
@@ -148,6 +143,23 @@ static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
return 0;
}
+/* Returns 1 if a DSM function is usable and 0 otherwise */
+static int nouveau_test_dsm(acpi_handle test_handle,
+ int (*dsm_func)(acpi_handle, int, int, uint32_t *),
+ int sfnc)
+{
+ u32 result = 0;
+
+ /* Function 0 returns a Buffer containing available functions. The args
+ * parameter is ignored for function 0, so just put 0 in it */
+ if (dsm_func(test_handle, 0, 0, &result))
+ return 0;
+
+ /* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. If
+ * the n-th bit is enabled, function n is supported */
+ return result & 1 && result & (1 << sfnc);
+}
+
static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id)
{
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)
{
acpi_handle dhandle, nvidia_handle;
acpi_status status;
- int ret, retval = 0;
- uint32_t result;
+ int retval = 0;
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
if (!dhandle)
@@ -224,13 +235,11 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
return false;
}
- ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED,
- NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result);
- if (ret == 0)
+ if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER))
retval |= NOUVEAU_DSM_HAS_MUX;
- ret = nouveau_optimus_dsm(dhandle, 0, 0, &result);
- if (ret == 0)
+ if (nouveau_test_dsm(dhandle, nouveau_optimus_dsm,
+ NOUVEAU_DSM_OPTIMUS_FN))
retval |= NOUVEAU_DSM_HAS_OPT;
if (retval)
--
1.7.5.4
From 58c5de8578e387ce0dbd8a77f9cbc36b2f5823a1 Mon Sep 17 00:00:00 2001
From: Peter Lekensteyn <lekensteyn@gmail.com>
Date: Sat, 17 Dec 2011 12:54:04 +0100
Subject: [PATCH 2/2] nouveau: Support Optimus models for vga_switcheroo
Newer nVidia cards with Optimus do not support/use the DSM switching functions.
Instead, it require a DSM function to be called prior to bringing a device into
D3 state. No other _DSM calls are necessary before/after enabling/disabling a
device. Switching between discrete and integrated GPU is not supported by
this Optimus _DSM call, therefore return on the switching method.
Signed-off-by: Peter Lekensteyn <lekensteyn@gmail.com>
---
drivers/gpu/drm/nouveau/nouveau_acpi.c | 44 +++++++++++++++++++++++++++---
drivers/gpu/drm/nouveau/nouveau_drv.h | 1 +
drivers/gpu/drm/nouveau/nouveau_state.c | 1 +
3 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 96756d0..7814a76 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -30,6 +30,8 @@
#define NOUVEAU_DSM_POWER_STAMINA 0x02
#define NOUVEAU_DSM_OPTIMUS_FN 0x1A
+#define NOUVEAU_DSM_OPTIMUS_ARGS 0x03000001
+
static struct nouveau_dsm_priv {
bool dsm_detected;
bool optimus_detected;
@@ -56,7 +58,8 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *
struct acpi_object_list input;
union acpi_object params[4];
union acpi_object *obj;
- int err;
+ int i, err;
+ char args_buff[4];
input.count = 4;
input.pointer = params;
@@ -68,7 +71,11 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *
params[2].type = ACPI_TYPE_INTEGER;
params[2].integer.value = func;
params[3].type = ACPI_TYPE_BUFFER;
- params[3].buffer.length = 0;
+ params[3].buffer.length = 4;
+ /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */
+ for (i = 0; i < 4; i++)
+ args_buff[i] = (arg >> i * 8) & 0xFF;
+ params[3].buffer.pointer = args_buff;
err = acpi_evaluate_object(handle, "_DSM", &input, &output);
if (err) {
@@ -180,6 +187,10 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero
static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id)
{
+ /* perhaps the _DSM functions are mutually exclusive, but prepare for
+ * the future */
+ if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected)
+ return 0;
if (id == VGA_SWITCHEROO_IGD)
return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA);
else
@@ -192,6 +203,11 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id,
if (id == VGA_SWITCHEROO_IGD)
return 0;
+ /* Optimus laptops have the card already disabled in
+ * nouveau_switcheroo_set_state */
+ if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected)
+ return 0;
+
return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state);
}
@@ -278,15 +294,22 @@ static bool nouveau_dsm_detect(void)
}
if (vga_count == 2 && has_dsm && guid_valid) {
- acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer);
+ acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME,
+ &buffer);
printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n",
- acpi_method_name);
+ acpi_method_name);
nouveau_dsm_priv.dsm_detected = true;
ret = true;
}
- if (has_optimus == 1)
+ if (has_optimus == 1) {
+ acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME,
+ &buffer);
+ printk(KERN_INFO "VGA switcheroo: detected Optimus DSM method %s handle\n",
+ acpi_method_name);
nouveau_dsm_priv.optimus_detected = true;
+ ret = true;
+ }
return ret;
}
@@ -302,6 +325,17 @@ void nouveau_register_dsm_handler(void)
vga_switcheroo_register_handler(&nouveau_dsm_handler);
}
+/* Must be called for Optimus models before the card can be turned off */
+void nouveau_switcheroo_optimus_dsm(void)
+{
+ u32 result = 0;
+ if (!nouveau_dsm_priv.optimus_detected)
+ return;
+
+ nouveau_optimus_dsm(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_FN,
+ NOUVEAU_DSM_OPTIMUS_ARGS, &result);
+}
+
void nouveau_unregister_dsm_handler(void)
{
vga_switcheroo_unregister_handler();
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 4c0be3a..061577c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1041,6 +1041,7 @@ extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
#if defined(CONFIG_ACPI)
void nouveau_register_dsm_handler(void);
void nouveau_unregister_dsm_handler(void);
+void nouveau_switcheroo_optimus_dsm(void);
int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
int nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index d8831ab..ef270cf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -525,6 +525,7 @@ static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
drm_kms_helper_poll_disable(dev);
+ nouveau_switcheroo_optimus_dsm();
nouveau_pci_suspend(pdev, pmm);
dev->switch_power_state = DRM_SWITCH_POWER_OFF;
}
--
1.7.5.4
[-- Attachment #3: Type: text/plain, Size: 181 bytes --]
_______________________________________________
Nouveau mailing list
Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: properly check for _DSM function support and Optimus support for vga_switcheroo
[not found] ` <CALBR5ZyE2ZRX7eFBhooB22e9BRf0f3H2xqtvXB2iwe8nvKKnvw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2011-12-19 4:39 ` Omar Andrés Zapata Mesa
[not found] ` <CAOB9epp8EdpetsPStfdnGNx5-2dKi42j3DQiVKN_dzMdFcssWA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 9+ messages in thread
From: Omar Andrés Zapata Mesa @ 2011-12-19 4:39 UTC (permalink / raw)
To: Lekensteyn; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
[-- Attachment #1.1: Type: text/plain, Size: 1963 bytes --]
Tested on toshiba m645 optimus intel/nvidia 310m
output
bbswitch: Found discrete VGA device 0000:01:00.0: \_SB_.PCI0.P0P2.VGA_
[21832.787656] bbswitch: detected an Optimus _DSM function
[21832.787664] bbswitch: Succesfully loaded. Discrete card 0000:01:00.0 is
on
but dont work nvidia video card. do it work with not mux optimus?
On Sat, Dec 17, 2011 at 5:50 PM, Lekensteyn <lekensteyn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Hello guys,
>
> I've prepared a patch based on my findings for the bbswitch module
> (https://github.com/Lekensteyn/acpi-stuff/tree/master/bbswitch). This
> adds a proper
> check whether a _DSM function is supported or not and make OFF / ON for
> vga_switcheroo work for nVidia Optimus models. The patch is based against
> the
> mainline kernel.
>
> It has been tested on my Clevo B7130 laptop running kernel 3.2 which has a
> GT425M
> dGPU:
> # cat /sys/kernel/debug/vgaswitcheroo/switch
> 0:IGD:+:Pwr:0000:00:02.0
> 1:DIS: :Pwr:0000:01:00.0
> # tee /sys/kernel/debug/vgaswitcheroo/switch <<<OFF
> OFF
> # cat /sys/kernel/debug/vgaswitcheroo/switch
> 0:IGD:+:Pwr:0000:00:02.0
> 1:DIS: :Off:0000:01:00.0
> # tee /sys/kernel/debug/vgaswitcheroo/switch <<<ON
> ON
> # cat /sys/kernel/debug/vgaswitcheroo/switch
> 0:IGD:+:Pwr:0000:00:02.0
> 1:DIS: :Pwr:0000:01:00.0
>
> The iGPU/dGPU LEDS on the keyboard also change as a result.
>
> A second patch to make the device stay off after suspend is in progress.
>
> Regards,
> Peter
>
>
> _______________________________________________
> Nouveau mailing list
> Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
> http://lists.freedesktop.org/mailman/listinfo/nouveau
>
>
--
Omar Andres Zapata Mesa
Fundamental Interaction Phenomenology Gruop (Gfif)
Head Developer
http://gfif.udea.edu.co
Gfif Developers (Gfif Dev)
Division of computer science
http://gfifdev.udea.edu.co
System Engineering Student
Universidad de Antioquia At Medellin - Colombia
Usuario Linux #490962
[-- Attachment #1.2: Type: text/html, Size: 3797 bytes --]
[-- Attachment #2: Type: text/plain, Size: 181 bytes --]
_______________________________________________
Nouveau mailing list
Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: properly check for _DSM function support and Optimus support for vga_switcheroo
[not found] ` <CAOB9epp8EdpetsPStfdnGNx5-2dKi42j3DQiVKN_dzMdFcssWA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2011-12-19 9:44 ` Lekensteyn
[not found] ` <CALBR5Zw0gEDqKrSUF3R30tSSC6DUgfhVm0Y1Mp60e4bB4ObijQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 9+ messages in thread
From: Lekensteyn @ 2011-12-19 9:44 UTC (permalink / raw)
To: Omar Andrés Zapata Mesa; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
[-- Attachment #1.1: Type: text/plain, Size: 2508 bytes --]
It's works on a muxless Clevo B7130 intel / nvidia GT425M. It has also
been tested
on the legacy optimus call, although that crashed X
http://pastebin.com/9Sum3tT3
That bug is said to be fixed
http://cgit.freedesktop.org/xorg/xserver/commit/?id=fb22a408c69a84f81905147de9e82cf66ffb6eb2
2011/12/19 Omar Andrés Zapata Mesa <andresete.chaos-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Tested on toshiba m645 optimus intel/nvidia 310m
> output
> bbswitch: Found discrete VGA device 0000:01:00.0: \_SB_.PCI0.P0P2.VGA_
> [21832.787656] bbswitch: detected an Optimus _DSM function
> [21832.787664] bbswitch: Succesfully loaded. Discrete card 0000:01:00.0 is
> on
> but dont work nvidia video card. do it work with not mux optimus?
>
>
> On Sat, Dec 17, 2011 at 5:50 PM, Lekensteyn <lekensteyn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>> Hello guys,
>>
>> I've prepared a patch based on my findings for the bbswitch module
>> (https://github.com/Lekensteyn/acpi-stuff/tree/master/bbswitch). This
>> adds a proper
>> check whether a _DSM function is supported or not and make OFF / ON for
>> vga_switcheroo work for nVidia Optimus models. The patch is based against
>> the
>> mainline kernel.
>>
>> It has been tested on my Clevo B7130 laptop running kernel 3.2 which has
>> a GT425M
>> dGPU:
>> # cat /sys/kernel/debug/vgaswitcheroo/switch
>> 0:IGD:+:Pwr:0000:00:02.0
>> 1:DIS: :Pwr:0000:01:00.0
>> # tee /sys/kernel/debug/vgaswitcheroo/switch <<<OFF
>> OFF
>> # cat /sys/kernel/debug/vgaswitcheroo/switch
>> 0:IGD:+:Pwr:0000:00:02.0
>> 1:DIS: :Off:0000:01:00.0
>> # tee /sys/kernel/debug/vgaswitcheroo/switch <<<ON
>> ON
>> # cat /sys/kernel/debug/vgaswitcheroo/switch
>> 0:IGD:+:Pwr:0000:00:02.0
>> 1:DIS: :Pwr:0000:01:00.0
>>
>> The iGPU/dGPU LEDS on the keyboard also change as a result.
>>
>> A second patch to make the device stay off after suspend is in progress.
>>
>> Regards,
>> Peter
>>
>>
>> _______________________________________________
>> Nouveau mailing list
>> Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
>> http://lists.freedesktop.org/mailman/listinfo/nouveau
>>
>>
>
>
> --
> Omar Andres Zapata Mesa
> Fundamental Interaction Phenomenology Gruop (Gfif)
> Head Developer
> http://gfif.udea.edu.co
> Gfif Developers (Gfif Dev)
> Division of computer science
> http://gfifdev.udea.edu.co
> System Engineering Student
> Universidad de Antioquia At Medellin - Colombia
> Usuario Linux #490962
>
>
[-- Attachment #1.2: Type: text/html, Size: 4759 bytes --]
[-- Attachment #2: Type: text/plain, Size: 181 bytes --]
_______________________________________________
Nouveau mailing list
Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: properly check for _DSM function support and Optimus support for vga_switcheroo
[not found] ` <CALBR5Zw0gEDqKrSUF3R30tSSC6DUgfhVm0Y1Mp60e4bB4ObijQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2011-12-19 10:04 ` Gianluca Cecchi
[not found] ` <CAG2kNCwBwRJ_VrS9NHnmGvOTTLuwmBKd5kG8OknJG+f20Kvqsg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 9+ messages in thread
From: Gianluca Cecchi @ 2011-12-19 10:04 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
>> On Sat, Dec 17, 2011 at 5:50 PM, Lekensteyn <lekensteyn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>>>
>>> Hello guys,
>>>
>>> I've prepared a patch based on my findings for the bbswitch module
>>> (https://github.com/Lekensteyn/acpi-stuff/tree/master/bbswitch). This
>>> adds a proper
>>> check whether a _DSM function is supported or not and make OFF / ON for
>>> vga_switcheroo work for nVidia Optimus models. The patch is based against
>>> the
>>> mainline kernel.
>>>
>>> It has been tested on my Clevo B7130 laptop running kernel 3.2 which has
Hello,
I have an Asus U36SD laptop with Optimus and Fedora 16 with kernel
3.1.5-6.fc16.x86_64
Any way I can test it?
Currently I'm using acpi_call to switch off nvidia card and gain 4w
for more battery life.
[g.cecchi@ope46 ~]$ lspci -vnnn|grep -i vga
00:02.0 VGA compatible controller [0300]: Intel Corporation 2nd
Generation Core Processor Family Integrated Graphics Controller
[8086:0126] (rev 09) (prog-if 00 [VGA controller])
01:00.0 VGA compatible controller [0300]: nVidia Corporation Device
[10de:1050] (rev ff) (prog-if ff)
What benefit would it give me? Chance to use nvidia for graphic
related apps ? With nouveau andor nvidia proprietary driver?
Thanks in advance for any pointer
Gianluca
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: properly check for _DSM function support and Optimus support for vga_switcheroo
[not found] ` <CAG2kNCwBwRJ_VrS9NHnmGvOTTLuwmBKd5kG8OknJG+f20Kvqsg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2011-12-19 13:26 ` Lekensteyn
2012-01-08 23:13 ` Lekensteyn
0 siblings, 1 reply; 9+ messages in thread
From: Lekensteyn @ 2011-12-19 13:26 UTC (permalink / raw)
To: Gianluca Cecchi; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
[-- Attachment #1.1: Type: text/plain, Size: 2009 bytes --]
A quickly written way to test this module is described for Ubuntu at
http://pastebin.com/c5XqKSsW. Basically, you need to apply the patch on
nouveau
and rebuild the nouveau kernel module.
A comparison of different methods that works for toggling the dGPU is
available:
https://github.com/Bumblebee-Project/Bumblebee/wiki/Comparison-of-PM-methods
Regards,
Lekensteyn
On Mon, Dec 19, 2011 at 11:04 AM, Gianluca Cecchi <gianluca.cecchi-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
> wrote:
> >> On Sat, Dec 17, 2011 at 5:50 PM, Lekensteyn <lekensteyn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> wrote:
> >>>
> >>> Hello guys,
> >>>
> >>> I've prepared a patch based on my findings for the bbswitch module
> >>> (https://github.com/Lekensteyn/acpi-stuff/tree/master/bbswitch). This
> >>> adds a proper
> >>> check whether a _DSM function is supported or not and make OFF / ON for
> >>> vga_switcheroo work for nVidia Optimus models. The patch is based
> against
> >>> the
> >>> mainline kernel.
> >>>
> >>> It has been tested on my Clevo B7130 laptop running kernel 3.2 which
> has
>
> Hello,
> I have an Asus U36SD laptop with Optimus and Fedora 16 with kernel
> 3.1.5-6.fc16.x86_64
> Any way I can test it?
> Currently I'm using acpi_call to switch off nvidia card and gain 4w
> for more battery life.
>
> [g.cecchi@ope46 ~]$ lspci -vnnn|grep -i vga
> 00:02.0 VGA compatible controller [0300]: Intel Corporation 2nd
> Generation Core Processor Family Integrated Graphics Controller
> [8086:0126] (rev 09) (prog-if 00 [VGA controller])
> 01:00.0 VGA compatible controller [0300]: nVidia Corporation Device
> [10de:1050] (rev ff) (prog-if ff)
>
> What benefit would it give me? Chance to use nvidia for graphic
> related apps ? With nouveau andor nvidia proprietary driver?
> Thanks in advance for any pointer
>
> Gianluca
> _______________________________________________
> Nouveau mailing list
> Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
> http://lists.freedesktop.org/mailman/listinfo/nouveau
>
[-- Attachment #1.2: Type: text/html, Size: 3115 bytes --]
[-- Attachment #2: Type: text/plain, Size: 181 bytes --]
_______________________________________________
Nouveau mailing list
Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: properly check for _DSM function support and Optimus support for vga_switcheroo
2011-12-19 13:26 ` Lekensteyn
@ 2012-01-08 23:13 ` Lekensteyn
[not found] ` <CALBR5Zxuwv-zBQfVr7By3su2rjWjcVapX7oCCfeybjBMPY9cbA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 9+ messages in thread
From: Lekensteyn @ 2012-01-08 23:13 UTC (permalink / raw)
To: Gianluca Cecchi; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
[-- Attachment #1.1: Type: text/plain, Size: 2379 bytes --]
Any activity on this? The newly attached patch contains one difference with
the previous
one: a dummy function has been added to avoid an error if ACPI is disabled.
Regards,
Lekensteyn
On Mon, Dec 19, 2011 at 2:26 PM, Lekensteyn <lekensteyn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> A quickly written way to test this module is described for Ubuntu at
> http://pastebin.com/c5XqKSsW. Basically, you need to apply the patch on
> nouveau
> and rebuild the nouveau kernel module.
>
> A comparison of different methods that works for toggling the dGPU is
> available:
>
> https://github.com/Bumblebee-Project/Bumblebee/wiki/Comparison-of-PM-methods
>
> Regards,
> Lekensteyn
>
>
> On Mon, Dec 19, 2011 at 11:04 AM, Gianluca Cecchi <
> gianluca.cecchi-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>> >> On Sat, Dec 17, 2011 at 5:50 PM, Lekensteyn <lekensteyn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> wrote:
>> >>>
>> >>> Hello guys,
>> >>>
>> >>> I've prepared a patch based on my findings for the bbswitch module
>> >>> (https://github.com/Lekensteyn/acpi-stuff/tree/master/bbswitch). This
>> >>> adds a proper
>> >>> check whether a _DSM function is supported or not and make OFF / ON
>> for
>> >>> vga_switcheroo work for nVidia Optimus models. The patch is based
>> against
>> >>> the
>> >>> mainline kernel.
>> >>>
>> >>> It has been tested on my Clevo B7130 laptop running kernel 3.2 which
>> has
>>
>> Hello,
>> I have an Asus U36SD laptop with Optimus and Fedora 16 with kernel
>> 3.1.5-6.fc16.x86_64
>> Any way I can test it?
>> Currently I'm using acpi_call to switch off nvidia card and gain 4w
>> for more battery life.
>>
>> [g.cecchi@ope46 ~]$ lspci -vnnn|grep -i vga
>> 00:02.0 VGA compatible controller [0300]: Intel Corporation 2nd
>> Generation Core Processor Family Integrated Graphics Controller
>> [8086:0126] (rev 09) (prog-if 00 [VGA controller])
>> 01:00.0 VGA compatible controller [0300]: nVidia Corporation Device
>> [10de:1050] (rev ff) (prog-if ff)
>>
>> What benefit would it give me? Chance to use nvidia for graphic
>> related apps ? With nouveau andor nvidia proprietary driver?
>> Thanks in advance for any pointer
>>
>> Gianluca
>> _______________________________________________
>> Nouveau mailing list
>> Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
>> http://lists.freedesktop.org/mailman/listinfo/nouveau
>>
>
>
[-- Attachment #1.2: Type: text/html, Size: 3811 bytes --]
[-- Attachment #2: nouveau-switcheroo-optimus.patch --]
[-- Type: text/x-diff, Size: 9131 bytes --]
From b6e1b5b316ae17ccb7def0a8b38e69ad4c99c55d Mon Sep 17 00:00:00 2001
From: Peter Lekensteyn <lekensteyn@gmail.com>
Date: Sat, 17 Dec 2011 12:53:43 +0100
Subject: [PATCH 1/2] 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>
---
drivers/gpu/drm/nouveau/nouveau_acpi.c | 35 ++++++++++++++++++++-----------
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 525744d..96756d0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -18,12 +18,6 @@
#include <linux/vga_switcheroo.h>
-#define NOUVEAU_DSM_SUPPORTED 0x00
-#define NOUVEAU_DSM_SUPPORTED_FUNCTIONS 0x00
-
-#define NOUVEAU_DSM_ACTIVE 0x01
-#define NOUVEAU_DSM_ACTIVE_QUERY 0x00
-
#define NOUVEAU_DSM_LED 0x02
#define NOUVEAU_DSM_LED_STATE 0x00
#define NOUVEAU_DSM_LED_OFF 0x10
@@ -35,6 +29,7 @@
#define NOUVEAU_DSM_POWER_SPEED 0x01
#define NOUVEAU_DSM_POWER_STAMINA 0x02
+#define NOUVEAU_DSM_OPTIMUS_FN 0x1A
static struct nouveau_dsm_priv {
bool dsm_detected;
bool optimus_detected;
@@ -148,6 +143,23 @@ static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
return 0;
}
+/* Returns 1 if a DSM function is usable and 0 otherwise */
+static int nouveau_test_dsm(acpi_handle test_handle,
+ int (*dsm_func)(acpi_handle, int, int, uint32_t *),
+ int sfnc)
+{
+ u32 result = 0;
+
+ /* Function 0 returns a Buffer containing available functions. The args
+ * parameter is ignored for function 0, so just put 0 in it */
+ if (dsm_func(test_handle, 0, 0, &result))
+ return 0;
+
+ /* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. If
+ * the n-th bit is enabled, function n is supported */
+ return result & 1 && result & (1 << sfnc);
+}
+
static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id)
{
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)
{
acpi_handle dhandle, nvidia_handle;
acpi_status status;
- int ret, retval = 0;
- uint32_t result;
+ int retval = 0;
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
if (!dhandle)
@@ -224,13 +235,11 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
return false;
}
- ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED,
- NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result);
- if (ret == 0)
+ if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER))
retval |= NOUVEAU_DSM_HAS_MUX;
- ret = nouveau_optimus_dsm(dhandle, 0, 0, &result);
- if (ret == 0)
+ if (nouveau_test_dsm(dhandle, nouveau_optimus_dsm,
+ NOUVEAU_DSM_OPTIMUS_FN))
retval |= NOUVEAU_DSM_HAS_OPT;
if (retval)
--
1.7.5.4
From 9c1a466321c9bdc44fb45205ebb5469da3d2adba Mon Sep 17 00:00:00 2001
From: Peter Lekensteyn <lekensteyn@gmail.com>
Date: Sat, 17 Dec 2011 12:54:04 +0100
Subject: [PATCH 2/2] nouveau: Support Optimus models for vga_switcheroo
Newer nVidia cards with Optimus do not support/use the DSM switching functions.
Instead, it require a DSM function to be called prior to bringing a device into
D3 state. No other _DSM calls are necessary before/after enabling/disabling a
device. Switching between discrete and integrated GPU is not supported by
this Optimus _DSM call, therefore return on the switching method.
Signed-off-by: Peter Lekensteyn <lekensteyn@gmail.com>
---
drivers/gpu/drm/nouveau/nouveau_acpi.c | 44 +++++++++++++++++++++++++++---
drivers/gpu/drm/nouveau/nouveau_drv.h | 2 +
drivers/gpu/drm/nouveau/nouveau_state.c | 1 +
3 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 96756d0..7814a76 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -30,6 +30,8 @@
#define NOUVEAU_DSM_POWER_STAMINA 0x02
#define NOUVEAU_DSM_OPTIMUS_FN 0x1A
+#define NOUVEAU_DSM_OPTIMUS_ARGS 0x03000001
+
static struct nouveau_dsm_priv {
bool dsm_detected;
bool optimus_detected;
@@ -56,7 +58,8 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *
struct acpi_object_list input;
union acpi_object params[4];
union acpi_object *obj;
- int err;
+ int i, err;
+ char args_buff[4];
input.count = 4;
input.pointer = params;
@@ -68,7 +71,11 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *
params[2].type = ACPI_TYPE_INTEGER;
params[2].integer.value = func;
params[3].type = ACPI_TYPE_BUFFER;
- params[3].buffer.length = 0;
+ params[3].buffer.length = 4;
+ /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */
+ for (i = 0; i < 4; i++)
+ args_buff[i] = (arg >> i * 8) & 0xFF;
+ params[3].buffer.pointer = args_buff;
err = acpi_evaluate_object(handle, "_DSM", &input, &output);
if (err) {
@@ -180,6 +187,10 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero
static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id)
{
+ /* perhaps the _DSM functions are mutually exclusive, but prepare for
+ * the future */
+ if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected)
+ return 0;
if (id == VGA_SWITCHEROO_IGD)
return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA);
else
@@ -192,6 +203,11 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id,
if (id == VGA_SWITCHEROO_IGD)
return 0;
+ /* Optimus laptops have the card already disabled in
+ * nouveau_switcheroo_set_state */
+ if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected)
+ return 0;
+
return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state);
}
@@ -278,15 +294,22 @@ static bool nouveau_dsm_detect(void)
}
if (vga_count == 2 && has_dsm && guid_valid) {
- acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer);
+ acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME,
+ &buffer);
printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n",
- acpi_method_name);
+ acpi_method_name);
nouveau_dsm_priv.dsm_detected = true;
ret = true;
}
- if (has_optimus == 1)
+ if (has_optimus == 1) {
+ acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME,
+ &buffer);
+ printk(KERN_INFO "VGA switcheroo: detected Optimus DSM method %s handle\n",
+ acpi_method_name);
nouveau_dsm_priv.optimus_detected = true;
+ ret = true;
+ }
return ret;
}
@@ -302,6 +325,17 @@ void nouveau_register_dsm_handler(void)
vga_switcheroo_register_handler(&nouveau_dsm_handler);
}
+/* Must be called for Optimus models before the card can be turned off */
+void nouveau_switcheroo_optimus_dsm(void)
+{
+ u32 result = 0;
+ if (!nouveau_dsm_priv.optimus_detected)
+ return;
+
+ nouveau_optimus_dsm(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_FN,
+ NOUVEAU_DSM_OPTIMUS_ARGS, &result);
+}
+
void nouveau_unregister_dsm_handler(void)
{
vga_switcheroo_unregister_handler();
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 4c0be3a..4f369f4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1041,12 +1041,14 @@ extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
#if defined(CONFIG_ACPI)
void nouveau_register_dsm_handler(void);
void nouveau_unregister_dsm_handler(void);
+void nouveau_switcheroo_optimus_dsm(void);
int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
int nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
#else
static inline void nouveau_register_dsm_handler(void) {}
static inline void nouveau_unregister_dsm_handler(void) {}
+static inline void nouveau_switcheroo_optimus_dsm(void) {}
static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; }
static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; }
static inline int nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return -EINVAL; }
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index d8831ab..ef270cf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -525,6 +525,7 @@ static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
drm_kms_helper_poll_disable(dev);
+ nouveau_switcheroo_optimus_dsm();
nouveau_pci_suspend(pdev, pmm);
dev->switch_power_state = DRM_SWITCH_POWER_OFF;
}
--
1.7.5.4
[-- Attachment #3: Type: text/plain, Size: 181 bytes --]
_______________________________________________
Nouveau mailing list
Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: properly check for _DSM function support and Optimus support for vga_switcheroo
[not found] ` <CALBR5Zxuwv-zBQfVr7By3su2rjWjcVapX7oCCfeybjBMPY9cbA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-01-09 22:45 ` Ben Skeggs
2012-01-12 17:29 ` Dave Airlie
0 siblings, 1 reply; 9+ messages in thread
From: Ben Skeggs @ 2012-01-09 22:45 UTC (permalink / raw)
To: Lekensteyn
Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, airlied-H+wXaHxf7aLQT0dZR+AlfA
On Mon, 2012-01-09 at 00:13 +0100, Lekensteyn wrote:
> Any activity on this? The newly attached patch contains one difference
> with the previous
> one: a dummy function has been added to avoid an error if ACPI is
> disabled.
Dave,
Any thoughts on this?
Ben.
>
> Regards,
> Lekensteyn
>
> On Mon, Dec 19, 2011 at 2:26 PM, Lekensteyn <lekensteyn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> wrote:
> A quickly written way to test this module is described for
> Ubuntu at
> http://pastebin.com/c5XqKSsW. Basically, you need to apply the
> patch on nouveau
> and rebuild the nouveau kernel module.
>
> A comparison of different methods that works for toggling the
> dGPU is available:
> https://github.com/Bumblebee-Project/Bumblebee/wiki/Comparison-of-PM-methods
>
> Regards,
> Lekensteyn
>
>
> On Mon, Dec 19, 2011 at 11:04 AM, Gianluca Cecchi
> <gianluca.cecchi-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> >> On Sat, Dec 17, 2011 at 5:50 PM, Lekensteyn
> <lekensteyn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> >>>
> >>> Hello guys,
> >>>
> >>> I've prepared a patch based on my findings for the
> bbswitch module
> >>>
> (https://github.com/Lekensteyn/acpi-stuff/tree/master/bbswitch). This
> >>> adds a proper
> >>> check whether a _DSM function is supported or not
> and make OFF / ON for
> >>> vga_switcheroo work for nVidia Optimus models. The
> patch is based against
> >>> the
> >>> mainline kernel.
> >>>
> >>> It has been tested on my Clevo B7130 laptop
> running kernel 3.2 which has
>
>
> Hello,
> I have an Asus U36SD laptop with Optimus and Fedora 16
> with kernel
> 3.1.5-6.fc16.x86_64
> Any way I can test it?
> Currently I'm using acpi_call to switch off nvidia
> card and gain 4w
> for more battery life.
>
> [g.cecchi@ope46 ~]$ lspci -vnnn|grep -i vga
> 00:02.0 VGA compatible controller [0300]: Intel
> Corporation 2nd
> Generation Core Processor Family Integrated Graphics
> Controller
> [8086:0126] (rev 09) (prog-if 00 [VGA controller])
> 01:00.0 VGA compatible controller [0300]: nVidia
> Corporation Device
> [10de:1050] (rev ff) (prog-if ff)
>
> What benefit would it give me? Chance to use nvidia
> for graphic
> related apps ? With nouveau andor nvidia proprietary
> driver?
> Thanks in advance for any pointer
>
> Gianluca
> _______________________________________________
> Nouveau mailing list
> Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
> http://lists.freedesktop.org/mailman/listinfo/nouveau
>
>
>
>
> _______________________________________________
> Nouveau mailing list
> Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
> http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: properly check for _DSM function support and Optimus support for vga_switcheroo
2012-01-09 22:45 ` Ben Skeggs
@ 2012-01-12 17:29 ` Dave Airlie
0 siblings, 0 replies; 9+ messages in thread
From: Dave Airlie @ 2012-01-12 17:29 UTC (permalink / raw)
To: skeggsb-Re5JQEeQqe8AvxtiuMwx3w
Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, airlied-H+wXaHxf7aLQT0dZR+AlfA
On Mon, Jan 9, 2012 at 10:45 PM, Ben Skeggs <skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On Mon, 2012-01-09 at 00:13 +0100, Lekensteyn wrote:
>> Any activity on this? The newly attached patch contains one difference
>> with the previous
>> one: a dummy function has been added to avoid an error if ACPI is
>> disabled.
> Dave,
>
> Any thoughts on this?
Yeah they both look fine, I'll test them on my machine tomorrow hopefully.
Dave.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-01-12 17:29 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-17 12:14 properly check for _DSM function support and Optimus support for vga_switcheroo Lekensteyn
[not found] ` <CALBR5ZxR9iuvT57bDZ8yW9ZkZjuoUhBTYw4HBsmsiwoRi4gSkw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-17 22:50 ` Lekensteyn
[not found] ` <CALBR5ZyE2ZRX7eFBhooB22e9BRf0f3H2xqtvXB2iwe8nvKKnvw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-19 4:39 ` Omar Andrés Zapata Mesa
[not found] ` <CAOB9epp8EdpetsPStfdnGNx5-2dKi42j3DQiVKN_dzMdFcssWA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-19 9:44 ` Lekensteyn
[not found] ` <CALBR5Zw0gEDqKrSUF3R30tSSC6DUgfhVm0Y1Mp60e4bB4ObijQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-19 10:04 ` Gianluca Cecchi
[not found] ` <CAG2kNCwBwRJ_VrS9NHnmGvOTTLuwmBKd5kG8OknJG+f20Kvqsg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-19 13:26 ` Lekensteyn
2012-01-08 23:13 ` Lekensteyn
[not found] ` <CALBR5Zxuwv-zBQfVr7By3su2rjWjcVapX7oCCfeybjBMPY9cbA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-01-09 22:45 ` Ben Skeggs
2012-01-12 17:29 ` Dave Airlie
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.