Commit 43e0f873 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-next-4.20' of git://people.freedesktop.org/~agd5f/linux into drm-next

- Fix flickering at low backlight levels on some systems
- Fix some overclocking regressions
- Vega20 updates for
- GPU recovery fixes
- Disable gfxoff on RV as some sbios/fw combinations are not stable yet
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181101151939.2828-1-alexander.deucher@amd.com
parents 52b50ae1 9d064be1
...@@ -135,7 +135,8 @@ static int acp_poweroff(struct generic_pm_domain *genpd) ...@@ -135,7 +135,8 @@ static int acp_poweroff(struct generic_pm_domain *genpd)
* 2. power off the acp tiles * 2. power off the acp tiles
* 3. check and enter ulv state * 3. check and enter ulv state
*/ */
if (adev->powerplay.pp_funcs->set_powergating_by_smu) if (adev->powerplay.pp_funcs &&
adev->powerplay.pp_funcs->set_powergating_by_smu)
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true); amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true);
} }
return 0; return 0;
...@@ -517,7 +518,8 @@ static int acp_set_powergating_state(void *handle, ...@@ -517,7 +518,8 @@ static int acp_set_powergating_state(void *handle,
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
bool enable = state == AMD_PG_STATE_GATE ? true : false; bool enable = state == AMD_PG_STATE_GATE ? true : false;
if (adev->powerplay.pp_funcs->set_powergating_by_smu) if (adev->powerplay.pp_funcs &&
adev->powerplay.pp_funcs->set_powergating_by_smu)
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, enable); amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, enable);
return 0; return 0;
......
...@@ -1493,8 +1493,6 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev) ...@@ -1493,8 +1493,6 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
} }
adev->powerplay.pp_feature = amdgpu_pp_feature_mask; adev->powerplay.pp_feature = amdgpu_pp_feature_mask;
if (amdgpu_sriov_vf(adev))
adev->powerplay.pp_feature &= ~PP_GFXOFF_MASK;
for (i = 0; i < adev->num_ip_blocks; i++) { for (i = 0; i < adev->num_ip_blocks; i++) {
if ((amdgpu_ip_block_mask & (1 << i)) == 0) { if ((amdgpu_ip_block_mask & (1 << i)) == 0) {
...@@ -1600,7 +1598,7 @@ static int amdgpu_device_fw_loading(struct amdgpu_device *adev) ...@@ -1600,7 +1598,7 @@ static int amdgpu_device_fw_loading(struct amdgpu_device *adev)
} }
} }
if (adev->powerplay.pp_funcs->load_firmware) { if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->load_firmware) {
r = adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle); r = adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle);
if (r) { if (r) {
pr_err("firmware loading failed\n"); pr_err("firmware loading failed\n");
...@@ -3341,7 +3339,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, ...@@ -3341,7 +3339,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
kthread_park(ring->sched.thread); kthread_park(ring->sched.thread);
if (job && job->base.sched == &ring->sched) if (job && job->base.sched != &ring->sched)
continue; continue;
drm_sched_hw_job_reset(&ring->sched, job ? &job->base : NULL); drm_sched_hw_job_reset(&ring->sched, job ? &job->base : NULL);
......
...@@ -114,8 +114,8 @@ uint amdgpu_pg_mask = 0xffffffff; ...@@ -114,8 +114,8 @@ uint amdgpu_pg_mask = 0xffffffff;
uint amdgpu_sdma_phase_quantum = 32; uint amdgpu_sdma_phase_quantum = 32;
char *amdgpu_disable_cu = NULL; char *amdgpu_disable_cu = NULL;
char *amdgpu_virtual_display = NULL; char *amdgpu_virtual_display = NULL;
/* OverDrive(bit 14) disabled by default*/ /* OverDrive(bit 14),gfxoff(bit 15),stutter mode(bit 17) disabled by default*/
uint amdgpu_pp_feature_mask = 0xffffbfff; uint amdgpu_pp_feature_mask = 0xfffd3fff;
int amdgpu_ngg = 0; int amdgpu_ngg = 0;
int amdgpu_prim_buf_per_se = 0; int amdgpu_prim_buf_per_se = 0;
int amdgpu_pos_buf_per_se = 0; int amdgpu_pos_buf_per_se = 0;
......
...@@ -392,7 +392,7 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) ...@@ -392,7 +392,7 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
if (!(adev->powerplay.pp_feature & PP_GFXOFF_MASK)) if (!(adev->powerplay.pp_feature & PP_GFXOFF_MASK))
return; return;
if (!adev->powerplay.pp_funcs->set_powergating_by_smu) if (!adev->powerplay.pp_funcs || !adev->powerplay.pp_funcs->set_powergating_by_smu)
return; return;
......
...@@ -704,7 +704,10 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, ...@@ -704,7 +704,10 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev,
return ret; return ret;
if (adev->powerplay.pp_funcs->force_clock_level) if (adev->powerplay.pp_funcs->force_clock_level)
amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask); ret = amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask);
if (ret)
return -EINVAL;
return count; return count;
} }
...@@ -737,7 +740,10 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, ...@@ -737,7 +740,10 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev,
return ret; return ret;
if (adev->powerplay.pp_funcs->force_clock_level) if (adev->powerplay.pp_funcs->force_clock_level)
amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask); ret = amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask);
if (ret)
return -EINVAL;
return count; return count;
} }
...@@ -770,7 +776,10 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, ...@@ -770,7 +776,10 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev,
return ret; return ret;
if (adev->powerplay.pp_funcs->force_clock_level) if (adev->powerplay.pp_funcs->force_clock_level)
amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask); ret = amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask);
if (ret)
return -EINVAL;
return count; return count;
} }
......
...@@ -542,7 +542,8 @@ static void amdgpu_vm_pt_next_leaf(struct amdgpu_device *adev, ...@@ -542,7 +542,8 @@ static void amdgpu_vm_pt_next_leaf(struct amdgpu_device *adev,
struct amdgpu_vm_pt_cursor *cursor) struct amdgpu_vm_pt_cursor *cursor)
{ {
amdgpu_vm_pt_next(adev, cursor); amdgpu_vm_pt_next(adev, cursor);
while (amdgpu_vm_pt_descendant(adev, cursor)); if (cursor->pfn != ~0ll)
while (amdgpu_vm_pt_descendant(adev, cursor));
} }
/** /**
...@@ -3234,8 +3235,10 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) ...@@ -3234,8 +3235,10 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
} }
rbtree_postorder_for_each_entry_safe(mapping, tmp, rbtree_postorder_for_each_entry_safe(mapping, tmp,
&vm->va.rb_root, rb) { &vm->va.rb_root, rb) {
/* Don't remove the mapping here, we don't want to trigger a
* rebalance and the tree is about to be destroyed anyway.
*/
list_del(&mapping->list); list_del(&mapping->list);
amdgpu_vm_it_remove(mapping, &vm->va);
kfree(mapping); kfree(mapping);
} }
list_for_each_entry_safe(mapping, tmp, &vm->freed, list) { list_for_each_entry_safe(mapping, tmp, &vm->freed, list) {
......
...@@ -4815,8 +4815,10 @@ static int gfx_v8_0_kcq_resume(struct amdgpu_device *adev) ...@@ -4815,8 +4815,10 @@ static int gfx_v8_0_kcq_resume(struct amdgpu_device *adev)
if (r) if (r)
goto done; goto done;
/* Test KCQs */ /* Test KCQs - reversing the order of rings seems to fix ring test failure
for (i = 0; i < adev->gfx.num_compute_rings; i++) { * after GPU reset
*/
for (i = adev->gfx.num_compute_rings - 1; i >= 0; i--) {
ring = &adev->gfx.compute_ring[i]; ring = &adev->gfx.compute_ring[i];
ring->ready = true; ring->ready = true;
r = amdgpu_ring_test_ring(ring); r = amdgpu_ring_test_ring(ring);
......
...@@ -280,7 +280,7 @@ void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev, ...@@ -280,7 +280,7 @@ void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev,
return; return;
if (enable && adev->pg_flags & AMD_PG_SUPPORT_MMHUB) { if (enable && adev->pg_flags & AMD_PG_SUPPORT_MMHUB) {
if (adev->powerplay.pp_funcs->set_powergating_by_smu) if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->set_powergating_by_smu)
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GMC, true); amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GMC, true);
} }
......
...@@ -1366,7 +1366,8 @@ static int sdma_v4_0_hw_init(void *handle) ...@@ -1366,7 +1366,8 @@ static int sdma_v4_0_hw_init(void *handle)
int r; int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs->set_powergating_by_smu) if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs &&
adev->powerplay.pp_funcs->set_powergating_by_smu)
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false); amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false);
sdma_v4_0_init_golden_registers(adev); sdma_v4_0_init_golden_registers(adev);
...@@ -1386,7 +1387,8 @@ static int sdma_v4_0_hw_fini(void *handle) ...@@ -1386,7 +1387,8 @@ static int sdma_v4_0_hw_fini(void *handle)
sdma_v4_0_ctx_switch_enable(adev, false); sdma_v4_0_ctx_switch_enable(adev, false);
sdma_v4_0_enable(adev, false); sdma_v4_0_enable(adev, false);
if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs->set_powergating_by_smu) if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs
&& adev->powerplay.pp_funcs->set_powergating_by_smu)
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, true); amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, true);
return 0; return 0;
......
...@@ -1524,6 +1524,13 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd) ...@@ -1524,6 +1524,13 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
{ {
struct amdgpu_display_manager *dm = bl_get_data(bd); struct amdgpu_display_manager *dm = bl_get_data(bd);
/*
* PWM interperts 0 as 100% rather than 0% because of HW
* limitation for level 0.So limiting minimum brightness level
* to 1.
*/
if (bd->props.brightness < 1)
return 1;
if (dc_link_set_backlight_level(dm->backlight_link, if (dc_link_set_backlight_level(dm->backlight_link,
bd->props.brightness, 0, 0)) bd->props.brightness, 0, 0))
return 0; return 0;
......
...@@ -101,7 +101,7 @@ bool dm_pp_apply_display_requirements( ...@@ -101,7 +101,7 @@ bool dm_pp_apply_display_requirements(
adev->pm.pm_display_cfg.displays[i].controller_id = dc_cfg->pipe_idx + 1; adev->pm.pm_display_cfg.displays[i].controller_id = dc_cfg->pipe_idx + 1;
} }
if (adev->powerplay.pp_funcs->display_configuration_change) if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_configuration_change)
adev->powerplay.pp_funcs->display_configuration_change( adev->powerplay.pp_funcs->display_configuration_change(
adev->powerplay.pp_handle, adev->powerplay.pp_handle,
&adev->pm.pm_display_cfg); &adev->pm.pm_display_cfg);
...@@ -304,7 +304,7 @@ bool dm_pp_get_clock_levels_by_type( ...@@ -304,7 +304,7 @@ bool dm_pp_get_clock_levels_by_type(
struct amd_pp_simple_clock_info validation_clks = { 0 }; struct amd_pp_simple_clock_info validation_clks = { 0 };
uint32_t i; uint32_t i;
if (adev->powerplay.pp_funcs->get_clock_by_type) { if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_clock_by_type) {
if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle, if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle,
dc_to_pp_clock_type(clk_type), &pp_clks)) { dc_to_pp_clock_type(clk_type), &pp_clks)) {
/* Error in pplib. Provide default values. */ /* Error in pplib. Provide default values. */
...@@ -315,7 +315,7 @@ bool dm_pp_get_clock_levels_by_type( ...@@ -315,7 +315,7 @@ bool dm_pp_get_clock_levels_by_type(
pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type); pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type);
if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks) { if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_display_mode_validation_clocks) {
if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks( if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks(
pp_handle, &validation_clks)) { pp_handle, &validation_clks)) {
/* Error in pplib. Provide default values. */ /* Error in pplib. Provide default values. */
...@@ -398,6 +398,9 @@ bool dm_pp_get_clock_levels_by_type_with_voltage( ...@@ -398,6 +398,9 @@ bool dm_pp_get_clock_levels_by_type_with_voltage(
struct pp_clock_levels_with_voltage pp_clk_info = {0}; struct pp_clock_levels_with_voltage pp_clk_info = {0};
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
if (!pp_funcs || !pp_funcs->get_clock_by_type_with_voltage)
return false;
if (pp_funcs->get_clock_by_type_with_voltage(pp_handle, if (pp_funcs->get_clock_by_type_with_voltage(pp_handle,
dc_to_pp_clock_type(clk_type), dc_to_pp_clock_type(clk_type),
&pp_clk_info)) &pp_clk_info))
...@@ -438,7 +441,7 @@ bool dm_pp_apply_clock_for_voltage_request( ...@@ -438,7 +441,7 @@ bool dm_pp_apply_clock_for_voltage_request(
if (!pp_clock_request.clock_type) if (!pp_clock_request.clock_type)
return false; return false;
if (adev->powerplay.pp_funcs->display_clock_voltage_request) if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_clock_voltage_request)
ret = adev->powerplay.pp_funcs->display_clock_voltage_request( ret = adev->powerplay.pp_funcs->display_clock_voltage_request(
adev->powerplay.pp_handle, adev->powerplay.pp_handle,
&pp_clock_request); &pp_clock_request);
...@@ -455,7 +458,7 @@ bool dm_pp_get_static_clocks( ...@@ -455,7 +458,7 @@ bool dm_pp_get_static_clocks(
struct amd_pp_clock_info pp_clk_info = {0}; struct amd_pp_clock_info pp_clk_info = {0};
int ret = 0; int ret = 0;
if (adev->powerplay.pp_funcs->get_current_clocks) if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_current_clocks)
ret = adev->powerplay.pp_funcs->get_current_clocks( ret = adev->powerplay.pp_funcs->get_current_clocks(
adev->powerplay.pp_handle, adev->powerplay.pp_handle,
&pp_clk_info); &pp_clk_info);
...@@ -505,6 +508,9 @@ void pp_rv_set_wm_ranges(struct pp_smu *pp, ...@@ -505,6 +508,9 @@ void pp_rv_set_wm_ranges(struct pp_smu *pp,
wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets; wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets;
wm_with_clock_ranges.num_wm_mcif_sets = ranges->num_writer_wm_sets; wm_with_clock_ranges.num_wm_mcif_sets = ranges->num_writer_wm_sets;
if (!pp_funcs || !pp_funcs->set_watermarks_for_clocks_ranges)
return;
for (i = 0; i < wm_with_clock_ranges.num_wm_dmif_sets; i++) { for (i = 0; i < wm_with_clock_ranges.num_wm_dmif_sets; i++) {
if (ranges->reader_wm_sets[i].wm_inst > 3) if (ranges->reader_wm_sets[i].wm_inst > 3)
wm_dce_clocks[i].wm_set_id = WM_SET_A; wm_dce_clocks[i].wm_set_id = WM_SET_A;
......
...@@ -568,7 +568,7 @@ static struct input_pixel_processor *dce110_ipp_create( ...@@ -568,7 +568,7 @@ static struct input_pixel_processor *dce110_ipp_create(
static const struct encoder_feature_support link_enc_feature = { static const struct encoder_feature_support link_enc_feature = {
.max_hdmi_deep_color = COLOR_DEPTH_121212, .max_hdmi_deep_color = COLOR_DEPTH_121212,
.max_hdmi_pixel_clock = 594000, .max_hdmi_pixel_clock = 300000,
.flags.bits.IS_HBR2_CAPABLE = true, .flags.bits.IS_HBR2_CAPABLE = true,
.flags.bits.IS_TPS3_CAPABLE = true .flags.bits.IS_TPS3_CAPABLE = true
}; };
......
...@@ -723,11 +723,14 @@ static int pp_dpm_force_clock_level(void *handle, ...@@ -723,11 +723,14 @@ static int pp_dpm_force_clock_level(void *handle,
pr_info("%s was not implemented.\n", __func__); pr_info("%s was not implemented.\n", __func__);
return 0; return 0;
} }
if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {
pr_info("force clock level is for dpm manual mode only.\n");
return -EINVAL;
}
mutex_lock(&hwmgr->smu_lock); mutex_lock(&hwmgr->smu_lock);
if (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) ret = hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask);
ret = hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask);
else
ret = -EINVAL;
mutex_unlock(&hwmgr->smu_lock); mutex_unlock(&hwmgr->smu_lock);
return ret; return ret;
} }
...@@ -963,6 +966,7 @@ static int pp_dpm_switch_power_profile(void *handle, ...@@ -963,6 +966,7 @@ static int pp_dpm_switch_power_profile(void *handle,
static int pp_set_power_limit(void *handle, uint32_t limit) static int pp_set_power_limit(void *handle, uint32_t limit)
{ {
struct pp_hwmgr *hwmgr = handle; struct pp_hwmgr *hwmgr = handle;
uint32_t max_power_limit;
if (!hwmgr || !hwmgr->pm_en) if (!hwmgr || !hwmgr->pm_en)
return -EINVAL; return -EINVAL;
...@@ -975,7 +979,13 @@ static int pp_set_power_limit(void *handle, uint32_t limit) ...@@ -975,7 +979,13 @@ static int pp_set_power_limit(void *handle, uint32_t limit)
if (limit == 0) if (limit == 0)
limit = hwmgr->default_power_limit; limit = hwmgr->default_power_limit;
if (limit > hwmgr->default_power_limit) max_power_limit = hwmgr->default_power_limit;
if (hwmgr->od_enabled) {
max_power_limit *= (100 + hwmgr->platform_descriptor.TDPODLimit);
max_power_limit /= 100;
}
if (limit > max_power_limit)
return -EINVAL; return -EINVAL;
mutex_lock(&hwmgr->smu_lock); mutex_lock(&hwmgr->smu_lock);
...@@ -994,8 +1004,13 @@ static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit) ...@@ -994,8 +1004,13 @@ static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit)
mutex_lock(&hwmgr->smu_lock); mutex_lock(&hwmgr->smu_lock);
if (default_limit) if (default_limit) {
*limit = hwmgr->default_power_limit; *limit = hwmgr->default_power_limit;
if (hwmgr->od_enabled) {
*limit *= (100 + hwmgr->platform_descriptor.TDPODLimit);
*limit /= 100;
}
}
else else
*limit = hwmgr->power_limit; *limit = hwmgr->power_limit;
...@@ -1303,12 +1318,12 @@ static int pp_enable_mgpu_fan_boost(void *handle) ...@@ -1303,12 +1318,12 @@ static int pp_enable_mgpu_fan_boost(void *handle)
{ {
struct pp_hwmgr *hwmgr = handle; struct pp_hwmgr *hwmgr = handle;
if (!hwmgr || !hwmgr->pm_en) if (!hwmgr)
return -EINVAL; return -EINVAL;
if (hwmgr->hwmgr_func->enable_mgpu_fan_boost == NULL) { if (!hwmgr->pm_en ||
hwmgr->hwmgr_func->enable_mgpu_fan_boost == NULL)
return 0; return 0;
}
mutex_lock(&hwmgr->smu_lock); mutex_lock(&hwmgr->smu_lock);
hwmgr->hwmgr_func->enable_mgpu_fan_boost(hwmgr); hwmgr->hwmgr_func->enable_mgpu_fan_boost(hwmgr);
......
...@@ -3588,9 +3588,10 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons ...@@ -3588,9 +3588,10 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons
break; break;
} }
if (i >= sclk_table->count) if (i >= sclk_table->count) {
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
else { sclk_table->dpm_levels[i-1].value = sclk;
} else {
/* TODO: Check SCLK in DAL's minimum clocks /* TODO: Check SCLK in DAL's minimum clocks
* in case DeepSleep divider update is required. * in case DeepSleep divider update is required.
*/ */
...@@ -3605,9 +3606,10 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons ...@@ -3605,9 +3606,10 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons
break; break;
} }
if (i >= mclk_table->count) if (i >= mclk_table->count) {
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
mclk_table->dpm_levels[i-1].value = mclk;
}
if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display) if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_MCLK; data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_MCLK;
......
...@@ -718,7 +718,7 @@ int smu_set_watermarks_for_clocks_ranges(void *wt_table, ...@@ -718,7 +718,7 @@ int smu_set_watermarks_for_clocks_ranges(void *wt_table,
table->WatermarkRow[1][i].MaxClock = table->WatermarkRow[1][i].MaxClock =
cpu_to_le16((uint16_t) cpu_to_le16((uint16_t)
(wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz) / (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz) /
100); 1000);
table->WatermarkRow[1][i].MinUclk = table->WatermarkRow[1][i].MinUclk =
cpu_to_le16((uint16_t) cpu_to_le16((uint16_t)
(wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz) / (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz) /
......
...@@ -1333,7 +1333,6 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) ...@@ -1333,7 +1333,6 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
if (hwmgr->platform_descriptor.overdriveLimit.memoryClock == 0) if (hwmgr->platform_descriptor.overdriveLimit.memoryClock == 0)
hwmgr->platform_descriptor.overdriveLimit.memoryClock = hwmgr->platform_descriptor.overdriveLimit.memoryClock =
dpm_table->dpm_levels[dpm_table->count-1].value; dpm_table->dpm_levels[dpm_table->count-1].value;
vega10_init_dpm_state(&(dpm_table->dpm_state)); vega10_init_dpm_state(&(dpm_table->dpm_state));
data->dpm_table.eclk_table.count = 0; data->dpm_table.eclk_table.count = 0;
...@@ -3249,6 +3248,37 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, ...@@ -3249,6 +3248,37 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input) static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input)
{ {
struct vega10_hwmgr *data = hwmgr->backend; struct vega10_hwmgr *data = hwmgr->backend;
const struct phm_set_power_state_input *states =
(const struct phm_set_power_state_input *)input;
const struct vega10_power_state *vega10_ps =
cast_const_phw_vega10_power_state(states->pnew_state);
struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
uint32_t sclk = vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].gfx_clock;
struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
uint32_t mclk = vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].mem_clock;
uint32_t i;
for (i = 0; i < sclk_table->count; i++) {
if (sclk == sclk_table->dpm_levels[i].value)
break;
}
if (i >= sclk_table->count) {
data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
sclk_table->dpm_levels[i-1].value = sclk;
}
for (i = 0; i < mclk_table->count; i++) {
if (mclk == mclk_table->dpm_levels[i].value)
break;
}
if (i >= mclk_table->count) {
data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
mclk_table->dpm_levels[i-1].value = mclk;
}
if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display) if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
data->need_update_dpm_table |= DPMTABLE_UPDATE_MCLK; data->need_update_dpm_table |= DPMTABLE_UPDATE_MCLK;
...@@ -4529,11 +4559,13 @@ static int vega10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value) ...@@ -4529,11 +4559,13 @@ static int vega10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
if (vega10_ps->performance_levels if (vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].gfx_clock > [vega10_ps->performance_level_count - 1].gfx_clock >
hwmgr->platform_descriptor.overdriveLimit.engineClock) hwmgr->platform_descriptor.overdriveLimit.engineClock) {
vega10_ps->performance_levels vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].gfx_clock = [vega10_ps->performance_level_count - 1].gfx_clock =
hwmgr->platform_descriptor.overdriveLimit.engineClock; hwmgr->platform_descriptor.overdriveLimit.engineClock;
pr_warn("max sclk supported by vbios is %d\n",
hwmgr->platform_descriptor.overdriveLimit.engineClock);
}
return 0; return 0;
} }
...@@ -4581,10 +4613,13 @@ static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value) ...@@ -4581,10 +4613,13 @@ static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
if (vega10_ps->performance_levels if (vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].mem_clock > [vega10_ps->performance_level_count - 1].mem_clock >
hwmgr->platform_descriptor.overdriveLimit.memoryClock) hwmgr->platform_descriptor.overdriveLimit.memoryClock) {
vega10_ps->performance_levels vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].mem_clock = [vega10_ps->performance_level_count - 1].mem_clock =
hwmgr->platform_descriptor.overdriveLimit.memoryClock; hwmgr->platform_descriptor.overdriveLimit.memoryClock;
pr_warn("max mclk supported by vbios is %d\n",
hwmgr->platform_descriptor.overdriveLimit.memoryClock);
}
return 0; return 0;
} }
......
...@@ -2356,6 +2356,13 @@ static int vega12_gfx_off_control(struct pp_hwmgr *hwmgr, bool enable) ...@@ -2356,6 +2356,13 @@ static int vega12_gfx_off_control(struct pp_hwmgr *hwmgr, bool enable)
return vega12_disable_gfx_off(hwmgr); return vega12_disable_gfx_off(hwmgr);
} }
static int vega12_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state,
PHM_PerformanceLevelDesignation designation, uint32_t index,
PHM_PerformanceLevel *level)
{
return 0;
}
static const struct pp_hwmgr_func vega12_hwmgr_funcs = { static const struct pp_hwmgr_func vega12_hwmgr_funcs = {
.backend_init = vega12_hwmgr_backend_init, .backend_init = vega12_hwmgr_backend_init,
.backend_fini = vega12_hwmgr_backend_fini, .backend_fini = vega12_hwmgr_backend_fini,
...@@ -2406,6 +2413,7 @@ static const struct pp_hwmgr_func vega12_hwmgr_funcs = { ...@@ -2406,6 +2413,7 @@ static const struct pp_hwmgr_func vega12_hwmgr_funcs = {
.register_irq_handlers = smu9_register_irq_handlers, .register_irq_handlers = smu9_register_irq_handlers,
.start_thermal_controller = vega12_start_thermal_controller, .start_thermal_controller = vega12_start_thermal_controller,
.powergate_gfx = vega12_gfx_off_control, .powergate_gfx = vega12_gfx_off_control,
.get_performance_level = vega12_get_performance_level,
}; };
int vega12_hwmgr_init(struct pp_hwmgr *hwmgr) int vega12_hwmgr_init(struct pp_hwmgr *hwmgr)
......
...@@ -1875,38 +1875,20 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr, ...@@ -1875,38 +1875,20 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr,
return ret; return ret;
} }
static int vega20_get_current_gfx_clk_freq(struct pp_hwmgr *hwmgr, uint32_t *gfx_freq) static int vega20_get_current_clk_freq(struct pp_hwmgr *hwmgr,
PPCLK_e clk_id, uint32_t *clk_freq)
{ {
uint32_t gfx_clk = 0;
int ret = 0; int ret = 0;
*gfx_freq = 0; *clk_freq = 0;
PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr, PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_GetDpmClockFreq, (PPCLK_GFXCLK << 16))) == 0, PPSMC_MSG_GetDpmClockFreq, (clk_id << 16))) == 0,
"[GetCurrentGfxClkFreq] Attempt to get Current GFXCLK Frequency Failed!", "[GetCurrentClkFreq] Attempt to get Current Frequency Failed!",
return ret); return ret);
gfx_clk = smum_get_argument(hwmgr); *clk_freq = smum_get_argument(hwmgr);
*gfx_freq = gfx_clk * 100; *clk_freq = *clk_freq * 100;
return 0;
}
static int vega20_get_current_mclk_freq(struct pp_hwmgr *hwmgr, uint32_t *mclk_freq)
{
uint32_t mem_clk = 0;
int ret = 0;
*mclk_freq = 0;
PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_GetDpmClockFreq, (PPCLK_UCLK << 16))) == 0,
"[GetCurrentMClkFreq] Attempt to get Current MCLK Frequency Failed!",
return ret);
mem_clk = smum_get_argument(hwmgr);
*mclk_freq = mem_clk * 100;
return 0; return 0;
} }
...@@ -1937,12 +1919,16 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx, ...@@ -1937,12 +1919,16 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx,
switch (idx) { switch (idx) {
case AMDGPU_PP_SENSOR_GFX_SCLK: case AMDGPU_PP_SENSOR_GFX_SCLK:
ret = vega20_get_current_gfx_clk_freq(hwmgr, (uint32_t *)value); ret = vega20_get_current_clk_freq(hwmgr,
PPCLK_GFXCLK,
(uint32_t *)value);
if (!ret) if (!ret)
*size = 4; *size = 4;
break; break;
case AMDGPU_PP_SENSOR_GFX_MCLK: case AMDGPU_PP_SENSOR_GFX_MCLK:
ret = vega20_get_current_mclk_freq(hwmgr, (uint32_t *)value); ret = vega20_get_current_clk_freq(hwmgr,
PPCLK_UCLK,
(uint32_t *)value);
if (!ret) if (!ret)
*size = 4; *size = 4;
break; break;
...@@ -2012,7 +1998,6 @@ int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr, ...@@ -2012,7 +1998,6 @@ int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) { if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) {
switch (clk_type) { switch (clk_type) {
case amd_pp_dcef_clock: case amd_pp_dcef_clock:
clk_freq = clock_req->clock_freq_in_khz / 100;
clk_select = PPCLK_DCEFCLK; clk_select = PPCLK_DCEFCLK;
break; break;
case amd_pp_disp_clock: case amd_pp_disp_clock:
...@@ -2041,11 +2026,20 @@ int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr, ...@@ -2041,11 +2026,20 @@ int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
return result; return result;
} }
static int vega20_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state,
PHM_PerformanceLevelDesignation designation, uint32_t index,
PHM_PerformanceLevel *level)
{
return 0;
}
static int vega20_notify_smc_display_config_after_ps_adjustment( static int vega20_notify_smc_display_config_after_ps_adjustment(
struct pp_hwmgr *hwmgr) struct pp_hwmgr *hwmgr)
{ {
struct vega20_hwmgr *data = struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend); (struct vega20_hwmgr *)(hwmgr->backend);
struct vega20_single_dpm_table *dpm_table =
&data->dpm_table.mem_table;
struct PP_Clocks min_clocks = {0}; struct PP_Clocks min_clocks = {0};
struct pp_display_clock_request clock_req; struct pp_display_clock_request clock_req;
int ret = 0; int ret = 0;
...@@ -2063,7 +2057,7 @@ static int vega20_notify_smc_display_config_after_ps_adjustment( ...@@ -2063,7 +2057,7 @@ static int vega20_notify_smc_display_config_after_ps_adjustment(
if (data->smu_features[GNLD_DPM_DCEFCLK].supported) { if (data->smu_features[GNLD_DPM_DCEFCLK].supported) {
clock_req.clock_type = amd_pp_dcef_clock; clock_req.clock_type = amd_pp_dcef_clock;
clock_req.clock_freq_in_khz = min_clocks.dcefClock; clock_req.clock_freq_in_khz = min_clocks.dcefClock * 10;
if (!vega20_display_clock_voltage_request(hwmgr, &clock_req)) { if (!vega20_display_clock_voltage_request(hwmgr, &clock_req)) {
if (data->smu_features[GNLD_DS_DCEFCLK].supported) if (data->smu_features[GNLD_DS_DCEFCLK].supported)
PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter( PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(
...@@ -2076,6 +2070,15 @@ static int vega20_notify_smc_display_config_after_ps_adjustment( ...@@ -2076,6 +2070,15 @@ static int vega20_notify_smc_display_config_after_ps_adjustment(
} }
} }
if (data->smu_features[GNLD_DPM_UCLK].enabled) {
dpm_table->dpm_state.hard_min_level = min_clocks.memoryClock / 100;
PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetHardMinByFreq,
(PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level)),
"[SetHardMinFreq] Set hard min uclk failed!",
return ret);
}
return 0; return 0;
} }
...@@ -2353,7 +2356,7 @@ static int vega20_get_sclks(struct pp_hwmgr *hwmgr, ...@@ -2353,7 +2356,7 @@ static int vega20_get_sclks(struct pp_hwmgr *hwmgr,
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
clocks->data[i].clocks_in_khz = clocks->data[i].clocks_in_khz =
dpm_table->dpm_levels[i].value * 100; dpm_table->dpm_levels[i].value * 1000;
clocks->data[i].latency_in_us = 0; clocks->data[i].latency_in_us = 0;
} }
...@@ -2383,7 +2386,7 @@ static int vega20_get_memclocks(struct pp_hwmgr *hwmgr, ...@@ -2383,7 +2386,7 @@ static int vega20_get_memclocks(struct pp_hwmgr *hwmgr,
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
clocks->data[i].clocks_in_khz = clocks->data[i].clocks_in_khz =
data->mclk_latency_table.entries[i].frequency = data->mclk_latency_table.entries[i].frequency =
dpm_table->dpm_levels[i].value * 100; dpm_table->dpm_levels[i].value * 1000;
clocks->data[i].latency_in_us = clocks->data[i].latency_in_us =
data->mclk_latency_table.entries[i].latency = data->mclk_latency_table.entries[i].latency =
vega20_get_mem_latency(hwmgr, dpm_table->dpm_levels[i].value); vega20_get_mem_latency(hwmgr, dpm_table->dpm_levels[i].value);
...@@ -2408,7 +2411,7 @@ static int vega20_get_dcefclocks(struct pp_hwmgr *hwmgr, ...@@ -2408,7 +2411,7 @@ static int vega20_get_dcefclocks(struct pp_hwmgr *hwmgr,
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
clocks->data[i].clocks_in_khz = clocks->data[i].clocks_in_khz =
dpm_table->dpm_levels[i].value * 100; dpm_table->dpm_levels[i].value * 1000;
clocks->data[i].latency_in_us = 0; clocks->data[i].latency_in_us = 0;
} }
...@@ -2431,7 +2434,7 @@ static int vega20_get_socclocks(struct pp_hwmgr *hwmgr, ...@@ -2431,7 +2434,7 @@ static int vega20_get_socclocks(struct pp_hwmgr *hwmgr,
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
clocks->data[i].clocks_in_khz = clocks->data[i].clocks_in_khz =
dpm_table->dpm_levels[i].value * 100; dpm_table->dpm_levels[i].value * 1000;
clocks->data[i].latency_in_us = 0; clocks->data[i].latency_in_us = 0;
} }
...@@ -2582,11 +2585,11 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, ...@@ -2582,11 +2585,11 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
return -EINVAL; return -EINVAL;
} }
if (input_clk < clocks.data[0].clocks_in_khz / 100 || if (input_clk < clocks.data[0].clocks_in_khz / 1000 ||
input_clk > od8_settings[OD8_SETTING_UCLK_FMAX].max_value) { input_clk > od8_settings[OD8_SETTING_UCLK_FMAX].max_value) {
pr_info("clock freq %d is not within allowed range [%d - %d]\n", pr_info("clock freq %d is not within allowed range [%d - %d]\n",
input_clk, input_clk,
clocks.data[0].clocks_in_khz / 100, clocks.data[0].clocks_in_khz / 1000,
od8_settings[OD8_SETTING_UCLK_FMAX].max_value); od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
return -EINVAL; return -EINVAL;
} }
...@@ -2726,7 +2729,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, ...@@ -2726,7 +2729,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
switch (type) { switch (type) {
case PP_SCLK: case PP_SCLK:
ret = vega20_get_current_gfx_clk_freq(hwmgr, &now); ret = vega20_get_current_clk_freq(hwmgr, PPCLK_GFXCLK, &now);
PP_ASSERT_WITH_CODE(!ret, PP_ASSERT_WITH_CODE(!ret,
"Attempt to get current gfx clk Failed!", "Attempt to get current gfx clk Failed!",
return ret); return ret);
...@@ -2738,12 +2741,12 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, ...@@ -2738,12 +2741,12 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
for (i = 0; i < clocks.num_levels; i++) for (i = 0; i < clocks.num_levels; i++)
size += sprintf(buf + size, "%d: %uMhz %s\n", size += sprintf(buf + size, "%d: %uMhz %s\n",
i, clocks.data[i].clocks_in_khz / 100, i, clocks.data[i].clocks_in_khz / 1000,
(clocks.data[i].clocks_in_khz == now) ? "*" : ""); (clocks.data[i].clocks_in_khz == now) ? "*" : "");
break; break;
case PP_MCLK: case PP_MCLK:
ret = vega20_get_current_mclk_freq(hwmgr, &now); ret = vega20_get_current_clk_freq(hwmgr, PPCLK_UCLK, &now);
PP_ASSERT_WITH_CODE(!ret, PP_ASSERT_WITH_CODE(!ret,
"Attempt to get current mclk freq Failed!", "Attempt to get current mclk freq Failed!",
return ret); return ret);
...@@ -2755,7 +2758,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, ...@@ -2755,7 +2758,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
for (i = 0; i < clocks.num_levels; i++) for (i = 0; i < clocks.num_levels; i++)
size += sprintf(buf + size, "%d: %uMhz %s\n", size += sprintf(buf + size, "%d: %uMhz %s\n",
i, clocks.data[i].clocks_in_khz / 100, i, clocks.data[i].clocks_in_khz / 1000,
(clocks.data[i].clocks_in_khz == now) ? "*" : ""); (clocks.data[i].clocks_in_khz == now) ? "*" : "");
break; break;
...@@ -2820,7 +2823,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, ...@@ -2820,7 +2823,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
return ret); return ret);
size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n", size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n",
clocks.data[0].clocks_in_khz / 100, clocks.data[0].clocks_in_khz / 1000,
od8_settings[OD8_SETTING_UCLK_FMAX].max_value); od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
} }
...@@ -3476,6 +3479,8 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = { ...@@ -3476,6 +3479,8 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
vega20_set_watermarks_for_clocks_ranges, vega20_set_watermarks_for_clocks_ranges,
.display_clock_voltage_request = .display_clock_voltage_request =
vega20_display_clock_voltage_request, vega20_display_clock_voltage_request,
.get_performance_level =
vega20_get_performance_level,
/* UMD pstate, profile related */ /* UMD pstate, profile related */
.force_dpm_level = .force_dpm_level =
vega20_dpm_force_dpm_level, vega20_dpm_force_dpm_level,
......
...@@ -642,8 +642,14 @@ static int check_powerplay_tables( ...@@ -642,8 +642,14 @@ static int check_powerplay_tables(
"Unsupported PPTable format!", return -1); "Unsupported PPTable format!", return -1);
PP_ASSERT_WITH_CODE(powerplay_table->sHeader.structuresize > 0, PP_ASSERT_WITH_CODE(powerplay_table->sHeader.structuresize > 0,
"Invalid PowerPlay Table!", return -1); "Invalid PowerPlay Table!", return -1);
PP_ASSERT_WITH_CODE(powerplay_table->smcPPTable.Version == PPTABLE_V20_SMU_VERSION,
"Unmatch PPTable version, vbios update may be needed!", return -1); if (powerplay_table->smcPPTable.Version != PPTABLE_V20_SMU_VERSION) {
pr_info("Unmatch PPTable version: "
"pptable from VBIOS is V%d while driver supported is V%d!",
powerplay_table->smcPPTable.Version,
PPTABLE_V20_SMU_VERSION);
return -EINVAL;
}
//dump_pptable(&powerplay_table->smcPPTable); //dump_pptable(&powerplay_table->smcPPTable);
...@@ -716,10 +722,6 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable ...@@ -716,10 +722,6 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable
"[appendVbiosPPTable] Failed to retrieve Smc Dpm Table from VBIOS!", "[appendVbiosPPTable] Failed to retrieve Smc Dpm Table from VBIOS!",
return -1); return -1);
memset(ppsmc_pptable->Padding32,
0,
sizeof(struct atom_smc_dpm_info_v4_4) -
sizeof(struct atom_common_table_header));
ppsmc_pptable->MaxVoltageStepGfx = smc_dpm_table->maxvoltagestepgfx; ppsmc_pptable->MaxVoltageStepGfx = smc_dpm_table->maxvoltagestepgfx;
ppsmc_pptable->MaxVoltageStepSoc = smc_dpm_table->maxvoltagestepsoc; ppsmc_pptable->MaxVoltageStepSoc = smc_dpm_table->maxvoltagestepsoc;
...@@ -778,22 +780,19 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable ...@@ -778,22 +780,19 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable
ppsmc_pptable->FllGfxclkSpreadPercent = smc_dpm_table->fllgfxclkspreadpercent; ppsmc_pptable->FllGfxclkSpreadPercent = smc_dpm_table->fllgfxclkspreadpercent;
ppsmc_pptable->FllGfxclkSpreadFreq = smc_dpm_table->fllgfxclkspreadfreq; ppsmc_pptable->FllGfxclkSpreadFreq = smc_dpm_table->fllgfxclkspreadfreq;
if ((smc_dpm_table->table_header.format_revision == 4) && for (i = 0; i < I2C_CONTROLLER_NAME_COUNT; i++) {
(smc_dpm_table->table_header.content_revision == 4)) { ppsmc_pptable->I2cControllers[i].Enabled =
for (i = 0; i < I2C_CONTROLLER_NAME_COUNT; i++) { smc_dpm_table->i2ccontrollers[i].enabled;
ppsmc_pptable->I2cControllers[i].Enabled = ppsmc_pptable->I2cControllers[i].SlaveAddress =
smc_dpm_table->i2ccontrollers[i].enabled; smc_dpm_table->i2ccontrollers[i].slaveaddress;
ppsmc_pptable->I2cControllers[i].SlaveAddress = ppsmc_pptable->I2cControllers[i].ControllerPort =
smc_dpm_table->i2ccontrollers[i].slaveaddress; smc_dpm_table->i2ccontrollers[i].controllerport;
ppsmc_pptable->I2cControllers[i].ControllerPort = ppsmc_pptable->I2cControllers[i].ThermalThrottler =
smc_dpm_table->i2ccontrollers[i].controllerport; smc_dpm_table->i2ccontrollers[i].thermalthrottler;
ppsmc_pptable->I2cControllers[i].ThermalThrottler = ppsmc_pptable->I2cControllers[i].I2cProtocol =
smc_dpm_table->i2ccontrollers[i].thermalthrottler; smc_dpm_table->i2ccontrollers[i].i2cprotocol;
ppsmc_pptable->I2cControllers[i].I2cProtocol = ppsmc_pptable->I2cControllers[i].I2cSpeed =
smc_dpm_table->i2ccontrollers[i].i2cprotocol; smc_dpm_table->i2ccontrollers[i].i2cspeed;
ppsmc_pptable->I2cControllers[i].I2cSpeed =
smc_dpm_table->i2ccontrollers[i].i2cspeed;
}
} }
return 0; return 0;
...@@ -882,15 +881,10 @@ static int init_powerplay_table_information( ...@@ -882,15 +881,10 @@ static int init_powerplay_table_information(
if (pptable_information->smc_pptable == NULL) if (pptable_information->smc_pptable == NULL)
return -ENOMEM; return -ENOMEM;
if (powerplay_table->smcPPTable.Version <= 2) memcpy(pptable_information->smc_pptable,
memcpy(pptable_information->smc_pptable, &(powerplay_table->smcPPTable),
&(powerplay_table->smcPPTable), sizeof(PPTable_t));
sizeof(PPTable_t) -
sizeof(I2cControllerConfig_t) * I2C_CONTROLLER_NAME_COUNT);
else
memcpy(pptable_information->smc_pptable,
&(powerplay_table->smcPPTable),
sizeof(PPTable_t));
result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable)); result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable));
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
// any structure is changed in this file // any structure is changed in this file
#define SMU11_DRIVER_IF_VERSION 0x12 #define SMU11_DRIVER_IF_VERSION 0x12
#define PPTABLE_V20_SMU_VERSION 2 #define PPTABLE_V20_SMU_VERSION 3
#define NUM_GFXCLK_DPM_LEVELS 16 #define NUM_GFXCLK_DPM_LEVELS 16
#define NUM_VCLK_DPM_LEVELS 8 #define NUM_VCLK_DPM_LEVELS 8
......
...@@ -71,7 +71,11 @@ static int smu8_send_msg_to_smc_async(struct pp_hwmgr *hwmgr, uint16_t msg) ...@@ -71,7 +71,11 @@ static int smu8_send_msg_to_smc_async(struct pp_hwmgr *hwmgr, uint16_t msg)
result = PHM_WAIT_FIELD_UNEQUAL(hwmgr, result = PHM_WAIT_FIELD_UNEQUAL(hwmgr,
SMU_MP1_SRBM2P_RESP_0, CONTENT, 0); SMU_MP1_SRBM2P_RESP_0, CONTENT, 0);
if (result != 0) { if (result != 0) {
/* Read the last message to SMU, to report actual cause */
uint32_t val = cgs_read_register(hwmgr->device,
mmSMU_MP1_SRBM2P_MSG_0);
pr_err("smu8_send_msg_to_smc_async (0x%04x) failed\n", msg); pr_err("smu8_send_msg_to_smc_async (0x%04x) failed\n", msg);
pr_err("SMU still servicing msg (0x%04x)\n", val);
return result; return result;
} }
......
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