Commit 302be1cb authored by Fudong Wang's avatar Fudong Wang Committed by Alex Deucher

drm/amd/display: Add smu write msg id fail retry process

A benchmark stress test (12-40 machines x 48hours) found that DCN315 has
cases where DC writes to an indirect register to set the smu clock msg
id, but when we go to read the same indirect register the returned msg
id doesn't match with what we just set it to. So, to fix this retry the
write until the register's value matches with the requested value.

Cc: stable@vger.kernel.org # 6.1+
Fixes: f9490399 ("drm/amd/display: Add DCN315 CLK_MGR")
Reviewed-by: default avatarCharlene Liu <charlene.liu@amd.com>
Acked-by: default avatarHamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: default avatarFudong Wang <fudong.wang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 3001e6d1
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#define MAX_INSTANCE 6 #define MAX_INSTANCE 6
#define MAX_SEGMENT 6 #define MAX_SEGMENT 6
#define SMU_REGISTER_WRITE_RETRY_COUNT 5
struct IP_BASE_INSTANCE { struct IP_BASE_INSTANCE {
unsigned int segment[MAX_SEGMENT]; unsigned int segment[MAX_SEGMENT];
...@@ -132,6 +133,8 @@ static int dcn315_smu_send_msg_with_param( ...@@ -132,6 +133,8 @@ static int dcn315_smu_send_msg_with_param(
unsigned int msg_id, unsigned int param) unsigned int msg_id, unsigned int param)
{ {
uint32_t result; uint32_t result;
uint32_t i = 0;
uint32_t read_back_data;
result = dcn315_smu_wait_for_response(clk_mgr, 10, 200000); result = dcn315_smu_wait_for_response(clk_mgr, 10, 200000);
...@@ -148,10 +151,19 @@ static int dcn315_smu_send_msg_with_param( ...@@ -148,10 +151,19 @@ static int dcn315_smu_send_msg_with_param(
/* Set the parameter register for the SMU message, unit is Mhz */ /* Set the parameter register for the SMU message, unit is Mhz */
REG_WRITE(MP1_SMN_C2PMSG_37, param); REG_WRITE(MP1_SMN_C2PMSG_37, param);
/* Trigger the message transaction by writing the message ID */ for (i = 0; i < SMU_REGISTER_WRITE_RETRY_COUNT; i++) {
generic_write_indirect_reg(CTX, /* Trigger the message transaction by writing the message ID */
REG_NBIO(RSMU_INDEX), REG_NBIO(RSMU_DATA), generic_write_indirect_reg(CTX,
mmMP1_C2PMSG_3, msg_id); REG_NBIO(RSMU_INDEX), REG_NBIO(RSMU_DATA),
mmMP1_C2PMSG_3, msg_id);
read_back_data = generic_read_indirect_reg(CTX,
REG_NBIO(RSMU_INDEX), REG_NBIO(RSMU_DATA),
mmMP1_C2PMSG_3);
if (read_back_data == msg_id)
break;
udelay(2);
smu_print("SMU msg id write fail %x times. \n", i + 1);
}
result = dcn315_smu_wait_for_response(clk_mgr, 10, 200000); result = dcn315_smu_wait_for_response(clk_mgr, 10, 200000);
......
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