[PATCH 13/14] drm/amd/display: Fix flickering caused by dccg

Hamza Mahfooz hamza.mahfooz at amd.com
Tue Aug 27 16:37:33 UTC 2024


From: Hansen Dsouza <Hansen.Dsouza at amd.com>

Always allow un-gating. Follow legacy workaround for repeated
dppclk dto updates

Reviewed-by: Muhammad Ahmed <ahmed.ahmed at amd.com>
Signed-off-by: Hansen Dsouza <Hansen.Dsouza at amd.com>
Signed-off-by: Hamza Mahfooz <hamza.mahfooz at amd.com>
---
 .../amd/display/dc/dccg/dcn20/dcn20_dccg.h    | 11 +++
 .../amd/display/dc/dccg/dcn35/dcn35_dccg.c    | 89 +++++++++++++------
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c   | 45 ----------
 3 files changed, 72 insertions(+), 73 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
index 6ac2bd86c4db..160c299419b7 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
@@ -328,6 +328,17 @@
 	type DPSTREAMCLK1_GATE_DISABLE;\
 	type DPSTREAMCLK2_GATE_DISABLE;\
 	type DPSTREAMCLK3_GATE_DISABLE;\
+	type SYMCLKA_FE_GATE_DISABLE;\
+	type SYMCLKB_FE_GATE_DISABLE;\
+	type SYMCLKC_FE_GATE_DISABLE;\
+	type SYMCLKD_FE_GATE_DISABLE;\
+	type SYMCLKE_FE_GATE_DISABLE;\
+	type SYMCLKA_GATE_DISABLE;\
+	type SYMCLKB_GATE_DISABLE;\
+	type SYMCLKC_GATE_DISABLE;\
+	type SYMCLKD_GATE_DISABLE;\
+	type SYMCLKE_GATE_DISABLE;\
+
 
 #define DCCG401_REG_FIELD_LIST(type) \
 	type OTG0_TMDS_PIXEL_RATE_DIV;\
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c
index 8b3722a0011b..838d72eaa87f 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c
@@ -24,6 +24,7 @@
 
 #include "reg_helper.h"
 #include "core_types.h"
+#include "resource.h"
 #include "dcn35_dccg.h"
 
 #define TO_DCN_DCCG(dccg)\
@@ -136,7 +137,7 @@ static void dccg35_set_dsc_clk_rcg(struct dccg *dccg, int inst, bool enable)
 {
 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
 
-	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
+	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc && enable)
 		return;
 
 	switch (inst) {
@@ -165,7 +166,7 @@ static void dccg35_set_symclk32_se_rcg(
 {
 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
 
-	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
+	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se && enable)
 		return;
 
 	/* SYMCLK32_ROOT_SE#_GATE_DISABLE will clock gate in DCCG */
@@ -204,7 +205,7 @@ static void dccg35_set_symclk32_le_rcg(
 {
 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
 
-	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
+	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le && enable)
 		return;
 
 	switch (inst) {
@@ -231,7 +232,7 @@ static void dccg35_set_physymclk_rcg(
 {
 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
 
-	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk && enable)
 		return;
 
 	switch (inst) {
@@ -262,35 +263,45 @@ static void dccg35_set_physymclk_rcg(
 }
 
 static void dccg35_set_symclk_fe_rcg(
-		struct dccg *dccg,
-		int inst,
-		bool enable)
+	struct dccg *dccg,
+	int inst,
+	bool enable)
 {
 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
 
-	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe && enable)
 		return;
 
 	switch (inst) {
 	case 0:
+		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+				   SYMCLKA_FE_GATE_DISABLE, enable ? 0 : 1);
 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
-				SYMCLKA_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
+				   SYMCLKA_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
 		break;
 	case 1:
+		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+				   SYMCLKB_FE_GATE_DISABLE, enable ? 0 : 1);
 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
-				SYMCLKB_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
+				   SYMCLKB_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
 		break;
 	case 2:
+		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+				   SYMCLKC_FE_GATE_DISABLE, enable ? 0 : 1);
 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
-				SYMCLKC_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
+				   SYMCLKC_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
 		break;
 	case 3:
+		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+				   SYMCLKD_FE_GATE_DISABLE, enable ? 0 : 1);
 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
-				SYMCLKD_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
+				   SYMCLKD_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
 		break;
 	case 4:
+		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+				   SYMCLKE_FE_GATE_DISABLE, enable ? 0 : 1);
 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
-				SYMCLKE_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
+				   SYMCLKE_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
 		break;
 	default:
 		BREAK_TO_DEBUGGER();
@@ -307,27 +318,37 @@ static void dccg35_set_symclk_be_rcg(
 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
 
 	/* TBD add symclk_be in rcg control bits */
-	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe && enable)
 		return;
 
 	switch (inst) {
 	case 0:
+		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+				   SYMCLKA_GATE_DISABLE, enable ? 0 : 1);
 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
 				   SYMCLKA_ROOT_GATE_DISABLE, enable ? 0 : 1);
 		break;
 	case 1:
+		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+				   SYMCLKB_GATE_DISABLE, enable ? 0 : 1);
 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
 				   SYMCLKB_ROOT_GATE_DISABLE, enable ? 0 : 1);
 		break;
 	case 2:
+		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+				   SYMCLKC_GATE_DISABLE, enable ? 0 : 1);
 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
 				   SYMCLKC_ROOT_GATE_DISABLE, enable ? 0 : 1);
 		break;
 	case 3:
+		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+				   SYMCLKD_GATE_DISABLE, enable ? 0 : 1);
 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
 				   SYMCLKD_ROOT_GATE_DISABLE, enable ? 0 : 1);
 		break;
 	case 4:
+		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+				   SYMCLKE_GATE_DISABLE, enable ? 0 : 1);
 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
 				   SYMCLKE_ROOT_GATE_DISABLE, enable ? 0 : 1);
 		break;
@@ -342,7 +363,7 @@ static void dccg35_set_dtbclk_p_rcg(struct dccg *dccg, int inst, bool enable)
 
 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
 
-	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
+	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable)
 		return;
 
 	switch (inst) {
@@ -370,7 +391,7 @@ static void dccg35_set_dppclk_rcg(struct dccg *dccg,
 
 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
 
-	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
+	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable)
 		return;
 
 	switch (inst) {
@@ -399,7 +420,7 @@ static void dccg35_set_dpstreamclk_rcg(
 {
 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
 
-	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
+	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream && enable)
 		return;
 
 	switch (inst) {
@@ -436,7 +457,7 @@ static void dccg35_set_smclk32_se_rcg(
 {
 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
 
-	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
+	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se && enable)
 		return;
 
 	switch (inst) {
@@ -1693,6 +1714,12 @@ static void dccg35_disable_symclk32_se(
 	}
 }
 
+static void dccg35_init_cb(struct dccg *dccg)
+{
+	(void)dccg;
+	/* Any RCG should be done when driver enter low power mode*/
+}
+
 void dccg35_init(struct dccg *dccg)
 {
 	int otg_inst;
@@ -2024,8 +2051,6 @@ static void dccg35_set_dpstreamclk_cb(
 	enum dtbclk_source dtb_clk_src;
 	enum dp_stream_clk_source dp_stream_clk_src;
 
-	ASSERT(otg_inst >= DP_STREAM_DTBCLK_P5);
-
 	switch (src) {
 	case REFCLK:
 		dtb_clk_src = DTBCLK_REFCLK;
@@ -2080,6 +2105,13 @@ static void dccg35_update_dpp_dto_cb(struct dccg *dccg, int dpp_inst,
 {
 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
 
+	if (dccg->dpp_clock_gated[dpp_inst]) {
+		/*
+		 * Do not update the DPPCLK DTO if the clock is stopped.
+		 */
+		return;
+	}
+
 	if (dccg->ref_dppclk && req_dppclk) {
 		int ref_dppclk = dccg->ref_dppclk;
 		int modulo, phase;
@@ -2107,19 +2139,20 @@ static void dccg35_update_dpp_dto_cb(struct dccg *dccg, int dpp_inst,
 }
 
 static void dccg35_dpp_root_clock_control_cb(
-		struct dccg *dccg,
-		unsigned int dpp_inst,
-		bool power_on)
+	struct dccg *dccg,
+	unsigned int dpp_inst,
+	bool power_on)
 {
+	if (dccg->dpp_clock_gated[dpp_inst] == power_on)
+		return;
 	/* power_on set indicates we need to ungate
 	 * Currently called from optimize_bandwidth and prepare_bandwidth calls
 	 * Since clock source is not passed restore to refclock on ungate
 	 * Redundant as gating when enabled is acheived through update_dpp_dto
 	 */
-	if (power_on)
-		dccg35_enable_dpp_clk_new(dccg, dpp_inst, DPP_REFCLK);
-	else
-		dccg35_disable_dpp_clk_new(dccg, dpp_inst);
+	dccg35_set_dppclk_rcg(dccg, dpp_inst, !power_on);
+
+	dccg->dpp_clock_gated[dpp_inst] = !power_on;
 }
 
 static void dccg35_enable_symclk32_se_cb(
@@ -2311,7 +2344,7 @@ static const struct dccg_funcs dccg35_funcs_new = {
 	.update_dpp_dto = dccg35_update_dpp_dto_cb,
 	.dpp_root_clock_control = dccg35_dpp_root_clock_control_cb,
 	.get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
-	.dccg_init = dccg35_init,
+	.dccg_init = dccg35_init_cb,
 	.set_dpstreamclk = dccg35_set_dpstreamclk_cb,
 	.set_dpstreamclk_root_clock_gating = dccg35_set_dpstreamclk_root_clock_gating_cb,
 	.enable_symclk32_se = dccg35_enable_symclk32_se_cb,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
index 7ed75c5fe25e..f3ea32820a40 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
@@ -147,37 +147,6 @@ void dcn35_init_hw(struct dc *dc)
 		hws->funcs.bios_golden_init(dc);
 	}
 
-	if (!dc->debug.disable_clock_gate) {
-		REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-		REG_WRITE(DCCG_GATE_DISABLE_CNTL2,  0);
-
-		/* Disable gating for PHYASYMCLK. This will be enabled in dccg if needed */
-		REG_UPDATE_5(DCCG_GATE_DISABLE_CNTL2, PHYASYMCLK_ROOT_GATE_DISABLE, 1,
-				PHYBSYMCLK_ROOT_GATE_DISABLE, 1,
-				PHYCSYMCLK_ROOT_GATE_DISABLE, 1,
-				PHYDSYMCLK_ROOT_GATE_DISABLE, 1,
-				PHYESYMCLK_ROOT_GATE_DISABLE, 1);
-
-		REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL4,
-				DPIASYMCLK0_GATE_DISABLE, 0,
-				DPIASYMCLK1_GATE_DISABLE, 0,
-				DPIASYMCLK2_GATE_DISABLE, 0,
-				DPIASYMCLK3_GATE_DISABLE, 0);
-
-		REG_WRITE(DCCG_GATE_DISABLE_CNTL5, 0xFFFFFFFF);
-		REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL5,
-				DTBCLK_P0_GATE_DISABLE, 0,
-				DTBCLK_P1_GATE_DISABLE, 0,
-				DTBCLK_P2_GATE_DISABLE, 0,
-				DTBCLK_P3_GATE_DISABLE, 0);
-		REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL5,
-				DPSTREAMCLK0_GATE_DISABLE, 0,
-				DPSTREAMCLK1_GATE_DISABLE, 0,
-				DPSTREAMCLK2_GATE_DISABLE, 0,
-				DPSTREAMCLK3_GATE_DISABLE, 0);
-
-	}
-
 	// Initialize the dccg
 	if (res_pool->dccg->funcs->dccg_init)
 		res_pool->dccg->funcs->dccg_init(res_pool->dccg);
@@ -309,20 +278,6 @@ void dcn35_init_hw(struct dc *dc)
 
 	if (!dc->debug.disable_clock_gate) {
 		/* enable all DCN clock gating */
-		REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
-		REG_UPDATE_5(DCCG_GATE_DISABLE_CNTL2, SYMCLKA_FE_GATE_DISABLE, 0,
-				SYMCLKB_FE_GATE_DISABLE, 0,
-				SYMCLKC_FE_GATE_DISABLE, 0,
-				SYMCLKD_FE_GATE_DISABLE, 0,
-				SYMCLKE_FE_GATE_DISABLE, 0);
-		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, HDMICHARCLK0_GATE_DISABLE, 0);
-		REG_UPDATE_5(DCCG_GATE_DISABLE_CNTL2, SYMCLKA_GATE_DISABLE, 0,
-				SYMCLKB_GATE_DISABLE, 0,
-				SYMCLKC_GATE_DISABLE, 0,
-				SYMCLKD_GATE_DISABLE, 0,
-				SYMCLKE_GATE_DISABLE, 0);
-
 		REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
 	}
 
-- 
2.46.0



More information about the amd-gfx mailing list