Commit c839d748 authored by Dave Airlie's avatar Dave Airlie Committed by Ben Skeggs

drm/nouveau: Add interface to detect optimus and v1 support

This is required to decide if we can auto-powerdown and how to implement it.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent bf2c886a
...@@ -35,6 +35,14 @@ static struct nouveau_dsm_priv { ...@@ -35,6 +35,14 @@ static struct nouveau_dsm_priv {
acpi_handle rom_handle; acpi_handle rom_handle;
} nouveau_dsm_priv; } nouveau_dsm_priv;
bool nouveau_is_optimus(void) {
return nouveau_dsm_priv.optimus_detected;
}
bool nouveau_is_v1_dsm(void) {
return nouveau_dsm_priv.dsm_detected;
}
#define NOUVEAU_DSM_HAS_MUX 0x1 #define NOUVEAU_DSM_HAS_MUX 0x1
#define NOUVEAU_DSM_HAS_OPT 0x2 #define NOUVEAU_DSM_HAS_OPT 0x2
...@@ -183,9 +191,7 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero ...@@ -183,9 +191,7 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero
static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id) static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id)
{ {
/* perhaps the _DSM functions are mutually exclusive, but prepare for if (!nouveau_dsm_priv.dsm_detected)
* the future */
if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected)
return 0; return 0;
if (id == VGA_SWITCHEROO_IGD) if (id == VGA_SWITCHEROO_IGD)
return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA); return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA);
...@@ -201,7 +207,7 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, ...@@ -201,7 +207,7 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id,
/* Optimus laptops have the card already disabled in /* Optimus laptops have the card already disabled in
* nouveau_switcheroo_set_state */ * nouveau_switcheroo_set_state */
if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected) if (!nouveau_dsm_priv.dsm_detected)
return 0; return 0;
return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state);
...@@ -283,24 +289,24 @@ static bool nouveau_dsm_detect(void) ...@@ -283,24 +289,24 @@ static bool nouveau_dsm_detect(void)
has_optimus = 1; has_optimus = 1;
} }
if (vga_count == 2 && has_dsm && guid_valid) { /* find the optimus DSM or the old v1 DSM */
if (has_optimus == 1) {
acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME,
&buffer); &buffer);
printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n", printk(KERN_INFO "VGA switcheroo: detected Optimus DSM method %s handle\n",
acpi_method_name); acpi_method_name);
nouveau_dsm_priv.dsm_detected = true; nouveau_dsm_priv.optimus_detected = true;
ret = true; ret = true;
} } else if (vga_count == 2 && has_dsm && guid_valid) {
if (has_optimus == 1) {
acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME,
&buffer); &buffer);
printk(KERN_INFO "VGA switcheroo: detected Optimus DSM method %s handle\n", printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n",
acpi_method_name); acpi_method_name);
nouveau_dsm_priv.optimus_detected = true; nouveau_dsm_priv.dsm_detected = true;
ret = true; ret = true;
} }
return ret; return ret;
} }
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#define ROM_BIOS_PAGE 4096 #define ROM_BIOS_PAGE 4096
#if defined(CONFIG_ACPI) #if defined(CONFIG_ACPI)
bool nouveau_is_optimus(void);
bool nouveau_is_v1_dsm(void);
void nouveau_register_dsm_handler(void); void nouveau_register_dsm_handler(void);
void nouveau_unregister_dsm_handler(void); void nouveau_unregister_dsm_handler(void);
void nouveau_switcheroo_optimus_dsm(void); void nouveau_switcheroo_optimus_dsm(void);
...@@ -11,6 +13,8 @@ int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); ...@@ -11,6 +13,8 @@ int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
bool nouveau_acpi_rom_supported(struct pci_dev *pdev); bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *); void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
#else #else
static inline bool nouveau_is_optimus(void) { return false; };
static inline bool nouveau_is_v1_dsm(void) { return false; };
static inline void nouveau_register_dsm_handler(void) {} static inline void nouveau_register_dsm_handler(void) {}
static inline void nouveau_unregister_dsm_handler(void) {} static inline void nouveau_unregister_dsm_handler(void) {}
static inline void nouveau_switcheroo_optimus_dsm(void) {} static inline void nouveau_switcheroo_optimus_dsm(void) {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment