Blob Blame History Raw
From 2bf554d7b07f715857c2ece97b40160106f7d8d9 Mon Sep 17 00:00:00 2001
From: Sung Joon Kim <sungkim@amd.com>
Date: Fri, 18 Aug 2023 12:05:11 -0400
Subject: drm/amd/display: Add IPS control flag
Git-commit: 93a66cef607cfee3953152bfe067038c5b21ea0e
Patch-mainline: v6.7-rc1
References: jsc#PED-3527 jsc#PED-5475 jsc#PED-6068 jsc#PED-6070 jsc#PED-6116 jsc#PED-6120 jsc#PED-5065 jsc#PED-5477 jsc#PED-5511 jsc#PED-6041 jsc#PED-6069 jsc#PED-6071

[why]
Currently, driver is not aware if IPS is supported. After PMFW helps
implement new message query functionality, driver will set IPS
capability flag.

[how]
Create new SMU hook function to query IPS capability. Based on the cap,
set appropriate flags to false for power-gating purposes. This will
avoid keeping SMU busy and offloading tasks to DMUB/driver.

Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Sung Joon Kim <sungkim@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c  | 18 +++++++
 .../amd/display/dc/clk_mgr/dcn35/dcn35_smu.c  | 13 ++++-
 .../amd/display/dc/clk_mgr/dcn35/dcn35_smu.h  |  1 +
 .../drm/amd/display/dc/dcn35/dcn35_pg_cntl.c  | 53 +++++++------------
 .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h   |  1 +
 5 files changed, 51 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
index b258eb37a859..819d273f011d 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
@@ -747,6 +747,16 @@ static void dcn35_exit_low_power_state(struct clk_mgr *clk_mgr_base)
 
 }
 
+static bool dcn35_is_ips_supported(struct clk_mgr *clk_mgr_base)
+{
+	struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+	bool ips_supported = true;
+
+	ips_supported = dcn35_smu_get_ips_supported(clk_mgr) ? true : false;
+
+	return ips_supported;
+}
+
 static void dcn35_init_clocks_fpga(struct clk_mgr *clk_mgr)
 {
 	dcn35_init_clocks(clk_mgr);
@@ -833,6 +843,7 @@ static struct clk_mgr_funcs dcn35_funcs = {
 	.notify_wm_ranges = dcn35_notify_wm_ranges,
 	.set_low_power_state = dcn35_set_low_power_state,
 	.exit_low_power_state = dcn35_exit_low_power_state,
+	.is_ips_supported = dcn35_is_ips_supported,
 };
 
 struct clk_mgr_funcs dcn35_fpga_funcs = {
@@ -988,6 +999,13 @@ void dcn35_clk_mgr_construct(
 		dm_helpers_free_gpu_mem(clk_mgr->base.base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
 				smu_dpm_clks.dpm_clks);
 
+	if (dcn35_smu_get_ips_supported(&clk_mgr->base)) {
+		ctx->dc->debug.ignore_pg = false;
+		ctx->dc->debug.dmcub_emulation = false;
+		ctx->dc->debug.disable_dpp_power_gate = false;
+		ctx->dc->debug.disable_hubp_power_gate = false;
+		ctx->dc->debug.disable_dsc_power_gate = false;
+	}
 }
 
 void dcn35_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c
index 9bd1e86901ec..f42c0a727dc8 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c
@@ -86,7 +86,10 @@
 #define VBIOSSMC_MSG_SetDtbClk                    0x17
 #define VBIOSSMC_MSG_DispPsrEntry                 0x18 ///< Display PSR entry, DMU
 #define VBIOSSMC_MSG_DispPsrExit                  0x19 ///< Display PSR exit, DMU
-#define VBIOSSMC_Message_Count                    0x1A
+#define VBIOSSMC_MSG_DisableLSdma                 0x1A ///< Disable LSDMA; only sent by VBIOS
+#define VBIOSSMC_MSG_DpControllerPhyStatus        0x1B ///< Inform PMFW about the pre conditions for turning SLDO2 on/off . bit[0]==1 precondition is met, bit[1-2] are for DPPHY number
+#define VBIOSSMC_MSG_QueryIPS2Support             0x1C ///< Return 1: support; else not supported
+#define VBIOSSMC_Message_Count                    0x1D
 
 #define VBIOSSMC_Status_BUSY                      0x0
 #define VBIOSSMC_Result_OK                        0x1
@@ -448,3 +451,11 @@ void dcn35_smu_exit_low_power_state(struct clk_mgr_internal *clk_mgr)
 		VBIOSSMC_MSG_DispPsrExit,
 		0);
 }
+
+int dcn35_smu_get_ips_supported(struct clk_mgr_internal *clk_mgr)
+{
+	return dcn35_smu_send_msg_with_param(
+			clk_mgr,
+			VBIOSSMC_MSG_QueryIPS2Support,
+			0);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.h
index 793d86c33d12..4d441d6db8d0 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.h
@@ -175,6 +175,7 @@ void dcn35_smu_set_dtbclk(struct clk_mgr_internal *clk_mgr, bool enable);
 void dcn35_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable);
 
 void dcn35_smu_exit_low_power_state(struct clk_mgr_internal *clk_mgr);
+int dcn35_smu_get_ips_supported(struct clk_mgr_internal *clk_mgr);
 int dcn35_smu_get_dtbclk(struct clk_mgr_internal *clk_mgr);
 int dcn35_smu_get_dprefclk(struct clk_mgr_internal *clk_mgr);
 #endif /* DAL_DC_35_SMU_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c
index 8b487d15c8ec..ccfd3102e5a0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c
@@ -84,10 +84,9 @@ void pg_cntl35_dsc_pg_control(struct pg_cntl *pg_cntl, unsigned int dsc_inst, bo
 		pg_cntl->ctx->dc->res_pool->dccg->funcs->enable_dsc(
 				pg_cntl->ctx->dc->res_pool->dccg, dsc_inst);
 
-	if (pg_cntl->ctx->dc->debug.disable_dsc_power_gate)
-		return;
-
-	if (pg_cntl->ctx->dc->idle_optimizations_allowed)
+	if (pg_cntl->ctx->dc->debug.ignore_pg ||
+		pg_cntl->ctx->dc->debug.disable_dsc_power_gate ||
+		pg_cntl->ctx->dc->idle_optimizations_allowed)
 		return;
 
 	block_enabled = pg_cntl35_dsc_pg_status(pg_cntl, dsc_inst);
@@ -98,8 +97,7 @@ void pg_cntl35_dsc_pg_control(struct pg_cntl *pg_cntl, unsigned int dsc_inst, bo
 		if (!block_enabled)
 			return;
 	}
-	if (pg_cntl->ctx->dc->debug.ignore_pg)
-		return;
+
 	REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
 	if (org_ip_request_cntl == 0)
 		REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
@@ -190,13 +188,10 @@ void pg_cntl35_hubp_dpp_pg_control(struct pg_cntl *pg_cntl, unsigned int hubp_dp
 	uint32_t org_ip_request_cntl;
 	bool block_enabled;
 
-	if (!power_on)
-		return;
-	if (pg_cntl->ctx->dc->debug.disable_hubp_power_gate ||
-		pg_cntl->ctx->dc->debug.disable_dpp_power_gate)
-		return;
-
-	if (pg_cntl->ctx->dc->idle_optimizations_allowed)
+	if (pg_cntl->ctx->dc->debug.ignore_pg ||
+		pg_cntl->ctx->dc->debug.disable_hubp_power_gate ||
+		pg_cntl->ctx->dc->debug.disable_dpp_power_gate ||
+		pg_cntl->ctx->dc->idle_optimizations_allowed)
 		return;
 
 	block_enabled = pg_cntl35_hubp_dpp_pg_status(pg_cntl, hubp_dpp_inst);
@@ -207,8 +202,7 @@ void pg_cntl35_hubp_dpp_pg_control(struct pg_cntl *pg_cntl, unsigned int hubp_dp
 		if (!block_enabled)
 			return;
 	}
-	if (pg_cntl->ctx->dc->debug.ignore_pg)
-		return;
+
 	REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
 	if (org_ip_request_cntl == 0)
 		REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
@@ -267,7 +261,8 @@ void pg_cntl35_hpo_pg_control(struct pg_cntl *pg_cntl, bool power_on)
 	uint32_t org_ip_request_cntl;
 	bool block_enabled;
 
-	if (pg_cntl->ctx->dc->idle_optimizations_allowed)
+	if (pg_cntl->ctx->dc->debug.ignore_pg ||
+		pg_cntl->ctx->dc->idle_optimizations_allowed)
 		return;
 
 	block_enabled = pg_cntl35_hpo_pg_status(pg_cntl);
@@ -278,8 +273,7 @@ void pg_cntl35_hpo_pg_control(struct pg_cntl *pg_cntl, bool power_on)
 		if (!block_enabled)
 			return;
 	}
-	if (pg_cntl->ctx->dc->debug.ignore_pg)
-		return;
+
 	REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
 	if (org_ip_request_cntl == 0)
 		REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
@@ -309,9 +303,8 @@ void pg_cntl35_io_clk_pg_control(struct pg_cntl *pg_cntl, bool power_on)
 	uint32_t org_ip_request_cntl;
 	bool block_enabled;
 
-	if (!power_on)
-		return;
-	if (pg_cntl->ctx->dc->idle_optimizations_allowed)
+	if (pg_cntl->ctx->dc->debug.ignore_pg ||
+		pg_cntl->ctx->dc->idle_optimizations_allowed)
 		return;
 
 	block_enabled = pg_cntl35_io_clk_status(pg_cntl);
@@ -322,8 +315,7 @@ void pg_cntl35_io_clk_pg_control(struct pg_cntl *pg_cntl, bool power_on)
 		if (!block_enabled)
 			return;
 	}
-	if (pg_cntl->ctx->dc->debug.ignore_pg)
-		return;
+
 	REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
 	if (org_ip_request_cntl == 0)
 		REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
@@ -351,7 +343,6 @@ static bool pg_cntl35_plane_otg_status(struct pg_cntl *pg_cntl)
 void pg_cntl35_mpcc_pg_control(struct pg_cntl *pg_cntl,
 	unsigned int mpcc_inst, bool power_on)
 {
-
 	if (pg_cntl->ctx->dc->idle_optimizations_allowed)
 		return;
 
@@ -362,7 +353,6 @@ void pg_cntl35_mpcc_pg_control(struct pg_cntl *pg_cntl,
 void pg_cntl35_opp_pg_control(struct pg_cntl *pg_cntl,
 	unsigned int opp_inst, bool power_on)
 {
-
 	if (pg_cntl->ctx->dc->idle_optimizations_allowed)
 		return;
 
@@ -373,7 +363,6 @@ void pg_cntl35_opp_pg_control(struct pg_cntl *pg_cntl,
 void pg_cntl35_optc_pg_control(struct pg_cntl *pg_cntl,
 	unsigned int optc_inst, bool power_on)
 {
-
 	if (pg_cntl->ctx->dc->idle_optimizations_allowed)
 		return;
 
@@ -392,12 +381,9 @@ void pg_cntl35_plane_otg_pg_control(struct pg_cntl *pg_cntl, bool power_on)
 	bool all_mpcc_disabled = true, all_opp_disabled = true;
 	bool all_optc_disabled = true, all_stream_disabled = true;
 
-	if (pg_cntl->ctx->dc->debug.disable_optc_power_gate)
-		return;
-
-	if (!power_on)
-		return;
-	if (pg_cntl->ctx->dc->idle_optimizations_allowed)
+	if (pg_cntl->ctx->dc->debug.ignore_pg ||
+		pg_cntl->ctx->dc->debug.disable_optc_power_gate ||
+		pg_cntl->ctx->dc->idle_optimizations_allowed)
 		return;
 
 	block_enabled = pg_cntl35_plane_otg_status(pg_cntl);
@@ -432,8 +418,7 @@ void pg_cntl35_plane_otg_pg_control(struct pg_cntl *pg_cntl, bool power_on)
 			|| !all_stream_disabled || pg_cntl->pg_res_enable[PG_DWB])
 			return;
 	}
-	if (pg_cntl->ctx->dc->debug.ignore_pg)
-		return;
+
 	REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
 	if (org_ip_request_cntl == 0)
 		REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
index 46312a7b8c2b..cb2dc3f75ae2 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
@@ -261,6 +261,7 @@ struct clk_mgr_funcs {
 
 	void (*set_low_power_state)(struct clk_mgr *clk_mgr);
 	void (*exit_low_power_state)(struct clk_mgr *clk_mgr);
+	bool (*is_ips_supported)(struct clk_mgr *clk_mgr);
 
 	void (*init_clocks)(struct clk_mgr *clk_mgr);
 
-- 
2.43.0