drm/radeon: clean up atpx power control handling
authorAlex Deucher <alexander.deucher@amd.com>
Wed, 1 Jun 2016 16:47:38 +0000 (12:47 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 7 Jul 2016 18:51:04 +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/radeon/radeon_atpx_handler.c

index 3e24fe0..55efbcd 100644 (file)
@@ -141,18 +141,12 @@ static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mas
  */
 static int radeon_atpx_validate(struct radeon_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 = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL);
                if (!info)
@@ -171,24 +165,36 @@ static int radeon_atpx_validate(struct radeon_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;
 }