summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFudong Wang <fudong.wang@amd.com>2023-08-11 08:24:59 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-09-13 09:48:41 +0200
commit247ee56a7865a16f571fc1ee350d3dcf372d74b7 (patch)
treecc85f593ff5efdb3f66543f72ee5e960b4eef449
parenta641e116f929d789f179fbebc7330cf7befa6c9a (diff)
drm/amd/display: Add smu write msg id fail retry process
commit 72105dcfa3d12b5af49311f857e3490baa225135 upstream. 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: f94903996140 ("drm/amd/display: Add DCN315 CLK_MGR") Reviewed-by: Charlene Liu <charlene.liu@amd.com> Acked-by: Hamza Mahfooz <hamza.mahfooz@amd.com> Signed-off-by: Fudong Wang <fudong.wang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c
index 925d6e13620e..1bbf85defd61 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c
@@ -32,6 +32,7 @@
#define MAX_INSTANCE 6
#define MAX_SEGMENT 6
+#define SMU_REGISTER_WRITE_RETRY_COUNT 5
struct IP_BASE_INSTANCE
{
@@ -134,6 +135,8 @@ static int dcn315_smu_send_msg_with_param(
unsigned int msg_id, unsigned int param)
{
uint32_t result;
+ uint32_t i = 0;
+ uint32_t read_back_data;
result = dcn315_smu_wait_for_response(clk_mgr, 10, 200000);
@@ -150,10 +153,19 @@ static int dcn315_smu_send_msg_with_param(
/* Set the parameter register for the SMU message, unit is Mhz */
REG_WRITE(MP1_SMN_C2PMSG_37, param);
- /* Trigger the message transaction by writing the message ID */
- generic_write_indirect_reg(CTX,
- REG_NBIO(RSMU_INDEX), REG_NBIO(RSMU_DATA),
- mmMP1_C2PMSG_3, msg_id);
+ for (i = 0; i < SMU_REGISTER_WRITE_RETRY_COUNT; i++) {
+ /* Trigger the message transaction by writing the message ID */
+ generic_write_indirect_reg(CTX,
+ 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);