Commit 6acaa6af authored by Andrey Grodzovsky's avatar Andrey Grodzovsky Committed by Alex Deucher

drm/amd/powerplay: Add interface to lock SMU HW I2C.

v2:
PPSMC_MSG_RequestI2CBus seems not to work and so to avoid conflict
over I2C bus and engine disable thermal control access to
force SMU stop using the I2C bus until the issue is reslolved.

Expose and call vega20_is_smc_ram_running to skip locking when SMU
FW is not yet loaded.

v3:
Remove the prevoius hack as the SMU found the bug.

v5: Typo fix
Signed-off-by: default avatarAndrey Grodzovsky <andrey.grodzovsky@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6a306806
......@@ -275,6 +275,7 @@ struct amd_pm_funcs {
int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size);
int (*set_mp1_state)(void *handle, enum pp_mp1_state mp1_state);
int (*smu_i2c_bus_access)(void *handle, bool acquire);
/* export to DC */
u32 (*get_sclk)(void *handle, bool low);
u32 (*get_mclk)(void *handle, bool low);
......
......@@ -1528,6 +1528,21 @@ static int pp_asic_reset_mode_2(void *handle)
return ret;
}
static int pp_smu_i2c_bus_access(void *handle, bool acquire)
{
struct pp_hwmgr *hwmgr = handle;
if (!hwmgr || !hwmgr->pm_en)
return -EINVAL;
if (hwmgr->hwmgr_func->smu_i2c_bus_access == NULL) {
pr_info_ratelimited("%s was not implemented.\n", __func__);
return -EINVAL;
}
return hwmgr->hwmgr_func->smu_i2c_bus_access(hwmgr, acquire);
}
static const struct amd_pm_funcs pp_dpm_funcs = {
.load_firmware = pp_dpm_load_fw,
.wait_for_fw_loading_complete = pp_dpm_fw_loading_complete,
......@@ -1585,4 +1600,5 @@ static const struct amd_pm_funcs pp_dpm_funcs = {
.get_ppfeature_status = pp_get_ppfeature_status,
.set_ppfeature_status = pp_set_ppfeature_status,
.asic_reset_mode_2 = pp_asic_reset_mode_2,
.smu_i2c_bus_access = pp_smu_i2c_bus_access,
};
......@@ -4089,6 +4089,24 @@ static int vega20_get_thermal_temperature_range(struct pp_hwmgr *hwmgr,
return 0;
}
static int vega20_smu_i2c_bus_access(struct pp_hwmgr *hwmgr, bool acquire)
{
int res;
/* I2C bus access can happen very early, when SMU not loaded yet */
if (!vega20_is_smc_ram_running(hwmgr))
return 0;
res = smum_send_msg_to_smc_with_parameter(hwmgr,
(acquire ?
PPSMC_MSG_RequestI2CBus :
PPSMC_MSG_ReleaseI2CBus),
0);
PP_ASSERT_WITH_CODE(!res, "[SmuI2CAccessBus] Failed to access bus!", return res);
return res;
}
static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
/* init/fini related */
.backend_init = vega20_hwmgr_backend_init,
......@@ -4156,6 +4174,7 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
.get_asic_baco_state = vega20_baco_get_state,
.set_asic_baco_state = vega20_baco_set_state,
.set_mp1_state = vega20_set_mp1_state,
.smu_i2c_bus_access = vega20_smu_i2c_bus_access,
};
int vega20_hwmgr_init(struct pp_hwmgr *hwmgr)
......
......@@ -354,6 +354,7 @@ struct pp_hwmgr_func {
int (*set_ppfeature_status)(struct pp_hwmgr *hwmgr, uint64_t ppfeature_masks);
int (*set_mp1_state)(struct pp_hwmgr *hwmgr, enum pp_mp1_state mp1_state);
int (*asic_reset)(struct pp_hwmgr *hwmgr, enum SMU_ASIC_RESET_MODE mode);
int (*smu_i2c_bus_access)(struct pp_hwmgr *hwmgr, bool aquire);
};
struct pp_table_func {
......
......@@ -44,7 +44,7 @@
#define smnMP0_FW_INTF 0x30101c0
#define smnMP1_PUB_CTRL 0x3010b14
static bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr)
bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr)
{
struct amdgpu_device *adev = hwmgr->adev;
uint32_t mp1_fw_flags;
......
......@@ -57,5 +57,7 @@ int vega20_get_activity_monitor_coeff(struct pp_hwmgr *hwmgr,
uint8_t *table, uint16_t workload_type);
int vega20_set_pptable_driver_address(struct pp_hwmgr *hwmgr);
bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr);
#endif
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