diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-09-04 12:01:28 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-09-11 11:44:28 -0400 |
commit | 136de91ea760b55bd52b707c1443f121e006962e (patch) | |
tree | b9af4f7ab3a747f3696107bdff56628894fabd4e /drivers/gpu | |
parent | 8c5c6fad61f9540a977e5731a8ae3bd8ba9083cb (diff) |
drm/radeon: dpm updates for KV
This updates dpm support for KV asics. Notably there
are some changes in acp handling and forcing performance
levels.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/kv_dpm.c | 103 |
1 files changed, 88 insertions, 15 deletions
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index c499dafd28fa..c87d1945a6f3 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c | |||
@@ -40,6 +40,7 @@ static int kv_calculate_dpm_settings(struct radeon_device *rdev); | |||
40 | static void kv_enable_new_levels(struct radeon_device *rdev); | 40 | static void kv_enable_new_levels(struct radeon_device *rdev); |
41 | static void kv_program_nbps_index_settings(struct radeon_device *rdev, | 41 | static void kv_program_nbps_index_settings(struct radeon_device *rdev, |
42 | struct radeon_ps *new_rps); | 42 | struct radeon_ps *new_rps); |
43 | static int kv_set_enabled_level(struct radeon_device *rdev, u32 level); | ||
43 | static int kv_set_enabled_levels(struct radeon_device *rdev); | 44 | static int kv_set_enabled_levels(struct radeon_device *rdev); |
44 | static int kv_force_dpm_highest(struct radeon_device *rdev); | 45 | static int kv_force_dpm_highest(struct radeon_device *rdev); |
45 | static int kv_force_dpm_lowest(struct radeon_device *rdev); | 46 | static int kv_force_dpm_lowest(struct radeon_device *rdev); |
@@ -519,7 +520,7 @@ static int kv_set_dpm_boot_state(struct radeon_device *rdev) | |||
519 | 520 | ||
520 | static void kv_program_vc(struct radeon_device *rdev) | 521 | static void kv_program_vc(struct radeon_device *rdev) |
521 | { | 522 | { |
522 | WREG32_SMC(CG_FTV_0, 0x3FFFC000); | 523 | WREG32_SMC(CG_FTV_0, 0x3FFFC100); |
523 | } | 524 | } |
524 | 525 | ||
525 | static void kv_clear_vc(struct radeon_device *rdev) | 526 | static void kv_clear_vc(struct radeon_device *rdev) |
@@ -638,7 +639,10 @@ static int kv_force_lowest_valid(struct radeon_device *rdev) | |||
638 | 639 | ||
639 | static int kv_unforce_levels(struct radeon_device *rdev) | 640 | static int kv_unforce_levels(struct radeon_device *rdev) |
640 | { | 641 | { |
641 | return kv_notify_message_to_smu(rdev, PPSMC_MSG_NoForcedLevel); | 642 | if (rdev->family == CHIP_KABINI) |
643 | return kv_notify_message_to_smu(rdev, PPSMC_MSG_NoForcedLevel); | ||
644 | else | ||
645 | return kv_set_enabled_levels(rdev); | ||
642 | } | 646 | } |
643 | 647 | ||
644 | static int kv_update_sclk_t(struct radeon_device *rdev) | 648 | static int kv_update_sclk_t(struct radeon_device *rdev) |
@@ -1076,6 +1080,13 @@ static int kv_enable_ulv(struct radeon_device *rdev, bool enable) | |||
1076 | PPSMC_MSG_EnableULV : PPSMC_MSG_DisableULV); | 1080 | PPSMC_MSG_EnableULV : PPSMC_MSG_DisableULV); |
1077 | } | 1081 | } |
1078 | 1082 | ||
1083 | static void kv_reset_acp_boot_level(struct radeon_device *rdev) | ||
1084 | { | ||
1085 | struct kv_power_info *pi = kv_get_pi(rdev); | ||
1086 | |||
1087 | pi->acp_boot_level = 0xff; | ||
1088 | } | ||
1089 | |||
1079 | static void kv_update_current_ps(struct radeon_device *rdev, | 1090 | static void kv_update_current_ps(struct radeon_device *rdev, |
1080 | struct radeon_ps *rps) | 1091 | struct radeon_ps *rps) |
1081 | { | 1092 | { |
@@ -1190,6 +1201,8 @@ int kv_dpm_enable(struct radeon_device *rdev) | |||
1190 | return ret; | 1201 | return ret; |
1191 | } | 1202 | } |
1192 | 1203 | ||
1204 | kv_reset_acp_boot_level(rdev); | ||
1205 | |||
1193 | if (rdev->irq.installed && | 1206 | if (rdev->irq.installed && |
1194 | r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { | 1207 | r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { |
1195 | ret = kv_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); | 1208 | ret = kv_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); |
@@ -1448,6 +1461,39 @@ static int kv_update_samu_dpm(struct radeon_device *rdev, bool gate) | |||
1448 | return kv_enable_samu_dpm(rdev, !gate); | 1461 | return kv_enable_samu_dpm(rdev, !gate); |
1449 | } | 1462 | } |
1450 | 1463 | ||
1464 | static u8 kv_get_acp_boot_level(struct radeon_device *rdev) | ||
1465 | { | ||
1466 | u8 i; | ||
1467 | struct radeon_clock_voltage_dependency_table *table = | ||
1468 | &rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table; | ||
1469 | |||
1470 | for (i = 0; i < table->count; i++) { | ||
1471 | if (table->entries[i].clk >= 0) /* XXX */ | ||
1472 | break; | ||
1473 | } | ||
1474 | |||
1475 | if (i >= table->count) | ||
1476 | i = table->count - 1; | ||
1477 | |||
1478 | return i; | ||
1479 | } | ||
1480 | |||
1481 | static void kv_update_acp_boot_level(struct radeon_device *rdev) | ||
1482 | { | ||
1483 | struct kv_power_info *pi = kv_get_pi(rdev); | ||
1484 | u8 acp_boot_level; | ||
1485 | |||
1486 | if (!pi->caps_stable_p_state) { | ||
1487 | acp_boot_level = kv_get_acp_boot_level(rdev); | ||
1488 | if (acp_boot_level != pi->acp_boot_level) { | ||
1489 | pi->acp_boot_level = acp_boot_level; | ||
1490 | kv_send_msg_to_smc_with_parameter(rdev, | ||
1491 | PPSMC_MSG_ACPDPM_SetEnabledMask, | ||
1492 | (1 << pi->acp_boot_level)); | ||
1493 | } | ||
1494 | } | ||
1495 | } | ||
1496 | |||
1451 | static int kv_update_acp_dpm(struct radeon_device *rdev, bool gate) | 1497 | static int kv_update_acp_dpm(struct radeon_device *rdev, bool gate) |
1452 | { | 1498 | { |
1453 | struct kv_power_info *pi = kv_get_pi(rdev); | 1499 | struct kv_power_info *pi = kv_get_pi(rdev); |
@@ -1459,7 +1505,7 @@ static int kv_update_acp_dpm(struct radeon_device *rdev, bool gate) | |||
1459 | if (pi->caps_stable_p_state) | 1505 | if (pi->caps_stable_p_state) |
1460 | pi->acp_boot_level = table->count - 1; | 1506 | pi->acp_boot_level = table->count - 1; |
1461 | else | 1507 | else |
1462 | pi->acp_boot_level = 0; | 1508 | pi->acp_boot_level = kv_get_acp_boot_level(rdev); |
1463 | 1509 | ||
1464 | ret = kv_copy_bytes_to_smc(rdev, | 1510 | ret = kv_copy_bytes_to_smc(rdev, |
1465 | pi->dpm_table_start + | 1511 | pi->dpm_table_start + |
@@ -1769,6 +1815,7 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) | |||
1769 | return ret; | 1815 | return ret; |
1770 | } | 1816 | } |
1771 | #endif | 1817 | #endif |
1818 | kv_update_acp_boot_level(rdev); | ||
1772 | kv_update_sclk_t(rdev); | 1819 | kv_update_sclk_t(rdev); |
1773 | kv_enable_nb_dpm(rdev); | 1820 | kv_enable_nb_dpm(rdev); |
1774 | } | 1821 | } |
@@ -1800,12 +1847,23 @@ void kv_dpm_setup_asic(struct radeon_device *rdev) | |||
1800 | 1847 | ||
1801 | void kv_dpm_reset_asic(struct radeon_device *rdev) | 1848 | void kv_dpm_reset_asic(struct radeon_device *rdev) |
1802 | { | 1849 | { |
1803 | kv_force_lowest_valid(rdev); | 1850 | struct kv_power_info *pi = kv_get_pi(rdev); |
1804 | kv_init_graphics_levels(rdev); | 1851 | |
1805 | kv_program_bootup_state(rdev); | 1852 | if (rdev->family == CHIP_KABINI) { |
1806 | kv_upload_dpm_settings(rdev); | 1853 | kv_force_lowest_valid(rdev); |
1807 | kv_force_lowest_valid(rdev); | 1854 | kv_init_graphics_levels(rdev); |
1808 | kv_unforce_levels(rdev); | 1855 | kv_program_bootup_state(rdev); |
1856 | kv_upload_dpm_settings(rdev); | ||
1857 | kv_force_lowest_valid(rdev); | ||
1858 | kv_unforce_levels(rdev); | ||
1859 | } else { | ||
1860 | kv_init_graphics_levels(rdev); | ||
1861 | kv_program_bootup_state(rdev); | ||
1862 | kv_freeze_sclk_dpm(rdev, true); | ||
1863 | kv_upload_dpm_settings(rdev); | ||
1864 | kv_freeze_sclk_dpm(rdev, false); | ||
1865 | kv_set_enabled_level(rdev, pi->graphics_boot_level); | ||
1866 | } | ||
1809 | } | 1867 | } |
1810 | 1868 | ||
1811 | //XXX use sumo_dpm_display_configuration_changed | 1869 | //XXX use sumo_dpm_display_configuration_changed |
@@ -1870,7 +1928,10 @@ static int kv_force_dpm_highest(struct radeon_device *rdev) | |||
1870 | break; | 1928 | break; |
1871 | } | 1929 | } |
1872 | 1930 | ||
1873 | return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); | 1931 | if (rdev->family == CHIP_KABINI) |
1932 | return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); | ||
1933 | else | ||
1934 | return kv_set_enabled_level(rdev, i); | ||
1874 | } | 1935 | } |
1875 | 1936 | ||
1876 | static int kv_force_dpm_lowest(struct radeon_device *rdev) | 1937 | static int kv_force_dpm_lowest(struct radeon_device *rdev) |
@@ -1887,7 +1948,10 @@ static int kv_force_dpm_lowest(struct radeon_device *rdev) | |||
1887 | break; | 1948 | break; |
1888 | } | 1949 | } |
1889 | 1950 | ||
1890 | return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); | 1951 | if (rdev->family == CHIP_KABINI) |
1952 | return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); | ||
1953 | else | ||
1954 | return kv_set_enabled_level(rdev, i); | ||
1891 | } | 1955 | } |
1892 | 1956 | ||
1893 | static u8 kv_get_sleep_divider_id_from_clock(struct radeon_device *rdev, | 1957 | static u8 kv_get_sleep_divider_id_from_clock(struct radeon_device *rdev, |
@@ -2033,12 +2097,12 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2033 | ps->dpmx_nb_ps_lo = 0x1; | 2097 | ps->dpmx_nb_ps_lo = 0x1; |
2034 | ps->dpmx_nb_ps_hi = 0x0; | 2098 | ps->dpmx_nb_ps_hi = 0x0; |
2035 | } else { | 2099 | } else { |
2036 | ps->dpm0_pg_nb_ps_lo = 0x1; | 2100 | ps->dpm0_pg_nb_ps_lo = 0x3; |
2037 | ps->dpm0_pg_nb_ps_hi = 0x0; | 2101 | ps->dpm0_pg_nb_ps_hi = 0x0; |
2038 | ps->dpmx_nb_ps_lo = 0x2; | 2102 | ps->dpmx_nb_ps_lo = 0x3; |
2039 | ps->dpmx_nb_ps_hi = 0x1; | 2103 | ps->dpmx_nb_ps_hi = 0x0; |
2040 | 2104 | ||
2041 | if (pi->sys_info.nb_dpm_enable && pi->battery_state) { | 2105 | if (pi->sys_info.nb_dpm_enable) { |
2042 | force_high = (mclk >= pi->sys_info.nbp_memory_clock[3]) || | 2106 | force_high = (mclk >= pi->sys_info.nbp_memory_clock[3]) || |
2043 | pi->video_start || (rdev->pm.dpm.new_active_crtc_count >= 3) || | 2107 | pi->video_start || (rdev->pm.dpm.new_active_crtc_count >= 3) || |
2044 | pi->disable_nb_ps3_in_battery; | 2108 | pi->disable_nb_ps3_in_battery; |
@@ -2204,6 +2268,15 @@ static void kv_enable_new_levels(struct radeon_device *rdev) | |||
2204 | } | 2268 | } |
2205 | } | 2269 | } |
2206 | 2270 | ||
2271 | static int kv_set_enabled_level(struct radeon_device *rdev, u32 level) | ||
2272 | { | ||
2273 | u32 new_mask = (1 << level); | ||
2274 | |||
2275 | return kv_send_msg_to_smc_with_parameter(rdev, | ||
2276 | PPSMC_MSG_SCLKDPM_SetEnabledMask, | ||
2277 | new_mask); | ||
2278 | } | ||
2279 | |||
2207 | static int kv_set_enabled_levels(struct radeon_device *rdev) | 2280 | static int kv_set_enabled_levels(struct radeon_device *rdev) |
2208 | { | 2281 | { |
2209 | struct kv_power_info *pi = kv_get_pi(rdev); | 2282 | struct kv_power_info *pi = kv_get_pi(rdev); |