drm/amdgpu: clean up atpx power control handling
authorAlex Deucher <alexander.deucher@amd.com>
Wed, 1 Jun 2016 16:42:35 +0000 (12:42 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 7 Jul 2016 18:51:00 +0000 (14:51 -0400)
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 <Hawking.Zhang@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c

index 3af1c3aceab39b8db9567a0ae1c72a25c549853d..1be2ce46921bc955e1da7da1a7e50009ad0a87db 100644 (file)
@@ -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;
 }