diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-05-06 12:15:33 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-08-30 16:30:18 -0400 |
commit | 58cb7632df30698900a474cb85fa292bafd73b2e (patch) | |
tree | 37fb5f5813b6dd7984a675ba2c08c1c77764522d /drivers/gpu/drm | |
parent | ef976ec4e2ae6d91a9aab5714071d1eed0115ed6 (diff) |
drm/radeon/dpm: add support for parsing the atom powertune table
Needed for DPM on CI.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/radeon/r600_dpm.c | 44 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 12 |
2 files changed, 56 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c index ccdf770dd770..e6905f011bfa 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.c +++ b/drivers/gpu/drm/radeon/r600_dpm.c | |||
@@ -1014,6 +1014,48 @@ int r600_parse_extended_power_table(struct radeon_device *rdev) | |||
1014 | rdev->pm.dpm.dyn_state.ppm_table->tj_max = | 1014 | rdev->pm.dpm.dyn_state.ppm_table->tj_max = |
1015 | le32_to_cpu(ppm->ulTjmax); | 1015 | le32_to_cpu(ppm->ulTjmax); |
1016 | } | 1016 | } |
1017 | if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7) && | ||
1018 | ext_hdr->usPowerTuneTableOffset) { | ||
1019 | u8 rev = *(u8 *)(mode_info->atom_context->bios + data_offset + | ||
1020 | le16_to_cpu(ext_hdr->usPowerTuneTableOffset)); | ||
1021 | ATOM_PowerTune_Table *pt; | ||
1022 | rdev->pm.dpm.dyn_state.cac_tdp_table = | ||
1023 | kzalloc(sizeof(struct radeon_cac_tdp_table), GFP_KERNEL); | ||
1024 | if (!rdev->pm.dpm.dyn_state.cac_tdp_table) { | ||
1025 | kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries); | ||
1026 | kfree(rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk.entries); | ||
1027 | kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk.entries); | ||
1028 | kfree(rdev->pm.dpm.dyn_state.cac_leakage_table.entries); | ||
1029 | kfree(rdev->pm.dpm.dyn_state.ppm_table); | ||
1030 | return -ENOMEM; | ||
1031 | } | ||
1032 | if (rev > 0) { | ||
1033 | ATOM_PPLIB_POWERTUNE_Table_V1 *ppt = (ATOM_PPLIB_POWERTUNE_Table_V1 *) | ||
1034 | (mode_info->atom_context->bios + data_offset + | ||
1035 | le16_to_cpu(ext_hdr->usPowerTuneTableOffset)); | ||
1036 | rdev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit = | ||
1037 | ppt->usMaximumPowerDeliveryLimit; | ||
1038 | pt = &ppt->power_tune_table; | ||
1039 | } else { | ||
1040 | ATOM_PPLIB_POWERTUNE_Table *ppt = (ATOM_PPLIB_POWERTUNE_Table *) | ||
1041 | (mode_info->atom_context->bios + data_offset + | ||
1042 | le16_to_cpu(ext_hdr->usPowerTuneTableOffset)); | ||
1043 | rdev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit = 255; | ||
1044 | pt = &ppt->power_tune_table; | ||
1045 | } | ||
1046 | rdev->pm.dpm.dyn_state.cac_tdp_table->tdp = le16_to_cpu(pt->usTDP); | ||
1047 | rdev->pm.dpm.dyn_state.cac_tdp_table->configurable_tdp = | ||
1048 | le16_to_cpu(pt->usConfigurableTDP); | ||
1049 | rdev->pm.dpm.dyn_state.cac_tdp_table->tdc = le16_to_cpu(pt->usTDC); | ||
1050 | rdev->pm.dpm.dyn_state.cac_tdp_table->battery_power_limit = | ||
1051 | le16_to_cpu(pt->usBatteryPowerLimit); | ||
1052 | rdev->pm.dpm.dyn_state.cac_tdp_table->small_power_limit = | ||
1053 | le16_to_cpu(pt->usSmallPowerLimit); | ||
1054 | rdev->pm.dpm.dyn_state.cac_tdp_table->low_cac_leakage = | ||
1055 | le16_to_cpu(pt->usLowCACLeakage); | ||
1056 | rdev->pm.dpm.dyn_state.cac_tdp_table->high_cac_leakage = | ||
1057 | le16_to_cpu(pt->usHighCACLeakage); | ||
1058 | } | ||
1017 | } | 1059 | } |
1018 | 1060 | ||
1019 | return 0; | 1061 | return 0; |
@@ -1033,6 +1075,8 @@ void r600_free_extended_power_table(struct radeon_device *rdev) | |||
1033 | kfree(rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries); | 1075 | kfree(rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries); |
1034 | if (rdev->pm.dpm.dyn_state.ppm_table) | 1076 | if (rdev->pm.dpm.dyn_state.ppm_table) |
1035 | kfree(rdev->pm.dpm.dyn_state.ppm_table); | 1077 | kfree(rdev->pm.dpm.dyn_state.ppm_table); |
1078 | if (rdev->pm.dpm.dyn_state.cac_tdp_table) | ||
1079 | kfree(rdev->pm.dpm.dyn_state.cac_tdp_table); | ||
1036 | } | 1080 | } |
1037 | 1081 | ||
1038 | enum radeon_pcie_gen r600_get_pcie_gen_support(struct radeon_device *rdev, | 1082 | enum radeon_pcie_gen r600_get_pcie_gen_support(struct radeon_device *rdev, |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3376107f3b1e..5a624b8bbbb9 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1308,6 +1308,17 @@ struct radeon_ppm_table { | |||
1308 | u32 tj_max; | 1308 | u32 tj_max; |
1309 | }; | 1309 | }; |
1310 | 1310 | ||
1311 | struct radeon_cac_tdp_table { | ||
1312 | u16 tdp; | ||
1313 | u16 configurable_tdp; | ||
1314 | u16 tdc; | ||
1315 | u16 battery_power_limit; | ||
1316 | u16 small_power_limit; | ||
1317 | u16 low_cac_leakage; | ||
1318 | u16 high_cac_leakage; | ||
1319 | u16 maximum_power_delivery_limit; | ||
1320 | }; | ||
1321 | |||
1311 | struct radeon_dpm_dynamic_state { | 1322 | struct radeon_dpm_dynamic_state { |
1312 | struct radeon_clock_voltage_dependency_table vddc_dependency_on_sclk; | 1323 | struct radeon_clock_voltage_dependency_table vddc_dependency_on_sclk; |
1313 | struct radeon_clock_voltage_dependency_table vddci_dependency_on_mclk; | 1324 | struct radeon_clock_voltage_dependency_table vddci_dependency_on_mclk; |
@@ -1325,6 +1336,7 @@ struct radeon_dpm_dynamic_state { | |||
1325 | struct radeon_cac_leakage_table cac_leakage_table; | 1336 | struct radeon_cac_leakage_table cac_leakage_table; |
1326 | struct radeon_phase_shedding_limits_table phase_shedding_limits_table; | 1337 | struct radeon_phase_shedding_limits_table phase_shedding_limits_table; |
1327 | struct radeon_ppm_table *ppm_table; | 1338 | struct radeon_ppm_table *ppm_table; |
1339 | struct radeon_cac_tdp_table *cac_tdp_table; | ||
1328 | }; | 1340 | }; |
1329 | 1341 | ||
1330 | struct radeon_dpm_fan { | 1342 | struct radeon_dpm_fan { |