drm/radeon/dpm: validate voltages against dispclk requirements
authorAlex Deucher <alexander.deucher@amd.com>
Fri, 22 Mar 2013 19:59:10 +0000 (15:59 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 27 Jun 2013 23:16:39 +0000 (19:16 -0400)
Validate the voltages against the voltage requirements of the
dispclk.  We currently don't adjust the disp clock so it never
changes, but we need to filter out voltage levels that are too
low none the less.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/btc_dpm.c
drivers/gpu/drm/radeon/ni_dpm.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_atombios.c

index e0d315e7fd010561ed4adaaaea902c8e77f57aa8..a55b23dce6da848420ddb9d4a4262e8b882a930a 100644 (file)
@@ -2178,21 +2178,26 @@ static void btc_apply_state_adjust_rules(struct radeon_device *rdev,
                                           ps->low.mclk, max_limits->vddci, &ps->low.vddci);
        btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
                                           ps->low.mclk, max_limits->vddc, &ps->low.vddc);
-       /* XXX validate the voltage required for display */
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
+                                          rdev->clock.current_dispclk, max_limits->vddc, &ps->low.vddc);
+
        btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
                                           ps->medium.sclk, max_limits->vddc, &ps->medium.vddc);
        btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
                                           ps->medium.mclk, max_limits->vddci, &ps->medium.vddci);
        btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
                                           ps->medium.mclk, max_limits->vddc, &ps->medium.vddc);
-       /* XXX validate the voltage required for display */
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
+                                          rdev->clock.current_dispclk, max_limits->vddc, &ps->medium.vddc);
+
        btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
                                           ps->high.sclk, max_limits->vddc, &ps->high.vddc);
        btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
                                           ps->high.mclk, max_limits->vddci, &ps->high.vddci);
        btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
                                           ps->high.mclk, max_limits->vddc, &ps->high.vddc);
-       /* XXX validate the voltage required for display */
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
+                                          rdev->clock.current_dispclk, max_limits->vddc, &ps->high.vddc);
 
        btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
                                      &ps->low.vddc, &ps->low.vddci);
@@ -2495,6 +2500,22 @@ int btc_dpm_init(struct radeon_device *rdev)
        if (ret)
                return ret;
 
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =
+               kzalloc(4 * sizeof(struct radeon_clock_voltage_dependency_entry), GFP_KERNEL);
+       if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) {
+               r600_free_extended_power_table(rdev);
+               return -ENOMEM;
+       }
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 800;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 800;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 800;
+
        if (rdev->pm.dpm.voltage_response_time == 0)
                rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
        if (rdev->pm.dpm.backbias_response_time == 0)
@@ -2628,6 +2649,7 @@ void btc_dpm_fini(struct radeon_device *rdev)
        }
        kfree(rdev->pm.dpm.ps);
        kfree(rdev->pm.dpm.priv);
+       kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
        r600_free_extended_power_table(rdev);
 }
 
index af059655055d106bcdd7f25f554a99289371a056..21c064badaa2de0f37d464b34df4a143e2b3288e 100644 (file)
@@ -866,7 +866,9 @@ static void ni_apply_state_adjust_rules(struct radeon_device *rdev,
                btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
                                                   ps->performance_levels[i].mclk,
                                                   max_limits->vddc,  &ps->performance_levels[i].vddc);
-               /* XXX validate the voltage required for display */
+               btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
+                                                  rdev->clock.current_dispclk,
+                                                  max_limits->vddc,  &ps->performance_levels[i].vddc);
        }
 
        for (i = 0; i < ps->performance_level_count; i++) {
@@ -3910,6 +3912,22 @@ int ni_dpm_init(struct radeon_device *rdev)
        if (ret)
                return ret;
 
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =
+               kzalloc(4 * sizeof(struct radeon_clock_voltage_dependency_entry), GFP_KERNEL);
+       if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) {
+               r600_free_extended_power_table(rdev);
+               return -ENOMEM;
+       }
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 720;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 810;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 900;
+
        ni_patch_dependency_tables_based_on_leakage(rdev);
 
        if (rdev->pm.dpm.voltage_response_time == 0)
@@ -4094,6 +4112,7 @@ void ni_dpm_fini(struct radeon_device *rdev)
        }
        kfree(rdev->pm.dpm.ps);
        kfree(rdev->pm.dpm.priv);
+       kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
        r600_free_extended_power_table(rdev);
 }
 
index e6ded6fc186bddf9cd6033bb92fdedd0328fb268..9de8ae20bc992b0f7199e05df93fc19bd05c907a 100644 (file)
@@ -200,6 +200,7 @@ struct radeon_clock {
        uint32_t default_mclk;
        uint32_t default_sclk;
        uint32_t default_dispclk;
+       uint32_t current_dispclk;
        uint32_t dp_extclk;
        uint32_t max_pixel_clock;
 };
@@ -1298,6 +1299,7 @@ struct radeon_dpm_dynamic_state {
        struct radeon_clock_voltage_dependency_table vddc_dependency_on_sclk;
        struct radeon_clock_voltage_dependency_table vddci_dependency_on_mclk;
        struct radeon_clock_voltage_dependency_table vddc_dependency_on_mclk;
+       struct radeon_clock_voltage_dependency_table vddc_dependency_on_dispclk;
        struct radeon_clock_array valid_sclk_values;
        struct radeon_clock_array valid_mclk_values;
        struct radeon_clock_and_voltage_limits max_clock_voltage_on_dc;
index 0ac7294867a3d6d214b1188793c47cbb6099848b..c707ed034713184475227358324b42e696c125ef 100644 (file)
@@ -1243,6 +1243,7 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
                        }
                        rdev->clock.dp_extclk =
                                le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
+                       rdev->clock.current_dispclk = rdev->clock.default_dispclk;
                }
                *dcpll = *p1pll;