From: Sung Joon Kim <sungkim@xxxxxxx> [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. Reviewed-by: Charlene Liu <charlene.liu@xxxxxxx> Acked-by: Qingqing Zhuo <qingqing.zhuo@xxxxxxx> Signed-off-by: Sung Joon Kim <sungkim@xxxxxxx> --- .../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.40.1