mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-28 20:02:17 +00:00
Merge tag 'amd-drm-fixes-5.16-2021-11-17' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes
amd-drm-fixes-5.16-2021-11-17: amdgpu: - Better debugging info for SMU msgs - Better error reporting when adding IP blocks - Fix UVD powergating regression on CZ - Clock reporting fix for navi1x - OLED panel backlight fix - Fix scaling on VGA/DVI for non-DC display code - Fix GLFCLK handling for RGP on some APUs - fix potential memory leak amdkfd: - GPU reset fix Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20211118041638.20831-1-alexander.deucher@amd.com
This commit is contained in:
commit
7d51040a69
15 changed files with 156 additions and 11 deletions
|
@ -827,6 +827,7 @@ static int amdgpu_connector_vga_get_modes(struct drm_connector *connector)
|
|||
|
||||
amdgpu_connector_get_edid(connector);
|
||||
ret = amdgpu_connector_ddc_get_modes(connector);
|
||||
amdgpu_get_native_mode(connector);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -3509,6 +3509,9 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
adev->rmmio_size = pci_resource_len(adev->pdev, 2);
|
||||
}
|
||||
|
||||
for (i = 0; i < AMD_IP_BLOCK_TYPE_NUM; i++)
|
||||
atomic_set(&adev->pm.pwr_state[i], POWER_STATE_UNKNOWN);
|
||||
|
||||
adev->rmmio = ioremap(adev->rmmio_base, adev->rmmio_size);
|
||||
if (adev->rmmio == NULL) {
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -587,6 +587,9 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Failed to add common ip block(GC_HWIP:0x%x)\n",
|
||||
adev->ip_versions[GC_HWIP][0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
|
@ -619,6 +622,9 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Failed to add gmc ip block(GC_HWIP:0x%x)\n",
|
||||
adev->ip_versions[GC_HWIP][0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
|
@ -648,6 +654,9 @@ static int amdgpu_discovery_set_ih_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Failed to add ih ip block(OSSSYS_HWIP:0x%x)\n",
|
||||
adev->ip_versions[OSSSYS_HWIP][0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
|
@ -688,6 +697,9 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Failed to add psp ip block(MP0_HWIP:0x%x)\n",
|
||||
adev->ip_versions[MP0_HWIP][0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
|
@ -726,6 +738,9 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Failed to add smu ip block(MP1_HWIP:0x%x)\n",
|
||||
adev->ip_versions[MP1_HWIP][0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
|
@ -753,6 +768,9 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Failed to add dm ip block(DCE_HWIP:0x%x)\n",
|
||||
adev->ip_versions[DCE_HWIP][0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (adev->ip_versions[DCI_HWIP][0]) {
|
||||
|
@ -763,6 +781,9 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Failed to add dm ip block(DCI_HWIP:0x%x)\n",
|
||||
adev->ip_versions[DCI_HWIP][0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
@ -796,6 +817,9 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Failed to add gfx ip block(GC_HWIP:0x%x)\n",
|
||||
adev->ip_versions[GC_HWIP][0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
|
@ -829,6 +853,9 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Failed to add sdma ip block(SDMA0_HWIP:0x%x)\n",
|
||||
adev->ip_versions[SDMA0_HWIP][0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
|
@ -845,6 +872,9 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &uvd_v7_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Failed to add uvd v7 ip block(UVD_HWIP:0x%x)\n",
|
||||
adev->ip_versions[UVD_HWIP][0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (adev->ip_versions[VCE_HWIP][0]) {
|
||||
|
@ -855,6 +885,9 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &vce_v4_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Failed to add VCE v4 ip block(VCE_HWIP:0x%x)\n",
|
||||
adev->ip_versions[VCE_HWIP][0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
|
@ -893,6 +926,9 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Failed to add vcn/jpeg ip block(UVD_HWIP:0x%x)\n",
|
||||
adev->ip_versions[UVD_HWIP][0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -386,6 +386,7 @@ struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev)
|
|||
"%s", "xgmi_hive_info");
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "XGMI: failed initializing kobject for xgmi hive\n");
|
||||
kobject_put(&hive->kobj);
|
||||
kfree(hive);
|
||||
hive = NULL;
|
||||
goto pro_end;
|
||||
|
|
|
@ -1226,6 +1226,11 @@ static int stop_cpsch(struct device_queue_manager *dqm)
|
|||
bool hanging;
|
||||
|
||||
dqm_lock(dqm);
|
||||
if (!dqm->sched_running) {
|
||||
dqm_unlock(dqm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!dqm->is_hws_hang)
|
||||
unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0);
|
||||
hanging = dqm->is_hws_hang || dqm->is_resetting;
|
||||
|
|
|
@ -4242,7 +4242,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
|||
} else if (dc_link_detect(link, DETECT_REASON_BOOT)) {
|
||||
amdgpu_dm_update_connector_after_detect(aconnector);
|
||||
register_backlight_device(dm, link);
|
||||
|
||||
if (dm->num_of_edps)
|
||||
update_connector_ext_caps(aconnector);
|
||||
if (psr_feature_enabled)
|
||||
amdgpu_dm_set_psr_caps(link);
|
||||
}
|
||||
|
|
|
@ -98,7 +98,8 @@ enum amd_ip_block_type {
|
|||
AMD_IP_BLOCK_TYPE_ACP,
|
||||
AMD_IP_BLOCK_TYPE_VCN,
|
||||
AMD_IP_BLOCK_TYPE_MES,
|
||||
AMD_IP_BLOCK_TYPE_JPEG
|
||||
AMD_IP_BLOCK_TYPE_JPEG,
|
||||
AMD_IP_BLOCK_TYPE_NUM,
|
||||
};
|
||||
|
||||
enum amd_clockgating_state {
|
||||
|
|
|
@ -927,6 +927,13 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block
|
|||
{
|
||||
int ret = 0;
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
enum ip_power_state pwr_state = gate ? POWER_STATE_OFF : POWER_STATE_ON;
|
||||
|
||||
if (atomic_read(&adev->pm.pwr_state[block_type]) == pwr_state) {
|
||||
dev_dbg(adev->dev, "IP block%d already in the target %s state!",
|
||||
block_type, gate ? "gate" : "ungate");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (block_type) {
|
||||
case AMD_IP_BLOCK_TYPE_UVD:
|
||||
|
@ -979,6 +986,9 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block
|
|||
break;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
atomic_set(&adev->pm.pwr_state[block_type], pwr_state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -417,6 +417,12 @@ struct amdgpu_dpm {
|
|||
enum amd_dpm_forced_level forced_level;
|
||||
};
|
||||
|
||||
enum ip_power_state {
|
||||
POWER_STATE_UNKNOWN,
|
||||
POWER_STATE_ON,
|
||||
POWER_STATE_OFF,
|
||||
};
|
||||
|
||||
struct amdgpu_pm {
|
||||
struct mutex mutex;
|
||||
u32 current_sclk;
|
||||
|
@ -452,6 +458,8 @@ struct amdgpu_pm {
|
|||
struct i2c_adapter smu_i2c;
|
||||
struct mutex smu_i2c_mutex;
|
||||
struct list_head pm_attr_list;
|
||||
|
||||
atomic_t pwr_state[AMD_IP_BLOCK_TYPE_NUM];
|
||||
};
|
||||
|
||||
#define R600_SSTU_DFLT 0
|
||||
|
|
|
@ -309,6 +309,7 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu,
|
|||
{
|
||||
int ret = 0, size = 0;
|
||||
uint32_t cur_value = 0;
|
||||
int i;
|
||||
|
||||
smu_cmn_get_sysfs_buf(&buf, &size);
|
||||
|
||||
|
@ -334,8 +335,6 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu,
|
|||
size += sysfs_emit_at(buf, size, "VDDC: %7umV %10umV\n",
|
||||
CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX);
|
||||
break;
|
||||
case SMU_GFXCLK:
|
||||
case SMU_SCLK:
|
||||
case SMU_FCLK:
|
||||
case SMU_MCLK:
|
||||
case SMU_SOCCLK:
|
||||
|
@ -346,6 +345,25 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu,
|
|||
return ret;
|
||||
size += sysfs_emit_at(buf, size, "0: %uMhz *\n", cur_value);
|
||||
break;
|
||||
case SMU_SCLK:
|
||||
case SMU_GFXCLK:
|
||||
ret = cyan_skillfish_get_current_clk_freq(smu, clk_type, &cur_value);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (cur_value == CYAN_SKILLFISH_SCLK_MAX)
|
||||
i = 2;
|
||||
else if (cur_value == CYAN_SKILLFISH_SCLK_MIN)
|
||||
i = 0;
|
||||
else
|
||||
i = 1;
|
||||
size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", CYAN_SKILLFISH_SCLK_MIN,
|
||||
i == 0 ? "*" : "");
|
||||
size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
|
||||
i == 1 ? cur_value : cyan_skillfish_sclk_default,
|
||||
i == 1 ? "*" : "");
|
||||
size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", CYAN_SKILLFISH_SCLK_MAX,
|
||||
i == 2 ? "*" : "");
|
||||
break;
|
||||
default:
|
||||
dev_warn(smu->adev->dev, "Unsupported clock type\n");
|
||||
return ret;
|
||||
|
|
|
@ -1265,7 +1265,7 @@ static int navi10_print_clk_levels(struct smu_context *smu,
|
|||
enum smu_clk_type clk_type, char *buf)
|
||||
{
|
||||
uint16_t *curve_settings;
|
||||
int i, size = 0, ret = 0;
|
||||
int i, levels, size = 0, ret = 0;
|
||||
uint32_t cur_value = 0, value = 0, count = 0;
|
||||
uint32_t freq_values[3] = {0};
|
||||
uint32_t mark_index = 0;
|
||||
|
@ -1319,14 +1319,17 @@ static int navi10_print_clk_levels(struct smu_context *smu,
|
|||
freq_values[1] = cur_value;
|
||||
mark_index = cur_value == freq_values[0] ? 0 :
|
||||
cur_value == freq_values[2] ? 2 : 1;
|
||||
if (mark_index != 1)
|
||||
freq_values[1] = (freq_values[0] + freq_values[2]) / 2;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
levels = 3;
|
||||
if (mark_index != 1) {
|
||||
levels = 2;
|
||||
freq_values[1] = freq_values[2];
|
||||
}
|
||||
|
||||
for (i = 0; i < levels; i++) {
|
||||
size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, freq_values[i],
|
||||
i == mark_index ? "*" : "");
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case SMU_PCIE:
|
||||
|
|
|
@ -683,6 +683,7 @@ static int vangogh_print_clk_levels(struct smu_context *smu,
|
|||
int i, size = 0, ret = 0;
|
||||
uint32_t cur_value = 0, value = 0, count = 0;
|
||||
bool cur_value_match_level = false;
|
||||
uint32_t min, max;
|
||||
|
||||
memset(&metrics, 0, sizeof(metrics));
|
||||
|
||||
|
@ -743,6 +744,13 @@ static int vangogh_print_clk_levels(struct smu_context *smu,
|
|||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case SMU_GFXCLK:
|
||||
case SMU_SCLK:
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetGfxclkFrequency, 0, &cur_value);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -768,6 +776,24 @@ static int vangogh_print_clk_levels(struct smu_context *smu,
|
|||
if (!cur_value_match_level)
|
||||
size += sysfs_emit_at(buf, size, " %uMhz *\n", cur_value);
|
||||
break;
|
||||
case SMU_GFXCLK:
|
||||
case SMU_SCLK:
|
||||
min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq;
|
||||
max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq;
|
||||
if (cur_value == max)
|
||||
i = 2;
|
||||
else if (cur_value == min)
|
||||
i = 0;
|
||||
else
|
||||
i = 1;
|
||||
size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min,
|
||||
i == 0 ? "*" : "");
|
||||
size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
|
||||
i == 1 ? cur_value : VANGOGH_UMD_PSTATE_STANDARD_GFXCLK,
|
||||
i == 1 ? "*" : "");
|
||||
size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max,
|
||||
i == 2 ? "*" : "");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -697,6 +697,11 @@ static int yellow_carp_get_current_clk_freq(struct smu_context *smu,
|
|||
case SMU_FCLK:
|
||||
return smu_cmn_send_smc_msg_with_param(smu,
|
||||
SMU_MSG_GetFclkFrequency, 0, value);
|
||||
case SMU_GFXCLK:
|
||||
case SMU_SCLK:
|
||||
return smu_cmn_send_smc_msg_with_param(smu,
|
||||
SMU_MSG_GetGfxclkFrequency, 0, value);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -967,6 +972,7 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu,
|
|||
{
|
||||
int i, size = 0, ret = 0;
|
||||
uint32_t cur_value = 0, value = 0, count = 0;
|
||||
uint32_t min, max;
|
||||
|
||||
smu_cmn_get_sysfs_buf(&buf, &size);
|
||||
|
||||
|
@ -1005,6 +1011,27 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu,
|
|||
cur_value == value ? "*" : "");
|
||||
}
|
||||
break;
|
||||
case SMU_GFXCLK:
|
||||
case SMU_SCLK:
|
||||
ret = yellow_carp_get_current_clk_freq(smu, clk_type, &cur_value);
|
||||
if (ret)
|
||||
goto print_clk_out;
|
||||
min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq;
|
||||
max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq;
|
||||
if (cur_value == max)
|
||||
i = 2;
|
||||
else if (cur_value == min)
|
||||
i = 0;
|
||||
else
|
||||
i = 1;
|
||||
size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min,
|
||||
i == 0 ? "*" : "");
|
||||
size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
|
||||
i == 1 ? cur_value : YELLOW_CARP_UMD_PSTATE_GFXCLK,
|
||||
i == 1 ? "*" : "");
|
||||
size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max,
|
||||
i == 2 ? "*" : "");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -24,5 +24,6 @@
|
|||
#define __YELLOW_CARP_PPT_H__
|
||||
|
||||
extern void yellow_carp_set_ppt_funcs(struct smu_context *smu);
|
||||
#define YELLOW_CARP_UMD_PSTATE_GFXCLK 1100
|
||||
|
||||
#endif
|
||||
|
|
|
@ -139,9 +139,13 @@ static void __smu_cmn_reg_print_error(struct smu_context *smu,
|
|||
const char *message = smu_get_message_name(smu, msg);
|
||||
|
||||
switch (reg_c2pmsg_90) {
|
||||
case SMU_RESP_NONE:
|
||||
case SMU_RESP_NONE: {
|
||||
u32 msg_idx = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66);
|
||||
u32 prm = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82);
|
||||
dev_err_ratelimited(adev->dev,
|
||||
"SMU: I'm not done with your previous command!");
|
||||
"SMU: I'm not done with your previous command: SMN_C2PMSG_66:0x%08X SMN_C2PMSG_82:0x%08X",
|
||||
msg_idx, prm);
|
||||
}
|
||||
break;
|
||||
case SMU_RESP_OK:
|
||||
/* The SMU executed the command. It completed with a
|
||||
|
|
Loading…
Reference in a new issue