Commit 4489cd62 authored by Alex Deucher's avatar Alex Deucher

drm/radeon/dpm: validate voltages against dispclk requirements

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: default avatarAlex Deucher <alexander.deucher@amd.com>
parent f907eec0
...@@ -2178,21 +2178,26 @@ static void btc_apply_state_adjust_rules(struct radeon_device *rdev, ...@@ -2178,21 +2178,26 @@ static void btc_apply_state_adjust_rules(struct radeon_device *rdev,
ps->low.mclk, max_limits->vddci, &ps->low.vddci); ps->low.mclk, max_limits->vddci, &ps->low.vddci);
btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
ps->low.mclk, max_limits->vddc, &ps->low.vddc); 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, btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
ps->medium.sclk, max_limits->vddc, &ps->medium.vddc); ps->medium.sclk, max_limits->vddc, &ps->medium.vddc);
btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
ps->medium.mclk, max_limits->vddci, &ps->medium.vddci); ps->medium.mclk, max_limits->vddci, &ps->medium.vddci);
btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
ps->medium.mclk, max_limits->vddc, &ps->medium.vddc); 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, btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
ps->high.sclk, max_limits->vddc, &ps->high.vddc); ps->high.sclk, max_limits->vddc, &ps->high.vddc);
btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
ps->high.mclk, max_limits->vddci, &ps->high.vddci); ps->high.mclk, max_limits->vddci, &ps->high.vddci);
btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
ps->high.mclk, max_limits->vddc, &ps->high.vddc); 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, btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
&ps->low.vddc, &ps->low.vddci); &ps->low.vddc, &ps->low.vddci);
...@@ -2495,6 +2500,22 @@ int btc_dpm_init(struct radeon_device *rdev) ...@@ -2495,6 +2500,22 @@ int btc_dpm_init(struct radeon_device *rdev)
if (ret) if (ret)
return 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) if (rdev->pm.dpm.voltage_response_time == 0)
rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT; rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
if (rdev->pm.dpm.backbias_response_time == 0) if (rdev->pm.dpm.backbias_response_time == 0)
...@@ -2628,6 +2649,7 @@ void btc_dpm_fini(struct radeon_device *rdev) ...@@ -2628,6 +2649,7 @@ void btc_dpm_fini(struct radeon_device *rdev)
} }
kfree(rdev->pm.dpm.ps); kfree(rdev->pm.dpm.ps);
kfree(rdev->pm.dpm.priv); kfree(rdev->pm.dpm.priv);
kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
r600_free_extended_power_table(rdev); r600_free_extended_power_table(rdev);
} }
......
...@@ -866,7 +866,9 @@ static void ni_apply_state_adjust_rules(struct radeon_device *rdev, ...@@ -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, btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
ps->performance_levels[i].mclk, ps->performance_levels[i].mclk,
max_limits->vddc, &ps->performance_levels[i].vddc); 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++) { for (i = 0; i < ps->performance_level_count; i++) {
...@@ -3910,6 +3912,22 @@ int ni_dpm_init(struct radeon_device *rdev) ...@@ -3910,6 +3912,22 @@ int ni_dpm_init(struct radeon_device *rdev)
if (ret) if (ret)
return 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); ni_patch_dependency_tables_based_on_leakage(rdev);
if (rdev->pm.dpm.voltage_response_time == 0) if (rdev->pm.dpm.voltage_response_time == 0)
...@@ -4094,6 +4112,7 @@ void ni_dpm_fini(struct radeon_device *rdev) ...@@ -4094,6 +4112,7 @@ void ni_dpm_fini(struct radeon_device *rdev)
} }
kfree(rdev->pm.dpm.ps); kfree(rdev->pm.dpm.ps);
kfree(rdev->pm.dpm.priv); kfree(rdev->pm.dpm.priv);
kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
r600_free_extended_power_table(rdev); r600_free_extended_power_table(rdev);
} }
......
...@@ -200,6 +200,7 @@ struct radeon_clock { ...@@ -200,6 +200,7 @@ struct radeon_clock {
uint32_t default_mclk; uint32_t default_mclk;
uint32_t default_sclk; uint32_t default_sclk;
uint32_t default_dispclk; uint32_t default_dispclk;
uint32_t current_dispclk;
uint32_t dp_extclk; uint32_t dp_extclk;
uint32_t max_pixel_clock; uint32_t max_pixel_clock;
}; };
...@@ -1298,6 +1299,7 @@ struct radeon_dpm_dynamic_state { ...@@ -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 vddc_dependency_on_sclk;
struct radeon_clock_voltage_dependency_table vddci_dependency_on_mclk; 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_mclk;
struct radeon_clock_voltage_dependency_table vddc_dependency_on_dispclk;
struct radeon_clock_array valid_sclk_values; struct radeon_clock_array valid_sclk_values;
struct radeon_clock_array valid_mclk_values; struct radeon_clock_array valid_mclk_values;
struct radeon_clock_and_voltage_limits max_clock_voltage_on_dc; struct radeon_clock_and_voltage_limits max_clock_voltage_on_dc;
......
...@@ -1243,6 +1243,7 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) ...@@ -1243,6 +1243,7 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
} }
rdev->clock.dp_extclk = rdev->clock.dp_extclk =
le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq); le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
rdev->clock.current_dispclk = rdev->clock.default_dispclk;
} }
*dcpll = *p1pll; *dcpll = *p1pll;
......
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