Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Set min dcfclk if pipe count is 0

[WHY]
Clocks don't get recalculated in 0 stream/0 pipe configs,
blocking S0i3 if dcfclk gets high enough

[HOW]
Create DCN31 copy of DCN30 bandwidth validation func which
doesn't entirely skip validation in 0 pipe scenarios

Override dcfclk to vlevel 0/min value during validation if pipe
count is 0

Reviewed-by: Eric Yang <Eric.Yang2@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Michael Strauss <michael.strauss@amd.com>
Tested-by: Daniel Wheeler <Daniel.Wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Michael Strauss and committed by
Alex Deucher
bc204778 e27c41d5

+70 -2
+1 -1
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
··· 1856 1856 return pipe; 1857 1857 } 1858 1858 1859 - static noinline bool dcn30_internal_validate_bw( 1859 + noinline bool dcn30_internal_validate_bw( 1860 1860 struct dc *dc, 1861 1861 struct dc_state *context, 1862 1862 display_e2e_pipe_params_st *pipes,
+7
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h
··· 55 55 56 56 bool dcn30_validate_bandwidth(struct dc *dc, struct dc_state *context, 57 57 bool fast_validate); 58 + bool dcn30_internal_validate_bw( 59 + struct dc *dc, 60 + struct dc_state *context, 61 + display_e2e_pipe_params_st *pipes, 62 + int *pipe_cnt_out, 63 + int *vlevel_out, 64 + bool fast_validate); 58 65 void dcn30_calculate_wm_and_dlg( 59 66 struct dc *dc, struct dc_state *context, 60 67 display_e2e_pipe_params_st *pipes,
+62 -1
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
··· 1827 1827 if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk) 1828 1828 dcfclk = context->bw_ctx.dml.soc.min_dcfclk; 1829 1829 1830 + /* We don't recalculate clocks for 0 pipe configs, which can block 1831 + * S0i3 as high clocks will block low power states 1832 + * Override any clocks that can block S0i3 to min here 1833 + */ 1834 + if (pipe_cnt == 0) { 1835 + context->bw_ctx.bw.dcn.clk.dcfclk_khz = dcfclk; // always should be vlevel 0 1836 + return; 1837 + } 1838 + 1830 1839 pipes[0].clks_cfg.voltage = vlevel; 1831 1840 pipes[0].clks_cfg.dcfclk_mhz = dcfclk; 1832 1841 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz; ··· 1961 1952 DC_FP_END(); 1962 1953 } 1963 1954 1955 + bool dcn31_validate_bandwidth(struct dc *dc, 1956 + struct dc_state *context, 1957 + bool fast_validate) 1958 + { 1959 + bool out = false; 1960 + 1961 + BW_VAL_TRACE_SETUP(); 1962 + 1963 + int vlevel = 0; 1964 + int pipe_cnt = 0; 1965 + display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL); 1966 + DC_LOGGER_INIT(dc->ctx->logger); 1967 + 1968 + BW_VAL_TRACE_COUNT(); 1969 + 1970 + out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate); 1971 + 1972 + // Disable fast_validate to set min dcfclk in alculate_wm_and_dlg 1973 + if (pipe_cnt == 0) 1974 + fast_validate = false; 1975 + 1976 + if (!out) 1977 + goto validate_fail; 1978 + 1979 + BW_VAL_TRACE_END_VOLTAGE_LEVEL(); 1980 + 1981 + if (fast_validate) { 1982 + BW_VAL_TRACE_SKIP(fast); 1983 + goto validate_out; 1984 + } 1985 + 1986 + dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); 1987 + 1988 + BW_VAL_TRACE_END_WATERMARKS(); 1989 + 1990 + goto validate_out; 1991 + 1992 + validate_fail: 1993 + DC_LOG_WARNING("Mode Validation Warning: %s failed alidation.\n", 1994 + dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states])); 1995 + 1996 + BW_VAL_TRACE_SKIP(fail); 1997 + out = false; 1998 + 1999 + validate_out: 2000 + kfree(pipes); 2001 + 2002 + BW_VAL_TRACE_FINISH(); 2003 + 2004 + return out; 2005 + } 2006 + 1964 2007 static struct dc_cap_funcs cap_funcs = { 1965 2008 .get_dcc_compression_cap = dcn20_get_dcc_compression_cap 1966 2009 }; ··· 2095 2034 .link_encs_assign = link_enc_cfg_link_encs_assign, 2096 2035 .link_enc_unassign = link_enc_cfg_link_enc_unassign, 2097 2036 .panel_cntl_create = dcn31_panel_cntl_create, 2098 - .validate_bandwidth = dcn30_validate_bandwidth, 2037 + .validate_bandwidth = dcn31_validate_bandwidth, 2099 2038 .calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg, 2100 2039 .update_soc_for_wm_a = dcn31_update_soc_for_wm_a, 2101 2040 .populate_dml_pipes = dcn31_populate_dml_pipes_from_context,