From 5c614792474bf80b87d6cd915d9db14406c9c779 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 1 Jun 2016 12:28:13 -0400 Subject: drm/amdgpu: disable power control on hybrid laptops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Windows 10 (and some 8.1) systems use standardized ACPI calls for hybrid laptops to control dGPU power. Detect those cases and disable the AMD specific ATPX power control. Reviewed-by: Hawking Zhang Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 35a1248aaa77..3af1c3aceab3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -183,6 +183,11 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) ATPX_DFP_SIGNAL_MUXED)) atpx->functions.disp_mux_cntl = true; + if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { + printk("Hybrid Graphics, ATPX dGPU power cntl disabled\n"); + atpx->functions.power_cntl = false; + } + kfree(info); } return 0; -- cgit v1.2.3 From 8d45f80ed08b1909988f38c094e5ace6d879ca10 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 1 Jun 2016 12:42:35 -0400 Subject: drm/amdgpu: clean up atpx power control handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The presence of the power control method should be determined via the presence of the method in function 0. However, some sbioses only set the appropriate bits in function 1 so use then to override a missing power control function. Reviewed-by: Hawking Zhang Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 51 ++++++++++++++---------- 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 3af1c3aceab3..1be2ce46921b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -142,18 +142,12 @@ static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mas */ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) { - /* make sure required functions are enabled */ - /* dGPU power control is required */ - if (atpx->functions.power_cntl == false) { - printk("ATPX dGPU power cntl not present, forcing\n"); - atpx->functions.power_cntl = true; - } + u32 valid_bits = 0; if (atpx->functions.px_params) { union acpi_object *info; struct atpx_px_params output; size_t size; - u32 valid_bits; info = amdgpu_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL); if (!info) @@ -172,24 +166,37 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) memcpy(&output, info->buffer.pointer, size); valid_bits = output.flags & output.valid_flags; - /* if separate mux flag is set, mux controls are required */ - if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) { - atpx->functions.i2c_mux_cntl = true; - atpx->functions.disp_mux_cntl = true; - } - /* if any outputs are muxed, mux controls are required */ - if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED | - ATPX_TV_SIGNAL_MUXED | - ATPX_DFP_SIGNAL_MUXED)) - atpx->functions.disp_mux_cntl = true; - - if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { - printk("Hybrid Graphics, ATPX dGPU power cntl disabled\n"); - atpx->functions.power_cntl = false; - } kfree(info); } + + /* if separate mux flag is set, mux controls are required */ + if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) { + atpx->functions.i2c_mux_cntl = true; + atpx->functions.disp_mux_cntl = true; + } + /* if any outputs are muxed, mux controls are required */ + if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED | + ATPX_TV_SIGNAL_MUXED | + ATPX_DFP_SIGNAL_MUXED)) + atpx->functions.disp_mux_cntl = true; + + + /* some bioses set these bits rather than flagging power_cntl as supported */ + if (valid_bits & (ATPX_DYNAMIC_PX_SUPPORTED | + ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED)) + atpx->functions.power_cntl = true; + + if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { + printk("Hybrid Graphics, ATPX dGPU power cntl disabled\n"); + atpx->functions.power_cntl = false; + } else if (atpx->functions.power_cntl == false) { + /* make sure required functions are enabled */ + /* dGPU power control is required */ + printk("ATPX dGPU power cntl not present, forcing\n"); + atpx->functions.power_cntl = true; + } + return 0; } -- cgit v1.2.3 From f81eb1a349d47694fe1e688336ca1b40ea3e248a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 1 Jun 2016 12:54:33 -0400 Subject: drm/amdgpu: add a delay after ATPX dGPU power off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ATPX dGPU power control requires a 200ms delay between power off and on. This should fix dGPU failures on resume from power off. Reviewed-by: Hawking Zhang Acked-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 1be2ce46921b..c5d280ce625b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "amd_acpi.h" @@ -271,6 +272,10 @@ static int amdgpu_atpx_set_discrete_state(struct amdgpu_atpx *atpx, u8 state) if (!info) return -EIO; kfree(info); + + /* 200ms delay is required after off */ + if (state == 0) + msleep(200); } return 0; } -- cgit v1.2.3 From a78fe13389f0ba509c830e7c442aeed143efbbbf Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 1 Jun 2016 13:08:21 -0400 Subject: drm/amdgpu/atpx: add a query for ATPX dGPU power control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The runtime pm sequence is different depending on whether or not the platform supports ATPX dGPU power control. Reviewed-by: Hawking Zhang Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 33bc79e378e1..3cc2bd797e51 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -2400,9 +2400,11 @@ bool amdgpu_device_is_px(struct drm_device *dev); #if defined(CONFIG_VGA_SWITCHEROO) void amdgpu_register_atpx_handler(void); void amdgpu_unregister_atpx_handler(void); +bool amdgpu_has_atpx_dgpu_power_cntl(void); #else static inline void amdgpu_register_atpx_handler(void) {} static inline void amdgpu_unregister_atpx_handler(void) {} +static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; } #endif /* diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index c5d280ce625b..7b11af1d8c4f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -64,6 +64,10 @@ bool amdgpu_has_atpx(void) { return amdgpu_atpx_priv.atpx_detected; } +bool amdgpu_has_atpx_dgpu_power_cntl(void) { + return amdgpu_atpx_priv.atpx.functions.power_cntl; +} + /** * amdgpu_atpx_call - call an ATPX method * -- cgit v1.2.3 From d85555f8851e7e9af05bb8dfa43f5e7e05e35292 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 1 Jun 2016 13:14:48 -0400 Subject: drm/amdgpu/atpx: drop forcing of dGPU power control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that we handle this correctly, there is no need to force it. Reviewed-by: Hawking Zhang Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 7b11af1d8c4f..90dfedc5a5ca 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -195,11 +195,6 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { printk("Hybrid Graphics, ATPX dGPU power cntl disabled\n"); atpx->functions.power_cntl = false; - } else if (atpx->functions.power_cntl == false) { - /* make sure required functions are enabled */ - /* dGPU power control is required */ - printk("ATPX dGPU power cntl not present, forcing\n"); - atpx->functions.power_cntl = true; } return 0; -- cgit v1.2.3 From 2f5af82eeab2622913f92aec3d08df33c5fd0b20 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 2 Jun 2016 09:04:01 -0400 Subject: drm/amdgpu/atpx: track whether if this is a hybrid graphics platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hybrid graphics in this case refers to systems which use the new platform d3 cold ACPI methods as opposed to ATPX for dGPU power control. Reviewed-by: Hawking Zhang Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 3cc2bd797e51..b6c8309ce891 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -2401,10 +2401,12 @@ bool amdgpu_device_is_px(struct drm_device *dev); void amdgpu_register_atpx_handler(void); void amdgpu_unregister_atpx_handler(void); bool amdgpu_has_atpx_dgpu_power_cntl(void); +bool amdgpu_is_atpx_hybrid(void); #else static inline void amdgpu_register_atpx_handler(void) {} static inline void amdgpu_unregister_atpx_handler(void) {} static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; } +static inline bool amdgpu_is_atpx_hybrid(void) { return false; } #endif /* diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 90dfedc5a5ca..3e973c7942f0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -28,6 +28,7 @@ struct amdgpu_atpx_functions { struct amdgpu_atpx { acpi_handle handle; struct amdgpu_atpx_functions functions; + bool is_hybrid; }; static struct amdgpu_atpx_priv { @@ -68,6 +69,10 @@ bool amdgpu_has_atpx_dgpu_power_cntl(void) { return amdgpu_atpx_priv.atpx.functions.power_cntl; } +bool amdgpu_is_atpx_hybrid(void) { + return amdgpu_atpx_priv.atpx.is_hybrid; +} + /** * amdgpu_atpx_call - call an ATPX method * @@ -192,9 +197,11 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED)) atpx->functions.power_cntl = true; + atpx->is_hybrid = false; if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { - printk("Hybrid Graphics, ATPX dGPU power cntl disabled\n"); + printk("ATPX Hybrid Graphics\n"); atpx->functions.power_cntl = false; + atpx->is_hybrid = true; } return 0; -- cgit v1.2.3 From c63695cc5e5f685e924e25a8f9555f6e846f1fc6 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 3 Jun 2016 17:06:18 -0400 Subject: drm/amdgpu: work around lack of upstream ACPI support for D3cold Until Dave's patch to support the new hybrid gfx ACPI method goes upstream, we can fallback to the old ATPX method which seems to still work. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 3e973c7942f0..0494fe7b62c0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -200,7 +200,16 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) atpx->is_hybrid = false; if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { printk("ATPX Hybrid Graphics\n"); +#if 1 + /* This is a temporary hack until the D3 cold support + * makes it upstream. The ATPX power_control method seems + * to still work on even if the system should be using + * the new standardized hybrid D3 cold ACPI interface. + */ + atpx->functions.power_cntl = true; +#else atpx->functions.power_cntl = false; +#endif atpx->is_hybrid = true; } -- cgit v1.2.3 From 6b1095eedd39b175f5ef7e50cb85f0cebb8e9ead Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 27 Jul 2016 14:52:35 -0400 Subject: drm/amdgpu: init atpx at switcheroo register time (v2) If we do it at enable time, it's too late for the feature checks. v2: drop .init setting as per Peter's comments Reviewed-by: Peter Wu Signed-off-by: Alex Deucher Cc: Peter Wu --- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 0494fe7b62c0..49de92600074 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -539,7 +539,6 @@ static int amdgpu_atpx_get_client_id(struct pci_dev *pdev) static const struct vga_switcheroo_handler amdgpu_atpx_handler = { .switchto = amdgpu_atpx_switchto, .power_state = amdgpu_atpx_power_state, - .init = amdgpu_atpx_init, .get_client_id = amdgpu_atpx_get_client_id, }; @@ -574,6 +573,7 @@ static bool amdgpu_atpx_detect(void) printk(KERN_INFO "vga_switcheroo: detected switching method %s handle\n", acpi_method_name); amdgpu_atpx_priv.atpx_detected = true; + amdgpu_atpx_init(); return true; } return false; -- cgit v1.2.3