Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Andrey Grodzovsky and committed by
Alex Deucher
6acaa6af 6a306806

+40 -1
+1
drivers/gpu/drm/amd/include/kgd_pp_interface.h
··· 275 275 int (*set_power_profile_mode)(void *handle, long *input, uint32_t size); 276 276 int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size); 277 277 int (*set_mp1_state)(void *handle, enum pp_mp1_state mp1_state); 278 + int (*smu_i2c_bus_access)(void *handle, bool acquire); 278 279 /* export to DC */ 279 280 u32 (*get_sclk)(void *handle, bool low); 280 281 u32 (*get_mclk)(void *handle, bool low);
+16
drivers/gpu/drm/amd/powerplay/amd_powerplay.c
··· 1528 1528 return ret; 1529 1529 } 1530 1530 1531 + static int pp_smu_i2c_bus_access(void *handle, bool acquire) 1532 + { 1533 + struct pp_hwmgr *hwmgr = handle; 1534 + 1535 + if (!hwmgr || !hwmgr->pm_en) 1536 + return -EINVAL; 1537 + 1538 + if (hwmgr->hwmgr_func->smu_i2c_bus_access == NULL) { 1539 + pr_info_ratelimited("%s was not implemented.\n", __func__); 1540 + return -EINVAL; 1541 + } 1542 + 1543 + return hwmgr->hwmgr_func->smu_i2c_bus_access(hwmgr, acquire); 1544 + } 1545 + 1531 1546 static const struct amd_pm_funcs pp_dpm_funcs = { 1532 1547 .load_firmware = pp_dpm_load_fw, 1533 1548 .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete, ··· 1600 1585 .get_ppfeature_status = pp_get_ppfeature_status, 1601 1586 .set_ppfeature_status = pp_set_ppfeature_status, 1602 1587 .asic_reset_mode_2 = pp_asic_reset_mode_2, 1588 + .smu_i2c_bus_access = pp_smu_i2c_bus_access, 1603 1589 };
+19
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
··· 4089 4089 return 0; 4090 4090 } 4091 4091 4092 + static int vega20_smu_i2c_bus_access(struct pp_hwmgr *hwmgr, bool acquire) 4093 + { 4094 + int res; 4095 + 4096 + /* I2C bus access can happen very early, when SMU not loaded yet */ 4097 + if (!vega20_is_smc_ram_running(hwmgr)) 4098 + return 0; 4099 + 4100 + res = smum_send_msg_to_smc_with_parameter(hwmgr, 4101 + (acquire ? 4102 + PPSMC_MSG_RequestI2CBus : 4103 + PPSMC_MSG_ReleaseI2CBus), 4104 + 0); 4105 + 4106 + PP_ASSERT_WITH_CODE(!res, "[SmuI2CAccessBus] Failed to access bus!", return res); 4107 + return res; 4108 + } 4109 + 4092 4110 static const struct pp_hwmgr_func vega20_hwmgr_funcs = { 4093 4111 /* init/fini related */ 4094 4112 .backend_init = vega20_hwmgr_backend_init, ··· 4174 4156 .get_asic_baco_state = vega20_baco_get_state, 4175 4157 .set_asic_baco_state = vega20_baco_set_state, 4176 4158 .set_mp1_state = vega20_set_mp1_state, 4159 + .smu_i2c_bus_access = vega20_smu_i2c_bus_access, 4177 4160 }; 4178 4161 4179 4162 int vega20_hwmgr_init(struct pp_hwmgr *hwmgr)
+1
drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
··· 354 354 int (*set_ppfeature_status)(struct pp_hwmgr *hwmgr, uint64_t ppfeature_masks); 355 355 int (*set_mp1_state)(struct pp_hwmgr *hwmgr, enum pp_mp1_state mp1_state); 356 356 int (*asic_reset)(struct pp_hwmgr *hwmgr, enum SMU_ASIC_RESET_MODE mode); 357 + int (*smu_i2c_bus_access)(struct pp_hwmgr *hwmgr, bool aquire); 357 358 }; 358 359 359 360 struct pp_table_func {
+1 -1
drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c
··· 44 44 #define smnMP0_FW_INTF 0x30101c0 45 45 #define smnMP1_PUB_CTRL 0x3010b14 46 46 47 - static bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr) 47 + bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr) 48 48 { 49 49 struct amdgpu_device *adev = hwmgr->adev; 50 50 uint32_t mp1_fw_flags;
+2
drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.h
··· 57 57 uint8_t *table, uint16_t workload_type); 58 58 int vega20_set_pptable_driver_address(struct pp_hwmgr *hwmgr); 59 59 60 + bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr); 61 + 60 62 #endif 61 63