aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Grodzovsky <andrey.grodzovsky@amd.com>2019-05-01 18:19:48 -0400
committerAlex Deucher <alexander.deucher@amd.com>2019-08-27 09:17:42 -0400
commit6acaa6af1501d17d40bb9aa5d76d5bb0b4936ed9 (patch)
tree8bcbf9b5913f2962718c223b77e7847718a05294
parent6a3068065fa4d6f931a12573d4bda5d85261cee2 (diff)
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>
-rw-r--r--drivers/gpu/drm/amd/include/kgd_pp_interface.h1
-rw-r--r--drivers/gpu/drm/amd/powerplay/amd_powerplay.c16
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c19
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hwmgr.h1
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c2
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.h2
6 files changed, 40 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 0de4e37fe7da..27cf0afaa0b4 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -275,6 +275,7 @@ struct amd_pm_funcs {
275 int (*set_power_profile_mode)(void *handle, long *input, uint32_t size); 275 int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
276 int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size); 276 int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size);
277 int (*set_mp1_state)(void *handle, enum pp_mp1_state mp1_state); 277 int (*set_mp1_state)(void *handle, enum pp_mp1_state mp1_state);
278 int (*smu_i2c_bus_access)(void *handle, bool acquire);
278/* export to DC */ 279/* export to DC */
279 u32 (*get_sclk)(void *handle, bool low); 280 u32 (*get_sclk)(void *handle, bool low);
280 u32 (*get_mclk)(void *handle, bool low); 281 u32 (*get_mclk)(void *handle, bool low);
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
index 7ef202761998..fa636cb462c1 100644
--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -1528,6 +1528,21 @@ static int pp_asic_reset_mode_2(void *handle)
1528 return ret; 1528 return ret;
1529} 1529}
1530 1530
1531static 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
1531static const struct amd_pm_funcs pp_dpm_funcs = { 1546static const struct amd_pm_funcs pp_dpm_funcs = {
1532 .load_firmware = pp_dpm_load_fw, 1547 .load_firmware = pp_dpm_load_fw,
1533 .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete, 1548 .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete,
@@ -1585,4 +1600,5 @@ static const struct amd_pm_funcs pp_dpm_funcs = {
1585 .get_ppfeature_status = pp_get_ppfeature_status, 1600 .get_ppfeature_status = pp_get_ppfeature_status,
1586 .set_ppfeature_status = pp_set_ppfeature_status, 1601 .set_ppfeature_status = pp_set_ppfeature_status,
1587 .asic_reset_mode_2 = pp_asic_reset_mode_2, 1602 .asic_reset_mode_2 = pp_asic_reset_mode_2,
1603 .smu_i2c_bus_access = pp_smu_i2c_bus_access,
1588}; 1604};
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
index 98a6f5305974..03e8288c3a0d 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
@@ -4089,6 +4089,24 @@ static int vega20_get_thermal_temperature_range(struct pp_hwmgr *hwmgr,
4089 return 0; 4089 return 0;
4090} 4090}
4091 4091
4092static 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
4092static const struct pp_hwmgr_func vega20_hwmgr_funcs = { 4110static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
4093 /* init/fini related */ 4111 /* init/fini related */
4094 .backend_init = vega20_hwmgr_backend_init, 4112 .backend_init = vega20_hwmgr_backend_init,
@@ -4156,6 +4174,7 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
4156 .get_asic_baco_state = vega20_baco_get_state, 4174 .get_asic_baco_state = vega20_baco_get_state,
4157 .set_asic_baco_state = vega20_baco_set_state, 4175 .set_asic_baco_state = vega20_baco_set_state,
4158 .set_mp1_state = vega20_set_mp1_state, 4176 .set_mp1_state = vega20_set_mp1_state,
4177 .smu_i2c_bus_access = vega20_smu_i2c_bus_access,
4159}; 4178};
4160 4179
4161int vega20_hwmgr_init(struct pp_hwmgr *hwmgr) 4180int vega20_hwmgr_init(struct pp_hwmgr *hwmgr)
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
index abeff1570277..7bf9a14bfa0b 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
@@ -354,6 +354,7 @@ struct pp_hwmgr_func {
354 int (*set_ppfeature_status)(struct pp_hwmgr *hwmgr, uint64_t ppfeature_masks); 354 int (*set_ppfeature_status)(struct pp_hwmgr *hwmgr, uint64_t ppfeature_masks);
355 int (*set_mp1_state)(struct pp_hwmgr *hwmgr, enum pp_mp1_state mp1_state); 355 int (*set_mp1_state)(struct pp_hwmgr *hwmgr, enum pp_mp1_state mp1_state);
356 int (*asic_reset)(struct pp_hwmgr *hwmgr, enum SMU_ASIC_RESET_MODE mode); 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
359struct pp_table_func { 360struct pp_table_func {
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c
index 3e97b83950dc..b9089c6bea85 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c
@@ -44,7 +44,7 @@
44#define smnMP0_FW_INTF 0x30101c0 44#define smnMP0_FW_INTF 0x30101c0
45#define smnMP1_PUB_CTRL 0x3010b14 45#define smnMP1_PUB_CTRL 0x3010b14
46 46
47static bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr) 47bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr)
48{ 48{
49 struct amdgpu_device *adev = hwmgr->adev; 49 struct amdgpu_device *adev = hwmgr->adev;
50 uint32_t mp1_fw_flags; 50 uint32_t mp1_fw_flags;
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.h
index ec953ab13e87..62ebbfd6068f 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.h
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.h
@@ -57,5 +57,7 @@ int vega20_get_activity_monitor_coeff(struct pp_hwmgr *hwmgr,
57 uint8_t *table, uint16_t workload_type); 57 uint8_t *table, uint16_t workload_type);
58int vega20_set_pptable_driver_address(struct pp_hwmgr *hwmgr); 58int vega20_set_pptable_driver_address(struct pp_hwmgr *hwmgr);
59 59
60bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr);
61
60#endif 62#endif
61 63