diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/kv_dpm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/kv_dpm.c | 64 |
1 files changed, 48 insertions, 16 deletions
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index 351db361239d..16ec9d56a234 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c | |||
@@ -1338,13 +1338,11 @@ static int kv_enable_uvd_dpm(struct radeon_device *rdev, bool enable) | |||
1338 | PPSMC_MSG_UVDDPM_Enable : PPSMC_MSG_UVDDPM_Disable); | 1338 | PPSMC_MSG_UVDDPM_Enable : PPSMC_MSG_UVDDPM_Disable); |
1339 | } | 1339 | } |
1340 | 1340 | ||
1341 | #if 0 | ||
1342 | static int kv_enable_vce_dpm(struct radeon_device *rdev, bool enable) | 1341 | static int kv_enable_vce_dpm(struct radeon_device *rdev, bool enable) |
1343 | { | 1342 | { |
1344 | return kv_notify_message_to_smu(rdev, enable ? | 1343 | return kv_notify_message_to_smu(rdev, enable ? |
1345 | PPSMC_MSG_VCEDPM_Enable : PPSMC_MSG_VCEDPM_Disable); | 1344 | PPSMC_MSG_VCEDPM_Enable : PPSMC_MSG_VCEDPM_Disable); |
1346 | } | 1345 | } |
1347 | #endif | ||
1348 | 1346 | ||
1349 | static int kv_enable_samu_dpm(struct radeon_device *rdev, bool enable) | 1347 | static int kv_enable_samu_dpm(struct radeon_device *rdev, bool enable) |
1350 | { | 1348 | { |
@@ -1389,7 +1387,6 @@ static int kv_update_uvd_dpm(struct radeon_device *rdev, bool gate) | |||
1389 | return kv_enable_uvd_dpm(rdev, !gate); | 1387 | return kv_enable_uvd_dpm(rdev, !gate); |
1390 | } | 1388 | } |
1391 | 1389 | ||
1392 | #if 0 | ||
1393 | static u8 kv_get_vce_boot_level(struct radeon_device *rdev) | 1390 | static u8 kv_get_vce_boot_level(struct radeon_device *rdev) |
1394 | { | 1391 | { |
1395 | u8 i; | 1392 | u8 i; |
@@ -1414,6 +1411,9 @@ static int kv_update_vce_dpm(struct radeon_device *rdev, | |||
1414 | int ret; | 1411 | int ret; |
1415 | 1412 | ||
1416 | if (radeon_new_state->evclk > 0 && radeon_current_state->evclk == 0) { | 1413 | if (radeon_new_state->evclk > 0 && radeon_current_state->evclk == 0) { |
1414 | kv_dpm_powergate_vce(rdev, false); | ||
1415 | /* turn the clocks on when encoding */ | ||
1416 | cik_update_cg(rdev, RADEON_CG_BLOCK_VCE, false); | ||
1417 | if (pi->caps_stable_p_state) | 1417 | if (pi->caps_stable_p_state) |
1418 | pi->vce_boot_level = table->count - 1; | 1418 | pi->vce_boot_level = table->count - 1; |
1419 | else | 1419 | else |
@@ -1436,11 +1436,13 @@ static int kv_update_vce_dpm(struct radeon_device *rdev, | |||
1436 | kv_enable_vce_dpm(rdev, true); | 1436 | kv_enable_vce_dpm(rdev, true); |
1437 | } else if (radeon_new_state->evclk == 0 && radeon_current_state->evclk > 0) { | 1437 | } else if (radeon_new_state->evclk == 0 && radeon_current_state->evclk > 0) { |
1438 | kv_enable_vce_dpm(rdev, false); | 1438 | kv_enable_vce_dpm(rdev, false); |
1439 | /* turn the clocks off when not encoding */ | ||
1440 | cik_update_cg(rdev, RADEON_CG_BLOCK_VCE, true); | ||
1441 | kv_dpm_powergate_vce(rdev, true); | ||
1439 | } | 1442 | } |
1440 | 1443 | ||
1441 | return 0; | 1444 | return 0; |
1442 | } | 1445 | } |
1443 | #endif | ||
1444 | 1446 | ||
1445 | static int kv_update_samu_dpm(struct radeon_device *rdev, bool gate) | 1447 | static int kv_update_samu_dpm(struct radeon_device *rdev, bool gate) |
1446 | { | 1448 | { |
@@ -1575,11 +1577,16 @@ static void kv_dpm_powergate_vce(struct radeon_device *rdev, bool gate) | |||
1575 | pi->vce_power_gated = gate; | 1577 | pi->vce_power_gated = gate; |
1576 | 1578 | ||
1577 | if (gate) { | 1579 | if (gate) { |
1578 | if (pi->caps_vce_pg) | 1580 | if (pi->caps_vce_pg) { |
1581 | /* XXX do we need a vce_v1_0_stop() ? */ | ||
1579 | kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerOFF); | 1582 | kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerOFF); |
1583 | } | ||
1580 | } else { | 1584 | } else { |
1581 | if (pi->caps_vce_pg) | 1585 | if (pi->caps_vce_pg) { |
1582 | kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerON); | 1586 | kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerON); |
1587 | vce_v2_0_resume(rdev); | ||
1588 | vce_v1_0_start(rdev); | ||
1589 | } | ||
1583 | } | 1590 | } |
1584 | } | 1591 | } |
1585 | 1592 | ||
@@ -1768,7 +1775,7 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) | |||
1768 | { | 1775 | { |
1769 | struct kv_power_info *pi = kv_get_pi(rdev); | 1776 | struct kv_power_info *pi = kv_get_pi(rdev); |
1770 | struct radeon_ps *new_ps = &pi->requested_rps; | 1777 | struct radeon_ps *new_ps = &pi->requested_rps; |
1771 | /*struct radeon_ps *old_ps = &pi->current_rps;*/ | 1778 | struct radeon_ps *old_ps = &pi->current_rps; |
1772 | int ret; | 1779 | int ret; |
1773 | 1780 | ||
1774 | if (pi->bapm_enable) { | 1781 | if (pi->bapm_enable) { |
@@ -1798,13 +1805,12 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) | |||
1798 | kv_set_enabled_levels(rdev); | 1805 | kv_set_enabled_levels(rdev); |
1799 | kv_force_lowest_valid(rdev); | 1806 | kv_force_lowest_valid(rdev); |
1800 | kv_unforce_levels(rdev); | 1807 | kv_unforce_levels(rdev); |
1801 | #if 0 | 1808 | |
1802 | ret = kv_update_vce_dpm(rdev, new_ps, old_ps); | 1809 | ret = kv_update_vce_dpm(rdev, new_ps, old_ps); |
1803 | if (ret) { | 1810 | if (ret) { |
1804 | DRM_ERROR("kv_update_vce_dpm failed\n"); | 1811 | DRM_ERROR("kv_update_vce_dpm failed\n"); |
1805 | return ret; | 1812 | return ret; |
1806 | } | 1813 | } |
1807 | #endif | ||
1808 | kv_update_sclk_t(rdev); | 1814 | kv_update_sclk_t(rdev); |
1809 | } | 1815 | } |
1810 | } else { | 1816 | } else { |
@@ -1823,13 +1829,11 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) | |||
1823 | kv_program_nbps_index_settings(rdev, new_ps); | 1829 | kv_program_nbps_index_settings(rdev, new_ps); |
1824 | kv_freeze_sclk_dpm(rdev, false); | 1830 | kv_freeze_sclk_dpm(rdev, false); |
1825 | kv_set_enabled_levels(rdev); | 1831 | kv_set_enabled_levels(rdev); |
1826 | #if 0 | ||
1827 | ret = kv_update_vce_dpm(rdev, new_ps, old_ps); | 1832 | ret = kv_update_vce_dpm(rdev, new_ps, old_ps); |
1828 | if (ret) { | 1833 | if (ret) { |
1829 | DRM_ERROR("kv_update_vce_dpm failed\n"); | 1834 | DRM_ERROR("kv_update_vce_dpm failed\n"); |
1830 | return ret; | 1835 | return ret; |
1831 | } | 1836 | } |
1832 | #endif | ||
1833 | kv_update_acp_boot_level(rdev); | 1837 | kv_update_acp_boot_level(rdev); |
1834 | kv_update_sclk_t(rdev); | 1838 | kv_update_sclk_t(rdev); |
1835 | kv_enable_nb_dpm(rdev); | 1839 | kv_enable_nb_dpm(rdev); |
@@ -2037,6 +2041,14 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2037 | struct radeon_clock_and_voltage_limits *max_limits = | 2041 | struct radeon_clock_and_voltage_limits *max_limits = |
2038 | &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; | 2042 | &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; |
2039 | 2043 | ||
2044 | if (new_rps->vce_active) { | ||
2045 | new_rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk; | ||
2046 | new_rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk; | ||
2047 | } else { | ||
2048 | new_rps->evclk = 0; | ||
2049 | new_rps->ecclk = 0; | ||
2050 | } | ||
2051 | |||
2040 | mclk = max_limits->mclk; | 2052 | mclk = max_limits->mclk; |
2041 | sclk = min_sclk; | 2053 | sclk = min_sclk; |
2042 | 2054 | ||
@@ -2056,6 +2068,11 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2056 | sclk = stable_p_state_sclk; | 2068 | sclk = stable_p_state_sclk; |
2057 | } | 2069 | } |
2058 | 2070 | ||
2071 | if (new_rps->vce_active) { | ||
2072 | if (sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk) | ||
2073 | sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk; | ||
2074 | } | ||
2075 | |||
2059 | ps->need_dfs_bypass = true; | 2076 | ps->need_dfs_bypass = true; |
2060 | 2077 | ||
2061 | for (i = 0; i < ps->num_levels; i++) { | 2078 | for (i = 0; i < ps->num_levels; i++) { |
@@ -2092,7 +2109,8 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2092 | } | 2109 | } |
2093 | } | 2110 | } |
2094 | 2111 | ||
2095 | pi->video_start = new_rps->dclk || new_rps->vclk; | 2112 | pi->video_start = new_rps->dclk || new_rps->vclk || |
2113 | new_rps->evclk || new_rps->ecclk; | ||
2096 | 2114 | ||
2097 | if ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == | 2115 | if ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == |
2098 | ATOM_PPLIB_CLASSIFICATION_UI_BATTERY) | 2116 | ATOM_PPLIB_CLASSIFICATION_UI_BATTERY) |
@@ -2538,9 +2556,6 @@ static int kv_parse_power_table(struct radeon_device *rdev) | |||
2538 | if (!rdev->pm.dpm.ps) | 2556 | if (!rdev->pm.dpm.ps) |
2539 | return -ENOMEM; | 2557 | return -ENOMEM; |
2540 | power_state_offset = (u8 *)state_array->states; | 2558 | power_state_offset = (u8 *)state_array->states; |
2541 | rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps); | ||
2542 | rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); | ||
2543 | rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime); | ||
2544 | for (i = 0; i < state_array->ucNumEntries; i++) { | 2559 | for (i = 0; i < state_array->ucNumEntries; i++) { |
2545 | u8 *idx; | 2560 | u8 *idx; |
2546 | power_state = (union pplib_power_state *)power_state_offset; | 2561 | power_state = (union pplib_power_state *)power_state_offset; |
@@ -2577,6 +2592,19 @@ static int kv_parse_power_table(struct radeon_device *rdev) | |||
2577 | power_state_offset += 2 + power_state->v2.ucNumDPMLevels; | 2592 | power_state_offset += 2 + power_state->v2.ucNumDPMLevels; |
2578 | } | 2593 | } |
2579 | rdev->pm.dpm.num_ps = state_array->ucNumEntries; | 2594 | rdev->pm.dpm.num_ps = state_array->ucNumEntries; |
2595 | |||
2596 | /* fill in the vce power states */ | ||
2597 | for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) { | ||
2598 | u32 sclk; | ||
2599 | clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx; | ||
2600 | clock_info = (union pplib_clock_info *) | ||
2601 | &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize]; | ||
2602 | sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow); | ||
2603 | sclk |= clock_info->sumo.ucEngineClockHigh << 16; | ||
2604 | rdev->pm.dpm.vce_states[i].sclk = sclk; | ||
2605 | rdev->pm.dpm.vce_states[i].mclk = 0; | ||
2606 | } | ||
2607 | |||
2580 | return 0; | 2608 | return 0; |
2581 | } | 2609 | } |
2582 | 2610 | ||
@@ -2590,6 +2618,10 @@ int kv_dpm_init(struct radeon_device *rdev) | |||
2590 | return -ENOMEM; | 2618 | return -ENOMEM; |
2591 | rdev->pm.dpm.priv = pi; | 2619 | rdev->pm.dpm.priv = pi; |
2592 | 2620 | ||
2621 | ret = r600_get_platform_caps(rdev); | ||
2622 | if (ret) | ||
2623 | return ret; | ||
2624 | |||
2593 | ret = r600_parse_extended_power_table(rdev); | 2625 | ret = r600_parse_extended_power_table(rdev); |
2594 | if (ret) | 2626 | if (ret) |
2595 | return ret; | 2627 | return ret; |
@@ -2623,7 +2655,7 @@ int kv_dpm_init(struct radeon_device *rdev) | |||
2623 | pi->caps_fps = false; /* true? */ | 2655 | pi->caps_fps = false; /* true? */ |
2624 | pi->caps_uvd_pg = true; | 2656 | pi->caps_uvd_pg = true; |
2625 | pi->caps_uvd_dpm = true; | 2657 | pi->caps_uvd_dpm = true; |
2626 | pi->caps_vce_pg = false; | 2658 | pi->caps_vce_pg = false; /* XXX true */ |
2627 | pi->caps_samu_pg = false; | 2659 | pi->caps_samu_pg = false; |
2628 | pi->caps_acp_pg = false; | 2660 | pi->caps_acp_pg = false; |
2629 | pi->caps_stable_p_state = false; | 2661 | pi->caps_stable_p_state = false; |