From 7e01a2ec96bf8a149c5e83d0352cf6ea286275cf Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Thu, 11 Jul 2019 10:23:17 +0800 Subject: drm/amd/powerplay: correct SW SMU valid mapping check Current implementation is not actually able to detect invalid message/table/workload mapping. Signed-off-by: Evan Quan Reviewed-by: Feifei Xu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/kgd_pp_interface.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/include/kgd_pp_interface.h') diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 9f661bf96ed0..9733bbf9bc72 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -141,6 +141,7 @@ enum PP_SMC_POWER_PROFILE { PP_SMC_POWER_PROFILE_VR = 0x4, PP_SMC_POWER_PROFILE_COMPUTE = 0x5, PP_SMC_POWER_PROFILE_CUSTOM = 0x6, + PP_SMC_POWER_PROFILE_COUNT, }; enum { -- cgit v1.2.3 From a2c28e34f8c42e35f5f2990d558d367152e63c27 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 25 Jul 2019 09:41:53 -0500 Subject: drm/amdgpu/powerplay: add a new interface to set the mp1 state This is required for certain cases such as various GPU resets (mode1, mode2), BACO, shutdown, unload, etc. to put the SMU into the appropriate state for when the hw is re-initialized. Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/kgd_pp_interface.h | 8 ++++++++ drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 16 ++++++++++++++++ drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 1 + 3 files changed, 25 insertions(+) (limited to 'drivers/gpu/drm/amd/include/kgd_pp_interface.h') diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 9733bbf9bc72..95edc3d3a9c4 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -171,6 +171,13 @@ enum PP_HWMON_TEMP { PP_TEMP_MAX }; +enum pp_mp1_state { + PP_MP1_STATE_NONE, + PP_MP1_STATE_SHUTDOWN, + PP_MP1_STATE_UNLOAD, + PP_MP1_STATE_RESET, +}; + #define PP_GROUP_MASK 0xF0000000 #define PP_GROUP_SHIFT 28 @@ -266,6 +273,7 @@ struct amd_pm_funcs { int (*get_power_profile_mode)(void *handle, char *buf); 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); /* export to DC */ u32 (*get_sclk)(void *handle, bool low); 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 bea1587d352d..88a2ef75b7e1 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -924,6 +924,21 @@ static int pp_odn_edit_dpm_table(void *handle, uint32_t type, long *input, uint3 return hwmgr->hwmgr_func->odn_edit_dpm_table(hwmgr, type, input, size); } +static int pp_dpm_set_mp1_state(void *handle, enum pp_mp1_state mp1_state) +{ + struct pp_hwmgr *hwmgr = handle; + + if (!hwmgr || !hwmgr->pm_en) + return -EINVAL; + + if (hwmgr->hwmgr_func->set_mp1_state == NULL) { + pr_info_ratelimited("%s was not implemented.\n", __func__); + return -EINVAL; + } + + return hwmgr->hwmgr_func->set_mp1_state(hwmgr, mp1_state); +} + static int pp_dpm_switch_power_profile(void *handle, enum PP_SMC_POWER_PROFILE type, bool en) { @@ -1525,6 +1540,7 @@ static const struct amd_pm_funcs pp_dpm_funcs = { .get_power_profile_mode = pp_get_power_profile_mode, .set_power_profile_mode = pp_set_power_profile_mode, .odn_edit_dpm_table = pp_odn_edit_dpm_table, + .set_mp1_state = pp_dpm_set_mp1_state, .set_power_limit = pp_set_power_limit, .get_power_limit = pp_get_power_limit, /* export to DC */ diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index c5989cb38b1b..07fd64aad2ae 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -344,6 +344,7 @@ struct pp_hwmgr_func { int (*set_asic_baco_state)(struct pp_hwmgr *hwmgr, enum BACO_STATE state); int (*get_ppfeature_status)(struct pp_hwmgr *hwmgr, char *buf); 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); }; struct pp_table_func { -- cgit v1.2.3 From 9829e3d89b6ea9027542d094cdb8a434eef4b3aa Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 22 Jul 2019 09:51:59 +0800 Subject: drm/amd/powerplay: add new sensor type for VCN powergate status VCN is widely used in new ASICs and different from tranditional UVD and VCE. Signed-off-by: Evan Quan Reviewed-by: Kenneth Feng Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/kgd_pp_interface.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/include/kgd_pp_interface.h') diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 95edc3d3a9c4..bba1291ae405 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -123,6 +123,7 @@ enum amd_pp_sensors { AMDGPU_PP_SENSOR_ENABLED_SMC_FEATURES_MASK, AMDGPU_PP_SENSOR_MIN_FAN_RPM, AMDGPU_PP_SENSOR_MAX_FAN_RPM, + AMDGPU_PP_SENSOR_VCN_POWER_STATE, }; enum amd_pp_task { -- cgit v1.2.3 From e97204ead61c79c292761c5c934a02dfe9967b71 Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Wed, 14 Aug 2019 16:26:35 -0400 Subject: drm/amd/poweplay: Add amd_pm_funcs callback for mode 2 Add callback to call the new mode2 reset interface. Signed-off-by: Andrey Grodzovsky Reviewed-by: Alex Deucher Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/kgd_pp_interface.h | 1 + drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) (limited to 'drivers/gpu/drm/amd/include/kgd_pp_interface.h') diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index bba1291ae405..0de4e37fe7da 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -310,6 +310,7 @@ struct amd_pm_funcs { int (*set_asic_baco_state)(void *handle, int state); int (*get_ppfeature_status)(void *handle, char *buf); int (*set_ppfeature_status)(void *handle, uint64_t ppfeature_masks); + int (*asic_reset_mode_2)(void *handle); }; #endif diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 2e3d9ef625bf..7ef202761998 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -1508,6 +1508,26 @@ static int pp_set_ppfeature_status(void *handle, uint64_t ppfeature_masks) return ret; } +static int pp_asic_reset_mode_2(void *handle) +{ + struct pp_hwmgr *hwmgr = handle; + int ret = 0; + + if (!hwmgr || !hwmgr->pm_en) + return -EINVAL; + + if (hwmgr->hwmgr_func->asic_reset == NULL) { + pr_info_ratelimited("%s was not implemented.\n", __func__); + return -EINVAL; + } + + mutex_lock(&hwmgr->smu_lock); + ret = hwmgr->hwmgr_func->asic_reset(hwmgr, SMU_ASIC_RESET_MODE_2); + mutex_unlock(&hwmgr->smu_lock); + + return ret; +} + 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, @@ -1564,4 +1584,5 @@ static const struct amd_pm_funcs pp_dpm_funcs = { .set_asic_baco_state = pp_set_asic_baco_state, .get_ppfeature_status = pp_get_ppfeature_status, .set_ppfeature_status = pp_set_ppfeature_status, + .asic_reset_mode_2 = pp_asic_reset_mode_2, }; -- cgit v1.2.3 From 6acaa6af1501d17d40bb9aa5d76d5bb0b4936ed9 Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Wed, 1 May 2019 18:19:48 -0400 Subject: 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 Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/kgd_pp_interface.h | 1 + drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 16 ++++++++++++++++ drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 19 +++++++++++++++++++ drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 1 + drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c | 2 +- drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.h | 2 ++ 6 files changed, 40 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/include/kgd_pp_interface.h') 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 { 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); 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) 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, }; 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, 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) 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 { 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 { 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 @@ #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; 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, 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 -- cgit v1.2.3