Message ID | 20230303043404.205928-1-koba.ko@canonical.com |
---|---|
State | New |
Headers | show |
Series | [SRU,Kinetic,PULL] Fix AMDGPU: kernel: RIP: 0010:kernel_fpu_begin_mask+0xa4/0xb0 Edit | expand |
On 03.03.23 05:34, Koba Ko wrote: > BugLink: https://bugs.launchpad.net/bugs/2009044 > > [Impact] > With AMD W6800, call trace will be printed during system boot > kernel: RIP: 0010:kernel_fpu_begin_mask+0xa4/0xb0 > > [Fix] > move FPU codes from dcn folder to dml folder. > also clean up the FPU codes on dcn folder. > > [Test Case] > 1. boot a machine with the AMD W6800. > 2. get into desktop and check the dmesg > > [Where problems could occur] > Medium, code refactoring so may occur some codes are left in original folder. > > [Misc Info] > all patches have been landed on Unstable/Lunar so SRU only for Kinetic. Rejected for the following reasons: - none of the patches has a BugLink - patch #3 "drm/amd/display: move FPU code from dcn30 clk mgr to DML folder" claims to be a cherry pick but hunk #2 to dcn30_clk_mgr.c does not apply. The upstream patch is replacing 65 lines while the backport only replaces 57. - patch #5 is neither a cherry pick. It adjusts removal by 6 lines which have already been dropped. - and this continues with patch #6 , #8, and #9. I did not bother to check what was changed there. While the changes I did look at were straight forward in the sense that things which were already missing were worked around when removing the rest. But this must be documented as backport notes. -Stefan > > ---------------------------------------------------------------- > The following changes since commit 1073c741148b00ad908fd5b335d6566fc4f6c23d: > > UBUNTU: Ubuntu-5.19.0-37.38 (2023-03-01 09:03:08 -0800) > > are available in the Git repository at: > > https://git.launchpad.net/~kobako/+git/kinetic_nxt lp2009044 > > for you to fetch changes up to 0543b19cac04f7edf5587cea6bd31801b0237b64: > > drm/amd/display: make variables static (2023-03-03 02:41:55 +0000) > > ---------------------------------------------------------------- > Magali Lemes (2): > drm/amd/display: include missing headers > drm/amd/display: make variables static > > Melissa Wen (4): > drm/amd/display: remove useless FPU protection wrapper from dcn31_resource file > drm/amd/display: move FPU code on dcn21 clk_mgr > drm/amd/display: move FPU code from dcn30 clk mgr to DML folder > drm/amd/display: move FPU code from dcn301 clk mgr to DML folder > > Rodrigo Siqueira (5): > drm/amd/display: Drop unnecessary FPU flags on dcn302 files > drm/amd/display: Remove FPU operations from dcn201 resources > drm/amd/display: Create patch bounding box function for isolate FPU > drm/amd/display: Remove FPU flags from DCN30 Makefile > drm/amd/display: Fix a compilation failure on PowerPC caused by FPU code > > drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile | 18 -- > .../drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 234 +-------------- > .../drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h | 7 + > .../amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c | 55 +--- > .../drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c | 85 +----- > .../drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h | 3 + > drivers/gpu/drm/amd/display/dc/dcn201/Makefile | 25 -- > .../drm/amd/display/dc/dcn201/dcn201_resource.c | 10 +- > drivers/gpu/drm/amd/display/dc/dcn30/Makefile | 32 -- > drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c | 8 - > drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h | 3 - > .../gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 19 +- > drivers/gpu/drm/amd/display/dc/dcn302/Makefile | 19 -- > .../gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 6 - > .../gpu/drm/amd/display/dc/dcn31/dcn31_resource.h | 1 - > .../drm/amd/display/dc/dcn315/dcn315_resource.h | 1 - > .../drm/amd/display/dc/dcn316/dcn316_resource.h | 1 - > drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c | 328 +++++++++++++++++++++ > .../gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 323 ++++++++++++++++++++ > .../gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h | 6 + > .../gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c | 83 +++++- > .../gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h | 3 + > .../gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c | 75 +++++ > .../gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c | 9 +- > .../drm/amd/display/dc/inc/hw/timing_generator.h | 2 - > 25 files changed, 859 insertions(+), 497 deletions(-) > create mode 100644 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c > > diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile > index 8178719176329..ffd005c460fcd 100644 > --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile > +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile > @@ -107,12 +107,6 @@ AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN201) > ############################################################################### > CLK_MGR_DCN21 = rn_clk_mgr.o rn_clk_mgr_vbios_smu.o > > -# prevent build errors regarding soft-float vs hard-float FP ABI tags > -# this code is currently unused on ppc64, as it applies to Renoir APUs only > -ifdef CONFIG_PPC64 > -CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn21/rn_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) > -endif > - > AMD_DAL_CLK_MGR_DCN21 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21)) > > AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) > @@ -121,12 +115,6 @@ AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) > ############################################################################### > CLK_MGR_DCN30 = dcn30_clk_mgr.o dcn30_clk_mgr_smu_msg.o > > -# prevent build errors regarding soft-float vs hard-float FP ABI tags > -# this code is currently unused on ppc64, as it applies to VanGogh APUs only > -ifdef CONFIG_PPC64 > -CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn30/dcn30_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) > -endif > - > AMD_DAL_CLK_MGR_DCN30 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn30/,$(CLK_MGR_DCN30)) > > AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN30) > @@ -135,12 +123,6 @@ AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN30) > ############################################################################### > CLK_MGR_DCN301 = vg_clk_mgr.o dcn301_smu.o > > -# prevent build errors regarding soft-float vs hard-float FP ABI tags > -# this code is currently unused on ppc64, as it applies to VanGogh APUs only > -ifdef CONFIG_PPC64 > -CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn301/vg_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) > -endif > - > AMD_DAL_CLK_MGR_DCN301 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn301/,$(CLK_MGR_DCN301)) > > AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN301) > diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c > index cf1b5f354ae99..0202dc682682b 100644 > --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c > +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c > @@ -26,10 +26,9 @@ > #include "dccg.h" > #include "clk_mgr_internal.h" > > - > #include "dcn20/dcn20_clk_mgr.h" > #include "rn_clk_mgr.h" > - > +#include "dml/dcn20/dcn20_fpu.h" > > #include "dce100/dce_clk_mgr.h" > #include "rn_clk_mgr_vbios_smu.h" > @@ -45,7 +44,6 @@ > > /* Constants */ > > -#define LPDDR_MEM_RETRAIN_LATENCY 4.977 /* Number obtained from LPDDR4 Training Counter Requirement doc */ > #define SMU_VER_55_51_0 0x373300 /* SMU Version that is able to set DISPCLK below 100MHz */ > > /* Macros */ > @@ -613,228 +611,6 @@ static struct clk_bw_params rn_bw_params = { > > }; > > -static struct wm_table ddr4_wm_table_gs = { > - .entries = { > - { > - .wm_inst = WM_A, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 7.09, > - .sr_enter_plus_exit_time_us = 8.14, > - .valid = true, > - }, > - { > - .wm_inst = WM_B, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 10.12, > - .sr_enter_plus_exit_time_us = 11.48, > - .valid = true, > - }, > - { > - .wm_inst = WM_C, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 10.12, > - .sr_enter_plus_exit_time_us = 11.48, > - .valid = true, > - }, > - { > - .wm_inst = WM_D, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 10.12, > - .sr_enter_plus_exit_time_us = 11.48, > - .valid = true, > - }, > - } > -}; > - > -static struct wm_table lpddr4_wm_table_gs = { > - .entries = { > - { > - .wm_inst = WM_A, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 5.32, > - .sr_enter_plus_exit_time_us = 6.38, > - .valid = true, > - }, > - { > - .wm_inst = WM_B, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 9.82, > - .sr_enter_plus_exit_time_us = 11.196, > - .valid = true, > - }, > - { > - .wm_inst = WM_C, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 9.89, > - .sr_enter_plus_exit_time_us = 11.24, > - .valid = true, > - }, > - { > - .wm_inst = WM_D, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 9.748, > - .sr_enter_plus_exit_time_us = 11.102, > - .valid = true, > - }, > - } > -}; > - > -static struct wm_table lpddr4_wm_table_with_disabled_ppt = { > - .entries = { > - { > - .wm_inst = WM_A, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 8.32, > - .sr_enter_plus_exit_time_us = 9.38, > - .valid = true, > - }, > - { > - .wm_inst = WM_B, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 9.82, > - .sr_enter_plus_exit_time_us = 11.196, > - .valid = true, > - }, > - { > - .wm_inst = WM_C, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 9.89, > - .sr_enter_plus_exit_time_us = 11.24, > - .valid = true, > - }, > - { > - .wm_inst = WM_D, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 9.748, > - .sr_enter_plus_exit_time_us = 11.102, > - .valid = true, > - }, > - } > -}; > - > -static struct wm_table ddr4_wm_table_rn = { > - .entries = { > - { > - .wm_inst = WM_A, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 11.90, > - .sr_enter_plus_exit_time_us = 12.80, > - .valid = true, > - }, > - { > - .wm_inst = WM_B, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 13.18, > - .sr_enter_plus_exit_time_us = 14.30, > - .valid = true, > - }, > - { > - .wm_inst = WM_C, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 13.18, > - .sr_enter_plus_exit_time_us = 14.30, > - .valid = true, > - }, > - { > - .wm_inst = WM_D, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 13.18, > - .sr_enter_plus_exit_time_us = 14.30, > - .valid = true, > - }, > - } > -}; > - > -static struct wm_table ddr4_1R_wm_table_rn = { > - .entries = { > - { > - .wm_inst = WM_A, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 13.90, > - .sr_enter_plus_exit_time_us = 14.80, > - .valid = true, > - }, > - { > - .wm_inst = WM_B, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 13.90, > - .sr_enter_plus_exit_time_us = 14.80, > - .valid = true, > - }, > - { > - .wm_inst = WM_C, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 13.90, > - .sr_enter_plus_exit_time_us = 14.80, > - .valid = true, > - }, > - { > - .wm_inst = WM_D, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 13.90, > - .sr_enter_plus_exit_time_us = 14.80, > - .valid = true, > - }, > - } > -}; > - > -static struct wm_table lpddr4_wm_table_rn = { > - .entries = { > - { > - .wm_inst = WM_A, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 7.32, > - .sr_enter_plus_exit_time_us = 8.38, > - .valid = true, > - }, > - { > - .wm_inst = WM_B, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 9.82, > - .sr_enter_plus_exit_time_us = 11.196, > - .valid = true, > - }, > - { > - .wm_inst = WM_C, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 9.89, > - .sr_enter_plus_exit_time_us = 11.24, > - .valid = true, > - }, > - { > - .wm_inst = WM_D, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 9.748, > - .sr_enter_plus_exit_time_us = 11.102, > - .valid = true, > - }, > - } > -}; > - > static unsigned int find_socclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage) > { > int i; > @@ -914,12 +690,10 @@ static void rn_clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params > /* > * WM set D will be re-purposed for memory retraining > */ > - bw_params->wm_table.entries[WM_D].pstate_latency_us = LPDDR_MEM_RETRAIN_LATENCY; > - bw_params->wm_table.entries[WM_D].wm_inst = WM_D; > - bw_params->wm_table.entries[WM_D].wm_type = WM_TYPE_RETRAINING; > - bw_params->wm_table.entries[WM_D].valid = true; > + DC_FP_START(); > + dcn21_clk_mgr_set_bw_params_wm_table(bw_params); > + DC_FP_END(); > } > - > } > > void rn_clk_mgr_construct( > diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h > index e4322fa5475b6..2e088c5171b28 100644 > --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h > +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h > @@ -29,6 +29,13 @@ > #include "clk_mgr.h" > #include "dm_pp_smu.h" > > +extern struct wm_table ddr4_wm_table_gs; > +extern struct wm_table lpddr4_wm_table_gs; > +extern struct wm_table lpddr4_wm_table_with_disabled_ppt; > +extern struct wm_table ddr4_wm_table_rn; > +extern struct wm_table ddr4_1R_wm_table_rn; > +extern struct wm_table lpddr4_wm_table_rn; > + > struct rn_clk_registers { > uint32_t CLK1_CLK0_CURRENT_CNT; /* DPREFCLK */ > }; > diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c > index 5ed6a93d1708c..e34a0e81facb6 100644 > --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c > +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c > @@ -29,6 +29,7 @@ > #include "dcn20/dcn20_clk_mgr.h" > #include "dce100/dce_clk_mgr.h" > #include "dcn30/dcn30_clk_mgr.h" > +#include "dml/dcn30/dcn30_fpu.h" > #include "reg_helper.h" > #include "core_types.h" > #include "dm_helpers.h" > @@ -97,57 +98,11 @@ static void dcn3_init_single_clock(struct clk_mgr_internal *clk_mgr, uint32_t cl > } > } > > -static noinline void dcn3_build_wm_range_table(struct clk_mgr_internal *clk_mgr) > +static void dcn3_build_wm_range_table(struct clk_mgr_internal *clk_mgr) > { > - /* defaults */ > - double pstate_latency_us = clk_mgr->base.ctx->dc->dml.soc.dram_clock_change_latency_us; > - double sr_exit_time_us = clk_mgr->base.ctx->dc->dml.soc.sr_exit_time_us; > - double sr_enter_plus_exit_time_us = clk_mgr->base.ctx->dc->dml.soc.sr_enter_plus_exit_time_us; > - uint16_t min_uclk_mhz = clk_mgr->base.bw_params->clk_table.entries[0].memclk_mhz; > - > - /* Set A - Normal - default values*/ > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].valid = true; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us = pstate_latency_us; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us = sr_exit_time_us; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_dcfclk = 0; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_dcfclk = 0xFFFF; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_uclk = min_uclk_mhz; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_uclk = 0xFFFF; > - > - /* Set B - Performance - higher minimum clocks */ > -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].valid = true; > -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us = pstate_latency_us; > -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us = sr_exit_time_us; > -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; > -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE; > -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_dcfclk = TUNED VALUE; > -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_dcfclk = 0xFFFF; > -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_uclk = TUNED VALUE; > -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_uclk = 0xFFFF; > - > - /* Set C - Dummy P-State - P-State latency set to "dummy p-state" value */ > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].valid = true; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = clk_mgr->base.ctx->dc->dml.soc.dummy_pstate_latency_us; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.wm_type = WATERMARKS_DUMMY_PSTATE; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_dcfclk = 0; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_dcfclk = 0xFFFF; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF; > - > - /* Set D - MALL - SR enter and exit times adjusted for MALL */ > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].valid = true; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us = pstate_latency_us; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us = 2; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us = 4; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.wm_type = WATERMARKS_MALL; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_dcfclk = 0; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_dcfclk = 0xFFFF; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_uclk = min_uclk_mhz; > - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_uclk = 0xFFFF; > + DC_FP_START(); > + dcn3_fpu_build_wm_range_table(&clk_mgr->base); > + DC_FP_END(); > } > > void dcn3_init_clocks(struct clk_mgr *clk_mgr_base) > diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c > index f310b0d25a076..24715ca2fa944 100644 > --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c > +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c > @@ -32,6 +32,9 @@ > // For dcn20_update_clocks_update_dpp_dto > #include "dcn20/dcn20_clk_mgr.h" > > +// For DML FPU code > +#include "dml/dcn20/dcn20_fpu.h" > + > #include "vg_clk_mgr.h" > #include "dcn301_smu.h" > #include "reg_helper.h" > @@ -526,81 +529,6 @@ static struct clk_bw_params vg_bw_params = { > > }; > > -static struct wm_table ddr4_wm_table = { > - .entries = { > - { > - .wm_inst = WM_A, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 6.09, > - .sr_enter_plus_exit_time_us = 7.14, > - .valid = true, > - }, > - { > - .wm_inst = WM_B, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 10.12, > - .sr_enter_plus_exit_time_us = 11.48, > - .valid = true, > - }, > - { > - .wm_inst = WM_C, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 10.12, > - .sr_enter_plus_exit_time_us = 11.48, > - .valid = true, > - }, > - { > - .wm_inst = WM_D, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.72, > - .sr_exit_time_us = 10.12, > - .sr_enter_plus_exit_time_us = 11.48, > - .valid = true, > - }, > - } > -}; > - > -static struct wm_table lpddr5_wm_table = { > - .entries = { > - { > - .wm_inst = WM_A, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 13.5, > - .sr_enter_plus_exit_time_us = 16.5, > - .valid = true, > - }, > - { > - .wm_inst = WM_B, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 13.5, > - .sr_enter_plus_exit_time_us = 16.5, > - .valid = true, > - }, > - { > - .wm_inst = WM_C, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 13.5, > - .sr_enter_plus_exit_time_us = 16.5, > - .valid = true, > - }, > - { > - .wm_inst = WM_D, > - .wm_type = WM_TYPE_PSTATE_CHG, > - .pstate_latency_us = 11.65333, > - .sr_exit_time_us = 13.5, > - .sr_enter_plus_exit_time_us = 16.5, > - .valid = true, > - }, > - } > -}; > - > - > static unsigned int find_dcfclk_for_voltage(const struct vg_dpm_clocks *clock_table, > unsigned int voltage) > { > @@ -670,10 +598,9 @@ static void vg_clk_mgr_helper_populate_bw_params( > /* > * WM set D will be re-purposed for memory retraining > */ > - bw_params->wm_table.entries[WM_D].pstate_latency_us = LPDDR_MEM_RETRAIN_LATENCY; > - bw_params->wm_table.entries[WM_D].wm_inst = WM_D; > - bw_params->wm_table.entries[WM_D].wm_type = WM_TYPE_RETRAINING; > - bw_params->wm_table.entries[WM_D].valid = true; > + DC_FP_START(); > + dcn21_clk_mgr_set_bw_params_wm_table(bw_params); > + DC_FP_END(); > } > > } > diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h > index 7255477307f13..75884f5729891 100644 > --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h > +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h > @@ -29,6 +29,9 @@ > > struct watermarks; > > +extern struct wm_table ddr4_wm_table; > +extern struct wm_table lpddr5_wm_table; > + > struct smu_watermark_set { > struct watermarks *wm_set; > union large_integer mc_address; > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/Makefile b/drivers/gpu/drm/amd/display/dc/dcn201/Makefile > index f68038ceb1b15..5c9ce2cebb0f6 100644 > --- a/drivers/gpu/drm/amd/display/dc/dcn201/Makefile > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/Makefile > @@ -6,31 +6,6 @@ DCN201 = dcn201_init.o dcn201_resource.o dcn201_hwseq.o \ > dcn201_mpc.o dcn201_hubp.o dcn201_opp.o dcn201_optc.o dcn201_dpp.o \ > dcn201_dccg.o dcn201_link_encoder.o > > -ifdef CONFIG_X86 > -CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o := -mhard-float -msse > -endif > - > -ifdef CONFIG_PPC64 > -CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o := -mhard-float -maltivec > -endif > - > -ifdef CONFIG_CC_IS_GCC > -ifeq ($(call cc-ifversion, -lt, 0701, y), y) > -IS_OLD_GCC = 1 > -endif > -CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o += -mhard-float > -endif > - > -ifdef CONFIG_X86 > -ifdef IS_OLD_GCC > -# Stack alignment mismatch, proceed with caution. > -# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 > -# (8B stack alignment). > -CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o += -mpreferred-stack-boundary=4 > -else > -CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o += -msse2 > -endif > -endif > AMD_DAL_DCN201 = $(addprefix $(AMDDALPATH)/dc/dcn201/,$(DCN201)) > > AMD_DISPLAY_FILES += $(AMD_DAL_DCN201) > diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c > index 0bb7d3dd53fa4..e549a79f3fe1a 100644 > --- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c > +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c > @@ -1036,6 +1036,14 @@ static bool dcn201_get_dcc_compression_cap(const struct dc *dc, > output); > } > > +static void dcn201_populate_dml_writeback_from_context(struct dc *dc, > + struct resource_context *res_ctx, > + display_e2e_pipe_params_st *pipes) > +{ > + DC_FP_START(); > + dcn201_populate_dml_writeback_from_context_fpu(dc, res_ctx, pipes); > + DC_FP_END(); > +} > > static void dcn201_destroy_resource_pool(struct resource_pool **pool) > { > @@ -1067,8 +1075,8 @@ static struct resource_funcs dcn201_res_pool_funcs = { > .add_dsc_to_stream_resource = NULL, > .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, > .acquire_idle_pipe_for_layer = dcn201_acquire_idle_pipe_for_layer, > + .populate_dml_writeback_from_context = dcn201_populate_dml_writeback_from_context, > .patch_unknown_plane_state = dcn20_patch_unknown_plane_state, > - .populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context, > .set_mcif_arb_params = dcn20_set_mcif_arb_params, > .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link > }; > diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/Makefile b/drivers/gpu/drm/amd/display/dc/dcn30/Makefile > index dfd77b3cc84d8..b7c2ae9ddfda3 100644 > --- a/drivers/gpu/drm/amd/display/dc/dcn30/Makefile > +++ b/drivers/gpu/drm/amd/display/dc/dcn30/Makefile > @@ -30,38 +30,6 @@ DCN30 = dcn30_init.o dcn30_hubbub.o dcn30_hubp.o dcn30_dpp.o dcn30_optc.o \ > dcn30_dpp_cm.o dcn30_dwb_cm.o dcn30_cm_common.o dcn30_mmhubbub.o \ > dcn30_dio_link_encoder.o dcn30_resource.o > > - > -ifdef CONFIG_X86 > -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -msse > -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -msse > -endif > - > -ifdef CONFIG_PPC64 > -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -mhard-float -maltivec > -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -mhard-float -maltivec > -endif > - > -ifdef CONFIG_CC_IS_GCC > -ifeq ($(call cc-ifversion, -lt, 0701, y), y) > -IS_OLD_GCC = 1 > -endif > -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o += -mhard-float > -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o += -mhard-float > -endif > - > -ifdef CONFIG_X86 > -ifdef IS_OLD_GCC > -# Stack alignment mismatch, proceed with caution. > -# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 > -# (8B stack alignment). > -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o += -mpreferred-stack-boundary=4 > -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o += -mpreferred-stack-boundary=4 > -else > -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o += -msse2 > -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o += -msse2 > -endif > -endif > - > AMD_DAL_DCN30 = $(addprefix $(AMDDALPATH)/dc/dcn30/,$(DCN30)) > > AMD_DISPLAY_FILES += $(AMD_DAL_DCN30) > diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c > index b604fb26f288d..4c57c001fd23b 100644 > --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c > +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c > @@ -186,14 +186,6 @@ void optc3_set_dsc_config(struct timing_generator *optc, > > } > > -void optc3_set_vrr_m_const(struct timing_generator *optc, > - double vtotal_avg) > -{ > - DC_FP_START(); > - optc3_fpu_set_vrr_m_const(optc, vtotal_avg); > - DC_FP_END(); > -} > - > void optc3_set_odm_bypass(struct timing_generator *optc, > const struct dc_crtc_timing *dc_crtc_timing) > { > diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h > index 97f11ef6e9f02..bd5743b73fa5b 100644 > --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h > +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h > @@ -320,9 +320,6 @@ void optc3_lock_doublebuffer_enable(struct timing_generator *optc); > > void optc3_lock_doublebuffer_disable(struct timing_generator *optc); > > -void optc3_set_vrr_m_const(struct timing_generator *optc, > - double vtotal_avg); > - > void optc3_set_drr_trigger_window(struct timing_generator *optc, > uint32_t window_start, uint32_t window_end); > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c > index 1c1a67c4cec1c..19ef63b13fe43 100644 > --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c > +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c > @@ -1520,26 +1520,11 @@ static bool init_soc_bounding_box(struct dc *dc, > loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator; > loaded_ip->max_num_dpp = pool->base.pipe_count; > loaded_ip->clamp_min_dcfclk = dc->config.clamp_min_dcfclk; > - > - DC_FP_START(); > dcn20_patch_bounding_box(dc, loaded_bb); > + DC_FP_START(); > + patch_dcn30_soc_bounding_box(dc, &dcn3_0_soc); > DC_FP_END(); > > - if (dc->ctx->dc_bios->funcs->get_soc_bb_info) { > - struct bp_soc_bb_info bb_info = {0}; > - > - if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) { > - if (bb_info.dram_clock_change_latency_100ns > 0) > - dcn3_0_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10; > - > - if (bb_info.dram_sr_enter_exit_latency_100ns > 0) > - dcn3_0_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10; > - > - if (bb_info.dram_sr_exit_latency_100ns > 0) > - dcn3_0_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10; > - } > - } > - > return true; > } > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/Makefile b/drivers/gpu/drm/amd/display/dc/dcn302/Makefile > index f9561d7f97a1d..ebd01cb467b79 100644 > --- a/drivers/gpu/drm/amd/display/dc/dcn302/Makefile > +++ b/drivers/gpu/drm/amd/display/dc/dcn302/Makefile > @@ -7,25 +7,6 @@ > > DCN3_02 = dcn302_init.o dcn302_hwseq.o dcn302_resource.o > > -ifdef CONFIG_X86 > -CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -msse > -endif > - > -ifdef CONFIG_PPC64 > -CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mhard-float -maltivec > -endif > - > -ifdef CONFIG_X86 > -ifdef IS_OLD_GCC > -# Stack alignment mismatch, proceed with caution. > -# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 > -# (8B stack alignment). > -CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o += -mpreferred-stack-boundary=4 > -else > -CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o += -msse2 > -endif > -endif > - > AMD_DAL_DCN3_02 = $(addprefix $(AMDDALPATH)/dc/dcn302/,$(DCN3_02)) > > AMD_DISPLAY_FILES += $(AMD_DAL_DCN3_02) > diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c > index 3d9f07d4770bf..fe21d33111729 100644 > --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c > +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c > @@ -1873,8 +1873,6 @@ static bool dcn31_resource_construct( > struct dc_context *ctx = dc->ctx; > struct irq_service_init_data init_data; > > - DC_FP_START(); > - > ctx->dc_bios->regs = &bios_regs; > > pool->base.res_cap = &res_cap_dcn31; > @@ -2182,13 +2180,9 @@ static bool dcn31_resource_construct( > > dc->dcn_ip->max_num_dpp = dcn3_1_ip.max_num_dpp; > > - DC_FP_END(); > - > return true; > > create_fail: > - > - DC_FP_END(); > dcn31_resource_destruct(pool); > > return false; > diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h > index 393458015d6a4..98ae95f378659 100644 > --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h > +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h > @@ -32,7 +32,6 @@ > container_of(pool, struct dcn31_resource_pool, base) > > extern struct _vcs_dpi_ip_params_st dcn3_1_ip; > -extern struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc; > > struct dcn31_resource_pool { > struct resource_pool base; > diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h > index 39929fa67a510..22849eaa6f243 100644 > --- a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h > +++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h > @@ -32,7 +32,6 @@ > container_of(pool, struct dcn315_resource_pool, base) > > extern struct _vcs_dpi_ip_params_st dcn3_15_ip; > -extern struct _vcs_dpi_ip_params_st dcn3_15_soc; > > struct dcn315_resource_pool { > struct resource_pool base; > diff --git a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h > index 0dc5a6c13ae7d..aba6d634131b4 100644 > --- a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h > +++ b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h > @@ -32,7 +32,6 @@ > container_of(pool, struct dcn316_resource_pool, base) > > extern struct _vcs_dpi_ip_params_st dcn3_16_ip; > -extern struct _vcs_dpi_ip_params_st dcn3_16_soc; > > struct dcn316_resource_pool { > struct resource_pool base; > diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c > new file mode 100644 > index 0000000000000..eff1f4e17689c > --- /dev/null > +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c > @@ -0,0 +1,328 @@ > +/* > + * Copyright 2022 Advanced Micro Devices, Inc. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + * Authors: AMD > + * > + */ > + > +#include "dcn32_optc.h" > + > +#include "dcn30/dcn30_optc.h" > +#include "dcn31/dcn31_optc.h" > +#include "reg_helper.h" > +#include "dc.h" > +#include "dcn_calc_math.h" > +#include "dc_dmub_srv.h" > + > +#define REG(reg)\ > + optc1->tg_regs->reg > + > +#define CTX \ > + optc1->base.ctx > + > +#undef FN > +#define FN(reg_name, field_name) \ > + optc1->tg_shift->field_name, optc1->tg_mask->field_name > + > +static void optc32_set_odm_combine(struct timing_generator *optc, int *opp_id, int opp_cnt, > + struct dc_crtc_timing *timing) > +{ > + struct optc *optc1 = DCN10TG_FROM_TG(optc); > + uint32_t memory_mask = 0; > + int h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right; > + int mpcc_hactive = h_active / opp_cnt; > + /* Each memory instance is 2048x(32x2) bits to support half line of 4096 */ > + int odm_mem_count = (h_active + 2047) / 2048; > + > + /* > + * display <= 4k : 2 memories + 2 pipes > + * 4k < display <= 8k : 4 memories + 2 pipes > + * 8k < display <= 12k : 6 memories + 4 pipes > + */ > + if (opp_cnt == 4) { > + if (odm_mem_count <= 2) > + memory_mask = 0x3; > + else if (odm_mem_count <= 4) > + memory_mask = 0xf; > + else > + memory_mask = 0x3f; > + } else { > + if (odm_mem_count <= 2) > + memory_mask = 0x1 << (opp_id[0] * 2) | 0x1 << (opp_id[1] * 2); > + else if (odm_mem_count <= 4) > + memory_mask = 0x3 << (opp_id[0] * 2) | 0x3 << (opp_id[1] * 2); > + else > + memory_mask = 0x77; > + } > + > + REG_SET(OPTC_MEMORY_CONFIG, 0, > + OPTC_MEM_SEL, memory_mask); > + > + if (opp_cnt == 2) { > + REG_SET_3(OPTC_DATA_SOURCE_SELECT, 0, > + OPTC_NUM_OF_INPUT_SEGMENT, 1, > + OPTC_SEG0_SRC_SEL, opp_id[0], > + OPTC_SEG1_SRC_SEL, opp_id[1]); > + } else if (opp_cnt == 4) { > + REG_SET_5(OPTC_DATA_SOURCE_SELECT, 0, > + OPTC_NUM_OF_INPUT_SEGMENT, 3, > + OPTC_SEG0_SRC_SEL, opp_id[0], > + OPTC_SEG1_SRC_SEL, opp_id[1], > + OPTC_SEG2_SRC_SEL, opp_id[2], > + OPTC_SEG3_SRC_SEL, opp_id[3]); > + } > + > + REG_UPDATE(OPTC_WIDTH_CONTROL, > + OPTC_SEGMENT_WIDTH, mpcc_hactive); > + > + REG_UPDATE(OTG_H_TIMING_CNTL, > + OTG_H_TIMING_DIV_MODE, opp_cnt - 1); > + optc1->opp_count = opp_cnt; > +} > + > +static void optc32_set_h_timing_div_manual_mode(struct timing_generator *optc, bool manual_mode) > +{ > + struct optc *optc1 = DCN10TG_FROM_TG(optc); > + > + REG_UPDATE(OTG_H_TIMING_CNTL, > + OTG_H_TIMING_DIV_MODE_MANUAL, manual_mode ? 1 : 0); > +} > +/** > + * Enable CRTC > + * Enable CRTC - call ASIC Control Object to enable Timing generator. > + */ > +static bool optc32_enable_crtc(struct timing_generator *optc) > +{ > + struct optc *optc1 = DCN10TG_FROM_TG(optc); > + > + /* opp instance for OTG, 1 to 1 mapping and odm will adjust */ > + REG_UPDATE(OPTC_DATA_SOURCE_SELECT, > + OPTC_SEG0_SRC_SEL, optc->inst); > + > + /* VTG enable first is for HW workaround */ > + REG_UPDATE(CONTROL, > + VTG0_ENABLE, 1); > + > + REG_SEQ_START(); > + > + /* Enable CRTC */ > + REG_UPDATE_2(OTG_CONTROL, > + OTG_DISABLE_POINT_CNTL, 2, > + OTG_MASTER_EN, 1); > + > + REG_SEQ_SUBMIT(); > + REG_SEQ_WAIT_DONE(); > + > + return true; > +} > + > +/* disable_crtc */ > +static bool optc32_disable_crtc(struct timing_generator *optc) > +{ > + struct optc *optc1 = DCN10TG_FROM_TG(optc); > + > + /* disable otg request until end of the first line > + * in the vertical blank region > + */ > + REG_UPDATE(OTG_CONTROL, > + OTG_MASTER_EN, 0); > + > + REG_UPDATE(CONTROL, > + VTG0_ENABLE, 0); > + > + /* CRTC disabled, so disable clock. */ > + REG_WAIT(OTG_CLOCK_CONTROL, > + OTG_BUSY, 0, > + 1, 100000); > + > + return true; > +} > + > +void optc32_phantom_crtc_post_enable(struct timing_generator *optc) > +{ > + struct optc *optc1 = DCN10TG_FROM_TG(optc); > + > + /* Disable immediately. */ > + REG_UPDATE_2(OTG_CONTROL, OTG_DISABLE_POINT_CNTL, 0, OTG_MASTER_EN, 0); > + > + /* CRTC disabled, so disable clock. */ > + REG_WAIT(OTG_CLOCK_CONTROL, OTG_BUSY, 0, 1, 100000); > +} > + > +static void optc32_set_odm_bypass(struct timing_generator *optc, > + const struct dc_crtc_timing *dc_crtc_timing) > +{ > + struct optc *optc1 = DCN10TG_FROM_TG(optc); > + enum h_timing_div_mode h_div = H_TIMING_NO_DIV; > + > + REG_SET_5(OPTC_DATA_SOURCE_SELECT, 0, > + OPTC_NUM_OF_INPUT_SEGMENT, 0, > + OPTC_SEG0_SRC_SEL, optc->inst, > + OPTC_SEG1_SRC_SEL, 0xf, > + OPTC_SEG2_SRC_SEL, 0xf, > + OPTC_SEG3_SRC_SEL, 0xf > + ); > + > + h_div = optc1_is_two_pixels_per_containter(dc_crtc_timing); > + REG_UPDATE(OTG_H_TIMING_CNTL, > + OTG_H_TIMING_DIV_MODE, h_div); > + > + REG_SET(OPTC_MEMORY_CONFIG, 0, > + OPTC_MEM_SEL, 0); > + optc1->opp_count = 1; > +} > + > +void optc32_setup_manual_trigger(struct timing_generator *optc) > +{ > + struct optc *optc1 = DCN10TG_FROM_TG(optc); > + struct dc *dc = optc->ctx->dc; > + > + if (dc->caps.dmub_caps.mclk_sw && !dc->debug.disable_fams) > + dc_dmub_srv_set_drr_manual_trigger_cmd(dc, optc->inst); > + else { > + /* > + * MIN_MASK_EN is gone and MASK is now always enabled. > + * > + * To get it to it work with manual trigger we need to make sure > + * we program the correct bit. > + */ > + REG_UPDATE_4(OTG_V_TOTAL_CONTROL, > + OTG_V_TOTAL_MIN_SEL, 1, > + OTG_V_TOTAL_MAX_SEL, 1, > + OTG_FORCE_LOCK_ON_EVENT, 0, > + OTG_SET_V_TOTAL_MIN_MASK, (1 << 1)); /* TRIGA */ > + > + // Setup manual flow control for EOF via TRIG_A > + optc->funcs->setup_manual_trigger(optc); > + } > +} > + > +void optc32_set_drr( > + struct timing_generator *optc, > + const struct drr_params *params) > +{ > + struct optc *optc1 = DCN10TG_FROM_TG(optc); > + > + if (params != NULL && > + params->vertical_total_max > 0 && > + params->vertical_total_min > 0) { > + > + if (params->vertical_total_mid != 0) { > + > + REG_SET(OTG_V_TOTAL_MID, 0, > + OTG_V_TOTAL_MID, params->vertical_total_mid - 1); > + > + REG_UPDATE_2(OTG_V_TOTAL_CONTROL, > + OTG_VTOTAL_MID_REPLACING_MAX_EN, 1, > + OTG_VTOTAL_MID_FRAME_NUM, > + (uint8_t)params->vertical_total_mid_frame_num); > + > + } > + > + optc->funcs->set_vtotal_min_max(optc, params->vertical_total_min - 1, params->vertical_total_max - 1); > + optc32_setup_manual_trigger(optc); > + } else { > + REG_UPDATE_4(OTG_V_TOTAL_CONTROL, > + OTG_SET_V_TOTAL_MIN_MASK, 0, > + OTG_V_TOTAL_MIN_SEL, 0, > + OTG_V_TOTAL_MAX_SEL, 0, > + OTG_FORCE_LOCK_ON_EVENT, 0); > + > + optc->funcs->set_vtotal_min_max(optc, 0, 0); > + } > +} > + > +static struct timing_generator_funcs dcn32_tg_funcs = { > + .validate_timing = optc1_validate_timing, > + .program_timing = optc1_program_timing, > + .setup_vertical_interrupt0 = optc1_setup_vertical_interrupt0, > + .setup_vertical_interrupt1 = optc1_setup_vertical_interrupt1, > + .setup_vertical_interrupt2 = optc1_setup_vertical_interrupt2, > + .program_global_sync = optc1_program_global_sync, > + .enable_crtc = optc32_enable_crtc, > + .disable_crtc = optc32_disable_crtc, > + .phantom_crtc_post_enable = optc32_phantom_crtc_post_enable, > + /* used by enable_timing_synchronization. Not need for FPGA */ > + .is_counter_moving = optc1_is_counter_moving, > + .get_position = optc1_get_position, > + .get_frame_count = optc1_get_vblank_counter, > + .get_scanoutpos = optc1_get_crtc_scanoutpos, > + .get_otg_active_size = optc1_get_otg_active_size, > + .set_early_control = optc1_set_early_control, > + /* used by enable_timing_synchronization. Not need for FPGA */ > + .wait_for_state = optc1_wait_for_state, > + .set_blank_color = optc3_program_blank_color, > + .did_triggered_reset_occur = optc1_did_triggered_reset_occur, > + .triplebuffer_lock = optc3_triplebuffer_lock, > + .triplebuffer_unlock = optc2_triplebuffer_unlock, > + .enable_reset_trigger = optc1_enable_reset_trigger, > + .enable_crtc_reset = optc1_enable_crtc_reset, > + .disable_reset_trigger = optc1_disable_reset_trigger, > + .lock = optc3_lock, > + .unlock = optc1_unlock, > + .lock_doublebuffer_enable = optc3_lock_doublebuffer_enable, > + .lock_doublebuffer_disable = optc3_lock_doublebuffer_disable, > + .enable_optc_clock = optc1_enable_optc_clock, > + .set_drr = optc31_set_drr, // TODO: Update to optc32_set_drr once FW headers are promoted > + .get_last_used_drr_vtotal = optc2_get_last_used_drr_vtotal, > + .set_vtotal_min_max = optc3_set_vtotal_min_max, > + .set_static_screen_control = optc1_set_static_screen_control, > + .program_stereo = optc1_program_stereo, > + .is_stereo_left_eye = optc1_is_stereo_left_eye, > + .tg_init = optc3_tg_init, > + .is_tg_enabled = optc1_is_tg_enabled, > + .is_optc_underflow_occurred = optc1_is_optc_underflow_occurred, > + .clear_optc_underflow = optc1_clear_optc_underflow, > + .setup_global_swap_lock = NULL, > + .get_crc = optc1_get_crc, > + .configure_crc = optc1_configure_crc, > + .set_dsc_config = optc3_set_dsc_config, > + .get_dsc_status = optc2_get_dsc_status, > + .set_dwb_source = NULL, > + .set_odm_bypass = optc32_set_odm_bypass, > + .set_odm_combine = optc32_set_odm_combine, > + .set_h_timing_div_manual_mode = optc32_set_h_timing_div_manual_mode, > + .get_optc_source = optc2_get_optc_source, > + .set_out_mux = optc3_set_out_mux, > + .set_drr_trigger_window = optc3_set_drr_trigger_window, > + .set_vtotal_change_limit = optc3_set_vtotal_change_limit, > + .set_gsl = optc2_set_gsl, > + .set_gsl_source_select = optc2_set_gsl_source_select, > + .set_vtg_params = optc1_set_vtg_params, > + .program_manual_trigger = optc2_program_manual_trigger, > + .setup_manual_trigger = optc2_setup_manual_trigger, > + .get_hw_timing = optc1_get_hw_timing, > +}; > + > +void dcn32_timing_generator_init(struct optc *optc1) > +{ > + optc1->base.funcs = &dcn32_tg_funcs; > + > + optc1->max_h_total = optc1->tg_mask->OTG_H_TOTAL + 1; > + optc1->max_v_total = optc1->tg_mask->OTG_V_TOTAL + 1; > + > + optc1->min_h_blank = 32; > + optc1->min_v_blank = 3; > + optc1->min_v_blank_interlace = 5; > + optc1->min_h_sync_width = 4; > + optc1->min_v_sync_width = 1; > +} > + > diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c > index f79dd40f8d811..b196b1f38c185 100644 > --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c > +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c > @@ -30,6 +30,7 @@ > #include "dchubbub.h" > #include "dcn20/dcn20_resource.h" > #include "dcn21/dcn21_resource.h" > +#include "clk_mgr/dcn21/rn_clk_mgr.h" > > #include "dcn20_fpu.h" > > @@ -42,6 +43,9 @@ > #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) > #endif > > +/* Constant */ > +#define LPDDR_MEM_RETRAIN_LATENCY 4.977 /* Number obtained from LPDDR4 Training Counter Requirement doc */ > + > /** > * DOC: DCN2x FPU manipulation Overview > * > @@ -650,6 +654,228 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { > .num_states = 8 > }; > > +struct wm_table ddr4_wm_table_gs = { > + .entries = { > + { > + .wm_inst = WM_A, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 7.09, > + .sr_enter_plus_exit_time_us = 8.14, > + .valid = true, > + }, > + { > + .wm_inst = WM_B, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 10.12, > + .sr_enter_plus_exit_time_us = 11.48, > + .valid = true, > + }, > + { > + .wm_inst = WM_C, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 10.12, > + .sr_enter_plus_exit_time_us = 11.48, > + .valid = true, > + }, > + { > + .wm_inst = WM_D, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 10.12, > + .sr_enter_plus_exit_time_us = 11.48, > + .valid = true, > + }, > + } > +}; > + > +struct wm_table lpddr4_wm_table_gs = { > + .entries = { > + { > + .wm_inst = WM_A, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 5.32, > + .sr_enter_plus_exit_time_us = 6.38, > + .valid = true, > + }, > + { > + .wm_inst = WM_B, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 9.82, > + .sr_enter_plus_exit_time_us = 11.196, > + .valid = true, > + }, > + { > + .wm_inst = WM_C, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 9.89, > + .sr_enter_plus_exit_time_us = 11.24, > + .valid = true, > + }, > + { > + .wm_inst = WM_D, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 9.748, > + .sr_enter_plus_exit_time_us = 11.102, > + .valid = true, > + }, > + } > +}; > + > +struct wm_table lpddr4_wm_table_with_disabled_ppt = { > + .entries = { > + { > + .wm_inst = WM_A, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 8.32, > + .sr_enter_plus_exit_time_us = 9.38, > + .valid = true, > + }, > + { > + .wm_inst = WM_B, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 9.82, > + .sr_enter_plus_exit_time_us = 11.196, > + .valid = true, > + }, > + { > + .wm_inst = WM_C, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 9.89, > + .sr_enter_plus_exit_time_us = 11.24, > + .valid = true, > + }, > + { > + .wm_inst = WM_D, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 9.748, > + .sr_enter_plus_exit_time_us = 11.102, > + .valid = true, > + }, > + } > +}; > + > +struct wm_table ddr4_wm_table_rn = { > + .entries = { > + { > + .wm_inst = WM_A, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 11.90, > + .sr_enter_plus_exit_time_us = 12.80, > + .valid = true, > + }, > + { > + .wm_inst = WM_B, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 13.18, > + .sr_enter_plus_exit_time_us = 14.30, > + .valid = true, > + }, > + { > + .wm_inst = WM_C, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 13.18, > + .sr_enter_plus_exit_time_us = 14.30, > + .valid = true, > + }, > + { > + .wm_inst = WM_D, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 13.18, > + .sr_enter_plus_exit_time_us = 14.30, > + .valid = true, > + }, > + } > +}; > + > +struct wm_table ddr4_1R_wm_table_rn = { > + .entries = { > + { > + .wm_inst = WM_A, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 13.90, > + .sr_enter_plus_exit_time_us = 14.80, > + .valid = true, > + }, > + { > + .wm_inst = WM_B, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 13.90, > + .sr_enter_plus_exit_time_us = 14.80, > + .valid = true, > + }, > + { > + .wm_inst = WM_C, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 13.90, > + .sr_enter_plus_exit_time_us = 14.80, > + .valid = true, > + }, > + { > + .wm_inst = WM_D, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 13.90, > + .sr_enter_plus_exit_time_us = 14.80, > + .valid = true, > + }, > + } > +}; > + > +struct wm_table lpddr4_wm_table_rn = { > + .entries = { > + { > + .wm_inst = WM_A, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 7.32, > + .sr_enter_plus_exit_time_us = 8.38, > + .valid = true, > + }, > + { > + .wm_inst = WM_B, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 9.82, > + .sr_enter_plus_exit_time_us = 11.196, > + .valid = true, > + }, > + { > + .wm_inst = WM_C, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 9.89, > + .sr_enter_plus_exit_time_us = 11.24, > + .valid = true, > + }, > + { > + .wm_inst = WM_D, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 9.748, > + .sr_enter_plus_exit_time_us = 11.102, > + .valid = true, > + }, > + } > +}; > + > void dcn20_populate_dml_writeback_from_context(struct dc *dc, > struct resource_context *res_ctx, > display_e2e_pipe_params_st *pipes) > @@ -2036,3 +2262,100 @@ void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params > > dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21); > } > + > +void dcn21_clk_mgr_set_bw_params_wm_table(struct clk_bw_params *bw_params) > +{ > + dc_assert_fp_enabled(); > + > + bw_params->wm_table.entries[WM_D].pstate_latency_us = LPDDR_MEM_RETRAIN_LATENCY; > + bw_params->wm_table.entries[WM_D].wm_inst = WM_D; > + bw_params->wm_table.entries[WM_D].wm_type = WM_TYPE_RETRAINING; > + bw_params->wm_table.entries[WM_D].valid = true; > +} > + > +void dcn201_populate_dml_writeback_from_context_fpu(struct dc *dc, > + struct resource_context *res_ctx, > + display_e2e_pipe_params_st *pipes) > +{ > + int pipe_cnt, i, j; > + double max_calc_writeback_dispclk; > + double writeback_dispclk; > + struct writeback_st dout_wb; > + > + dc_assert_fp_enabled(); > + > + for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { > + struct dc_stream_state *stream = res_ctx->pipe_ctx[i].stream; > + > + if (!stream) > + continue; > + max_calc_writeback_dispclk = 0; > + > + /* Set writeback information */ > + pipes[pipe_cnt].dout.wb_enable = 0; > + pipes[pipe_cnt].dout.num_active_wb = 0; > + for (j = 0; j < stream->num_wb_info; j++) { > + struct dc_writeback_info *wb_info = &stream->writeback_info[j]; > + > + if (wb_info->wb_enabled && wb_info->writeback_source_plane && > + (wb_info->writeback_source_plane == res_ctx->pipe_ctx[i].plane_state)) { > + pipes[pipe_cnt].dout.wb_enable = 1; > + pipes[pipe_cnt].dout.num_active_wb++; > + dout_wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_en ? > + wb_info->dwb_params.cnv_params.crop_height : > + wb_info->dwb_params.cnv_params.src_height; > + dout_wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_en ? > + wb_info->dwb_params.cnv_params.crop_width : > + wb_info->dwb_params.cnv_params.src_width; > + dout_wb.wb_dst_width = wb_info->dwb_params.dest_width; > + dout_wb.wb_dst_height = wb_info->dwb_params.dest_height; > + dout_wb.wb_htaps_luma = wb_info->dwb_params.scaler_taps.h_taps; > + dout_wb.wb_vtaps_luma = wb_info->dwb_params.scaler_taps.v_taps;; > + dout_wb.wb_htaps_chroma = wb_info->dwb_params.scaler_taps.h_taps_c; > + dout_wb.wb_vtaps_chroma = wb_info->dwb_params.scaler_taps.v_taps_c; > + dout_wb.wb_hratio = wb_info->dwb_params.cnv_params.crop_en ? > + (double)wb_info->dwb_params.cnv_params.crop_width / > + (double)wb_info->dwb_params.dest_width : > + (double)wb_info->dwb_params.cnv_params.src_width / > + (double)wb_info->dwb_params.dest_width; > + dout_wb.wb_vratio = wb_info->dwb_params.cnv_params.crop_en ? > + (double)wb_info->dwb_params.cnv_params.crop_height / > + (double)wb_info->dwb_params.dest_height : > + (double)wb_info->dwb_params.cnv_params.src_height / > + (double)wb_info->dwb_params.dest_height; > + if (wb_info->dwb_params.out_format == dwb_scaler_mode_yuv420) { > + if (wb_info->dwb_params.output_depth == DWB_OUTPUT_PIXEL_DEPTH_8BPC) > + dout_wb.wb_pixel_format = dm_420_8; > + else > + dout_wb.wb_pixel_format = dm_420_10; > + } else > + dout_wb.wb_pixel_format = dm_444_32; > + > + /* Workaround for cases where multiple writebacks are connected to same plane > + * In which case, need to compute worst case and set the associated writeback parameters > + * This workaround is necessary due to DML computation assuming only 1 set of writeback > + * parameters per pipe */ > + writeback_dispclk = CalculateWriteBackDISPCLK( > + dout_wb.wb_pixel_format, > + pipes[pipe_cnt].pipe.dest.pixel_rate_mhz, > + dout_wb.wb_hratio, > + dout_wb.wb_vratio, > + dout_wb.wb_htaps_luma, > + dout_wb.wb_vtaps_luma, > + dout_wb.wb_htaps_chroma, > + dout_wb.wb_vtaps_chroma, > + dout_wb.wb_dst_width, > + pipes[pipe_cnt].pipe.dest.htotal, > + 2); > + > + if (writeback_dispclk > max_calc_writeback_dispclk) { > + max_calc_writeback_dispclk = writeback_dispclk; > + pipes[pipe_cnt].dout.wb = dout_wb; > + } > + } > + } > + > + pipe_cnt++; > + } > + > +} > diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h > index aa892193e4854..c51badf7b68a9 100644 > --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h > +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h > @@ -82,4 +82,10 @@ bool dcn21_validate_bandwidth_fp(struct dc *dc, > bool fast_validate); > void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params); > > +void dcn21_clk_mgr_set_bw_params_wm_table(struct clk_bw_params *bw_params); > + > +void dcn201_populate_dml_writeback_from_context_fpu(struct dc *dc, > + struct resource_context *res_ctx, > + display_e2e_pipe_params_st *pipes); > + > #endif /* __DCN20_FPU_H__ */ > diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c > index 574676a0711ae..8bc1bc55e6352 100644 > --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c > +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c > @@ -29,7 +29,7 @@ > #include "dcn20/dcn20_resource.h" > #include "dcn30/dcn30_resource.h" > > - > +#include "clk_mgr/dcn30/dcn30_smu11_driver_if.h" > #include "display_mode_vba_30.h" > #include "dcn30_fpu.h" > > @@ -614,4 +614,85 @@ void dcn30_fpu_update_bw_bounding_box(struct dc *dc, > > } > > +void dcn3_fpu_build_wm_range_table(struct clk_mgr *base) > +{ > + /* defaults */ > + double pstate_latency_us = base->ctx->dc->dml.soc.dram_clock_change_latency_us; > + double sr_exit_time_us = base->ctx->dc->dml.soc.sr_exit_time_us; > + double sr_enter_plus_exit_time_us = base->ctx->dc->dml.soc.sr_enter_plus_exit_time_us; > + uint16_t min_uclk_mhz = base->bw_params->clk_table.entries[0].memclk_mhz; > + > + dc_assert_fp_enabled(); > + > + /* Set A - Normal - default values*/ > + base->bw_params->wm_table.nv_entries[WM_A].valid = true; > + base->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us = pstate_latency_us; > + base->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us = sr_exit_time_us; > + base->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; > + base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE; > + base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_dcfclk = 0; > + base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_dcfclk = 0xFFFF; > + base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_uclk = min_uclk_mhz; > + base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_uclk = 0xFFFF; > + > + /* Set B - Performance - higher minimum clocks */ > +// base->bw_params->wm_table.nv_entries[WM_B].valid = true; > +// base->bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us = pstate_latency_us; > +// base->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us = sr_exit_time_us; > +// base->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; > +// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE; > +// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_dcfclk = TUNED VALUE; > +// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_dcfclk = 0xFFFF; > +// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_uclk = TUNED VALUE; > +// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_uclk = 0xFFFF; > + > + /* Set C - Dummy P-State - P-State latency set to "dummy p-state" value */ > + base->bw_params->wm_table.nv_entries[WM_C].valid = true; > + base->bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 0; > + base->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us; > + base->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; > + base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.wm_type = WATERMARKS_DUMMY_PSTATE; > + base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_dcfclk = 0; > + base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_dcfclk = 0xFFFF; > + base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz; > + base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF; > + base->bw_params->dummy_pstate_table[0].dram_speed_mts = 1600; > + base->bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 38; > + base->bw_params->dummy_pstate_table[1].dram_speed_mts = 8000; > + base->bw_params->dummy_pstate_table[1].dummy_pstate_latency_us = 9; > + base->bw_params->dummy_pstate_table[2].dram_speed_mts = 10000; > + base->bw_params->dummy_pstate_table[2].dummy_pstate_latency_us = 8; > + base->bw_params->dummy_pstate_table[3].dram_speed_mts = 16000; > + base->bw_params->dummy_pstate_table[3].dummy_pstate_latency_us = 5; > + > + /* Set D - MALL - SR enter and exit times adjusted for MALL */ > + base->bw_params->wm_table.nv_entries[WM_D].valid = true; > + base->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us = pstate_latency_us; > + base->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us = 2; > + base->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us = 4; > + base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.wm_type = WATERMARKS_MALL; > + base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_dcfclk = 0; > + base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_dcfclk = 0xFFFF; > + base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_uclk = min_uclk_mhz; > + base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_uclk = 0xFFFF; > +} > > +void patch_dcn30_soc_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *dcn3_0_ip) > +{ > + dc_assert_fp_enabled(); > + > + if (dc->ctx->dc_bios->funcs->get_soc_bb_info) { > + struct bp_soc_bb_info bb_info = {0}; > + > + if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) { > + if (bb_info.dram_clock_change_latency_100ns > 0) > + dcn3_0_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10; > + > + if (bb_info.dram_sr_enter_exit_latency_100ns > 0) > + dcn3_0_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10; > + > + if (bb_info.dram_sr_exit_latency_100ns > 0) > + dcn3_0_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10; > + } > + } > +} > diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h > index dedfe7b5f1731..595ce88cfa69a 100644 > --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h > +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h > @@ -63,5 +63,8 @@ void dcn30_fpu_update_bw_bounding_box(struct dc *dc, > unsigned int *dcfclk_mhz, > unsigned int *dram_speed_mts); > > +void dcn3_fpu_build_wm_range_table(struct clk_mgr *base); > + > +void patch_dcn30_soc_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *dcn3_0_ip); > > #endif /* __DCN30_FPU_H__*/ > diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c > index 0a7a338649731..e391e4e26d610 100644 > --- a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c > +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c > @@ -26,6 +26,7 @@ > #include "clk_mgr.h" > #include "dcn20/dcn20_resource.h" > #include "dcn301/dcn301_resource.h" > +#include "clk_mgr/dcn301/vg_clk_mgr.h" > > #include "dml/dcn20/dcn20_fpu.h" > #include "dcn301_fpu.h" > @@ -214,6 +215,80 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc = { > .urgent_latency_adjustment_fabric_clock_reference_mhz = 0, > }; > > +struct wm_table ddr4_wm_table = { > + .entries = { > + { > + .wm_inst = WM_A, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 6.09, > + .sr_enter_plus_exit_time_us = 7.14, > + .valid = true, > + }, > + { > + .wm_inst = WM_B, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 10.12, > + .sr_enter_plus_exit_time_us = 11.48, > + .valid = true, > + }, > + { > + .wm_inst = WM_C, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 10.12, > + .sr_enter_plus_exit_time_us = 11.48, > + .valid = true, > + }, > + { > + .wm_inst = WM_D, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.72, > + .sr_exit_time_us = 10.12, > + .sr_enter_plus_exit_time_us = 11.48, > + .valid = true, > + }, > + } > +}; > + > +struct wm_table lpddr5_wm_table = { > + .entries = { > + { > + .wm_inst = WM_A, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 13.5, > + .sr_enter_plus_exit_time_us = 16.5, > + .valid = true, > + }, > + { > + .wm_inst = WM_B, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 13.5, > + .sr_enter_plus_exit_time_us = 16.5, > + .valid = true, > + }, > + { > + .wm_inst = WM_C, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 13.5, > + .sr_enter_plus_exit_time_us = 16.5, > + .valid = true, > + }, > + { > + .wm_inst = WM_D, > + .wm_type = WM_TYPE_PSTATE_CHG, > + .pstate_latency_us = 11.65333, > + .sr_exit_time_us = 13.5, > + .sr_enter_plus_exit_time_us = 16.5, > + .valid = true, > + }, > + } > +}; > + > static void calculate_wm_set_for_vlevel(int vlevel, > struct wm_range_table_entry *table_entry, > struct dcn_watermarks *wm_set, > diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c > index 54db2eca9e6b7..47e6bc934bad4 100644 > --- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c > +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c > @@ -25,6 +25,9 @@ > > #include "resource.h" > #include "clk_mgr.h" > +#include "dcn31/dcn31_resource.h" > +#include "dcn315/dcn315_resource.h" > +#include "dcn316/dcn316_resource.h" > > #include "dml/dcn20/dcn20_fpu.h" > #include "dcn31_fpu.h" > @@ -114,7 +117,7 @@ struct _vcs_dpi_ip_params_st dcn3_1_ip = { > .dcc_supported = true, > }; > > -struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc = { > +static struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc = { > /*TODO: correct dispclk/dppclk voltage level determination*/ > .clock_limits = { > { > @@ -259,7 +262,7 @@ struct _vcs_dpi_ip_params_st dcn3_15_ip = { > .dcc_supported = true, > }; > > -struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = { > +static struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = { > .sr_exit_time_us = 9.0, > .sr_enter_plus_exit_time_us = 11.0, > .sr_exit_z8_time_us = 50.0, > @@ -354,7 +357,7 @@ struct _vcs_dpi_ip_params_st dcn3_16_ip = { > .dcc_supported = true, > }; > > -struct _vcs_dpi_soc_bounding_box_st dcn3_16_soc = { > +static struct _vcs_dpi_soc_bounding_box_st dcn3_16_soc = { > /*TODO: correct dispclk/dppclk voltage level determination*/ > .clock_limits = { > { > diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h > index 554d2e33bd7f1..56f34dba3cb2a 100644 > --- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h > +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h > @@ -298,8 +298,6 @@ struct timing_generator_funcs { > int group_idx, > uint32_t gsl_ready_signal); > void (*set_out_mux)(struct timing_generator *tg, enum otg_out_mux_dest dest); > - void (*set_vrr_m_const)(struct timing_generator *optc, > - double vtotal_avg); > void (*set_drr_trigger_window)(struct timing_generator *optc, > uint32_t window_start, uint32_t window_end); > void (*set_vtotal_change_limit)(struct timing_generator *optc, >
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile index 8178719176329..ffd005c460fcd 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile @@ -107,12 +107,6 @@ AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN201) ############################################################################### CLK_MGR_DCN21 = rn_clk_mgr.o rn_clk_mgr_vbios_smu.o -# prevent build errors regarding soft-float vs hard-float FP ABI tags -# this code is currently unused on ppc64, as it applies to Renoir APUs only -ifdef CONFIG_PPC64 -CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn21/rn_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) -endif - AMD_DAL_CLK_MGR_DCN21 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21)) AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) @@ -121,12 +115,6 @@ AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) ############################################################################### CLK_MGR_DCN30 = dcn30_clk_mgr.o dcn30_clk_mgr_smu_msg.o -# prevent build errors regarding soft-float vs hard-float FP ABI tags -# this code is currently unused on ppc64, as it applies to VanGogh APUs only -ifdef CONFIG_PPC64 -CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn30/dcn30_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) -endif - AMD_DAL_CLK_MGR_DCN30 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn30/,$(CLK_MGR_DCN30)) AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN30) @@ -135,12 +123,6 @@ AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN30) ############################################################################### CLK_MGR_DCN301 = vg_clk_mgr.o dcn301_smu.o -# prevent build errors regarding soft-float vs hard-float FP ABI tags -# this code is currently unused on ppc64, as it applies to VanGogh APUs only -ifdef CONFIG_PPC64 -CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn301/vg_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) -endif - AMD_DAL_CLK_MGR_DCN301 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn301/,$(CLK_MGR_DCN301)) AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN301) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c index cf1b5f354ae99..0202dc682682b 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c @@ -26,10 +26,9 @@ #include "dccg.h" #include "clk_mgr_internal.h" - #include "dcn20/dcn20_clk_mgr.h" #include "rn_clk_mgr.h" - +#include "dml/dcn20/dcn20_fpu.h" #include "dce100/dce_clk_mgr.h" #include "rn_clk_mgr_vbios_smu.h" @@ -45,7 +44,6 @@ /* Constants */ -#define LPDDR_MEM_RETRAIN_LATENCY 4.977 /* Number obtained from LPDDR4 Training Counter Requirement doc */ #define SMU_VER_55_51_0 0x373300 /* SMU Version that is able to set DISPCLK below 100MHz */ /* Macros */ @@ -613,228 +611,6 @@ static struct clk_bw_params rn_bw_params = { }; -static struct wm_table ddr4_wm_table_gs = { - .entries = { - { - .wm_inst = WM_A, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 7.09, - .sr_enter_plus_exit_time_us = 8.14, - .valid = true, - }, - { - .wm_inst = WM_B, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 10.12, - .sr_enter_plus_exit_time_us = 11.48, - .valid = true, - }, - { - .wm_inst = WM_C, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 10.12, - .sr_enter_plus_exit_time_us = 11.48, - .valid = true, - }, - { - .wm_inst = WM_D, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 10.12, - .sr_enter_plus_exit_time_us = 11.48, - .valid = true, - }, - } -}; - -static struct wm_table lpddr4_wm_table_gs = { - .entries = { - { - .wm_inst = WM_A, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 5.32, - .sr_enter_plus_exit_time_us = 6.38, - .valid = true, - }, - { - .wm_inst = WM_B, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 9.82, - .sr_enter_plus_exit_time_us = 11.196, - .valid = true, - }, - { - .wm_inst = WM_C, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 9.89, - .sr_enter_plus_exit_time_us = 11.24, - .valid = true, - }, - { - .wm_inst = WM_D, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 9.748, - .sr_enter_plus_exit_time_us = 11.102, - .valid = true, - }, - } -}; - -static struct wm_table lpddr4_wm_table_with_disabled_ppt = { - .entries = { - { - .wm_inst = WM_A, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 8.32, - .sr_enter_plus_exit_time_us = 9.38, - .valid = true, - }, - { - .wm_inst = WM_B, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 9.82, - .sr_enter_plus_exit_time_us = 11.196, - .valid = true, - }, - { - .wm_inst = WM_C, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 9.89, - .sr_enter_plus_exit_time_us = 11.24, - .valid = true, - }, - { - .wm_inst = WM_D, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 9.748, - .sr_enter_plus_exit_time_us = 11.102, - .valid = true, - }, - } -}; - -static struct wm_table ddr4_wm_table_rn = { - .entries = { - { - .wm_inst = WM_A, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 11.90, - .sr_enter_plus_exit_time_us = 12.80, - .valid = true, - }, - { - .wm_inst = WM_B, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 13.18, - .sr_enter_plus_exit_time_us = 14.30, - .valid = true, - }, - { - .wm_inst = WM_C, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 13.18, - .sr_enter_plus_exit_time_us = 14.30, - .valid = true, - }, - { - .wm_inst = WM_D, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 13.18, - .sr_enter_plus_exit_time_us = 14.30, - .valid = true, - }, - } -}; - -static struct wm_table ddr4_1R_wm_table_rn = { - .entries = { - { - .wm_inst = WM_A, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 13.90, - .sr_enter_plus_exit_time_us = 14.80, - .valid = true, - }, - { - .wm_inst = WM_B, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 13.90, - .sr_enter_plus_exit_time_us = 14.80, - .valid = true, - }, - { - .wm_inst = WM_C, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 13.90, - .sr_enter_plus_exit_time_us = 14.80, - .valid = true, - }, - { - .wm_inst = WM_D, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 13.90, - .sr_enter_plus_exit_time_us = 14.80, - .valid = true, - }, - } -}; - -static struct wm_table lpddr4_wm_table_rn = { - .entries = { - { - .wm_inst = WM_A, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 7.32, - .sr_enter_plus_exit_time_us = 8.38, - .valid = true, - }, - { - .wm_inst = WM_B, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 9.82, - .sr_enter_plus_exit_time_us = 11.196, - .valid = true, - }, - { - .wm_inst = WM_C, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 9.89, - .sr_enter_plus_exit_time_us = 11.24, - .valid = true, - }, - { - .wm_inst = WM_D, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 9.748, - .sr_enter_plus_exit_time_us = 11.102, - .valid = true, - }, - } -}; - static unsigned int find_socclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage) { int i; @@ -914,12 +690,10 @@ static void rn_clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params /* * WM set D will be re-purposed for memory retraining */ - bw_params->wm_table.entries[WM_D].pstate_latency_us = LPDDR_MEM_RETRAIN_LATENCY; - bw_params->wm_table.entries[WM_D].wm_inst = WM_D; - bw_params->wm_table.entries[WM_D].wm_type = WM_TYPE_RETRAINING; - bw_params->wm_table.entries[WM_D].valid = true; + DC_FP_START(); + dcn21_clk_mgr_set_bw_params_wm_table(bw_params); + DC_FP_END(); } - } void rn_clk_mgr_construct( diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h index e4322fa5475b6..2e088c5171b28 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h @@ -29,6 +29,13 @@ #include "clk_mgr.h" #include "dm_pp_smu.h" +extern struct wm_table ddr4_wm_table_gs; +extern struct wm_table lpddr4_wm_table_gs; +extern struct wm_table lpddr4_wm_table_with_disabled_ppt; +extern struct wm_table ddr4_wm_table_rn; +extern struct wm_table ddr4_1R_wm_table_rn; +extern struct wm_table lpddr4_wm_table_rn; + struct rn_clk_registers { uint32_t CLK1_CLK0_CURRENT_CNT; /* DPREFCLK */ }; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c index 5ed6a93d1708c..e34a0e81facb6 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c @@ -29,6 +29,7 @@ #include "dcn20/dcn20_clk_mgr.h" #include "dce100/dce_clk_mgr.h" #include "dcn30/dcn30_clk_mgr.h" +#include "dml/dcn30/dcn30_fpu.h" #include "reg_helper.h" #include "core_types.h" #include "dm_helpers.h" @@ -97,57 +98,11 @@ static void dcn3_init_single_clock(struct clk_mgr_internal *clk_mgr, uint32_t cl } } -static noinline void dcn3_build_wm_range_table(struct clk_mgr_internal *clk_mgr) +static void dcn3_build_wm_range_table(struct clk_mgr_internal *clk_mgr) { - /* defaults */ - double pstate_latency_us = clk_mgr->base.ctx->dc->dml.soc.dram_clock_change_latency_us; - double sr_exit_time_us = clk_mgr->base.ctx->dc->dml.soc.sr_exit_time_us; - double sr_enter_plus_exit_time_us = clk_mgr->base.ctx->dc->dml.soc.sr_enter_plus_exit_time_us; - uint16_t min_uclk_mhz = clk_mgr->base.bw_params->clk_table.entries[0].memclk_mhz; - - /* Set A - Normal - default values*/ - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].valid = true; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us = pstate_latency_us; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us = sr_exit_time_us; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_dcfclk = 0; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_dcfclk = 0xFFFF; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_uclk = min_uclk_mhz; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_uclk = 0xFFFF; - - /* Set B - Performance - higher minimum clocks */ -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].valid = true; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us = pstate_latency_us; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us = sr_exit_time_us; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_dcfclk = TUNED VALUE; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_dcfclk = 0xFFFF; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_uclk = TUNED VALUE; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_uclk = 0xFFFF; - - /* Set C - Dummy P-State - P-State latency set to "dummy p-state" value */ - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].valid = true; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = clk_mgr->base.ctx->dc->dml.soc.dummy_pstate_latency_us; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.wm_type = WATERMARKS_DUMMY_PSTATE; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_dcfclk = 0; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_dcfclk = 0xFFFF; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF; - - /* Set D - MALL - SR enter and exit times adjusted for MALL */ - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].valid = true; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us = pstate_latency_us; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us = 2; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us = 4; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.wm_type = WATERMARKS_MALL; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_dcfclk = 0; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_dcfclk = 0xFFFF; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_uclk = min_uclk_mhz; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_uclk = 0xFFFF; + DC_FP_START(); + dcn3_fpu_build_wm_range_table(&clk_mgr->base); + DC_FP_END(); } void dcn3_init_clocks(struct clk_mgr *clk_mgr_base) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c index f310b0d25a076..24715ca2fa944 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c @@ -32,6 +32,9 @@ // For dcn20_update_clocks_update_dpp_dto #include "dcn20/dcn20_clk_mgr.h" +// For DML FPU code +#include "dml/dcn20/dcn20_fpu.h" + #include "vg_clk_mgr.h" #include "dcn301_smu.h" #include "reg_helper.h" @@ -526,81 +529,6 @@ static struct clk_bw_params vg_bw_params = { }; -static struct wm_table ddr4_wm_table = { - .entries = { - { - .wm_inst = WM_A, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 6.09, - .sr_enter_plus_exit_time_us = 7.14, - .valid = true, - }, - { - .wm_inst = WM_B, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 10.12, - .sr_enter_plus_exit_time_us = 11.48, - .valid = true, - }, - { - .wm_inst = WM_C, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 10.12, - .sr_enter_plus_exit_time_us = 11.48, - .valid = true, - }, - { - .wm_inst = WM_D, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, - .sr_exit_time_us = 10.12, - .sr_enter_plus_exit_time_us = 11.48, - .valid = true, - }, - } -}; - -static struct wm_table lpddr5_wm_table = { - .entries = { - { - .wm_inst = WM_A, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 13.5, - .sr_enter_plus_exit_time_us = 16.5, - .valid = true, - }, - { - .wm_inst = WM_B, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 13.5, - .sr_enter_plus_exit_time_us = 16.5, - .valid = true, - }, - { - .wm_inst = WM_C, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 13.5, - .sr_enter_plus_exit_time_us = 16.5, - .valid = true, - }, - { - .wm_inst = WM_D, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, - .sr_exit_time_us = 13.5, - .sr_enter_plus_exit_time_us = 16.5, - .valid = true, - }, - } -}; - - static unsigned int find_dcfclk_for_voltage(const struct vg_dpm_clocks *clock_table, unsigned int voltage) { @@ -670,10 +598,9 @@ static void vg_clk_mgr_helper_populate_bw_params( /* * WM set D will be re-purposed for memory retraining */ - bw_params->wm_table.entries[WM_D].pstate_latency_us = LPDDR_MEM_RETRAIN_LATENCY; - bw_params->wm_table.entries[WM_D].wm_inst = WM_D; - bw_params->wm_table.entries[WM_D].wm_type = WM_TYPE_RETRAINING; - bw_params->wm_table.entries[WM_D].valid = true; + DC_FP_START(); + dcn21_clk_mgr_set_bw_params_wm_table(bw_params); + DC_FP_END(); } } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h index 7255477307f13..75884f5729891 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h @@ -29,6 +29,9 @@ struct watermarks; +extern struct wm_table ddr4_wm_table; +extern struct wm_table lpddr5_wm_table; + struct smu_watermark_set { struct watermarks *wm_set; union large_integer mc_address; diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/Makefile b/drivers/gpu/drm/amd/display/dc/dcn201/Makefile index f68038ceb1b15..5c9ce2cebb0f6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn201/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn201/Makefile @@ -6,31 +6,6 @@ DCN201 = dcn201_init.o dcn201_resource.o dcn201_hwseq.o \ dcn201_mpc.o dcn201_hubp.o dcn201_opp.o dcn201_optc.o dcn201_dpp.o \ dcn201_dccg.o dcn201_link_encoder.o -ifdef CONFIG_X86 -CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o := -mhard-float -msse -endif - -ifdef CONFIG_PPC64 -CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o := -mhard-float -maltivec -endif - -ifdef CONFIG_CC_IS_GCC -ifeq ($(call cc-ifversion, -lt, 0701, y), y) -IS_OLD_GCC = 1 -endif -CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o += -mhard-float -endif - -ifdef CONFIG_X86 -ifdef IS_OLD_GCC -# Stack alignment mismatch, proceed with caution. -# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 -# (8B stack alignment). -CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o += -mpreferred-stack-boundary=4 -else -CFLAGS_$(AMDDALPATH)/dc/dcn201/dcn201_resource.o += -msse2 -endif -endif AMD_DAL_DCN201 = $(addprefix $(AMDDALPATH)/dc/dcn201/,$(DCN201)) AMD_DISPLAY_FILES += $(AMD_DAL_DCN201) diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c index 0bb7d3dd53fa4..e549a79f3fe1a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c @@ -1036,6 +1036,14 @@ static bool dcn201_get_dcc_compression_cap(const struct dc *dc, output); } +static void dcn201_populate_dml_writeback_from_context(struct dc *dc, + struct resource_context *res_ctx, + display_e2e_pipe_params_st *pipes) +{ + DC_FP_START(); + dcn201_populate_dml_writeback_from_context_fpu(dc, res_ctx, pipes); + DC_FP_END(); +} static void dcn201_destroy_resource_pool(struct resource_pool **pool) { @@ -1067,8 +1075,8 @@ static struct resource_funcs dcn201_res_pool_funcs = { .add_dsc_to_stream_resource = NULL, .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, .acquire_idle_pipe_for_layer = dcn201_acquire_idle_pipe_for_layer, + .populate_dml_writeback_from_context = dcn201_populate_dml_writeback_from_context, .patch_unknown_plane_state = dcn20_patch_unknown_plane_state, - .populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context, .set_mcif_arb_params = dcn20_set_mcif_arb_params, .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/Makefile b/drivers/gpu/drm/amd/display/dc/dcn30/Makefile index dfd77b3cc84d8..b7c2ae9ddfda3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn30/Makefile @@ -30,38 +30,6 @@ DCN30 = dcn30_init.o dcn30_hubbub.o dcn30_hubp.o dcn30_dpp.o dcn30_optc.o \ dcn30_dpp_cm.o dcn30_dwb_cm.o dcn30_cm_common.o dcn30_mmhubbub.o \ dcn30_dio_link_encoder.o dcn30_resource.o - -ifdef CONFIG_X86 -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -msse -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -msse -endif - -ifdef CONFIG_PPC64 -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -mhard-float -maltivec -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -mhard-float -maltivec -endif - -ifdef CONFIG_CC_IS_GCC -ifeq ($(call cc-ifversion, -lt, 0701, y), y) -IS_OLD_GCC = 1 -endif -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o += -mhard-float -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o += -mhard-float -endif - -ifdef CONFIG_X86 -ifdef IS_OLD_GCC -# Stack alignment mismatch, proceed with caution. -# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 -# (8B stack alignment). -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o += -mpreferred-stack-boundary=4 -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o += -mpreferred-stack-boundary=4 -else -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o += -msse2 -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o += -msse2 -endif -endif - AMD_DAL_DCN30 = $(addprefix $(AMDDALPATH)/dc/dcn30/,$(DCN30)) AMD_DISPLAY_FILES += $(AMD_DAL_DCN30) diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c index b604fb26f288d..4c57c001fd23b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c @@ -186,14 +186,6 @@ void optc3_set_dsc_config(struct timing_generator *optc, } -void optc3_set_vrr_m_const(struct timing_generator *optc, - double vtotal_avg) -{ - DC_FP_START(); - optc3_fpu_set_vrr_m_const(optc, vtotal_avg); - DC_FP_END(); -} - void optc3_set_odm_bypass(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h index 97f11ef6e9f02..bd5743b73fa5b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h @@ -320,9 +320,6 @@ void optc3_lock_doublebuffer_enable(struct timing_generator *optc); void optc3_lock_doublebuffer_disable(struct timing_generator *optc); -void optc3_set_vrr_m_const(struct timing_generator *optc, - double vtotal_avg); - void optc3_set_drr_trigger_window(struct timing_generator *optc, uint32_t window_start, uint32_t window_end); diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 1c1a67c4cec1c..19ef63b13fe43 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -1520,26 +1520,11 @@ static bool init_soc_bounding_box(struct dc *dc, loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator; loaded_ip->max_num_dpp = pool->base.pipe_count; loaded_ip->clamp_min_dcfclk = dc->config.clamp_min_dcfclk; - - DC_FP_START(); dcn20_patch_bounding_box(dc, loaded_bb); + DC_FP_START(); + patch_dcn30_soc_bounding_box(dc, &dcn3_0_soc); DC_FP_END(); - if (dc->ctx->dc_bios->funcs->get_soc_bb_info) { - struct bp_soc_bb_info bb_info = {0}; - - if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) { - if (bb_info.dram_clock_change_latency_100ns > 0) - dcn3_0_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10; - - if (bb_info.dram_sr_enter_exit_latency_100ns > 0) - dcn3_0_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10; - - if (bb_info.dram_sr_exit_latency_100ns > 0) - dcn3_0_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10; - } - } - return true; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/Makefile b/drivers/gpu/drm/amd/display/dc/dcn302/Makefile index f9561d7f97a1d..ebd01cb467b79 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn302/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn302/Makefile @@ -7,25 +7,6 @@ DCN3_02 = dcn302_init.o dcn302_hwseq.o dcn302_resource.o -ifdef CONFIG_X86 -CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -msse -endif - -ifdef CONFIG_PPC64 -CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mhard-float -maltivec -endif - -ifdef CONFIG_X86 -ifdef IS_OLD_GCC -# Stack alignment mismatch, proceed with caution. -# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 -# (8B stack alignment). -CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o += -mpreferred-stack-boundary=4 -else -CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o += -msse2 -endif -endif - AMD_DAL_DCN3_02 = $(addprefix $(AMDDALPATH)/dc/dcn302/,$(DCN3_02)) AMD_DISPLAY_FILES += $(AMD_DAL_DCN3_02) diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c index 3d9f07d4770bf..fe21d33111729 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c @@ -1873,8 +1873,6 @@ static bool dcn31_resource_construct( struct dc_context *ctx = dc->ctx; struct irq_service_init_data init_data; - DC_FP_START(); - ctx->dc_bios->regs = &bios_regs; pool->base.res_cap = &res_cap_dcn31; @@ -2182,13 +2180,9 @@ static bool dcn31_resource_construct( dc->dcn_ip->max_num_dpp = dcn3_1_ip.max_num_dpp; - DC_FP_END(); - return true; create_fail: - - DC_FP_END(); dcn31_resource_destruct(pool); return false; diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h index 393458015d6a4..98ae95f378659 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h @@ -32,7 +32,6 @@ container_of(pool, struct dcn31_resource_pool, base) extern struct _vcs_dpi_ip_params_st dcn3_1_ip; -extern struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc; struct dcn31_resource_pool { struct resource_pool base; diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h index 39929fa67a510..22849eaa6f243 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h @@ -32,7 +32,6 @@ container_of(pool, struct dcn315_resource_pool, base) extern struct _vcs_dpi_ip_params_st dcn3_15_ip; -extern struct _vcs_dpi_ip_params_st dcn3_15_soc; struct dcn315_resource_pool { struct resource_pool base; diff --git a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h index 0dc5a6c13ae7d..aba6d634131b4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h @@ -32,7 +32,6 @@ container_of(pool, struct dcn316_resource_pool, base) extern struct _vcs_dpi_ip_params_st dcn3_16_ip; -extern struct _vcs_dpi_ip_params_st dcn3_16_soc; struct dcn316_resource_pool { struct resource_pool base; diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c new file mode 100644 index 0000000000000..eff1f4e17689c --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c @@ -0,0 +1,328 @@ +/* + * Copyright 2022 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include "dcn32_optc.h" + +#include "dcn30/dcn30_optc.h" +#include "dcn31/dcn31_optc.h" +#include "reg_helper.h" +#include "dc.h" +#include "dcn_calc_math.h" +#include "dc_dmub_srv.h" + +#define REG(reg)\ + optc1->tg_regs->reg + +#define CTX \ + optc1->base.ctx + +#undef FN +#define FN(reg_name, field_name) \ + optc1->tg_shift->field_name, optc1->tg_mask->field_name + +static void optc32_set_odm_combine(struct timing_generator *optc, int *opp_id, int opp_cnt, + struct dc_crtc_timing *timing) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + uint32_t memory_mask = 0; + int h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right; + int mpcc_hactive = h_active / opp_cnt; + /* Each memory instance is 2048x(32x2) bits to support half line of 4096 */ + int odm_mem_count = (h_active + 2047) / 2048; + + /* + * display <= 4k : 2 memories + 2 pipes + * 4k < display <= 8k : 4 memories + 2 pipes + * 8k < display <= 12k : 6 memories + 4 pipes + */ + if (opp_cnt == 4) { + if (odm_mem_count <= 2) + memory_mask = 0x3; + else if (odm_mem_count <= 4) + memory_mask = 0xf; + else + memory_mask = 0x3f; + } else { + if (odm_mem_count <= 2) + memory_mask = 0x1 << (opp_id[0] * 2) | 0x1 << (opp_id[1] * 2); + else if (odm_mem_count <= 4) + memory_mask = 0x3 << (opp_id[0] * 2) | 0x3 << (opp_id[1] * 2); + else + memory_mask = 0x77; + } + + REG_SET(OPTC_MEMORY_CONFIG, 0, + OPTC_MEM_SEL, memory_mask); + + if (opp_cnt == 2) { + REG_SET_3(OPTC_DATA_SOURCE_SELECT, 0, + OPTC_NUM_OF_INPUT_SEGMENT, 1, + OPTC_SEG0_SRC_SEL, opp_id[0], + OPTC_SEG1_SRC_SEL, opp_id[1]); + } else if (opp_cnt == 4) { + REG_SET_5(OPTC_DATA_SOURCE_SELECT, 0, + OPTC_NUM_OF_INPUT_SEGMENT, 3, + OPTC_SEG0_SRC_SEL, opp_id[0], + OPTC_SEG1_SRC_SEL, opp_id[1], + OPTC_SEG2_SRC_SEL, opp_id[2], + OPTC_SEG3_SRC_SEL, opp_id[3]); + } + + REG_UPDATE(OPTC_WIDTH_CONTROL, + OPTC_SEGMENT_WIDTH, mpcc_hactive); + + REG_UPDATE(OTG_H_TIMING_CNTL, + OTG_H_TIMING_DIV_MODE, opp_cnt - 1); + optc1->opp_count = opp_cnt; +} + +static void optc32_set_h_timing_div_manual_mode(struct timing_generator *optc, bool manual_mode) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + REG_UPDATE(OTG_H_TIMING_CNTL, + OTG_H_TIMING_DIV_MODE_MANUAL, manual_mode ? 1 : 0); +} +/** + * Enable CRTC + * Enable CRTC - call ASIC Control Object to enable Timing generator. + */ +static bool optc32_enable_crtc(struct timing_generator *optc) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + /* opp instance for OTG, 1 to 1 mapping and odm will adjust */ + REG_UPDATE(OPTC_DATA_SOURCE_SELECT, + OPTC_SEG0_SRC_SEL, optc->inst); + + /* VTG enable first is for HW workaround */ + REG_UPDATE(CONTROL, + VTG0_ENABLE, 1); + + REG_SEQ_START(); + + /* Enable CRTC */ + REG_UPDATE_2(OTG_CONTROL, + OTG_DISABLE_POINT_CNTL, 2, + OTG_MASTER_EN, 1); + + REG_SEQ_SUBMIT(); + REG_SEQ_WAIT_DONE(); + + return true; +} + +/* disable_crtc */ +static bool optc32_disable_crtc(struct timing_generator *optc) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + /* disable otg request until end of the first line + * in the vertical blank region + */ + REG_UPDATE(OTG_CONTROL, + OTG_MASTER_EN, 0); + + REG_UPDATE(CONTROL, + VTG0_ENABLE, 0); + + /* CRTC disabled, so disable clock. */ + REG_WAIT(OTG_CLOCK_CONTROL, + OTG_BUSY, 0, + 1, 100000); + + return true; +} + +void optc32_phantom_crtc_post_enable(struct timing_generator *optc) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + /* Disable immediately. */ + REG_UPDATE_2(OTG_CONTROL, OTG_DISABLE_POINT_CNTL, 0, OTG_MASTER_EN, 0); + + /* CRTC disabled, so disable clock. */ + REG_WAIT(OTG_CLOCK_CONTROL, OTG_BUSY, 0, 1, 100000); +} + +static void optc32_set_odm_bypass(struct timing_generator *optc, + const struct dc_crtc_timing *dc_crtc_timing) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + enum h_timing_div_mode h_div = H_TIMING_NO_DIV; + + REG_SET_5(OPTC_DATA_SOURCE_SELECT, 0, + OPTC_NUM_OF_INPUT_SEGMENT, 0, + OPTC_SEG0_SRC_SEL, optc->inst, + OPTC_SEG1_SRC_SEL, 0xf, + OPTC_SEG2_SRC_SEL, 0xf, + OPTC_SEG3_SRC_SEL, 0xf + ); + + h_div = optc1_is_two_pixels_per_containter(dc_crtc_timing); + REG_UPDATE(OTG_H_TIMING_CNTL, + OTG_H_TIMING_DIV_MODE, h_div); + + REG_SET(OPTC_MEMORY_CONFIG, 0, + OPTC_MEM_SEL, 0); + optc1->opp_count = 1; +} + +void optc32_setup_manual_trigger(struct timing_generator *optc) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + struct dc *dc = optc->ctx->dc; + + if (dc->caps.dmub_caps.mclk_sw && !dc->debug.disable_fams) + dc_dmub_srv_set_drr_manual_trigger_cmd(dc, optc->inst); + else { + /* + * MIN_MASK_EN is gone and MASK is now always enabled. + * + * To get it to it work with manual trigger we need to make sure + * we program the correct bit. + */ + REG_UPDATE_4(OTG_V_TOTAL_CONTROL, + OTG_V_TOTAL_MIN_SEL, 1, + OTG_V_TOTAL_MAX_SEL, 1, + OTG_FORCE_LOCK_ON_EVENT, 0, + OTG_SET_V_TOTAL_MIN_MASK, (1 << 1)); /* TRIGA */ + + // Setup manual flow control for EOF via TRIG_A + optc->funcs->setup_manual_trigger(optc); + } +} + +void optc32_set_drr( + struct timing_generator *optc, + const struct drr_params *params) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + if (params != NULL && + params->vertical_total_max > 0 && + params->vertical_total_min > 0) { + + if (params->vertical_total_mid != 0) { + + REG_SET(OTG_V_TOTAL_MID, 0, + OTG_V_TOTAL_MID, params->vertical_total_mid - 1); + + REG_UPDATE_2(OTG_V_TOTAL_CONTROL, + OTG_VTOTAL_MID_REPLACING_MAX_EN, 1, + OTG_VTOTAL_MID_FRAME_NUM, + (uint8_t)params->vertical_total_mid_frame_num); + + } + + optc->funcs->set_vtotal_min_max(optc, params->vertical_total_min - 1, params->vertical_total_max - 1); + optc32_setup_manual_trigger(optc); + } else { + REG_UPDATE_4(OTG_V_TOTAL_CONTROL, + OTG_SET_V_TOTAL_MIN_MASK, 0, + OTG_V_TOTAL_MIN_SEL, 0, + OTG_V_TOTAL_MAX_SEL, 0, + OTG_FORCE_LOCK_ON_EVENT, 0); + + optc->funcs->set_vtotal_min_max(optc, 0, 0); + } +} + +static struct timing_generator_funcs dcn32_tg_funcs = { + .validate_timing = optc1_validate_timing, + .program_timing = optc1_program_timing, + .setup_vertical_interrupt0 = optc1_setup_vertical_interrupt0, + .setup_vertical_interrupt1 = optc1_setup_vertical_interrupt1, + .setup_vertical_interrupt2 = optc1_setup_vertical_interrupt2, + .program_global_sync = optc1_program_global_sync, + .enable_crtc = optc32_enable_crtc, + .disable_crtc = optc32_disable_crtc, + .phantom_crtc_post_enable = optc32_phantom_crtc_post_enable, + /* used by enable_timing_synchronization. Not need for FPGA */ + .is_counter_moving = optc1_is_counter_moving, + .get_position = optc1_get_position, + .get_frame_count = optc1_get_vblank_counter, + .get_scanoutpos = optc1_get_crtc_scanoutpos, + .get_otg_active_size = optc1_get_otg_active_size, + .set_early_control = optc1_set_early_control, + /* used by enable_timing_synchronization. Not need for FPGA */ + .wait_for_state = optc1_wait_for_state, + .set_blank_color = optc3_program_blank_color, + .did_triggered_reset_occur = optc1_did_triggered_reset_occur, + .triplebuffer_lock = optc3_triplebuffer_lock, + .triplebuffer_unlock = optc2_triplebuffer_unlock, + .enable_reset_trigger = optc1_enable_reset_trigger, + .enable_crtc_reset = optc1_enable_crtc_reset, + .disable_reset_trigger = optc1_disable_reset_trigger, + .lock = optc3_lock, + .unlock = optc1_unlock, + .lock_doublebuffer_enable = optc3_lock_doublebuffer_enable, + .lock_doublebuffer_disable = optc3_lock_doublebuffer_disable, + .enable_optc_clock = optc1_enable_optc_clock, + .set_drr = optc31_set_drr, // TODO: Update to optc32_set_drr once FW headers are promoted + .get_last_used_drr_vtotal = optc2_get_last_used_drr_vtotal, + .set_vtotal_min_max = optc3_set_vtotal_min_max, + .set_static_screen_control = optc1_set_static_screen_control, + .program_stereo = optc1_program_stereo, + .is_stereo_left_eye = optc1_is_stereo_left_eye, + .tg_init = optc3_tg_init, + .is_tg_enabled = optc1_is_tg_enabled, + .is_optc_underflow_occurred = optc1_is_optc_underflow_occurred, + .clear_optc_underflow = optc1_clear_optc_underflow, + .setup_global_swap_lock = NULL, + .get_crc = optc1_get_crc, + .configure_crc = optc1_configure_crc, + .set_dsc_config = optc3_set_dsc_config, + .get_dsc_status = optc2_get_dsc_status, + .set_dwb_source = NULL, + .set_odm_bypass = optc32_set_odm_bypass, + .set_odm_combine = optc32_set_odm_combine, + .set_h_timing_div_manual_mode = optc32_set_h_timing_div_manual_mode, + .get_optc_source = optc2_get_optc_source, + .set_out_mux = optc3_set_out_mux, + .set_drr_trigger_window = optc3_set_drr_trigger_window, + .set_vtotal_change_limit = optc3_set_vtotal_change_limit, + .set_gsl = optc2_set_gsl, + .set_gsl_source_select = optc2_set_gsl_source_select, + .set_vtg_params = optc1_set_vtg_params, + .program_manual_trigger = optc2_program_manual_trigger, + .setup_manual_trigger = optc2_setup_manual_trigger, + .get_hw_timing = optc1_get_hw_timing, +}; + +void dcn32_timing_generator_init(struct optc *optc1) +{ + optc1->base.funcs = &dcn32_tg_funcs; + + optc1->max_h_total = optc1->tg_mask->OTG_H_TOTAL + 1; + optc1->max_v_total = optc1->tg_mask->OTG_V_TOTAL + 1; + + optc1->min_h_blank = 32; + optc1->min_v_blank = 3; + optc1->min_v_blank_interlace = 5; + optc1->min_h_sync_width = 4; + optc1->min_v_sync_width = 1; +} + diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c index f79dd40f8d811..b196b1f38c185 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c @@ -30,6 +30,7 @@ #include "dchubbub.h" #include "dcn20/dcn20_resource.h" #include "dcn21/dcn21_resource.h" +#include "clk_mgr/dcn21/rn_clk_mgr.h" #include "dcn20_fpu.h" @@ -42,6 +43,9 @@ #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) #endif +/* Constant */ +#define LPDDR_MEM_RETRAIN_LATENCY 4.977 /* Number obtained from LPDDR4 Training Counter Requirement doc */ + /** * DOC: DCN2x FPU manipulation Overview * @@ -650,6 +654,228 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { .num_states = 8 }; +struct wm_table ddr4_wm_table_gs = { + .entries = { + { + .wm_inst = WM_A, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 7.09, + .sr_enter_plus_exit_time_us = 8.14, + .valid = true, + }, + { + .wm_inst = WM_B, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 10.12, + .sr_enter_plus_exit_time_us = 11.48, + .valid = true, + }, + { + .wm_inst = WM_C, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 10.12, + .sr_enter_plus_exit_time_us = 11.48, + .valid = true, + }, + { + .wm_inst = WM_D, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 10.12, + .sr_enter_plus_exit_time_us = 11.48, + .valid = true, + }, + } +}; + +struct wm_table lpddr4_wm_table_gs = { + .entries = { + { + .wm_inst = WM_A, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 5.32, + .sr_enter_plus_exit_time_us = 6.38, + .valid = true, + }, + { + .wm_inst = WM_B, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 9.82, + .sr_enter_plus_exit_time_us = 11.196, + .valid = true, + }, + { + .wm_inst = WM_C, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 9.89, + .sr_enter_plus_exit_time_us = 11.24, + .valid = true, + }, + { + .wm_inst = WM_D, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 9.748, + .sr_enter_plus_exit_time_us = 11.102, + .valid = true, + }, + } +}; + +struct wm_table lpddr4_wm_table_with_disabled_ppt = { + .entries = { + { + .wm_inst = WM_A, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 8.32, + .sr_enter_plus_exit_time_us = 9.38, + .valid = true, + }, + { + .wm_inst = WM_B, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 9.82, + .sr_enter_plus_exit_time_us = 11.196, + .valid = true, + }, + { + .wm_inst = WM_C, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 9.89, + .sr_enter_plus_exit_time_us = 11.24, + .valid = true, + }, + { + .wm_inst = WM_D, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 9.748, + .sr_enter_plus_exit_time_us = 11.102, + .valid = true, + }, + } +}; + +struct wm_table ddr4_wm_table_rn = { + .entries = { + { + .wm_inst = WM_A, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 11.90, + .sr_enter_plus_exit_time_us = 12.80, + .valid = true, + }, + { + .wm_inst = WM_B, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 13.18, + .sr_enter_plus_exit_time_us = 14.30, + .valid = true, + }, + { + .wm_inst = WM_C, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 13.18, + .sr_enter_plus_exit_time_us = 14.30, + .valid = true, + }, + { + .wm_inst = WM_D, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 13.18, + .sr_enter_plus_exit_time_us = 14.30, + .valid = true, + }, + } +}; + +struct wm_table ddr4_1R_wm_table_rn = { + .entries = { + { + .wm_inst = WM_A, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 13.90, + .sr_enter_plus_exit_time_us = 14.80, + .valid = true, + }, + { + .wm_inst = WM_B, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 13.90, + .sr_enter_plus_exit_time_us = 14.80, + .valid = true, + }, + { + .wm_inst = WM_C, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 13.90, + .sr_enter_plus_exit_time_us = 14.80, + .valid = true, + }, + { + .wm_inst = WM_D, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 13.90, + .sr_enter_plus_exit_time_us = 14.80, + .valid = true, + }, + } +}; + +struct wm_table lpddr4_wm_table_rn = { + .entries = { + { + .wm_inst = WM_A, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 7.32, + .sr_enter_plus_exit_time_us = 8.38, + .valid = true, + }, + { + .wm_inst = WM_B, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 9.82, + .sr_enter_plus_exit_time_us = 11.196, + .valid = true, + }, + { + .wm_inst = WM_C, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 9.89, + .sr_enter_plus_exit_time_us = 11.24, + .valid = true, + }, + { + .wm_inst = WM_D, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 9.748, + .sr_enter_plus_exit_time_us = 11.102, + .valid = true, + }, + } +}; + void dcn20_populate_dml_writeback_from_context(struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes) @@ -2036,3 +2262,100 @@ void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21); } + +void dcn21_clk_mgr_set_bw_params_wm_table(struct clk_bw_params *bw_params) +{ + dc_assert_fp_enabled(); + + bw_params->wm_table.entries[WM_D].pstate_latency_us = LPDDR_MEM_RETRAIN_LATENCY; + bw_params->wm_table.entries[WM_D].wm_inst = WM_D; + bw_params->wm_table.entries[WM_D].wm_type = WM_TYPE_RETRAINING; + bw_params->wm_table.entries[WM_D].valid = true; +} + +void dcn201_populate_dml_writeback_from_context_fpu(struct dc *dc, + struct resource_context *res_ctx, + display_e2e_pipe_params_st *pipes) +{ + int pipe_cnt, i, j; + double max_calc_writeback_dispclk; + double writeback_dispclk; + struct writeback_st dout_wb; + + dc_assert_fp_enabled(); + + for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { + struct dc_stream_state *stream = res_ctx->pipe_ctx[i].stream; + + if (!stream) + continue; + max_calc_writeback_dispclk = 0; + + /* Set writeback information */ + pipes[pipe_cnt].dout.wb_enable = 0; + pipes[pipe_cnt].dout.num_active_wb = 0; + for (j = 0; j < stream->num_wb_info; j++) { + struct dc_writeback_info *wb_info = &stream->writeback_info[j]; + + if (wb_info->wb_enabled && wb_info->writeback_source_plane && + (wb_info->writeback_source_plane == res_ctx->pipe_ctx[i].plane_state)) { + pipes[pipe_cnt].dout.wb_enable = 1; + pipes[pipe_cnt].dout.num_active_wb++; + dout_wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_en ? + wb_info->dwb_params.cnv_params.crop_height : + wb_info->dwb_params.cnv_params.src_height; + dout_wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_en ? + wb_info->dwb_params.cnv_params.crop_width : + wb_info->dwb_params.cnv_params.src_width; + dout_wb.wb_dst_width = wb_info->dwb_params.dest_width; + dout_wb.wb_dst_height = wb_info->dwb_params.dest_height; + dout_wb.wb_htaps_luma = wb_info->dwb_params.scaler_taps.h_taps; + dout_wb.wb_vtaps_luma = wb_info->dwb_params.scaler_taps.v_taps;; + dout_wb.wb_htaps_chroma = wb_info->dwb_params.scaler_taps.h_taps_c; + dout_wb.wb_vtaps_chroma = wb_info->dwb_params.scaler_taps.v_taps_c; + dout_wb.wb_hratio = wb_info->dwb_params.cnv_params.crop_en ? + (double)wb_info->dwb_params.cnv_params.crop_width / + (double)wb_info->dwb_params.dest_width : + (double)wb_info->dwb_params.cnv_params.src_width / + (double)wb_info->dwb_params.dest_width; + dout_wb.wb_vratio = wb_info->dwb_params.cnv_params.crop_en ? + (double)wb_info->dwb_params.cnv_params.crop_height / + (double)wb_info->dwb_params.dest_height : + (double)wb_info->dwb_params.cnv_params.src_height / + (double)wb_info->dwb_params.dest_height; + if (wb_info->dwb_params.out_format == dwb_scaler_mode_yuv420) { + if (wb_info->dwb_params.output_depth == DWB_OUTPUT_PIXEL_DEPTH_8BPC) + dout_wb.wb_pixel_format = dm_420_8; + else + dout_wb.wb_pixel_format = dm_420_10; + } else + dout_wb.wb_pixel_format = dm_444_32; + + /* Workaround for cases where multiple writebacks are connected to same plane + * In which case, need to compute worst case and set the associated writeback parameters + * This workaround is necessary due to DML computation assuming only 1 set of writeback + * parameters per pipe */ + writeback_dispclk = CalculateWriteBackDISPCLK( + dout_wb.wb_pixel_format, + pipes[pipe_cnt].pipe.dest.pixel_rate_mhz, + dout_wb.wb_hratio, + dout_wb.wb_vratio, + dout_wb.wb_htaps_luma, + dout_wb.wb_vtaps_luma, + dout_wb.wb_htaps_chroma, + dout_wb.wb_vtaps_chroma, + dout_wb.wb_dst_width, + pipes[pipe_cnt].pipe.dest.htotal, + 2); + + if (writeback_dispclk > max_calc_writeback_dispclk) { + max_calc_writeback_dispclk = writeback_dispclk; + pipes[pipe_cnt].dout.wb = dout_wb; + } + } + } + + pipe_cnt++; + } + +} diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h index aa892193e4854..c51badf7b68a9 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h @@ -82,4 +82,10 @@ bool dcn21_validate_bandwidth_fp(struct dc *dc, bool fast_validate); void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params); +void dcn21_clk_mgr_set_bw_params_wm_table(struct clk_bw_params *bw_params); + +void dcn201_populate_dml_writeback_from_context_fpu(struct dc *dc, + struct resource_context *res_ctx, + display_e2e_pipe_params_st *pipes); + #endif /* __DCN20_FPU_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c index 574676a0711ae..8bc1bc55e6352 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c @@ -29,7 +29,7 @@ #include "dcn20/dcn20_resource.h" #include "dcn30/dcn30_resource.h" - +#include "clk_mgr/dcn30/dcn30_smu11_driver_if.h" #include "display_mode_vba_30.h" #include "dcn30_fpu.h" @@ -614,4 +614,85 @@ void dcn30_fpu_update_bw_bounding_box(struct dc *dc, } +void dcn3_fpu_build_wm_range_table(struct clk_mgr *base) +{ + /* defaults */ + double pstate_latency_us = base->ctx->dc->dml.soc.dram_clock_change_latency_us; + double sr_exit_time_us = base->ctx->dc->dml.soc.sr_exit_time_us; + double sr_enter_plus_exit_time_us = base->ctx->dc->dml.soc.sr_enter_plus_exit_time_us; + uint16_t min_uclk_mhz = base->bw_params->clk_table.entries[0].memclk_mhz; + + dc_assert_fp_enabled(); + + /* Set A - Normal - default values*/ + base->bw_params->wm_table.nv_entries[WM_A].valid = true; + base->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us = pstate_latency_us; + base->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us = sr_exit_time_us; + base->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; + base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE; + base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_dcfclk = 0; + base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_dcfclk = 0xFFFF; + base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_uclk = min_uclk_mhz; + base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_uclk = 0xFFFF; + + /* Set B - Performance - higher minimum clocks */ +// base->bw_params->wm_table.nv_entries[WM_B].valid = true; +// base->bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us = pstate_latency_us; +// base->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us = sr_exit_time_us; +// base->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; +// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE; +// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_dcfclk = TUNED VALUE; +// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_dcfclk = 0xFFFF; +// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_uclk = TUNED VALUE; +// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_uclk = 0xFFFF; + + /* Set C - Dummy P-State - P-State latency set to "dummy p-state" value */ + base->bw_params->wm_table.nv_entries[WM_C].valid = true; + base->bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 0; + base->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us; + base->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; + base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.wm_type = WATERMARKS_DUMMY_PSTATE; + base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_dcfclk = 0; + base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_dcfclk = 0xFFFF; + base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz; + base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF; + base->bw_params->dummy_pstate_table[0].dram_speed_mts = 1600; + base->bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 38; + base->bw_params->dummy_pstate_table[1].dram_speed_mts = 8000; + base->bw_params->dummy_pstate_table[1].dummy_pstate_latency_us = 9; + base->bw_params->dummy_pstate_table[2].dram_speed_mts = 10000; + base->bw_params->dummy_pstate_table[2].dummy_pstate_latency_us = 8; + base->bw_params->dummy_pstate_table[3].dram_speed_mts = 16000; + base->bw_params->dummy_pstate_table[3].dummy_pstate_latency_us = 5; + + /* Set D - MALL - SR enter and exit times adjusted for MALL */ + base->bw_params->wm_table.nv_entries[WM_D].valid = true; + base->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us = pstate_latency_us; + base->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us = 2; + base->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us = 4; + base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.wm_type = WATERMARKS_MALL; + base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_dcfclk = 0; + base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_dcfclk = 0xFFFF; + base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_uclk = min_uclk_mhz; + base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_uclk = 0xFFFF; +} +void patch_dcn30_soc_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *dcn3_0_ip) +{ + dc_assert_fp_enabled(); + + if (dc->ctx->dc_bios->funcs->get_soc_bb_info) { + struct bp_soc_bb_info bb_info = {0}; + + if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) { + if (bb_info.dram_clock_change_latency_100ns > 0) + dcn3_0_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10; + + if (bb_info.dram_sr_enter_exit_latency_100ns > 0) + dcn3_0_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10; + + if (bb_info.dram_sr_exit_latency_100ns > 0) + dcn3_0_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10; + } + } +} diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h index dedfe7b5f1731..595ce88cfa69a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h @@ -63,5 +63,8 @@ void dcn30_fpu_update_bw_bounding_box(struct dc *dc, unsigned int *dcfclk_mhz, unsigned int *dram_speed_mts); +void dcn3_fpu_build_wm_range_table(struct clk_mgr *base); + +void patch_dcn30_soc_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *dcn3_0_ip); #endif /* __DCN30_FPU_H__*/ diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c index 0a7a338649731..e391e4e26d610 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c @@ -26,6 +26,7 @@ #include "clk_mgr.h" #include "dcn20/dcn20_resource.h" #include "dcn301/dcn301_resource.h" +#include "clk_mgr/dcn301/vg_clk_mgr.h" #include "dml/dcn20/dcn20_fpu.h" #include "dcn301_fpu.h" @@ -214,6 +215,80 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc = { .urgent_latency_adjustment_fabric_clock_reference_mhz = 0, }; +struct wm_table ddr4_wm_table = { + .entries = { + { + .wm_inst = WM_A, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 6.09, + .sr_enter_plus_exit_time_us = 7.14, + .valid = true, + }, + { + .wm_inst = WM_B, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 10.12, + .sr_enter_plus_exit_time_us = 11.48, + .valid = true, + }, + { + .wm_inst = WM_C, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 10.12, + .sr_enter_plus_exit_time_us = 11.48, + .valid = true, + }, + { + .wm_inst = WM_D, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.72, + .sr_exit_time_us = 10.12, + .sr_enter_plus_exit_time_us = 11.48, + .valid = true, + }, + } +}; + +struct wm_table lpddr5_wm_table = { + .entries = { + { + .wm_inst = WM_A, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 13.5, + .sr_enter_plus_exit_time_us = 16.5, + .valid = true, + }, + { + .wm_inst = WM_B, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 13.5, + .sr_enter_plus_exit_time_us = 16.5, + .valid = true, + }, + { + .wm_inst = WM_C, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 13.5, + .sr_enter_plus_exit_time_us = 16.5, + .valid = true, + }, + { + .wm_inst = WM_D, + .wm_type = WM_TYPE_PSTATE_CHG, + .pstate_latency_us = 11.65333, + .sr_exit_time_us = 13.5, + .sr_enter_plus_exit_time_us = 16.5, + .valid = true, + }, + } +}; + static void calculate_wm_set_for_vlevel(int vlevel, struct wm_range_table_entry *table_entry, struct dcn_watermarks *wm_set, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c index 54db2eca9e6b7..47e6bc934bad4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c @@ -25,6 +25,9 @@ #include "resource.h" #include "clk_mgr.h" +#include "dcn31/dcn31_resource.h" +#include "dcn315/dcn315_resource.h" +#include "dcn316/dcn316_resource.h" #include "dml/dcn20/dcn20_fpu.h" #include "dcn31_fpu.h" @@ -114,7 +117,7 @@ struct _vcs_dpi_ip_params_st dcn3_1_ip = { .dcc_supported = true, }; -struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc = { +static struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc = { /*TODO: correct dispclk/dppclk voltage level determination*/ .clock_limits = { { @@ -259,7 +262,7 @@ struct _vcs_dpi_ip_params_st dcn3_15_ip = { .dcc_supported = true, }; -struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = { +static struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = { .sr_exit_time_us = 9.0, .sr_enter_plus_exit_time_us = 11.0, .sr_exit_z8_time_us = 50.0, @@ -354,7 +357,7 @@ struct _vcs_dpi_ip_params_st dcn3_16_ip = { .dcc_supported = true, }; -struct _vcs_dpi_soc_bounding_box_st dcn3_16_soc = { +static struct _vcs_dpi_soc_bounding_box_st dcn3_16_soc = { /*TODO: correct dispclk/dppclk voltage level determination*/ .clock_limits = { { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h index 554d2e33bd7f1..56f34dba3cb2a 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h @@ -298,8 +298,6 @@ struct timing_generator_funcs { int group_idx, uint32_t gsl_ready_signal); void (*set_out_mux)(struct timing_generator *tg, enum otg_out_mux_dest dest); - void (*set_vrr_m_const)(struct timing_generator *optc, - double vtotal_avg); void (*set_drr_trigger_window)(struct timing_generator *optc, uint32_t window_start, uint32_t window_end); void (*set_vtotal_change_limit)(struct timing_generator *optc,