[PATCH 14/23] drm/amd/display: DAL ACR, dc part, fix missing dcn30

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ian Chen <ian.chen@xxxxxxx>

[Why]
- missing in dcn30 function
- Fix a divide by 0 when ACR trigger

[How]
- Add IS_SMU_TIMEOUT() to dcn30_smu_send_msg_with_param
- Add zero check in dcn20_update_clocks_update_dentist

Acked-by: Alan Liu <HaoPing.Liu@xxxxxxx>
Signed-off-by: Ian Chen <ian.chen@xxxxxxx>
---
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  | 22 +++++++++++++------
 .../dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c  | 11 +++++++++-
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index fb82e9f9738e..0d30d1d9d67e 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -126,16 +126,24 @@ void dcn20_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
 
 void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr, struct dc_state *context)
 {
-	int dpp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
-			* clk_mgr->base.dentist_vco_freq_khz / clk_mgr->base.clks.dppclk_khz;
-	int disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
-			* clk_mgr->base.dentist_vco_freq_khz / clk_mgr->base.clks.dispclk_khz;
-
-	uint32_t dppclk_wdivider = dentist_get_did_from_divider(dpp_divider);
-	uint32_t dispclk_wdivider = dentist_get_did_from_divider(disp_divider);
+	int dpp_divider = 0;
+	int disp_divider = 0;
+	uint32_t dppclk_wdivider = 0;
+	uint32_t dispclk_wdivider = 0;
 	uint32_t current_dispclk_wdivider;
 	uint32_t i;
 
+	if (clk_mgr->base.clks.dppclk_khz == 0 || clk_mgr->base.clks.dispclk_khz == 0)
+		return;
+
+	dpp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+		* clk_mgr->base.dentist_vco_freq_khz / clk_mgr->base.clks.dppclk_khz;
+	disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+		* clk_mgr->base.dentist_vco_freq_khz / clk_mgr->base.clks.dispclk_khz;
+
+	dppclk_wdivider = dentist_get_did_from_divider(dpp_divider);
+	dispclk_wdivider = dentist_get_did_from_divider(disp_divider);
+
 	REG_GET(DENTIST_DISPCLK_CNTL,
 			DENTIST_DISPCLK_WDIVIDER, &current_dispclk_wdivider);
 
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c
index bfc960579760..1fbf1c105dc1 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c
@@ -28,6 +28,8 @@
 
 #include "clk_mgr_internal.h"
 #include "reg_helper.h"
+#include "dm_helpers.h"
+
 #include "dalsmc.h"
 #include "dcn30_smu11_driver_if.h"
 
@@ -74,6 +76,7 @@ static uint32_t dcn30_smu_wait_for_response(struct clk_mgr_internal *clk_mgr, un
 
 static bool dcn30_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr, uint32_t msg_id, uint32_t param_in, uint32_t *param_out)
 {
+	uint32_t result;
 	/* Wait for response register to be ready */
 	dcn30_smu_wait_for_response(clk_mgr, 10, 200000);
 
@@ -86,8 +89,14 @@ static bool dcn30_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr, uint
 	/* Trigger the message transaction by writing the message ID */
 	REG_WRITE(DAL_MSG_REG, msg_id);
 
+	result = dcn30_smu_wait_for_response(clk_mgr, 10, 200000);
+
+	if (IS_SMU_TIMEOUT(result)) {
+		dm_helpers_smu_timeout(CTX, msg_id, param_in, 10 * 200000);
+	}
+
 	/* Wait for response */
-	if (dcn30_smu_wait_for_response(clk_mgr, 10, 200000) == DALSMC_Result_OK) {
+	if (result == DALSMC_Result_OK) {
 		if (param_out)
 			*param_out = REG_READ(DAL_ARG_REG);
 
-- 
2.36.1




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux