summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2024-09-27 08:13:52 +0200
committerPaolo Abeni <pabeni@redhat.com>2024-09-27 08:13:52 +0200
commit3a39d672e7f48b8d6b91a09afa4b55352773b4b5 (patch)
treef7ec4043b508f48430dd09ac338c38acf7d5a6cd /drivers/gpu/drm/amd/display
parent151ac45348afc5b56baa584c7cd4876addf461ff (diff)
parent62a0e2fa40c5c06742b8b4997ba5095a3ec28503 (diff)
downloadlwn-3a39d672e7f48b8d6b91a09afa4b55352773b4b5.tar.gz
lwn-3a39d672e7f48b8d6b91a09afa4b55352773b4b5.zip
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Cross-merge networking fixes after downstream PR. No conflicts and no adjacent changes. Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c167
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c60
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c5
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c30
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c135
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c8
-rw-r--r--drivers/gpu/drm/amd/display/dc/Makefile1
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c27
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table2.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c34
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c303
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c211
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c225
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c56
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_stat.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_state.c14
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h27
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c93
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h24
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_hw_types.h7
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_spl_translate.c102
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_spl_translate.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_stream.h12
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_types.h20
-rw-r--r--drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h17
-rw-r--r--drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c1469
-rw-r--r--drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c32
-rw-r--r--drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_audio.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_audio.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_aux.c10
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c20
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/Makefile3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/Makefile6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn301/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn303/Makefile13
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn314/Makefile10
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn401/Makefile10
-rw-r--r--drivers/gpu/drm/amd/display/dc/dio/Makefile18
-rw-r--r--drivers/gpu/drm/amd/display/dc/dio/dcn301/dcn301_dio_link_encoder.c (renamed from drivers/gpu/drm/amd/display/dc/dcn301/dcn301_dio_link_encoder.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dio/dcn301/dcn301_dio_link_encoder.h (renamed from drivers/gpu/drm/amd/display/dc/dcn301/dcn301_dio_link_encoder.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dio/dcn314/dcn314_dio_stream_encoder.c (renamed from drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dio/dcn314/dcn314_dio_stream_encoder.h (renamed from drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dio/dcn321/dcn321_dio_link_encoder.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c29
-rw-r--r--drivers/gpu/drm/amd/display/dc/dm_helpers.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c11
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/Makefile8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c114
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c167
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/bounding_boxes/dcn3_soc_bb.h8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/bounding_boxes/dcn4_soc_bb.h25
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_dchub_registers.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_display_cfg_types.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_policy_types.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_soc_parameter_types.h17
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_types.h14
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c127
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c987
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_factory.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_factory.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c224
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.h38
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h35
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_utils.c631
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_utils.h39
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c169
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_factory.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_factory.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_dcn4.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_dcn4.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn3.c12
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn3.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4.c1250
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4.h25
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c590
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_factory.c8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_factory.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_standalone_libraries/lib_float_math.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_standalone_libraries/lib_float_math.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_optimization.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_optimization.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c23
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.c23
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_debug.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_debug.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_internal_shared_types.h27
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c56
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c10
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp_cm.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c27
-rw-r--r--drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c19
-rw-r--r--drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c590
-rw-r--r--drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dwb/Makefile9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_cm_common.h (renamed from drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb.c (renamed from drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb.h (renamed from drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb_cm.c (renamed from drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dwb/dcn35/dcn35_dwb.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/dcn401/hw_factory_dcn401.c16
-rw-r--r--drivers/gpu/drm/amd/display/dc/hpo/Makefile15
-rw-r--r--drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.c (renamed from drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.h (renamed from drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.c (renamed from drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.h (renamed from drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c387
-rw-r--r--drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c65
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c25
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_init.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c54
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_init.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_init.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_init.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c21
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_init.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c13
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c108
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c75
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c235
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c10
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h19
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/core_types.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/audio.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h13
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/optc.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/transform.h10
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/resource.h7
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c13
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c12
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_detection.c8
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_dpms.c45
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_factory.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c69
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c14
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile9
-rw-r--r--drivers/gpu/drm/amd/display/dc/mmhubbub/dcn20/dcn20_mmhubbub.c (renamed from drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/mmhubbub/dcn20/dcn20_mmhubbub.h (renamed from drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/mpc/Makefile27
-rw-r--r--drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.c (renamed from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.h (renamed from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/mpc/dcn20/dcn20_mpc.c (renamed from drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/mpc/dcn20/dcn20_mpc.h (renamed from drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/mpc/dcn30/dcn30_mpc.c (renamed from drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c)2
-rw-r--r--drivers/gpu/drm/amd/display/dc/mpc/dcn30/dcn30_mpc.h (renamed from drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/opp/Makefile16
-rw-r--r--drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.c (renamed from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.h (renamed from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.c (renamed from drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.h (renamed from drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.c10
-rw-r--r--drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h7
-rw-r--r--drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.c8
-rw-r--r--drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.c36
-rw-r--r--drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c11
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c14
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c11
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/dc_spl.c1359
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/dc_spl.h8
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.c15
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.h15
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.c352
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.h35
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.c1726
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.h38
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.c92
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.h55
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h110
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.c151
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.h29
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/spl_debug.h25
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.c497
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.h525
-rw-r--r--drivers/gpu/drm/amd/display/dc/spl/spl_os_types.h55
-rw-r--r--drivers/gpu/drm/amd/display/dmub/dmub_srv.h3
-rw-r--r--drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h52
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c4
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c4
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c4
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c4
-rw-r--r--drivers/gpu/drm/amd/display/include/fixed31_32.h6
-rw-r--r--drivers/gpu/drm/amd/display/include/logger_types.h1
-rw-r--r--drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c18
255 files changed, 10628 insertions, 4679 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1e069fa5211e..0cff66735cfe 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -176,6 +176,7 @@ MODULE_FIRMWARE(FIRMWARE_DCN_401_DMUB);
static int amdgpu_dm_init(struct amdgpu_device *adev);
static void amdgpu_dm_fini(struct amdgpu_device *adev);
static bool is_freesync_video_mode(const struct drm_display_mode *mode, struct amdgpu_dm_connector *aconnector);
+static void reset_freesync_config_for_crtc(struct dm_crtc_state *new_crtc_state);
static enum drm_mode_subconnector get_subconnector_type(struct dc_link *link)
{
@@ -877,6 +878,7 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params)
"HPD_IRQ",
"SET_CONFIGC_REPLY",
"DPIA_NOTIFICATION",
+ "HPD_SENSE_NOTIFY",
};
do {
@@ -1740,7 +1742,7 @@ static struct dml2_soc_bb *dm_dmub_get_vbios_bounding_box(struct amdgpu_device *
/* Send the chunk */
ret = dm_dmub_send_vbios_gpint_command(adev, send_addrs[i], chunk, 30000);
if (ret != DMUB_STATUS_OK)
- /* No need to free bb here since it shall be done unconditionally <elsewhere> */
+ /* No need to free bb here since it shall be done in dm_sw_fini() */
return NULL;
}
@@ -1886,6 +1888,12 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
if (amdgpu_dc_debug_mask & DC_DISABLE_IPS)
init_data.flags.disable_ips = DMUB_IPS_DISABLE_ALL;
+ else if (amdgpu_dc_debug_mask & DC_DISABLE_IPS_DYNAMIC)
+ init_data.flags.disable_ips = DMUB_IPS_DISABLE_DYNAMIC;
+ else if (amdgpu_dc_debug_mask & DC_DISABLE_IPS2_DYNAMIC)
+ init_data.flags.disable_ips = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
+ else if (amdgpu_dc_debug_mask & DC_FORCE_IPS_ENABLE)
+ init_data.flags.disable_ips = DMUB_IPS_ENABLE;
else
init_data.flags.disable_ips = dm_get_default_ips_mode(adev);
@@ -2242,7 +2250,7 @@ static int load_dmcu_fw(struct amdgpu_device *adev)
return 0;
}
- r = amdgpu_ucode_request(adev, &adev->dm.fw_dmcu, fw_name_dmcu);
+ r = amdgpu_ucode_request(adev, &adev->dm.fw_dmcu, "%s", fw_name_dmcu);
if (r == -ENODEV) {
/* DMCU firmware is not necessary, so don't raise a fuss if it's missing */
DRM_DEBUG_KMS("dm: DMCU firmware not found\n");
@@ -2489,8 +2497,17 @@ static int dm_sw_init(void *handle)
static int dm_sw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ struct dal_allocation *da;
+
+ list_for_each_entry(da, &adev->dm.da_list, list) {
+ if (adev->dm.bb_from_dmub == (void *) da->cpu_ptr) {
+ amdgpu_bo_free_kernel(&da->bo, &da->gpu_addr, &da->cpu_ptr);
+ list_del(&da->list);
+ kfree(da);
+ break;
+ }
+ }
- kfree(adev->dm.bb_from_dmub);
adev->dm.bb_from_dmub = NULL;
kfree(adev->dm.dmub_fb_info);
@@ -2592,9 +2609,9 @@ static int dm_late_init(void *handle)
static void resume_mst_branch_status(struct drm_dp_mst_topology_mgr *mgr)
{
+ u8 buf[UUID_SIZE];
+ guid_t guid;
int ret;
- u8 guid[16];
- u64 tmp64;
mutex_lock(&mgr->lock);
if (!mgr->mst_primary)
@@ -2615,26 +2632,27 @@ static void resume_mst_branch_status(struct drm_dp_mst_topology_mgr *mgr)
}
/* Some hubs forget their guids after they resume */
- ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16);
- if (ret != 16) {
+ ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, buf, sizeof(buf));
+ if (ret != sizeof(buf)) {
drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n");
goto out_fail;
}
- if (memchr_inv(guid, 0, 16) == NULL) {
- tmp64 = get_jiffies_64();
- memcpy(&guid[0], &tmp64, sizeof(u64));
- memcpy(&guid[8], &tmp64, sizeof(u64));
+ import_guid(&guid, buf);
- ret = drm_dp_dpcd_write(mgr->aux, DP_GUID, guid, 16);
+ if (guid_is_null(&guid)) {
+ guid_gen(&guid);
+ export_guid(buf, &guid);
- if (ret != 16) {
+ ret = drm_dp_dpcd_write(mgr->aux, DP_GUID, buf, sizeof(buf));
+
+ if (ret != sizeof(buf)) {
drm_dbg_kms(mgr->dev, "check mstb guid failed - undocked during suspend?\n");
goto out_fail;
}
}
- memcpy(mgr->mst_primary->guid, guid, 16);
+ guid_copy(&mgr->mst_primary->guid, &guid);
out_fail:
mutex_unlock(&mgr->lock);
@@ -3230,8 +3248,11 @@ static int dm_resume(void *handle)
drm_connector_list_iter_end(&iter);
/* Force mode set in atomic commit */
- for_each_new_crtc_in_state(dm->cached_state, crtc, new_crtc_state, i)
+ for_each_new_crtc_in_state(dm->cached_state, crtc, new_crtc_state, i) {
new_crtc_state->active_changed = true;
+ dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+ reset_freesync_config_for_crtc(dm_new_crtc_state);
+ }
/*
* atomic_check is expected to create the dc states. We need to release
@@ -4874,18 +4895,14 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
/* Determine whether to enable Replay support by default. */
if (!(amdgpu_dc_debug_mask & DC_DISABLE_REPLAY)) {
switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
-/*
- * Disabled by default due to https://gitlab.freedesktop.org/drm/amd/-/issues/3344
- * case IP_VERSION(3, 1, 4):
- * case IP_VERSION(3, 1, 5):
- * case IP_VERSION(3, 1, 6):
- * case IP_VERSION(3, 2, 0):
- * case IP_VERSION(3, 2, 1):
- * case IP_VERSION(3, 5, 0):
- * case IP_VERSION(3, 5, 1):
- * replay_feature_enabled = true;
- * break;
- */
+ case IP_VERSION(3, 1, 4):
+ case IP_VERSION(3, 2, 0):
+ case IP_VERSION(3, 2, 1):
+ case IP_VERSION(3, 5, 0):
+ case IP_VERSION(3, 5, 1):
+ replay_feature_enabled = true;
+ break;
+
default:
replay_feature_enabled = amdgpu_dc_feature_mask & DC_REPLAY_MASK;
break;
@@ -4972,12 +4989,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
if (psr_feature_enabled)
amdgpu_dm_set_psr_caps(link);
-
- /* TODO: Fix vblank control helpers to delay PSR entry to allow this when
- * PSR is also supported.
- */
- if (link->psr_settings.psr_feature_enabled)
- adev_to_drm(adev)->vblank_disable_immediate = false;
}
}
amdgpu_set_panel_orientation(&aconnector->base);
@@ -5182,7 +5193,7 @@ static int dm_init_microcode(struct amdgpu_device *adev)
/* ASIC doesn't support DMUB. */
return 0;
}
- r = amdgpu_ucode_request(adev, &adev->dm.dmub_fw, fw_name_dmub);
+ r = amdgpu_ucode_request(adev, &adev->dm.dmub_fw, "%s", fw_name_dmub);
return r;
}
@@ -6471,7 +6482,8 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
dc_link_get_highest_encoding_format(aconnector->dc_link),
&stream->timing.dsc_cfg)) {
stream->timing.flags.DSC = 1;
- DRM_DEBUG_DRIVER("%s: [%s] DSC is selected from SST RX\n", __func__, drm_connector->name);
+ DRM_DEBUG_DRIVER("%s: SST_DSC [%s] DSC is selected from SST RX\n",
+ __func__, drm_connector->name);
}
} else if (sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER) {
timing_bw_in_kbps = dc_bandwidth_in_kbps_from_timing(&stream->timing,
@@ -6490,7 +6502,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
dc_link_get_highest_encoding_format(aconnector->dc_link),
&stream->timing.dsc_cfg)) {
stream->timing.flags.DSC = 1;
- DRM_DEBUG_DRIVER("%s: [%s] DSC is selected from DP-HDMI PCON\n",
+ DRM_DEBUG_DRIVER("%s: SST_DSC [%s] DSC is selected from DP-HDMI PCON\n",
__func__, drm_connector->name);
}
}
@@ -7233,6 +7245,9 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
int requested_bpc = drm_state ? drm_state->max_requested_bpc : 8;
enum dc_status dc_result = DC_OK;
+ if (!dm_state)
+ return NULL;
+
do {
stream = create_stream_for_sink(connector, drm_mode,
dm_state, old_stream,
@@ -8270,7 +8285,7 @@ static int amdgpu_dm_encoder_init(struct drm_device *dev,
static void manage_dm_interrupts(struct amdgpu_device *adev,
struct amdgpu_crtc *acrtc,
- bool enable)
+ struct dm_crtc_state *acrtc_state)
{
/*
* We have no guarantee that the frontend index maps to the same
@@ -8282,9 +8297,31 @@ static void manage_dm_interrupts(struct amdgpu_device *adev,
amdgpu_display_crtc_idx_to_irq_type(
adev,
acrtc->crtc_id);
+ struct drm_vblank_crtc_config config = {0};
+ struct dc_crtc_timing *timing;
+ int offdelay;
+
+ if (acrtc_state) {
+ if (amdgpu_ip_version(adev, DCE_HWIP, 0) <
+ IP_VERSION(3, 5, 0) ||
+ acrtc_state->stream->link->psr_settings.psr_version <
+ DC_PSR_VERSION_UNSUPPORTED) {
+ timing = &acrtc_state->stream->timing;
+
+ /* at least 2 frames */
+ offdelay = DIV64_U64_ROUND_UP((u64)20 *
+ timing->v_total *
+ timing->h_total,
+ timing->pix_clk_100hz);
+
+ config.offdelay_ms = offdelay ?: 30;
+ } else {
+ config.disable_immediate = true;
+ }
+
+ drm_crtc_vblank_on_config(&acrtc->base,
+ &config);
- if (enable) {
- drm_crtc_vblank_on(&acrtc->base);
amdgpu_irq_get(
adev,
&adev->pageflip_irq,
@@ -8750,7 +8787,8 @@ static void amdgpu_dm_update_cursor(struct drm_plane *plane,
adev->dm.dc->caps.color.dpp.gamma_corr)
attributes.attribute_flags.bits.ENABLE_CURSOR_DEGAMMA = 1;
- attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0];
+ if (afb)
+ attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0];
if (crtc_state->stream) {
if (!dc_stream_set_cursor_attributes(crtc_state->stream,
@@ -9340,7 +9378,7 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
if (acrtc)
old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base);
- if (!acrtc->wb_enabled)
+ if (!acrtc || !acrtc->wb_enabled)
continue;
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
@@ -9358,7 +9396,7 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
if (old_crtc_state->active &&
(!new_crtc_state->active ||
drm_atomic_crtc_needs_modeset(new_crtc_state))) {
- manage_dm_interrupts(adev, acrtc, false);
+ manage_dm_interrupts(adev, acrtc, NULL);
dc_stream_release(dm_old_crtc_state->stream);
}
}
@@ -9744,9 +9782,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
DRM_INFO("[HDCP_DM] hdcp_update_display enable_encryption = %x\n", enable_encryption);
- hdcp_update_display(
- adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector,
- new_con_state->hdcp_content_type, enable_encryption);
+ if (aconnector->dc_link)
+ hdcp_update_display(
+ adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector,
+ new_con_state->hdcp_content_type, enable_encryption);
}
}
@@ -9873,7 +9912,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
drm_atomic_crtc_needs_modeset(new_crtc_state))) {
dc_stream_retain(dm_new_crtc_state->stream);
acrtc->dm_irq_params.stream = dm_new_crtc_state->stream;
- manage_dm_interrupts(adev, acrtc, true);
+ manage_dm_interrupts(adev, acrtc, dm_new_crtc_state);
}
/* Handle vrr on->off / off->on transitions */
amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, dm_new_crtc_state);
@@ -11651,7 +11690,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
if (dc_resource_is_dsc_encoding_supported(dc)) {
ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars);
if (ret) {
- drm_dbg_atomic(dev, "compute_mst_dsc_configs_for_state() failed\n");
+ drm_dbg_atomic(dev, "MST_DSC compute_mst_dsc_configs_for_state() failed\n");
ret = -EINVAL;
goto fail;
}
@@ -11672,7 +11711,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
*/
ret = drm_dp_mst_atomic_check(state);
if (ret) {
- drm_dbg_atomic(dev, "drm_dp_mst_atomic_check() failed\n");
+ drm_dbg_atomic(dev, "MST drm_dp_mst_atomic_check() failed\n");
goto fail;
}
status = dc_validate_global_state(dc, dm_state->context, true);
@@ -11766,25 +11805,6 @@ fail:
return ret;
}
-static bool is_dp_capable_without_timing_msa(struct dc *dc,
- struct amdgpu_dm_connector *amdgpu_dm_connector)
-{
- u8 dpcd_data;
- bool capable = false;
-
- if (amdgpu_dm_connector->dc_link &&
- dm_helpers_dp_read_dpcd(
- NULL,
- amdgpu_dm_connector->dc_link,
- DP_DOWN_STREAM_PORT_COUNT,
- &dpcd_data,
- sizeof(dpcd_data))) {
- capable = (dpcd_data & DP_MSA_TIMING_PAR_IGNORED) ? true:false;
- }
-
- return capable;
-}
-
static bool dm_edid_parser_send_cea(struct amdgpu_display_manager *dm,
unsigned int offset,
unsigned int total_length,
@@ -12087,8 +12107,8 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
sink->sink_signal == SIGNAL_TYPE_EDP)) {
bool edid_check_required = false;
- if (is_dp_capable_without_timing_msa(adev->dm.dc,
- amdgpu_dm_connector)) {
+ if (amdgpu_dm_connector->dc_link &&
+ amdgpu_dm_connector->dc_link->dpcd_caps.allow_invalid_MSA_timing_param) {
if (edid->features & DRM_EDID_FEATURE_CONTINUOUS_FREQ) {
amdgpu_dm_connector->min_vfreq = connector->display_info.monitor_range.min_vfreq;
amdgpu_dm_connector->max_vfreq = connector->display_info.monitor_range.max_vfreq;
@@ -12170,7 +12190,8 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
}
}
- as_type = dm_get_adaptive_sync_support_type(amdgpu_dm_connector->dc_link);
+ if (amdgpu_dm_connector->dc_link)
+ as_type = dm_get_adaptive_sync_support_type(amdgpu_dm_connector->dc_link);
if (as_type == FREESYNC_TYPE_PCON_IN_WHITELIST) {
i = parse_hdmi_amd_vsdb(amdgpu_dm_connector, edid, &vsdb_info);
@@ -12194,6 +12215,12 @@ update:
if (dm_con_state)
dm_con_state->freesync_capable = freesync_capable;
+ if (connector->state && amdgpu_dm_connector->dc_link && !freesync_capable &&
+ amdgpu_dm_connector->dc_link->replay_settings.config.replay_supported) {
+ amdgpu_dm_connector->dc_link->replay_settings.config.replay_supported = false;
+ amdgpu_dm_connector->dc_link->replay_settings.replay_feature_enabled = false;
+ }
+
if (connector->vrr_capable_property)
drm_connector_set_vrr_capable_property(connector,
freesync_capable);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 99014339aaa3..a2cf2c066a76 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -251,9 +251,10 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work)
else if (dm->active_vblank_irq_count)
dm->active_vblank_irq_count--;
- dc_allow_idle_optimizations(dm->dc, dm->active_vblank_irq_count == 0);
-
- DRM_DEBUG_KMS("Allow idle optimizations (MALL): %d\n", dm->active_vblank_irq_count == 0);
+ if (dm->active_vblank_irq_count > 0) {
+ DRM_DEBUG_KMS("Allow idle optimizations (MALL): false\n");
+ dc_allow_idle_optimizations(dm->dc, false);
+ }
/*
* Control PSR based on vblank requirements from OS
@@ -272,6 +273,11 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work)
vblank_work->stream->link->replay_settings.replay_feature_enabled);
}
+ if (dm->active_vblank_irq_count == 0) {
+ DRM_DEBUG_KMS("Allow idle optimizations (MALL): true\n");
+ dc_allow_idle_optimizations(dm->dc, true);
+ }
+
mutex_unlock(&dm->dc_lock);
dc_stream_release(vblank_work->stream);
@@ -286,11 +292,14 @@ static inline int amdgpu_dm_crtc_set_vblank(struct drm_crtc *crtc, bool enable)
struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state);
struct amdgpu_display_manager *dm = &adev->dm;
struct vblank_control_work *work;
+ int irq_type;
int rc = 0;
if (acrtc->otg_inst == -1)
goto skip;
+ irq_type = amdgpu_display_crtc_idx_to_irq_type(adev, acrtc->crtc_id);
+
if (enable) {
/* vblank irq on -> Only need vupdate irq in vrr mode */
if (amdgpu_dm_crtc_vrr_active(acrtc_state))
@@ -303,13 +312,52 @@ static inline int amdgpu_dm_crtc_set_vblank(struct drm_crtc *crtc, bool enable)
if (rc)
return rc;
- rc = (enable)
- ? amdgpu_irq_get(adev, &adev->crtc_irq, acrtc->crtc_id)
- : amdgpu_irq_put(adev, &adev->crtc_irq, acrtc->crtc_id);
+ /* crtc vblank or vstartup interrupt */
+ if (enable) {
+ rc = amdgpu_irq_get(adev, &adev->crtc_irq, irq_type);
+ drm_dbg_vbl(crtc->dev, "Get crtc_irq ret=%d\n", rc);
+ } else {
+ rc = amdgpu_irq_put(adev, &adev->crtc_irq, irq_type);
+ drm_dbg_vbl(crtc->dev, "Put crtc_irq ret=%d\n", rc);
+ }
if (rc)
return rc;
+ /*
+ * hubp surface flip interrupt
+ *
+ * We have no guarantee that the frontend index maps to the same
+ * backend index - some even map to more than one.
+ *
+ * TODO: Use a different interrupt or check DC itself for the mapping.
+ */
+ if (enable) {
+ rc = amdgpu_irq_get(adev, &adev->pageflip_irq, irq_type);
+ drm_dbg_vbl(crtc->dev, "Get pageflip_irq ret=%d\n", rc);
+ } else {
+ rc = amdgpu_irq_put(adev, &adev->pageflip_irq, irq_type);
+ drm_dbg_vbl(crtc->dev, "Put pageflip_irq ret=%d\n", rc);
+ }
+
+ if (rc)
+ return rc;
+
+#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+ /* crtc vline0 interrupt, only available on DCN+ */
+ if (amdgpu_ip_version(adev, DCE_HWIP, 0) != 0) {
+ if (enable) {
+ rc = amdgpu_irq_get(adev, &adev->vline0_irq, irq_type);
+ drm_dbg_vbl(crtc->dev, "Get vline0_irq ret=%d\n", rc);
+ } else {
+ rc = amdgpu_irq_put(adev, &adev->vline0_irq, irq_type);
+ drm_dbg_vbl(crtc->dev, "Put vline0_irq ret=%d\n", rc);
+ }
+
+ if (rc)
+ return rc;
+ }
+#endif
skip:
if (amdgpu_in_reset(adev))
return 0;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 62cb59f00929..db56b0aa5454 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -3804,9 +3804,12 @@ static int trigger_hpd_mst_set(void *data, u64 val)
if (aconnector->dc_link->type == dc_connection_mst_branch &&
aconnector->mst_mgr.aux) {
mutex_lock(&adev->dm.dc_lock);
- dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);
+ ret = dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);
mutex_unlock(&adev->dm.dc_lock);
+ if (!ret)
+ DRM_ERROR("DM_MST: Failed to detect dc link!");
+
ret = drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true);
if (ret < 0)
DRM_ERROR("DM_MST: Failed to set the device into MST mode!");
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index b490ae67b6be..50109d13d967 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -759,7 +759,7 @@ static uint8_t write_dsc_enable_synaptics_non_virtual_dpcd_mst(
uint8_t ret = 0;
drm_dbg_dp(aux->drm_dev,
- "Configure DSC to non-virtual dpcd synaptics\n");
+ "MST_DSC Configure DSC to non-virtual dpcd synaptics\n");
if (enable) {
/* When DSC is enabled on previous boot and reboot with the hub,
@@ -772,7 +772,7 @@ static uint8_t write_dsc_enable_synaptics_non_virtual_dpcd_mst(
apply_synaptics_fifo_reset_wa(aux);
ret = drm_dp_dpcd_write(aux, DP_DSC_ENABLE, &enable, 1);
- DRM_INFO("Send DSC enable to synaptics\n");
+ DRM_INFO("MST_DSC Send DSC enable to synaptics\n");
} else {
/* Synaptics hub not support virtual dpcd,
@@ -781,7 +781,7 @@ static uint8_t write_dsc_enable_synaptics_non_virtual_dpcd_mst(
*/
if (!stream->link->link_status.link_active) {
ret = drm_dp_dpcd_write(aux, DP_DSC_ENABLE, &enable, 1);
- DRM_INFO("Send DSC disable to synaptics\n");
+ DRM_INFO("MST_DSC Send DSC disable to synaptics\n");
}
}
@@ -823,14 +823,14 @@ bool dm_helpers_dp_write_dsc_enable(
DP_DSC_ENABLE,
&enable_passthrough, 1);
drm_dbg_dp(dev,
- "Sent DSC pass-through enable to virtual dpcd port, ret = %u\n",
+ "MST_DSC Sent DSC pass-through enable to virtual dpcd port, ret = %u\n",
ret);
}
ret = drm_dp_dpcd_write(aconnector->dsc_aux,
DP_DSC_ENABLE, &enable_dsc, 1);
drm_dbg_dp(dev,
- "Sent DSC decoding enable to %s port, ret = %u\n",
+ "MST_DSC Sent DSC decoding enable to %s port, ret = %u\n",
(port->passthrough_aux) ? "remote RX" :
"virtual dpcd",
ret);
@@ -838,7 +838,7 @@ bool dm_helpers_dp_write_dsc_enable(
ret = drm_dp_dpcd_write(aconnector->dsc_aux,
DP_DSC_ENABLE, &enable_dsc, 1);
drm_dbg_dp(dev,
- "Sent DSC decoding disable to %s port, ret = %u\n",
+ "MST_DSC Sent DSC decoding disable to %s port, ret = %u\n",
(port->passthrough_aux) ? "remote RX" :
"virtual dpcd",
ret);
@@ -848,7 +848,7 @@ bool dm_helpers_dp_write_dsc_enable(
DP_DSC_ENABLE,
&enable_passthrough, 1);
drm_dbg_dp(dev,
- "Sent DSC pass-through disable to virtual dpcd port, ret = %u\n",
+ "MST_DSC Sent DSC pass-through disable to virtual dpcd port, ret = %u\n",
ret);
}
}
@@ -858,12 +858,12 @@ bool dm_helpers_dp_write_dsc_enable(
if (stream->sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_NONE) {
ret = dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1);
drm_dbg_dp(dev,
- "Send DSC %s to SST RX\n",
+ "SST_DSC Send DSC %s to SST RX\n",
enable_dsc ? "enable" : "disable");
} else if (stream->sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER) {
ret = dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1);
drm_dbg_dp(dev,
- "Send DSC %s to DP-HDMI PCON\n",
+ "SST_DSC Send DSC %s to DP-HDMI PCON\n",
enable_dsc ? "enable" : "disable");
}
}
@@ -1286,3 +1286,15 @@ enum adaptive_sync_type dm_get_adaptive_sync_support_type(struct dc_link *link)
return as_type;
}
+
+bool dm_helpers_is_fullscreen(struct dc_context *ctx, struct dc_stream_state *stream)
+{
+ // TODO
+ return false;
+}
+
+bool dm_helpers_is_hdr_on(struct dc_context *ctx, struct dc_stream_state *stream)
+{
+ // TODO
+ return false;
+} \ No newline at end of file
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 2e9f6da1acdc..c0c61c03984c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -253,7 +253,7 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto
aconnector->dsc_aux = &aconnector->mst_root->dm_dp_aux.aux;
/* synaptics cascaded MST hub case */
- if (!aconnector->dsc_aux && is_synaptics_cascaded_panamera(aconnector->dc_link, port))
+ if (is_synaptics_cascaded_panamera(aconnector->dc_link, port))
aconnector->dsc_aux = port->mgr->aux;
if (!aconnector->dsc_aux)
@@ -578,6 +578,8 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
if (!aconnector)
return NULL;
+ DRM_DEBUG_DRIVER("%s: Create aconnector 0x%p for port 0x%p\n", __func__, aconnector, port);
+
connector = &aconnector->base;
aconnector->mst_output_port = port;
aconnector->mst_root = master;
@@ -872,11 +874,11 @@ static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *p
if (params[i].sink) {
if (params[i].sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
params[i].sink->sink_signal != SIGNAL_TYPE_NONE)
- DRM_DEBUG_DRIVER("%s i=%d dispname=%s\n", __func__, i,
+ DRM_DEBUG_DRIVER("MST_DSC %s i=%d dispname=%s\n", __func__, i,
params[i].sink->edid_caps.display_name);
}
- DRM_DEBUG_DRIVER("dsc=%d bits_per_pixel=%d pbn=%d\n",
+ DRM_DEBUG_DRIVER("MST_DSC dsc=%d bits_per_pixel=%d pbn=%d\n",
params[i].timing->flags.DSC,
params[i].timing->dsc_cfg.bits_per_pixel,
vars[i + k].pbn);
@@ -1054,6 +1056,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
if (next_index == -1)
break;
+ DRM_DEBUG_DRIVER("MST_DSC index #%d, try no compression\n", next_index);
vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
ret = drm_dp_atomic_find_time_slots(state,
params[next_index].port->mgr,
@@ -1064,10 +1067,12 @@ static int try_disable_dsc(struct drm_atomic_state *state,
ret = drm_dp_mst_atomic_check(state);
if (ret == 0) {
+ DRM_DEBUG_DRIVER("MST_DSC index #%d, greedily disable dsc\n", next_index);
vars[next_index].dsc_enabled = false;
vars[next_index].bpp_x16 = 0;
} else {
- vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
+ DRM_DEBUG_DRIVER("MST_DSC index #%d, restore minimum compression\n", next_index);
+ vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps, fec_overhead_multiplier_x1000);
ret = drm_dp_atomic_find_time_slots(state,
params[next_index].port->mgr,
params[next_index].port,
@@ -1082,6 +1087,15 @@ static int try_disable_dsc(struct drm_atomic_state *state,
return 0;
}
+static void log_dsc_params(int count, struct dsc_mst_fairness_vars *vars, int k)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ DRM_DEBUG_DRIVER("MST_DSC DSC params: stream #%d --- dsc_enabled = %d, bpp_x16 = %d, pbn = %d\n",
+ i, vars[i + k].dsc_enabled, vars[i + k].bpp_x16, vars[i + k].pbn);
+}
+
static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
struct dc_state *dc_state,
struct dc_link *dc_link,
@@ -1104,6 +1118,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
return PTR_ERR(mst_state);
/* Set up params */
+ DRM_DEBUG_DRIVER("%s: MST_DSC Set up params for %d streams\n", __func__, dc_state->stream_count);
for (i = 0; i < dc_state->stream_count; i++) {
struct dc_dsc_policy dsc_policy = {0};
@@ -1145,6 +1160,9 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
params[count].bw_range.stream_kbps = dc_bandwidth_in_kbps_from_timing(&stream->timing,
dc_link_get_highest_encoding_format(dc_link));
+ DRM_DEBUG_DRIVER("MST_DSC #%d stream 0x%p - max_kbps = %u, min_kbps = %u, uncompressed_kbps = %u\n",
+ count, stream, params[count].bw_range.max_kbps, params[count].bw_range.min_kbps,
+ params[count].bw_range.stream_kbps);
count++;
}
@@ -1159,6 +1177,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
*link_vars_start_index += count;
/* Try no compression */
+ DRM_DEBUG_DRIVER("MST_DSC Try no compression\n");
for (i = 0; i < count; i++) {
vars[i + k].aconnector = params[i].aconnector;
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
@@ -1177,7 +1196,10 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
return ret;
}
+ log_dsc_params(count, vars, k);
+
/* Try max compression */
+ DRM_DEBUG_DRIVER("MST_DSC Try max compression\n");
for (i = 0; i < count; i++) {
if (params[i].compression_possible && params[i].clock_force_enable != DSC_CLK_FORCE_DISABLE) {
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps, fec_overhead_multiplier_x1000);
@@ -1201,14 +1223,26 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
if (ret != 0)
return ret;
+ log_dsc_params(count, vars, k);
+
/* Optimize degree of compression */
+ DRM_DEBUG_DRIVER("MST_DSC Try optimize compression\n");
ret = increase_dsc_bpp(state, mst_state, dc_link, params, vars, count, k);
- if (ret < 0)
+ if (ret < 0) {
+ DRM_DEBUG_DRIVER("MST_DSC Failed to optimize compression\n");
return ret;
+ }
+ log_dsc_params(count, vars, k);
+
+ DRM_DEBUG_DRIVER("MST_DSC Try disable compression\n");
ret = try_disable_dsc(state, dc_link, params, vars, count, k);
- if (ret < 0)
+ if (ret < 0) {
+ DRM_DEBUG_DRIVER("MST_DSC Failed to disable compression\n");
return ret;
+ }
+
+ log_dsc_params(count, vars, k);
set_dsc_configs_from_fairness_vars(params, vars, count, k);
@@ -1230,17 +1264,19 @@ static bool is_dsc_need_re_compute(
/* only check phy used by dsc mst branch */
if (dc_link->type != dc_connection_mst_branch)
- return false;
+ goto out;
/* add a check for older MST DSC with no virtual DPCDs */
if (needs_dsc_aux_workaround(dc_link) &&
(!(dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT ||
dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT)))
- return false;
+ goto out;
for (i = 0; i < MAX_PIPES; i++)
stream_on_link[i] = NULL;
+ DRM_DEBUG_DRIVER("%s: MST_DSC check on %d streams in new dc_state\n", __func__, dc_state->stream_count);
+
/* check if there is mode change in new request */
for (i = 0; i < dc_state->stream_count; i++) {
struct drm_crtc_state *new_crtc_state;
@@ -1250,6 +1286,8 @@ static bool is_dsc_need_re_compute(
if (!stream)
continue;
+ DRM_DEBUG_DRIVER("%s:%d MST_DSC checking #%d stream 0x%p\n", __func__, __LINE__, i, stream);
+
/* check if stream using the same link for mst */
if (stream->link != dc_link)
continue;
@@ -1262,8 +1300,11 @@ static bool is_dsc_need_re_compute(
new_stream_on_link_num++;
new_conn_state = drm_atomic_get_new_connector_state(state, &aconnector->base);
- if (!new_conn_state)
+ if (!new_conn_state) {
+ DRM_DEBUG_DRIVER("%s:%d MST_DSC no new_conn_state for stream 0x%p, aconnector 0x%p\n",
+ __func__, __LINE__, stream, aconnector);
continue;
+ }
if (IS_ERR(new_conn_state))
continue;
@@ -1272,21 +1313,36 @@ static bool is_dsc_need_re_compute(
continue;
new_crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
- if (!new_crtc_state)
+ if (!new_crtc_state) {
+ DRM_DEBUG_DRIVER("%s:%d MST_DSC no new_crtc_state for crtc of stream 0x%p, aconnector 0x%p\n",
+ __func__, __LINE__, stream, aconnector);
continue;
+ }
if (IS_ERR(new_crtc_state))
continue;
if (new_crtc_state->enable && new_crtc_state->active) {
if (new_crtc_state->mode_changed || new_crtc_state->active_changed ||
- new_crtc_state->connectors_changed)
- return true;
+ new_crtc_state->connectors_changed) {
+ DRM_DEBUG_DRIVER("%s:%d MST_DSC dsc recompute required."
+ "stream 0x%p in new dc_state\n",
+ __func__, __LINE__, stream);
+ is_dsc_need_re_compute = true;
+ goto out;
+ }
}
}
- if (new_stream_on_link_num == 0)
- return false;
+ if (new_stream_on_link_num == 0) {
+ DRM_DEBUG_DRIVER("%s:%d MST_DSC no mode change request for streams in new dc_state\n",
+ __func__, __LINE__);
+ is_dsc_need_re_compute = false;
+ goto out;
+ }
+
+ DRM_DEBUG_DRIVER("%s: MST_DSC check on %d streams in current dc_state\n",
+ __func__, dc->current_state->stream_count);
/* check current_state if there stream on link but it is not in
* new request state
@@ -1310,11 +1366,18 @@ static bool is_dsc_need_re_compute(
if (j == new_stream_on_link_num) {
/* not in new state */
+ DRM_DEBUG_DRIVER("%s:%d MST_DSC dsc recompute required."
+ "stream 0x%p in current dc_state but not in new dc_state\n",
+ __func__, __LINE__, stream);
is_dsc_need_re_compute = true;
break;
}
}
+out:
+ DRM_DEBUG_DRIVER("%s: MST_DSC dsc recompute %s\n",
+ __func__, is_dsc_need_re_compute ? "required" : "not required");
+
return is_dsc_need_re_compute;
}
@@ -1343,6 +1406,9 @@ int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
+ DRM_DEBUG_DRIVER("%s: MST_DSC compute mst dsc configs for stream 0x%p, aconnector 0x%p\n",
+ __func__, stream, aconnector);
+
if (!aconnector || !aconnector->dc_sink || !aconnector->mst_output_port)
continue;
@@ -1375,8 +1441,11 @@ int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
stream = dc_state->streams[i];
if (stream->timing.flags.DSC == 1)
- if (dc_stream_add_dsc_to_resource(stream->ctx->dc, dc_state, stream) != DC_OK)
+ if (dc_stream_add_dsc_to_resource(stream->ctx->dc, dc_state, stream) != DC_OK) {
+ DRM_DEBUG_DRIVER("%s:%d MST_DSC Failed to request dsc hw resource for stream 0x%p\n",
+ __func__, __LINE__, stream);
return -EINVAL;
+ }
}
return ret;
@@ -1405,6 +1474,9 @@ static int pre_compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
+ DRM_DEBUG_DRIVER("MST_DSC pre compute mst dsc configs for #%d stream 0x%p, aconnector 0x%p\n",
+ i, stream, aconnector);
+
if (!aconnector || !aconnector->dc_sink || !aconnector->mst_output_port)
continue;
@@ -1494,12 +1566,12 @@ int pre_validate_dsc(struct drm_atomic_state *state,
int ret = 0;
if (!is_dsc_precompute_needed(state)) {
- DRM_INFO_ONCE("DSC precompute is not needed.\n");
+ DRM_INFO_ONCE("%s:%d MST_DSC dsc precompute is not needed\n", __func__, __LINE__);
return 0;
}
ret = dm_atomic_get_state(state, dm_state_ptr);
if (ret != 0) {
- DRM_INFO_ONCE("dm_atomic_get_state() failed\n");
+ DRM_INFO_ONCE("%s:%d MST_DSC dm_atomic_get_state() failed\n", __func__, __LINE__);
return ret;
}
dm_state = *dm_state_ptr;
@@ -1553,7 +1625,8 @@ int pre_validate_dsc(struct drm_atomic_state *state,
ret = pre_compute_mst_dsc_configs_for_state(state, local_dc_state, vars);
if (ret != 0) {
- DRM_INFO_ONCE("pre_compute_mst_dsc_configs_for_state() failed\n");
+ DRM_INFO_ONCE("%s:%d MST_DSC dsc pre_compute_mst_dsc_configs_for_state() failed\n",
+ __func__, __LINE__);
ret = -EINVAL;
goto clean_exit;
}
@@ -1567,12 +1640,15 @@ int pre_validate_dsc(struct drm_atomic_state *state,
if (local_dc_state->streams[i] &&
dc_is_timing_changed(stream, local_dc_state->streams[i])) {
- DRM_INFO_ONCE("crtc[%d] needs mode_changed\n", i);
+ DRM_INFO_ONCE("%s:%d MST_DSC crtc[%d] needs mode_change\n", __func__, __LINE__, i);
} else {
int ind = find_crtc_index_in_state_by_stream(state, stream);
- if (ind >= 0)
+ if (ind >= 0) {
+ DRM_INFO_ONCE("%s:%d MST_DSC no mode changed for stream 0x%p\n",
+ __func__, __LINE__, stream);
state->crtcs[ind].new_state->mode_changed = 0;
+ }
}
}
clean_exit:
@@ -1697,7 +1773,7 @@ enum dc_status dm_dp_mst_is_port_support_mode(
end_to_end_bw_in_kbps = min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps);
if (stream_kbps <= end_to_end_bw_in_kbps) {
- DRM_DEBUG_DRIVER("No DSC needed. End-to-end bw sufficient.");
+ DRM_DEBUG_DRIVER("MST_DSC no dsc required. End-to-end bw sufficient\n");
return DC_OK;
}
@@ -1710,7 +1786,8 @@ enum dc_status dm_dp_mst_is_port_support_mode(
/*capable of dsc passthough. dsc bitstream along the entire path*/
if (aconnector->mst_output_port->passthrough_aux) {
if (bw_range.min_kbps > end_to_end_bw_in_kbps) {
- DRM_DEBUG_DRIVER("DSC passthrough. Max dsc compression can't fit into end-to-end bw\n");
+ DRM_DEBUG_DRIVER("MST_DSC dsc passthrough and decode at endpoint"
+ "Max dsc compression bw can't fit into end-to-end bw\n");
return DC_FAIL_BANDWIDTH_VALIDATE;
}
} else {
@@ -1721,7 +1798,8 @@ enum dc_status dm_dp_mst_is_port_support_mode(
/*Get last DP link BW capability*/
if (dp_get_link_current_set_bw(&aconnector->mst_output_port->aux, &end_link_bw)) {
if (stream_kbps > end_link_bw) {
- DRM_DEBUG_DRIVER("DSC decode at last link. Mode required bw can't fit into available bw\n");
+ DRM_DEBUG_DRIVER("MST_DSC dsc decode at last link."
+ "Mode required bw can't fit into last link\n");
return DC_FAIL_BANDWIDTH_VALIDATE;
}
}
@@ -1734,7 +1812,8 @@ enum dc_status dm_dp_mst_is_port_support_mode(
virtual_channel_bw_in_kbps = kbps_from_pbn(immediate_upstream_port->full_pbn);
virtual_channel_bw_in_kbps = min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps);
if (bw_range.min_kbps > virtual_channel_bw_in_kbps) {
- DRM_DEBUG_DRIVER("DSC decode at last link. Max dsc compression can't fit into MST available bw\n");
+ DRM_DEBUG_DRIVER("MST_DSC dsc decode at last link."
+ "Max dsc compression can't fit into MST available bw\n");
return DC_FAIL_BANDWIDTH_VALIDATE;
}
}
@@ -1751,9 +1830,9 @@ enum dc_status dm_dp_mst_is_port_support_mode(
dc_link_get_highest_encoding_format(stream->link),
&stream->timing.dsc_cfg)) {
stream->timing.flags.DSC = 1;
- DRM_DEBUG_DRIVER("Require dsc and dsc config found\n");
+ DRM_DEBUG_DRIVER("MST_DSC require dsc and dsc config found\n");
} else {
- DRM_DEBUG_DRIVER("Require dsc but can't find appropriate dsc config\n");
+ DRM_DEBUG_DRIVER("MST_DSC require dsc but can't find appropriate dsc config\n");
return DC_FAIL_BANDWIDTH_VALIDATE;
}
@@ -1775,11 +1854,11 @@ enum dc_status dm_dp_mst_is_port_support_mode(
if (branch_max_throughput_mps != 0 &&
((stream->timing.pix_clk_100hz / 10) > branch_max_throughput_mps * 1000)) {
- DRM_DEBUG_DRIVER("DSC is required but max throughput mps fails");
+ DRM_DEBUG_DRIVER("MST_DSC require dsc but max throughput mps fails\n");
return DC_FAIL_BANDWIDTH_VALIDATE;
}
} else {
- DRM_DEBUG_DRIVER("DSC is required but can't find common dsc config.");
+ DRM_DEBUG_DRIVER("MST_DSC require dsc but can't find common dsc config\n");
return DC_FAIL_BANDWIDTH_VALIDATE;
}
#endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 5cb11cc2d063..25f63b2e7a8e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1283,6 +1283,7 @@ int amdgpu_dm_plane_get_cursor_position(struct drm_plane *plane, struct drm_crtc
struct dc_cursor_position *position)
{
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+ struct amdgpu_device *adev = drm_to_adev(plane->dev);
int x, y;
int xorigin = 0, yorigin = 0;
@@ -1314,12 +1315,14 @@ int amdgpu_dm_plane_get_cursor_position(struct drm_plane *plane, struct drm_crtc
y = 0;
}
position->enable = true;
- position->translate_by_source = true;
position->x = x;
position->y = y;
position->x_hotspot = xorigin;
position->y_hotspot = yorigin;
+ if (amdgpu_ip_version(adev, DCE_HWIP, 0) < IP_VERSION(4, 0, 1))
+ position->translate_by_source = true;
+
return 0;
}
@@ -1377,7 +1380,8 @@ void amdgpu_dm_plane_handle_cursor_update(struct drm_plane *plane,
adev->dm.dc->caps.color.dpp.gamma_corr)
attributes.attribute_flags.bits.ENABLE_CURSOR_DEGAMMA = 1;
- attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0];
+ if (afb)
+ attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0];
if (crtc_state->stream) {
mutex_lock(&adev->dm.dc_lock);
diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile
index 80069651def3..8992e697759f 100644
--- a/drivers/gpu/drm/amd/display/dc/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/Makefile
@@ -35,7 +35,6 @@ DC_LIBS += dcn201
DC_LIBS += dcn30
DC_LIBS += dcn301
DC_LIBS += dcn31
-DC_LIBS += dcn314
DC_LIBS += dml
DC_LIBS += dml2
endif
diff --git a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
index 506f82cd5cc6..88d3f9d7dd55 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
@@ -486,3 +486,30 @@ int dc_fixpt_s4d19(struct fixed31_32 arg)
else
return ux_dy(arg.value, 4, 19);
}
+
+struct fixed31_32 dc_fixpt_from_ux_dy(unsigned int value,
+ unsigned int integer_bits,
+ unsigned int fractional_bits)
+{
+ struct fixed31_32 fixpt_value = dc_fixpt_zero;
+ struct fixed31_32 fixpt_int_value = dc_fixpt_zero;
+ long long frac_mask = ((long long)1 << (long long)integer_bits) - 1;
+
+ fixpt_value.value = (long long)value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
+ frac_mask = frac_mask << fractional_bits;
+ fixpt_int_value.value = value & frac_mask;
+ fixpt_int_value.value <<= (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
+ fixpt_value.value |= fixpt_int_value.value;
+ return fixpt_value;
+}
+
+struct fixed31_32 dc_fixpt_from_int_dy(unsigned int int_value,
+ unsigned int frac_value,
+ unsigned int integer_bits,
+ unsigned int fractional_bits)
+{
+ struct fixed31_32 fixpt_value = dc_fixpt_from_int(int_value);
+
+ fixpt_value.value |= (long long)frac_value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
+ return fixpt_value;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
index 4254bdfefe38..7d18f372ce7a 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
@@ -227,7 +227,7 @@ static void init_transmitter_control(struct bios_parser *bp)
uint8_t frev;
uint8_t crev = 0;
- if (!BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev))
+ if (!BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev) && (bp->base.ctx->dc->ctx->dce_version <= DCN_VERSION_2_0))
BREAK_TO_DEBUGGER();
switch (crev) {
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
index 78df96882d6e..f8409453434c 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
@@ -195,7 +195,7 @@ void dce11_pplib_apply_display_requirements(
* , then change minimum memory clock based on real-time bandwidth
* limitation.
*/
- if ((dc->ctx->asic_id.chip_family == FAMILY_AI) &&
+ if (dc->bw_vbios && (dc->ctx->asic_id.chip_family == FAMILY_AI) &&
ASICREV_IS_VEGA20_P(dc->ctx->asic_id.hw_internal_rev) && (context->stream_count >= 2)) {
pp_display_cfg->min_memory_clock_khz = max(pp_display_cfg->min_memory_clock_khz,
(uint32_t) div64_s64(
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
index 70ee0089a20d..97164b5585a8 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
@@ -120,25 +120,40 @@ static int dcn35_get_active_display_cnt_wa(
return display_count;
}
-
static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context,
bool safe_to_lower, bool disable)
{
struct dc *dc = clk_mgr_base->ctx->dc;
int i;
+ if (dc->ctx->dce_environment == DCE_ENV_DIAG)
+ return;
+
for (i = 0; i < dc->res_pool->pipe_count; ++i) {
+ struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+ struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
struct pipe_ctx *pipe = safe_to_lower
? &context->res_ctx.pipe_ctx[i]
: &dc->current_state->res_ctx.pipe_ctx[i];
-
+ bool stream_changed_otg_dig_on = false;
if (pipe->top_pipe || pipe->prev_odm_pipe)
continue;
+ stream_changed_otg_dig_on = old_pipe->stream && new_pipe->stream &&
+ old_pipe->stream != new_pipe->stream &&
+ old_pipe->stream_res.tg == new_pipe->stream_res.tg &&
+ new_pipe->stream->link_enc && !new_pipe->stream->dpms_off &&
+ new_pipe->stream->link_enc->funcs->is_dig_enabled &&
+ new_pipe->stream->link_enc->funcs->is_dig_enabled(
+ new_pipe->stream->link_enc) &&
+ new_pipe->stream_res.stream_enc &&
+ new_pipe->stream_res.stream_enc->funcs->is_fifo_enabled &&
+ new_pipe->stream_res.stream_enc->funcs->is_fifo_enabled(new_pipe->stream_res.stream_enc);
if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal) ||
- !pipe->stream->link_enc)) {
+ !pipe->stream->link_enc) && !stream_changed_otg_dig_on) {
+ /* This w/a should not trigger when we have a dig active */
if (disable) {
- if (pipe->stream_res.tg && pipe->stream_res.tg->funcs->disable_crtc)
- pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
+ if (pipe->stream_res.tg && pipe->stream_res.tg->funcs->immediate_disable_crtc)
+ pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
reset_sync_context_for_pipe(dc, context, i);
} else {
@@ -367,6 +382,9 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
dcn35_disable_otg_wa(clk_mgr_base, context, safe_to_lower, true);
+ if (dc->debug.min_disp_clk_khz > 0 && new_clocks->dispclk_khz < dc->debug.min_disp_clk_khz)
+ new_clocks->dispclk_khz = dc->debug.min_disp_clk_khz;
+
clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
dcn35_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
dcn35_disable_otg_wa(clk_mgr_base, context, safe_to_lower, false);
@@ -1082,7 +1100,7 @@ void dcn35_clk_mgr_construct(
clk_mgr->smu_wm_set.wm_set = (struct dcn35_watermarks *)dm_helpers_allocate_gpu_mem(
clk_mgr->base.base.ctx,
- DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
+ DC_MEM_ALLOC_TYPE_GART,
sizeof(struct dcn35_watermarks),
&clk_mgr->smu_wm_set.mc_address.quad_part);
@@ -1094,7 +1112,7 @@ void dcn35_clk_mgr_construct(
smu_dpm_clks.dpm_clks = (DpmClocks_t_dcn35 *)dm_helpers_allocate_gpu_mem(
clk_mgr->base.base.ctx,
- DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
+ DC_MEM_ALLOC_TYPE_GART,
sizeof(DpmClocks_t_dcn35),
&smu_dpm_clks.mc_address.quad_part);
@@ -1191,7 +1209,7 @@ void dcn35_clk_mgr_construct(
}
if (smu_dpm_clks.dpm_clks && smu_dpm_clks.mc_address.quad_part != 0)
- dm_helpers_free_gpu_mem(clk_mgr->base.base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
+ dm_helpers_free_gpu_mem(clk_mgr->base.base.ctx, DC_MEM_ALLOC_TYPE_GART,
smu_dpm_clks.dpm_clks);
if (ctx->dc->config.disable_ips != DMUB_IPS_DISABLE_ALL) {
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
index 45fe17a46890..8cfc5f435937 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
@@ -14,6 +14,7 @@
#include "core_types.h"
#include "dm_helpers.h"
#include "link.h"
+#include "dc_state_priv.h"
#include "atomfirmware.h"
#include "dcn401_smu14_driver_if.h"
@@ -29,6 +30,7 @@
#define mmCLK01_CLK0_CLK2_DFS_CNTL 0x16E6F
#define mmCLK01_CLK0_CLK3_DFS_CNTL 0x16E72
#define mmCLK01_CLK0_CLK4_DFS_CNTL 0x16E75
+#define mmCLK20_CLK2_CLK2_DFS_CNTL 0x1B051
#define CLK0_CLK_PLL_REQ__FbMult_int_MASK 0x000001ffUL
#define CLK0_CLK_PLL_REQ__PllSpineDiv_MASK 0x0000f000UL
@@ -302,6 +304,197 @@ void dcn401_init_clocks(struct clk_mgr *clk_mgr_base)
dcn401_build_wm_range_table(clk_mgr_base);
}
+static void dcn401_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass,
+ struct clk_mgr *clk_mgr_base, struct clk_log_info *log_info)
+{
+ struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+ uint32_t dprefclk_did = 0;
+ uint32_t dcfclk_did = 0;
+ uint32_t dtbclk_did = 0;
+ uint32_t dispclk_did = 0;
+ uint32_t dppclk_did = 0;
+ uint32_t fclk_did = 0;
+ uint32_t target_div = 0;
+
+ /* DFS Slice 0 is used for DISPCLK */
+ dispclk_did = REG_READ(CLK0_CLK0_DFS_CNTL);
+ /* DFS Slice 1 is used for DPPCLK */
+ dppclk_did = REG_READ(CLK0_CLK1_DFS_CNTL);
+ /* DFS Slice 2 is used for DPREFCLK */
+ dprefclk_did = REG_READ(CLK0_CLK2_DFS_CNTL);
+ /* DFS Slice 3 is used for DCFCLK */
+ dcfclk_did = REG_READ(CLK0_CLK3_DFS_CNTL);
+ /* DFS Slice 4 is used for DTBCLK */
+ dtbclk_did = REG_READ(CLK0_CLK4_DFS_CNTL);
+ /* DFS Slice _ is used for FCLK */
+ fclk_did = REG_READ(CLK2_CLK2_DFS_CNTL);
+
+ /* Convert DISPCLK DFS Slice DID to divider*/
+ target_div = dentist_get_divider_from_did(dispclk_did);
+ //Get dispclk in khz
+ regs_and_bypass->dispclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+ * clk_mgr->base.dentist_vco_freq_khz) / target_div;
+
+ /* Convert DISPCLK DFS Slice DID to divider*/
+ target_div = dentist_get_divider_from_did(dppclk_did);
+ //Get dppclk in khz
+ regs_and_bypass->dppclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+ * clk_mgr->base.dentist_vco_freq_khz) / target_div;
+
+ /* Convert DPREFCLK DFS Slice DID to divider*/
+ target_div = dentist_get_divider_from_did(dprefclk_did);
+ //Get dprefclk in khz
+ regs_and_bypass->dprefclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+ * clk_mgr->base.dentist_vco_freq_khz) / target_div;
+
+ /* Convert DCFCLK DFS Slice DID to divider*/
+ target_div = dentist_get_divider_from_did(dcfclk_did);
+ //Get dcfclk in khz
+ regs_and_bypass->dcfclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+ * clk_mgr->base.dentist_vco_freq_khz) / target_div;
+
+ /* Convert DTBCLK DFS Slice DID to divider*/
+ target_div = dentist_get_divider_from_did(dtbclk_did);
+ //Get dtbclk in khz
+ regs_and_bypass->dtbclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+ * clk_mgr->base.dentist_vco_freq_khz) / target_div;
+
+ /* Convert DTBCLK DFS Slice DID to divider*/
+ target_div = dentist_get_divider_from_did(fclk_did);
+ //Get fclk in khz
+ regs_and_bypass->fclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+ * clk_mgr->base.dentist_vco_freq_khz) / target_div;
+}
+
+static bool dcn401_check_native_scaling(struct pipe_ctx *pipe)
+{
+ bool is_native_scaling = false;
+ int width = pipe->plane_state->src_rect.width;
+ int height = pipe->plane_state->src_rect.height;
+
+ if (pipe->stream->timing.h_addressable == width &&
+ pipe->stream->timing.v_addressable == height &&
+ pipe->plane_state->dst_rect.width == width &&
+ pipe->plane_state->dst_rect.height == height)
+ is_native_scaling = true;
+
+ return is_native_scaling;
+}
+
+static void dcn401_auto_dpm_test_log(
+ struct dc_clocks *new_clocks,
+ struct clk_mgr_internal *clk_mgr,
+ struct dc_state *context)
+{
+ unsigned int mall_ss_size_bytes;
+ int dramclk_khz_override, fclk_khz_override, num_fclk_levels;
+
+ struct pipe_ctx *pipe_ctx_list[MAX_PIPES];
+ int active_pipe_count = 0;
+
+ for (int i = 0; i < MAX_PIPES; i++) {
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+ if (pipe_ctx->stream && dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM) {
+ pipe_ctx_list[active_pipe_count] = pipe_ctx;
+ active_pipe_count++;
+ }
+ }
+
+ msleep(5);
+
+ mall_ss_size_bytes = context->bw_ctx.bw.dcn.mall_ss_size_bytes;
+
+ struct clk_log_info log_info = {0};
+ struct clk_state_registers_and_bypass clk_register_dump;
+
+ dcn401_dump_clk_registers(&clk_register_dump, &clk_mgr->base, &log_info);
+
+ // Overrides for these clocks in case there is no p_state change support
+ dramclk_khz_override = new_clocks->dramclk_khz;
+ fclk_khz_override = new_clocks->fclk_khz;
+
+ num_fclk_levels = clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_fclk_levels - 1;
+
+ if (!new_clocks->p_state_change_support)
+ dramclk_khz_override = clk_mgr->base.bw_params->max_memclk_mhz * 1000;
+
+ if (!new_clocks->fclk_p_state_change_support)
+ fclk_khz_override = clk_mgr->base.bw_params->clk_table.entries[num_fclk_levels].fclk_mhz * 1000;
+
+
+ ////////////////////////////////////////////////////////////////////////////
+ // IMPORTANT: When adding more clocks to these logs, do NOT put a newline
+ // anywhere other than at the very end of the string.
+ //
+ // Formatting example (make sure to have " - " between each entry):
+ //
+ // AutoDPMTest: clk1:%d - clk2:%d - clk3:%d - clk4:%d\n"
+ ////////////////////////////////////////////////////////////////////////////
+ if (active_pipe_count > 0 &&
+ new_clocks->dramclk_khz > 0 &&
+ new_clocks->fclk_khz > 0 &&
+ new_clocks->dcfclk_khz > 0 &&
+ new_clocks->dppclk_khz > 0) {
+
+ uint32_t pix_clk_list[MAX_PIPES] = {0};
+ int p_state_list[MAX_PIPES] = {0};
+ int disp_src_width_list[MAX_PIPES] = {0};
+ int disp_src_height_list[MAX_PIPES] = {0};
+ uint64_t disp_src_refresh_list[MAX_PIPES] = {0};
+ bool is_scaled_list[MAX_PIPES] = {0};
+
+ for (int i = 0; i < active_pipe_count; i++) {
+ struct pipe_ctx *curr_pipe_ctx = pipe_ctx_list[i];
+ uint64_t refresh_rate;
+
+ pix_clk_list[i] = curr_pipe_ctx->stream->timing.pix_clk_100hz;
+ p_state_list[i] = curr_pipe_ctx->p_state_type;
+
+ refresh_rate = (curr_pipe_ctx->stream->timing.pix_clk_100hz * (uint64_t)100 +
+ curr_pipe_ctx->stream->timing.v_total
+ * (uint64_t) curr_pipe_ctx->stream->timing.h_total - (uint64_t)1);
+ refresh_rate = div_u64(refresh_rate, curr_pipe_ctx->stream->timing.v_total);
+ refresh_rate = div_u64(refresh_rate, curr_pipe_ctx->stream->timing.h_total);
+ disp_src_refresh_list[i] = refresh_rate;
+
+ if (curr_pipe_ctx->plane_state) {
+ is_scaled_list[i] = !(dcn401_check_native_scaling(curr_pipe_ctx));
+ disp_src_width_list[i] = curr_pipe_ctx->plane_state->src_rect.width;
+ disp_src_height_list[i] = curr_pipe_ctx->plane_state->src_rect.height;
+ }
+ }
+
+ DC_LOG_AUTO_DPM_TEST("AutoDPMTest: dramclk:%d - fclk:%d - "
+ "dcfclk:%d - dppclk:%d - dispclk_hw:%d - "
+ "dppclk_hw:%d - dprefclk_hw:%d - dcfclk_hw:%d - "
+ "dtbclk_hw:%d - fclk_hw:%d - pix_clk_0:%d - pix_clk_1:%d - "
+ "pix_clk_2:%d - pix_clk_3:%d - mall_ss_size:%d - p_state_type_0:%d - "
+ "p_state_type_1:%d - p_state_type_2:%d - p_state_type_3:%d - "
+ "pix_width_0:%d - pix_height_0:%d - refresh_rate_0:%lld - is_scaled_0:%d - "
+ "pix_width_1:%d - pix_height_1:%d - refresh_rate_1:%lld - is_scaled_1:%d - "
+ "pix_width_2:%d - pix_height_2:%d - refresh_rate_2:%lld - is_scaled_2:%d - "
+ "pix_width_3:%d - pix_height_3:%d - refresh_rate_3:%lld - is_scaled_3:%d - LOG_END\n",
+ dramclk_khz_override,
+ fclk_khz_override,
+ new_clocks->dcfclk_khz,
+ new_clocks->dppclk_khz,
+ clk_register_dump.dispclk,
+ clk_register_dump.dppclk,
+ clk_register_dump.dprefclk,
+ clk_register_dump.dcfclk,
+ clk_register_dump.dtbclk,
+ clk_register_dump.fclk,
+ pix_clk_list[0], pix_clk_list[1], pix_clk_list[3], pix_clk_list[2],
+ mall_ss_size_bytes,
+ p_state_list[0], p_state_list[1], p_state_list[2], p_state_list[3],
+ disp_src_width_list[0], disp_src_height_list[0], disp_src_refresh_list[0], is_scaled_list[0],
+ disp_src_width_list[1], disp_src_height_list[1], disp_src_refresh_list[1], is_scaled_list[1],
+ disp_src_width_list[2], disp_src_height_list[2], disp_src_refresh_list[2], is_scaled_list[2],
+ disp_src_width_list[3], disp_src_height_list[3], disp_src_refresh_list[3], is_scaled_list[3]);
+ }
+}
+
static void dcn401_update_clocks_update_dtb_dto(struct clk_mgr_internal *clk_mgr,
struct dc_state *context,
int ref_dtbclk_khz)
@@ -324,10 +517,12 @@ static void dcn401_update_clocks_update_dtb_dto(struct clk_mgr_internal *clk_mgr
if (!use_hpo_encoder)
continue;
- otg_master->clock_source->funcs->program_pix_clk(
+ if (otg_master->stream_res.pix_clk_params.controller_id > CONTROLLER_ID_UNDEFINED)
+ otg_master->clock_source->funcs->program_pix_clk(
otg_master->clock_source,
&otg_master->stream_res.pix_clk_params,
- dccg->ctx->dc->link_srv->dp_get_encoding_format(&otg_master->link_config.dp_link_settings),
+ dccg->ctx->dc->link_srv->dp_get_encoding_format(
+ &otg_master->link_config.dp_link_settings),
&otg_master->pll_settings);
}
}
@@ -738,12 +933,12 @@ static void dcn401_execute_block_sequence(struct clk_mgr *clk_mgr_base, unsigned
static unsigned int dcn401_build_update_bandwidth_clocks_sequence(
struct clk_mgr *clk_mgr_base,
struct dc_state *context,
+ struct dc_clocks *new_clocks,
bool safe_to_lower)
{
struct clk_mgr_internal *clk_mgr_internal = TO_CLK_MGR_INTERNAL(clk_mgr_base);
struct dcn401_clk_mgr *clk_mgr401 = TO_DCN401_CLK_MGR(clk_mgr_internal);
struct dc *dc = clk_mgr_base->ctx->dc;
- struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
struct dcn401_clk_mgr_block_sequence *block_sequence = clk_mgr401->block_sequence;
bool enter_display_off = false;
bool update_active_fclk = false;
@@ -1025,13 +1220,13 @@ static unsigned int dcn401_build_update_bandwidth_clocks_sequence(
static unsigned int dcn401_build_update_display_clocks_sequence(
struct clk_mgr *clk_mgr_base,
struct dc_state *context,
+ struct dc_clocks *new_clocks,
bool safe_to_lower)
{
struct clk_mgr_internal *clk_mgr_internal = TO_CLK_MGR_INTERNAL(clk_mgr_base);
struct dcn401_clk_mgr *clk_mgr401 = TO_DCN401_CLK_MGR(clk_mgr_internal);
struct dc *dc = clk_mgr_base->ctx->dc;
struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu;
- struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
struct dcn401_clk_mgr_block_sequence *block_sequence = clk_mgr401->block_sequence;
bool force_reset = false;
bool update_dispclk = false;
@@ -1171,9 +1366,6 @@ static void dcn401_update_clocks(struct clk_mgr *clk_mgr_base,
unsigned int num_steps = 0;
- if (dc->work_arounds.skip_clock_update)
- return;
-
if (dc->debug.enable_legacy_clock_update) {
dcn401_update_clocks_legacy(clk_mgr_base, context, safe_to_lower);
return;
@@ -1182,6 +1374,7 @@ static void dcn401_update_clocks(struct clk_mgr *clk_mgr_base,
/* build bandwidth related clocks update sequence */
num_steps = dcn401_build_update_bandwidth_clocks_sequence(clk_mgr_base,
context,
+ &context->bw_ctx.bw.dcn.clk,
safe_to_lower);
/* execute sequence */
@@ -1190,10 +1383,15 @@ static void dcn401_update_clocks(struct clk_mgr *clk_mgr_base,
/* build display related clocks update sequence */
num_steps = dcn401_build_update_display_clocks_sequence(clk_mgr_base,
context,
+ &context->bw_ctx.bw.dcn.clk,
safe_to_lower);
/* execute sequence */
dcn401_execute_block_sequence(clk_mgr_base, num_steps);
+
+ if (dc->config.enable_auto_dpm_test_logs)
+ dcn401_auto_dpm_test_log(&context->bw_ctx.bw.dcn.clk, TO_CLK_MGR_INTERNAL(clk_mgr_base), context);
+
}
@@ -1218,59 +1416,6 @@ static uint32_t dcn401_get_vco_frequency_from_reg(struct clk_mgr_internal *clk_m
return dc_fixpt_floor(pll_req);
}
-static void dcn401_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass,
- struct clk_mgr *clk_mgr_base, struct clk_log_info *log_info)
-{
- struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
- uint32_t dprefclk_did = 0;
- uint32_t dcfclk_did = 0;
- uint32_t dtbclk_did = 0;
- uint32_t dispclk_did = 0;
- uint32_t dppclk_did = 0;
- uint32_t target_div = 0;
-
- /* DFS Slice 0 is used for DISPCLK */
- dispclk_did = REG_READ(CLK0_CLK0_DFS_CNTL);
- /* DFS Slice 1 is used for DPPCLK */
- dppclk_did = REG_READ(CLK0_CLK1_DFS_CNTL);
- /* DFS Slice 2 is used for DPREFCLK */
- dprefclk_did = REG_READ(CLK0_CLK2_DFS_CNTL);
- /* DFS Slice 3 is used for DCFCLK */
- dcfclk_did = REG_READ(CLK0_CLK3_DFS_CNTL);
- /* DFS Slice 4 is used for DTBCLK */
- dtbclk_did = REG_READ(CLK0_CLK4_DFS_CNTL);
-
- /* Convert DISPCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dispclk_did);
- //Get dispclk in khz
- regs_and_bypass->dispclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
- * clk_mgr->base.dentist_vco_freq_khz) / target_div;
-
- /* Convert DISPCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dppclk_did);
- //Get dppclk in khz
- regs_and_bypass->dppclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
- * clk_mgr->base.dentist_vco_freq_khz) / target_div;
-
- /* Convert DPREFCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dprefclk_did);
- //Get dprefclk in khz
- regs_and_bypass->dprefclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
- * clk_mgr->base.dentist_vco_freq_khz) / target_div;
-
- /* Convert DCFCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dcfclk_did);
- //Get dcfclk in khz
- regs_and_bypass->dcfclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
- * clk_mgr->base.dentist_vco_freq_khz) / target_div;
-
- /* Convert DTBCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dtbclk_did);
- //Get dtbclk in khz
- regs_and_bypass->dtbclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
- * clk_mgr->base.dentist_vco_freq_khz) / target_div;
-}
-
static void dcn401_clock_read_ss_info(struct clk_mgr_internal *clk_mgr)
{
struct dc_bios *bp = clk_mgr->base.ctx->dc_bios;
@@ -1330,33 +1475,34 @@ static void dcn401_notify_wm_ranges(struct clk_mgr *clk_mgr_base)
static void dcn401_set_hard_min_memclk(struct clk_mgr *clk_mgr_base, bool current_mode)
{
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+ const struct dc *dc = clk_mgr->base.ctx->dc;
+ struct dc_state *context = dc->current_state;
+ struct dc_clocks new_clocks;
+ int num_steps;
if (!clk_mgr->smu_present || !dcn401_is_ppclk_dpm_enabled(clk_mgr, PPCLK_UCLK))
return;
+ /* build clock update */
+ memcpy(&new_clocks, &clk_mgr_base->clks, sizeof(struct dc_clocks));
+
if (current_mode) {
- if (clk_mgr_base->clks.p_state_change_support)
- dcn401_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
- khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz));
- else
- dcn401_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
- clk_mgr_base->bw_params->max_memclk_mhz);
+ new_clocks.dramclk_khz = context->bw_ctx.bw.dcn.clk.dramclk_khz;
+ new_clocks.idle_dramclk_khz = context->bw_ctx.bw.dcn.clk.idle_dramclk_khz;
+ new_clocks.p_state_change_support = context->bw_ctx.bw.dcn.clk.p_state_change_support;
} else {
- dcn401_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
- clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz);
+ new_clocks.dramclk_khz = clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz * 1000;
+ new_clocks.idle_dramclk_khz = new_clocks.dramclk_khz;
+ new_clocks.p_state_change_support = true;
}
-}
-
-/* Set max memclk to highest DPM value */
-static void dcn401_set_hard_max_memclk(struct clk_mgr *clk_mgr_base)
-{
- struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
- if (!clk_mgr->smu_present || !dcn401_is_ppclk_dpm_enabled(clk_mgr, PPCLK_UCLK))
- return;
+ num_steps = dcn401_build_update_bandwidth_clocks_sequence(clk_mgr_base,
+ context,
+ &new_clocks,
+ true);
- dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK,
- clk_mgr_base->bw_params->max_memclk_mhz);
+ /* execute sequence */
+ dcn401_execute_block_sequence(clk_mgr_base, num_steps);
}
/* Get current memclk states, update bounding box */
@@ -1487,7 +1633,6 @@ static struct clk_mgr_funcs dcn401_funcs = {
.init_clocks = dcn401_init_clocks,
.notify_wm_ranges = dcn401_notify_wm_ranges,
.set_hard_min_memclk = dcn401_set_hard_min_memclk,
- .set_hard_max_memclk = dcn401_set_hard_max_memclk,
.get_memclk_states_from_smu = dcn401_get_memclk_states_from_smu,
.are_clock_states_equal = dcn401_are_clock_states_equal,
.enable_pme_wa = dcn401_enable_pme_wa,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 85a2ef82afa5..ae788154896c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1254,7 +1254,8 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
if (pipe->stream && pipe->plane_state) {
- set_p_state_switch_method(dc, context, pipe);
+ if (!dc->debug.using_dml2)
+ set_p_state_switch_method(dc, context, pipe);
dc_update_visual_confirm_color(dc, context, pipe);
}
@@ -1351,80 +1352,6 @@ static void disable_vbios_mode_if_required(
}
}
-/**
- * wait_for_blank_complete - wait for all active OPPs to finish pending blank
- * pattern updates
- *
- * @dc: [in] dc reference
- * @context: [in] hardware context in use
- */
-static void wait_for_blank_complete(struct dc *dc,
- struct dc_state *context)
-{
- struct pipe_ctx *opp_head;
- struct dce_hwseq *hws = dc->hwseq;
- int i;
-
- if (!hws->funcs.wait_for_blank_complete)
- return;
-
- for (i = 0; i < MAX_PIPES; i++) {
- opp_head = &context->res_ctx.pipe_ctx[i];
-
- if (!resource_is_pipe_type(opp_head, OPP_HEAD) ||
- dc_state_get_pipe_subvp_type(context, opp_head) == SUBVP_PHANTOM)
- continue;
-
- hws->funcs.wait_for_blank_complete(opp_head->stream_res.opp);
- }
-}
-
-static void wait_for_odm_update_pending_complete(struct dc *dc, struct dc_state *context)
-{
- struct pipe_ctx *otg_master;
- struct timing_generator *tg;
- int i;
-
- for (i = 0; i < MAX_PIPES; i++) {
- otg_master = &context->res_ctx.pipe_ctx[i];
- if (!resource_is_pipe_type(otg_master, OTG_MASTER) ||
- dc_state_get_pipe_subvp_type(context, otg_master) == SUBVP_PHANTOM)
- continue;
- tg = otg_master->stream_res.tg;
- if (tg->funcs->wait_odm_doublebuffer_pending_clear)
- tg->funcs->wait_odm_doublebuffer_pending_clear(tg);
- }
-
- /* ODM update may require to reprogram blank pattern for each OPP */
- wait_for_blank_complete(dc, context);
-}
-
-static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
-{
- int i;
- PERF_TRACE();
- for (i = 0; i < MAX_PIPES; i++) {
- int count = 0;
- struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-
- if (!pipe->plane_state || dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_PHANTOM)
- continue;
-
- /* Timeout 100 ms */
- while (count < 100000) {
- /* Must set to false to start with, due to OR in update function */
- pipe->plane_state->status.is_flip_pending = false;
- dc->hwss.update_pending_status(pipe);
- if (!pipe->plane_state->status.is_flip_pending)
- break;
- udelay(1);
- count++;
- }
- ASSERT(!pipe->plane_state->status.is_flip_pending);
- }
- PERF_TRACE();
-}
-
/* Public functions */
struct dc *dc_create(const struct dc_init_data *init_params)
@@ -1822,10 +1749,18 @@ bool dc_validate_boot_timing(const struct dc *dc,
tg->funcs->get_optc_source(tg,
&numOdmPipes, &id_src[0], &id_src[1]);
- if (numOdmPipes == 2)
+ if (numOdmPipes == 2) {
pix_clk_100hz *= 2;
- if (numOdmPipes == 4)
+ } else if (numOdmPipes == 4) {
pix_clk_100hz *= 4;
+ } else if (se && se->funcs->get_pixels_per_cycle) {
+ uint32_t pixels_per_cycle = se->funcs->get_pixels_per_cycle(se);
+
+ if (pixels_per_cycle != 1 && !dc->debug.enable_dp_dig_pixel_rate_div_policy)
+ return false;
+
+ pix_clk_100hz *= pixels_per_cycle;
+ }
// Note: In rare cases, HW pixclk may differ from crtc's pixclk
// slightly due to rounding issues in 10 kHz units.
@@ -2100,12 +2035,12 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
if (context->stream_count > get_seamless_boot_stream_count(context) ||
context->stream_count == 0) {
/* Must wait for no flips to be pending before doing optimize bw */
- wait_for_no_pipes_pending(dc, context);
+ hwss_wait_for_no_pipes_pending(dc, context);
/*
* optimized dispclk depends on ODM setup. Need to wait for ODM
* update pending complete before optimizing bandwidth.
*/
- wait_for_odm_update_pending_complete(dc, context);
+ hwss_wait_for_odm_update_pending_complete(dc, context);
/* pplib is notified if disp_num changed */
dc->hwss.optimize_bandwidth(dc, context);
/* Need to do otg sync again as otg could be out of sync due to otg
@@ -2716,6 +2651,10 @@ static enum surface_update_type check_update_surfaces_for_stream(
overall_type = UPDATE_TYPE_FULL;
}
+ if (stream_update && stream_update->hw_cursor_req) {
+ overall_type = UPDATE_TYPE_FULL;
+ }
+
/* some stream updates require passive update */
if (stream_update) {
union stream_update_flags *su_flags = &stream_update->stream->update_flags;
@@ -2751,6 +2690,9 @@ static enum surface_update_type check_update_surfaces_for_stream(
stream_update->vrr_active_variable || stream_update->vrr_active_fixed))
su_flags->bits.fams_changed = 1;
+ if (stream_update->scaler_sharpener_update)
+ su_flags->bits.scaler_sharpener = 1;
+
if (su_flags->raw != 0)
overall_type = UPDATE_TYPE_FULL;
@@ -3011,6 +2953,9 @@ static void copy_stream_update_to_stream(struct dc *dc,
if (update->vrr_infopacket)
stream->vrr_infopacket = *update->vrr_infopacket;
+ if (update->hw_cursor_req)
+ stream->hw_cursor_req = *update->hw_cursor_req;
+
if (update->allow_freesync)
stream->allow_freesync = *update->allow_freesync;
@@ -3080,6 +3025,8 @@ static void copy_stream_update_to_stream(struct dc *dc,
update->dsc_config = NULL;
}
}
+ if (update->scaler_sharpener_update)
+ stream->scaler_sharpener_update = *update->scaler_sharpener_update;
}
static void backup_planes_and_stream_state(
@@ -3704,7 +3651,8 @@ static void commit_planes_for_stream_fast(struct dc *dc,
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
if (pipe->stream && pipe->plane_state) {
- set_p_state_switch_method(dc, context, pipe);
+ if (!dc->debug.using_dml2)
+ set_p_state_switch_method(dc, context, pipe);
if (dc->debug.visual_confirm)
dc_update_visual_confirm_color(dc, context, pipe);
@@ -3739,7 +3687,7 @@ static void commit_planes_for_stream_fast(struct dc *dc,
surface_count,
stream,
context);
- } else {
+ } else if (stream_status) {
build_dmub_cmd_list(dc,
srf_updates,
surface_count,
@@ -3769,47 +3717,6 @@ static void commit_planes_for_stream_fast(struct dc *dc,
top_pipe_to_program->stream->update_flags.raw = 0;
}
-static void wait_for_outstanding_hw_updates(struct dc *dc, struct dc_state *dc_context)
-{
-/*
- * This function calls HWSS to wait for any potentially double buffered
- * operations to complete. It should be invoked as a pre-amble prior
- * to full update programming before asserting any HW locks.
- */
- int pipe_idx;
- int opp_inst;
- int opp_count = dc->res_pool->res_cap->num_opp;
- struct hubp *hubp;
- int mpcc_inst;
- const struct pipe_ctx *pipe_ctx;
-
- for (pipe_idx = 0; pipe_idx < dc->res_pool->pipe_count; pipe_idx++) {
- pipe_ctx = &dc_context->res_ctx.pipe_ctx[pipe_idx];
-
- if (!pipe_ctx->stream)
- continue;
-
- if (pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear)
- pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear(pipe_ctx->stream_res.tg);
-
- hubp = pipe_ctx->plane_res.hubp;
- if (!hubp)
- continue;
-
- mpcc_inst = hubp->inst;
- // MPCC inst is equal to pipe index in practice
- for (opp_inst = 0; opp_inst < opp_count; opp_inst++) {
- if ((dc->res_pool->opps[opp_inst] != NULL) &&
- (dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst])) {
- dc->res_pool->mpc->funcs->wait_for_idle(dc->res_pool->mpc, mpcc_inst);
- dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst] = false;
- break;
- }
- }
- }
- wait_for_odm_update_pending_complete(dc, dc_context);
-}
-
static void commit_planes_for_stream(struct dc *dc,
struct dc_surface_update *srf_updates,
int surface_count,
@@ -3833,13 +3740,14 @@ static void commit_planes_for_stream(struct dc *dc,
dc_z10_restore(dc);
if (update_type == UPDATE_TYPE_FULL)
- wait_for_outstanding_hw_updates(dc, context);
+ hwss_process_outstanding_hw_updates(dc, dc->current_state);
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
if (pipe->stream && pipe->plane_state) {
- set_p_state_switch_method(dc, context, pipe);
+ if (!dc->debug.using_dml2)
+ set_p_state_switch_method(dc, context, pipe);
if (dc->debug.visual_confirm)
dc_update_visual_confirm_color(dc, context, pipe);
@@ -4127,7 +4035,8 @@ static void commit_planes_for_stream(struct dc *dc,
}
if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
- if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
+ if (top_pipe_to_program &&
+ top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
top_pipe_to_program->stream_res.tg->funcs->wait_for_state(
top_pipe_to_program->stream_res.tg,
CRTC_STATE_VACTIVE);
@@ -4335,7 +4244,8 @@ static void backup_and_set_minimal_pipe_split_policy(struct dc *dc,
dc->debug.force_disable_subvp = true;
for (i = 0; i < context->stream_count; i++) {
policy->force_odm[i] = context->streams[i]->debug.force_odm_combine_segments;
- context->streams[i]->debug.force_odm_combine_segments = 0;
+ if (context->streams[i]->debug.allow_transition_for_forced_odm)
+ context->streams[i]->debug.force_odm_combine_segments = 0;
}
}
@@ -4686,7 +4596,7 @@ static bool commit_minimal_transition_state(struct dc *dc,
return true;
}
-static void populate_fast_updates(struct dc_fast_update *fast_update,
+void populate_fast_updates(struct dc_fast_update *fast_update,
struct dc_surface_update *srf_updates,
int surface_count,
struct dc_stream_update *stream_update)
@@ -4696,6 +4606,9 @@ static void populate_fast_updates(struct dc_fast_update *fast_update,
if (stream_update) {
fast_update[0].out_transfer_func = stream_update->out_transfer_func;
fast_update[0].output_csc_transform = stream_update->output_csc_transform;
+ } else {
+ fast_update[0].out_transfer_func = NULL;
+ fast_update[0].output_csc_transform = NULL;
}
for (i = 0; i < surface_count; i++) {
@@ -4729,6 +4642,26 @@ static bool fast_updates_exist(struct dc_fast_update *fast_update, int surface_c
return false;
}
+bool fast_nonaddr_updates_exist(struct dc_fast_update *fast_update, int surface_count)
+{
+ int i;
+
+ if (fast_update[0].out_transfer_func ||
+ fast_update[0].output_csc_transform)
+ return true;
+
+ for (i = 0; i < surface_count; i++) {
+ if (fast_update[i].input_csc_color_matrix ||
+ fast_update[i].gamma ||
+ fast_update[i].gamut_remap_matrix ||
+ fast_update[i].coeff_reduction_factor ||
+ fast_update[i].cursor_csc_color_matrix)
+ return true;
+ }
+
+ return false;
+}
+
static bool full_update_required(struct dc *dc,
struct dc_surface_update *srf_updates,
int surface_count,
@@ -4785,7 +4718,8 @@ static bool full_update_required(struct dc *dc,
stream_update->func_shaper ||
stream_update->lut3d_func ||
stream_update->pending_test_pattern ||
- stream_update->crtc_timing_adjust))
+ stream_update->crtc_timing_adjust ||
+ stream_update->scaler_sharpener_update))
return true;
if (stream) {
@@ -5233,6 +5167,8 @@ void dc_set_power_state(struct dc *dc, enum dc_acpi_cm_power_state power_state)
dc_z10_restore(dc);
+ dc_dmub_srv_notify_fw_dc_power_state(dc->ctx->dmub_srv, power_state);
+
dc->hwss.init_hw(dc);
if (dc->hwss.init_sys_ctx != NULL &&
@@ -5244,6 +5180,8 @@ void dc_set_power_state(struct dc *dc, enum dc_acpi_cm_power_state power_state)
default:
ASSERT(dc->current_state->stream_count == 0);
+ dc_dmub_srv_notify_fw_dc_power_state(dc->ctx->dmub_srv, power_state);
+
dc_state_destruct(dc->current_state);
break;
@@ -5382,7 +5320,8 @@ void dc_allow_idle_optimizations_internal(struct dc *dc, bool allow, char const
if (allow == dc->idle_optimizations_allowed)
return;
- if (dc->hwss.apply_idle_power_optimizations && dc->hwss.apply_idle_power_optimizations(dc, allow))
+ if (dc->hwss.apply_idle_power_optimizations && dc->clk_mgr != NULL &&
+ dc->hwss.apply_idle_power_optimizations(dc, allow))
dc->idle_optimizations_allowed = allow;
}
@@ -5451,9 +5390,10 @@ static void blank_and_force_memclk(struct dc *dc, bool apply, unsigned int memcl
hubp->funcs->set_blank_regs(hubp, true);
}
}
-
- dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, memclk_mhz);
- dc->clk_mgr->funcs->set_min_memclk(dc->clk_mgr, memclk_mhz);
+ if (dc->clk_mgr->funcs->set_max_memclk)
+ dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, memclk_mhz);
+ if (dc->clk_mgr->funcs->set_min_memclk)
+ dc->clk_mgr->funcs->set_min_memclk(dc->clk_mgr, memclk_mhz);
for (i = 0; i < dc->res_pool->pipe_count; i++) {
pipe = &context->res_ctx.pipe_ctx[i];
@@ -5502,7 +5442,7 @@ void dc_enable_dcmode_clk_limit(struct dc *dc, bool enable)
if (enable && !dc->clk_mgr->dc_mode_softmax_enabled) {
if (p_state_change_support) {
- if (funcMin <= softMax)
+ if (funcMin <= softMax && dc->clk_mgr->funcs->set_max_memclk)
dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, softMax);
// else: No-Op
} else {
@@ -5512,7 +5452,7 @@ void dc_enable_dcmode_clk_limit(struct dc *dc, bool enable)
}
} else if (!enable && dc->clk_mgr->dc_mode_softmax_enabled) {
if (p_state_change_support) {
- if (funcMin <= softMax)
+ if (funcMin <= softMax && dc->clk_mgr->funcs->set_max_memclk)
dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, maxDPM);
// else: No-Op
} else {
@@ -5563,6 +5503,9 @@ void dc_mclk_switch_using_fw_based_vblank_stretch_shut_down(struct dc *dc)
*/
bool dc_is_dmub_outbox_supported(struct dc *dc)
{
+ if (!dc->caps.dmcub_support)
+ return false;
+
switch (dc->ctx->asic_id.chip_family) {
case FAMILY_YELLOW_CARP:
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index 87e36d51c56d..7ee2be8f82c4 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -636,57 +636,59 @@ void hwss_build_fast_sequence(struct dc *dc,
while (current_pipe) {
current_mpc_pipe = current_pipe;
while (current_mpc_pipe) {
- if (dc->hwss.set_flip_control_gsl && current_mpc_pipe->plane_state && current_mpc_pipe->plane_state->update_flags.raw) {
- block_sequence[*num_steps].params.set_flip_control_gsl_params.pipe_ctx = current_mpc_pipe;
- block_sequence[*num_steps].params.set_flip_control_gsl_params.flip_immediate = current_mpc_pipe->plane_state->flip_immediate;
- block_sequence[*num_steps].func = HUBP_SET_FLIP_CONTROL_GSL;
- (*num_steps)++;
- }
- if (dc->hwss.program_triplebuffer && dc->debug.enable_tri_buf && current_mpc_pipe->plane_state->update_flags.raw) {
- block_sequence[*num_steps].params.program_triplebuffer_params.dc = dc;
- block_sequence[*num_steps].params.program_triplebuffer_params.pipe_ctx = current_mpc_pipe;
- block_sequence[*num_steps].params.program_triplebuffer_params.enableTripleBuffer = current_mpc_pipe->plane_state->triplebuffer_flips;
- block_sequence[*num_steps].func = HUBP_PROGRAM_TRIPLEBUFFER;
- (*num_steps)++;
- }
- if (dc->hwss.update_plane_addr && current_mpc_pipe->plane_state->update_flags.bits.addr_update) {
- if (resource_is_pipe_type(current_mpc_pipe, OTG_MASTER) &&
- stream_status->mall_stream_config.type == SUBVP_MAIN) {
- block_sequence[*num_steps].params.subvp_save_surf_addr.dc_dmub_srv = dc->ctx->dmub_srv;
- block_sequence[*num_steps].params.subvp_save_surf_addr.addr = &current_mpc_pipe->plane_state->address;
- block_sequence[*num_steps].params.subvp_save_surf_addr.subvp_index = current_mpc_pipe->subvp_index;
- block_sequence[*num_steps].func = DMUB_SUBVP_SAVE_SURF_ADDR;
+ if (current_mpc_pipe->plane_state) {
+ if (dc->hwss.set_flip_control_gsl && current_mpc_pipe->plane_state->update_flags.raw) {
+ block_sequence[*num_steps].params.set_flip_control_gsl_params.pipe_ctx = current_mpc_pipe;
+ block_sequence[*num_steps].params.set_flip_control_gsl_params.flip_immediate = current_mpc_pipe->plane_state->flip_immediate;
+ block_sequence[*num_steps].func = HUBP_SET_FLIP_CONTROL_GSL;
+ (*num_steps)++;
+ }
+ if (dc->hwss.program_triplebuffer && dc->debug.enable_tri_buf && current_mpc_pipe->plane_state->update_flags.raw) {
+ block_sequence[*num_steps].params.program_triplebuffer_params.dc = dc;
+ block_sequence[*num_steps].params.program_triplebuffer_params.pipe_ctx = current_mpc_pipe;
+ block_sequence[*num_steps].params.program_triplebuffer_params.enableTripleBuffer = current_mpc_pipe->plane_state->triplebuffer_flips;
+ block_sequence[*num_steps].func = HUBP_PROGRAM_TRIPLEBUFFER;
+ (*num_steps)++;
+ }
+ if (dc->hwss.update_plane_addr && current_mpc_pipe->plane_state->update_flags.bits.addr_update) {
+ if (resource_is_pipe_type(current_mpc_pipe, OTG_MASTER) &&
+ stream_status->mall_stream_config.type == SUBVP_MAIN) {
+ block_sequence[*num_steps].params.subvp_save_surf_addr.dc_dmub_srv = dc->ctx->dmub_srv;
+ block_sequence[*num_steps].params.subvp_save_surf_addr.addr = &current_mpc_pipe->plane_state->address;
+ block_sequence[*num_steps].params.subvp_save_surf_addr.subvp_index = current_mpc_pipe->subvp_index;
+ block_sequence[*num_steps].func = DMUB_SUBVP_SAVE_SURF_ADDR;
+ (*num_steps)++;
+ }
+
+ block_sequence[*num_steps].params.update_plane_addr_params.dc = dc;
+ block_sequence[*num_steps].params.update_plane_addr_params.pipe_ctx = current_mpc_pipe;
+ block_sequence[*num_steps].func = HUBP_UPDATE_PLANE_ADDR;
(*num_steps)++;
}
- block_sequence[*num_steps].params.update_plane_addr_params.dc = dc;
- block_sequence[*num_steps].params.update_plane_addr_params.pipe_ctx = current_mpc_pipe;
- block_sequence[*num_steps].func = HUBP_UPDATE_PLANE_ADDR;
- (*num_steps)++;
- }
-
- if (hws->funcs.set_input_transfer_func && current_mpc_pipe->plane_state->update_flags.bits.gamma_change) {
- block_sequence[*num_steps].params.set_input_transfer_func_params.dc = dc;
- block_sequence[*num_steps].params.set_input_transfer_func_params.pipe_ctx = current_mpc_pipe;
- block_sequence[*num_steps].params.set_input_transfer_func_params.plane_state = current_mpc_pipe->plane_state;
- block_sequence[*num_steps].func = DPP_SET_INPUT_TRANSFER_FUNC;
- (*num_steps)++;
- }
+ if (hws->funcs.set_input_transfer_func && current_mpc_pipe->plane_state->update_flags.bits.gamma_change) {
+ block_sequence[*num_steps].params.set_input_transfer_func_params.dc = dc;
+ block_sequence[*num_steps].params.set_input_transfer_func_params.pipe_ctx = current_mpc_pipe;
+ block_sequence[*num_steps].params.set_input_transfer_func_params.plane_state = current_mpc_pipe->plane_state;
+ block_sequence[*num_steps].func = DPP_SET_INPUT_TRANSFER_FUNC;
+ (*num_steps)++;
+ }
- if (dc->hwss.program_gamut_remap && current_mpc_pipe->plane_state->update_flags.bits.gamut_remap_change) {
- block_sequence[*num_steps].params.program_gamut_remap_params.pipe_ctx = current_mpc_pipe;
- block_sequence[*num_steps].func = DPP_PROGRAM_GAMUT_REMAP;
- (*num_steps)++;
- }
- if (current_mpc_pipe->plane_state->update_flags.bits.input_csc_change) {
- block_sequence[*num_steps].params.setup_dpp_params.pipe_ctx = current_mpc_pipe;
- block_sequence[*num_steps].func = DPP_SETUP_DPP;
- (*num_steps)++;
- }
- if (current_mpc_pipe->plane_state->update_flags.bits.coeff_reduction_change) {
- block_sequence[*num_steps].params.program_bias_and_scale_params.pipe_ctx = current_mpc_pipe;
- block_sequence[*num_steps].func = DPP_PROGRAM_BIAS_AND_SCALE;
- (*num_steps)++;
+ if (dc->hwss.program_gamut_remap && current_mpc_pipe->plane_state->update_flags.bits.gamut_remap_change) {
+ block_sequence[*num_steps].params.program_gamut_remap_params.pipe_ctx = current_mpc_pipe;
+ block_sequence[*num_steps].func = DPP_PROGRAM_GAMUT_REMAP;
+ (*num_steps)++;
+ }
+ if (current_mpc_pipe->plane_state->update_flags.bits.input_csc_change) {
+ block_sequence[*num_steps].params.setup_dpp_params.pipe_ctx = current_mpc_pipe;
+ block_sequence[*num_steps].func = DPP_SETUP_DPP;
+ (*num_steps)++;
+ }
+ if (current_mpc_pipe->plane_state->update_flags.bits.coeff_reduction_change) {
+ block_sequence[*num_steps].params.program_bias_and_scale_params.pipe_ctx = current_mpc_pipe;
+ block_sequence[*num_steps].func = DPP_PROGRAM_BIAS_AND_SCALE;
+ (*num_steps)++;
+ }
}
if (hws->funcs.set_output_transfer_func && current_mpc_pipe->stream->update_flags.bits.out_tf) {
block_sequence[*num_steps].params.set_output_transfer_func_params.dc = dc;
@@ -901,12 +903,12 @@ void hwss_program_bias_and_scale(union block_sequence_params *params)
struct pipe_ctx *pipe_ctx = params->program_bias_and_scale_params.pipe_ctx;
struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
- struct dc_bias_and_scale bns_params = {0};
+ struct dc_bias_and_scale bns_params = plane_state->bias_and_scale;
//TODO :for CNVC set scale and bias registers if necessary
- build_prescale_params(&bns_params, plane_state);
- if (dpp->funcs->dpp_program_bias_and_scale)
+ if (dpp->funcs->dpp_program_bias_and_scale) {
dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params);
+ }
}
void hwss_power_on_mpc_mem_pwr(union block_sequence_params *params)
@@ -976,3 +978,126 @@ void get_surface_tile_visual_confirm_color(
break;
}
}
+
+/**
+ * hwss_wait_for_all_blank_complete - wait for all active OPPs to finish pending blank
+ * pattern updates
+ *
+ * @dc: [in] dc reference
+ * @context: [in] hardware context in use
+ */
+void hwss_wait_for_all_blank_complete(struct dc *dc,
+ struct dc_state *context)
+{
+ struct pipe_ctx *opp_head;
+ struct dce_hwseq *hws = dc->hwseq;
+ int i;
+
+ if (!hws->funcs.wait_for_blank_complete)
+ return;
+
+ for (i = 0; i < MAX_PIPES; i++) {
+ opp_head = &context->res_ctx.pipe_ctx[i];
+
+ if (!resource_is_pipe_type(opp_head, OPP_HEAD) ||
+ dc_state_get_pipe_subvp_type(context, opp_head) == SUBVP_PHANTOM)
+ continue;
+
+ hws->funcs.wait_for_blank_complete(opp_head->stream_res.opp);
+ }
+}
+
+void hwss_wait_for_odm_update_pending_complete(struct dc *dc, struct dc_state *context)
+{
+ struct pipe_ctx *otg_master;
+ struct timing_generator *tg;
+ int i;
+
+ for (i = 0; i < MAX_PIPES; i++) {
+ otg_master = &context->res_ctx.pipe_ctx[i];
+ if (!resource_is_pipe_type(otg_master, OTG_MASTER) ||
+ dc_state_get_pipe_subvp_type(context, otg_master) == SUBVP_PHANTOM)
+ continue;
+ tg = otg_master->stream_res.tg;
+ if (tg->funcs->wait_odm_doublebuffer_pending_clear)
+ tg->funcs->wait_odm_doublebuffer_pending_clear(tg);
+ }
+
+ /* ODM update may require to reprogram blank pattern for each OPP */
+ hwss_wait_for_all_blank_complete(dc, context);
+}
+
+void hwss_wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
+{
+ int i;
+ for (i = 0; i < MAX_PIPES; i++) {
+ int count = 0;
+ struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+ if (!pipe->plane_state || dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_PHANTOM)
+ continue;
+
+ /* Timeout 100 ms */
+ while (count < 100000) {
+ /* Must set to false to start with, due to OR in update function */
+ pipe->plane_state->status.is_flip_pending = false;
+ dc->hwss.update_pending_status(pipe);
+ if (!pipe->plane_state->status.is_flip_pending)
+ break;
+ udelay(1);
+ count++;
+ }
+ ASSERT(!pipe->plane_state->status.is_flip_pending);
+ }
+}
+
+void hwss_wait_for_outstanding_hw_updates(struct dc *dc, struct dc_state *dc_context)
+{
+/*
+ * This function calls HWSS to wait for any potentially double buffered
+ * operations to complete. It should be invoked as a pre-amble prior
+ * to full update programming before asserting any HW locks.
+ */
+ int pipe_idx;
+ int opp_inst;
+ int opp_count = dc->res_pool->res_cap->num_opp;
+ struct hubp *hubp;
+ int mpcc_inst;
+ const struct pipe_ctx *pipe_ctx;
+
+ for (pipe_idx = 0; pipe_idx < dc->res_pool->pipe_count; pipe_idx++) {
+ pipe_ctx = &dc_context->res_ctx.pipe_ctx[pipe_idx];
+
+ if (!pipe_ctx->stream)
+ continue;
+
+ if (pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear)
+ pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear(pipe_ctx->stream_res.tg);
+
+ hubp = pipe_ctx->plane_res.hubp;
+ if (!hubp)
+ continue;
+
+ mpcc_inst = hubp->inst;
+ // MPCC inst is equal to pipe index in practice
+ for (opp_inst = 0; opp_inst < opp_count; opp_inst++) {
+ if ((dc->res_pool->opps[opp_inst] != NULL) &&
+ (dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst])) {
+ dc->res_pool->mpc->funcs->wait_for_idle(dc->res_pool->mpc, mpcc_inst);
+ dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst] = false;
+ break;
+ }
+ }
+ }
+ hwss_wait_for_odm_update_pending_complete(dc, dc_context);
+}
+
+void hwss_process_outstanding_hw_updates(struct dc *dc, struct dc_state *dc_context)
+{
+ /* wait for outstanding updates */
+ hwss_wait_for_outstanding_hw_updates(dc, dc_context);
+
+ /* perform outstanding post update programming */
+ if (dc->hwss.program_outstanding_updates)
+ dc->hwss.program_outstanding_updates(dc, dc_context);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index bcb5267b5a6b..c7599c40d4be 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -342,11 +342,6 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc,
res_pool->ref_clocks.xtalin_clock_inKhz;
res_pool->ref_clocks.dchub_ref_clock_inKhz =
res_pool->ref_clocks.xtalin_clock_inKhz;
- if (dc->debug.using_dml2)
- if (res_pool->hubbub && res_pool->hubbub->funcs->get_dchub_ref_freq)
- res_pool->hubbub->funcs->get_dchub_ref_freq(res_pool->hubbub,
- res_pool->ref_clocks.dccg_ref_clock_inKhz,
- &res_pool->ref_clocks.dchub_ref_clock_inKhz);
} else
ASSERT_CRITICAL(false);
}
@@ -1511,8 +1506,6 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = plane_state->per_pixel_alpha;
- spl_out->scl_data.h_active = pipe_ctx->plane_res.scl_data.h_active;
- spl_out->scl_data.v_active = pipe_ctx->plane_res.scl_data.v_active;
// Convert pipe_ctx to respective input params for SPL
translate_SPL_in_params_from_pipe_ctx(pipe_ctx, spl_in);
@@ -3241,6 +3234,8 @@ static bool are_stream_backends_same(
bool dc_is_stream_unchanged(
struct dc_stream_state *old_stream, struct dc_stream_state *stream)
{
+ if (!old_stream || !stream)
+ return false;
if (!are_stream_backends_same(old_stream, stream))
return false;
@@ -3771,8 +3766,10 @@ static bool planes_changed_for_existing_stream(struct dc_state *context,
}
}
- if (!stream_status)
+ if (!stream_status) {
ASSERT(0);
+ return false;
+ }
for (i = 0; i < set_count; i++)
if (set[i].stream == stream)
@@ -5164,7 +5161,7 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy(
sec_pipe->stream_res.opp = sec_pipe->top_pipe->stream_res.opp;
if (sec_pipe->stream->timing.flags.DSC == 1) {
#if defined(CONFIG_DRM_AMD_DC_FP)
- dcn20_acquire_dsc(dc, &state->res_ctx, &sec_pipe->stream_res.dsc, pipe_idx);
+ dcn20_acquire_dsc(dc, &state->res_ctx, &sec_pipe->stream_res.dsc, sec_pipe->stream_res.opp->inst);
#endif
ASSERT(sec_pipe->stream_res.dsc);
if (sec_pipe->stream_res.dsc == NULL)
@@ -5271,3 +5268,44 @@ void resource_init_common_dml2_callbacks(struct dc *dc, struct dml2_configuratio
dml2_options->svp_pstate.callbacks.remove_phantom_streams_and_planes = &dc_state_remove_phantom_streams_and_planes;
dml2_options->svp_pstate.callbacks.release_phantom_streams_and_planes = &dc_state_release_phantom_streams_and_planes;
}
+
+/* Returns number of DET segments allocated for a given OTG_MASTER pipe */
+int resource_calculate_det_for_stream(struct dc_state *state, struct pipe_ctx *otg_master)
+{
+ struct pipe_ctx *opp_heads[MAX_PIPES];
+ struct pipe_ctx *dpp_pipes[MAX_PIPES];
+
+ int dpp_count = 0;
+ int det_segments = 0;
+
+ if (!otg_master->stream)
+ return 0;
+
+ int slice_count = resource_get_opp_heads_for_otg_master(otg_master,
+ &state->res_ctx, opp_heads);
+
+ for (int slice_idx = 0; slice_idx < slice_count; slice_idx++) {
+ if (opp_heads[slice_idx]->plane_state) {
+ dpp_count = resource_get_dpp_pipes_for_opp_head(
+ opp_heads[slice_idx],
+ &state->res_ctx,
+ dpp_pipes);
+ for (int dpp_idx = 0; dpp_idx < dpp_count; dpp_idx++)
+ det_segments += dpp_pipes[dpp_idx]->hubp_regs.det_size;
+ }
+ }
+ return det_segments;
+}
+
+bool resource_is_hpo_acquired(struct dc_state *context)
+{
+ int i;
+
+ for (i = 0; i < MAX_HPO_DP2_ENCODERS; i++) {
+ if (context->res_ctx.is_hpo_dp_stream_enc_acquired[i]) {
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stat.c b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c
index cd6570a1e20e..fe9f99f1bdf9 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stat.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c
@@ -61,6 +61,7 @@ void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification
/* For HPD/HPD RX, convert dpia port index into link index */
if (notify->type == DMUB_NOTIFICATION_HPD ||
notify->type == DMUB_NOTIFICATION_HPD_IRQ ||
+ notify->type == DMUB_NOTIFICATION_AUX_REPLY ||
notify->type == DMUB_NOTIFICATION_DPIA_NOTIFICATION ||
notify->type == DMUB_NOTIFICATION_SET_CONFIG_REPLY) {
notify->link_index =
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_state.c b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
index e990346e51f6..2597e3fd562b 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_state.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
@@ -211,10 +211,16 @@ struct dc_state *dc_state_create(struct dc *dc, struct dc_state_create_params *p
#ifdef CONFIG_DRM_AMD_DC_FP
if (dc->debug.using_dml2) {
dml2_opt->use_clock_dc_limits = false;
- dml2_create(dc, dml2_opt, &state->bw_ctx.dml2);
+ if (!dml2_create(dc, dml2_opt, &state->bw_ctx.dml2)) {
+ dc_state_release(state);
+ return NULL;
+ }
dml2_opt->use_clock_dc_limits = true;
- dml2_create(dc, dml2_opt, &state->bw_ctx.dml2_dc_power_source);
+ if (!dml2_create(dc, dml2_opt, &state->bw_ctx.dml2_dc_power_source)) {
+ dc_state_release(state);
+ return NULL;
+ }
}
#endif
@@ -961,10 +967,10 @@ bool dc_state_is_fams2_in_use(
bool is_fams2_in_use = false;
if (state)
- is_fams2_in_use |= state->bw_ctx.bw.dcn.fams2_stream_count > 0;
+ is_fams2_in_use |= state->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable;
if (dc->current_state)
- is_fams2_in_use |= dc->current_state->bw_ctx.bw.dcn.fams2_stream_count > 0;
+ is_fams2_in_use |= dc->current_state->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable;
return is_fams2_in_use;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 73cdebcd9f37..4c94dd38be4b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -55,7 +55,7 @@ struct aux_payload;
struct set_config_cmd_payload;
struct dmub_notification;
-#define DC_VER "3.2.291"
+#define DC_VER "3.2.299"
#define MAX_SURFACES 3
#define MAX_PLANES 6
@@ -261,10 +261,7 @@ struct dc_caps {
bool zstate_support;
bool ips_support;
uint32_t num_of_internal_disp;
- uint32_t max_dwb_htap;
- uint32_t max_dwb_vtap;
enum dp_protocol_version max_dp_protocol_version;
- bool spdif_aud;
unsigned int mall_size_per_mem_channel;
unsigned int mall_size_total;
unsigned int cursor_cache_size;
@@ -309,8 +306,6 @@ struct dc_bug_wa {
uint8_t dcfclk_ds: 1;
} clock_update_disable_mask;
bool skip_psr_ips_crtc_disable;
- //Customer Specific WAs
- uint32_t force_backlight_start_level;
};
struct dc_dcc_surface_param {
struct dc_size surface_size;
@@ -466,6 +461,7 @@ struct dc_config {
bool use_assr_psp_message;
bool support_edp0_on_dp1;
unsigned int enable_fpo_flicker_detection;
+ bool disable_hbr_audio_dp2;
};
enum visual_confirm {
@@ -513,6 +509,7 @@ enum in_game_fams_config {
INGAME_FAMS_SINGLE_DISP_ENABLE, // enable in-game fams
INGAME_FAMS_DISABLE, // disable in-game fams
INGAME_FAMS_MULTI_DISP_ENABLE, //enable in-game fams for multi-display
+ INGAME_FAMS_MULTI_DISP_CLAMPED_ONLY, //enable in-game fams for multi-display only for clamped RR strategies
};
/**
@@ -764,7 +761,8 @@ union dpia_debug_options {
uint32_t extend_aux_rd_interval:1; /* bit 2 */
uint32_t disable_mst_dsc_work_around:1; /* bit 3 */
uint32_t enable_force_tbt3_work_around:1; /* bit 4 */
- uint32_t reserved:27;
+ uint32_t disable_usb4_pm_support:1; /* bit 5 */
+ uint32_t reserved:26;
} bits;
uint32_t raw;
};
@@ -981,6 +979,7 @@ struct dc_debug_options {
bool disable_z10;
bool enable_z9_disable_interface;
bool psr_skip_crtc_disable;
+ uint32_t ips_skip_crtc_disable_mask;
union dpia_debug_options dpia_debug;
bool disable_fixed_vs_aux_timeout_wa;
uint32_t fixed_vs_aux_delay_config_wa;
@@ -1053,8 +1052,10 @@ struct dc_debug_options {
unsigned int disable_spl;
unsigned int force_easf;
unsigned int force_sharpness;
+ unsigned int force_sharpness_level;
unsigned int force_lls;
bool notify_dpia_hr_bw;
+ bool enable_ips_visual_confirm;
};
@@ -1291,7 +1292,7 @@ struct dc_plane_state {
struct dc_gamma gamma_correction;
struct dc_transfer_func in_transfer_func;
- struct dc_bias_and_scale *bias_and_scale;
+ struct dc_bias_and_scale bias_and_scale;
struct dc_csc_transform input_csc_color_matrix;
struct fixed31_32 coeff_reduction_factor;
struct fixed31_32 hdr_mult;
@@ -1348,7 +1349,7 @@ struct dc_plane_state {
enum mpcc_movable_cm_location mcm_location;
struct dc_csc_transform cursor_csc_color_matrix;
bool adaptive_sharpness_en;
- unsigned int sharpnessX1000;
+ int sharpness_level;
enum linear_light_scaling linear_light_scaling;
};
@@ -1368,7 +1369,6 @@ struct dc_plane_info {
int global_alpha_value;
bool input_csc_enabled;
int layer_index;
- bool front_buffer_rendering_active;
enum chroma_cositing cositing;
};
@@ -1585,6 +1585,12 @@ bool dc_acquire_release_mpc_3dlut(
bool dc_resource_is_dsc_encoding_supported(const struct dc *dc);
void get_audio_check(struct audio_info *aud_modes,
struct audio_check *aud_chk);
+
+bool fast_nonaddr_updates_exist(struct dc_fast_update *fast_update, int surface_count);
+void populate_fast_updates(struct dc_fast_update *fast_update,
+ struct dc_surface_update *srf_updates,
+ int surface_count,
+ struct dc_stream_update *stream_update);
/*
* Set up streams and links associated to drive sinks
* The streams parameter is an absolute set of all active streams.
@@ -1756,6 +1762,7 @@ struct dc_link {
bool dongle_mode_timing_override;
bool blank_stream_on_ocs_change;
bool read_dpcd204h_on_irq_hpd;
+ bool disable_assr_for_uhbr;
} wa_flags;
struct link_mst_stream_allocation_table mst_stream_alloc_table;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index ded13026c8ff..1e7de0f03290 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -979,6 +979,9 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv)
DC_LOG_DEBUG(" inbox0_rptr : %08x", diag_data.inbox0_rptr);
DC_LOG_DEBUG(" inbox0_wptr : %08x", diag_data.inbox0_wptr);
DC_LOG_DEBUG(" inbox0_size : %08x", diag_data.inbox0_size);
+ DC_LOG_DEBUG(" outbox1_rptr : %08x", diag_data.outbox1_rptr);
+ DC_LOG_DEBUG(" outbox1_wptr : %08x", diag_data.outbox1_wptr);
+ DC_LOG_DEBUG(" outbox1_size : %08x", diag_data.outbox1_size);
DC_LOG_DEBUG(" is_enabled : %d", diag_data.is_dmcub_enabled);
DC_LOG_DEBUG(" is_soft_reset : %d", diag_data.is_dmcub_soft_reset);
DC_LOG_DEBUG(" is_secure_reset : %d", diag_data.is_dmcub_secure_reset);
@@ -1282,7 +1285,7 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle)
union dmub_shared_state_ips_driver_signals new_signals;
DC_LOG_IPS(
- "%s wait idle (ips1_commit=%d ips2_commit=%d)",
+ "%s wait idle (ips1_commit=%u ips2_commit=%u)",
__func__,
ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit);
@@ -1328,7 +1331,7 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle)
}
DC_LOG_IPS(
- "%s send allow_idle=%d (ips1_commit=%d ips2_commit=%d)",
+ "%s send allow_idle=%d (ips1_commit=%u ips2_commit=%u)",
__func__,
allow_idle,
ips_fw->signals.bits.ips1_commit,
@@ -1371,7 +1374,7 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
dc_dmub_srv->driver_signals = ips_driver->signals;
DC_LOG_IPS(
- "%s (allow ips1=%d ips2=%d) (commit ips1=%d ips2=%d) (count rcg=%d ips1=%d ips2=%d)",
+ "%s (allow ips1=%u ips2=%u) (commit ips1=%u ips2=%u) (count rcg=%u ips1=%u ips2=%u)",
__func__,
ips_driver->signals.bits.allow_ips1,
ips_driver->signals.bits.allow_ips2,
@@ -1390,7 +1393,7 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
(!dc->debug.optimize_ips_handshake ||
ips_fw->signals.bits.ips2_commit || !ips_fw->signals.bits.in_idle)) {
DC_LOG_IPS(
- "wait IPS2 eval (ips1_commit=%d ips2_commit=%d)",
+ "wait IPS2 eval (ips1_commit=%u ips2_commit=%u)",
ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit);
@@ -1399,7 +1402,7 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
if (ips_fw->signals.bits.ips2_commit) {
DC_LOG_IPS(
- "exit IPS2 #1 (ips1_commit=%d ips2_commit=%d)",
+ "exit IPS2 #1 (ips1_commit=%u ips2_commit=%u)",
ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit);
@@ -1407,7 +1410,7 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
dc->clk_mgr->funcs->exit_low_power_state(dc->clk_mgr);
DC_LOG_IPS(
- "wait IPS2 entry delay (ips1_commit=%d ips2_commit=%d)",
+ "wait IPS2 entry delay (ips1_commit=%u ips2_commit=%u)",
ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit);
@@ -1415,14 +1418,14 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
udelay(dc->debug.ips2_entry_delay_us);
DC_LOG_IPS(
- "exit IPS2 #2 (ips1_commit=%d ips2_commit=%d)",
+ "exit IPS2 #2 (ips1_commit=%u ips2_commit=%u)",
ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit);
dc->clk_mgr->funcs->exit_low_power_state(dc->clk_mgr);
DC_LOG_IPS(
- "wait IPS2 commit clear (ips1_commit=%d ips2_commit=%d)",
+ "wait IPS2 commit clear (ips1_commit=%u ips2_commit=%u)",
ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit);
@@ -1430,7 +1433,7 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
udelay(1);
DC_LOG_IPS(
- "wait hw_pwr_up (ips1_commit=%d ips2_commit=%d)",
+ "wait hw_pwr_up (ips1_commit=%u ips2_commit=%u)",
ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit);
@@ -1438,7 +1441,7 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
ASSERT(0);
DC_LOG_IPS(
- "resync inbox1 (ips1_commit=%d ips2_commit=%d)",
+ "resync inbox1 (ips1_commit=%u ips2_commit=%u)",
ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit);
@@ -1449,7 +1452,7 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
dc_dmub_srv_notify_idle(dc, false);
if (prev_driver_signals.bits.allow_ips1) {
DC_LOG_IPS(
- "wait for IPS1 commit clear (ips1_commit=%d ips2_commit=%d)",
+ "wait for IPS1 commit clear (ips1_commit=%u ips2_commit=%u)",
ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit);
@@ -1457,7 +1460,7 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
udelay(1);
DC_LOG_IPS(
- "wait for IPS1 commit clear done (ips1_commit=%d ips2_commit=%d)",
+ "wait for IPS1 commit clear done (ips1_commit=%u ips2_commit=%u)",
ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit);
}
@@ -1466,14 +1469,14 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
if (!dc_dmub_srv_is_hw_pwr_up(dc->ctx->dmub_srv, true))
ASSERT(0);
- DC_LOG_IPS("%s exit (count rcg=%d ips1=%d ips2=%d)",
+ DC_LOG_IPS("%s exit (count rcg=%u ips1=%u ips2=%u)",
__func__,
rcg_exit_count,
ips1_exit_count,
ips2_exit_count);
}
-void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state powerState)
+void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state power_state)
{
struct dmub_srv *dmub;
@@ -1482,12 +1485,38 @@ void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_c
dmub = dc_dmub_srv->dmub;
- if (powerState == DC_ACPI_CM_POWER_STATE_D0)
+ if (power_state == DC_ACPI_CM_POWER_STATE_D0)
dmub_srv_set_power_state(dmub, DMUB_POWER_STATE_D0);
else
dmub_srv_set_power_state(dmub, DMUB_POWER_STATE_D3);
}
+void dc_dmub_srv_notify_fw_dc_power_state(struct dc_dmub_srv *dc_dmub_srv,
+ enum dc_acpi_cm_power_state power_state)
+{
+ union dmub_rb_cmd cmd;
+
+ if (!dc_dmub_srv)
+ return;
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ cmd.idle_opt_set_dc_power_state.header.type = DMUB_CMD__IDLE_OPT;
+ cmd.idle_opt_set_dc_power_state.header.sub_type = DMUB_CMD__IDLE_OPT_SET_DC_POWER_STATE;
+ cmd.idle_opt_set_dc_power_state.header.payload_bytes =
+ sizeof(cmd.idle_opt_set_dc_power_state) - sizeof(cmd.idle_opt_set_dc_power_state.header);
+
+ if (power_state == DC_ACPI_CM_POWER_STATE_D0) {
+ cmd.idle_opt_set_dc_power_state.data.power_state = DMUB_IDLE_OPT_DC_POWER_STATE_D0;
+ } else if (power_state == DC_ACPI_CM_POWER_STATE_D3) {
+ cmd.idle_opt_set_dc_power_state.data.power_state = DMUB_IDLE_OPT_DC_POWER_STATE_D3;
+ } else {
+ cmd.idle_opt_set_dc_power_state.data.power_state = DMUB_IDLE_OPT_DC_POWER_STATE_UNKNOWN;
+ }
+
+ dc_wake_and_execute_dmub_cmd(dc_dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+}
+
bool dc_dmub_srv_should_detect(struct dc_dmub_srv *dc_dmub_srv)
{
volatile const struct dmub_shared_state_ips_fw *ips_fw;
@@ -1672,22 +1701,17 @@ void dc_dmub_srv_fams2_update_config(struct dc *dc,
global_cmd->header.sub_type = DMUB_CMD__FAMS2_CONFIG;
global_cmd->header.payload_bytes = sizeof(struct dmub_rb_cmd_fams2) - sizeof(struct dmub_cmd_header);
- /* send global configuration parameters */
- global_cmd->config.global.max_allow_delay_us = 100 * 1000; //100ms
- global_cmd->config.global.lock_wait_time_us = 5000; //5ms
- global_cmd->config.global.recovery_timeout_us = 5000; //5ms
- global_cmd->config.global.hwfq_flip_programming_delay_us = 100; //100us
-
- /* copy static feature configuration */
- global_cmd->config.global.features.all = dc->debug.fams2_config.all;
+ if (enable) {
+ /* send global configuration parameters */
+ memcpy(&global_cmd->config.global, &context->bw_ctx.bw.dcn.fams2_global_config, sizeof(struct dmub_cmd_fams2_global_config));
- /* apply feature configuration based on current driver state */
- global_cmd->config.global.features.bits.enable_visual_confirm = dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS2;
- global_cmd->config.global.features.bits.enable = enable;
+ /* copy static feature configuration overrides */
+ global_cmd->config.global.features.bits.enable_stall_recovery = dc->debug.fams2_config.bits.enable_stall_recovery;
+ global_cmd->config.global.features.bits.enable_debug = dc->debug.fams2_config.bits.enable_debug;
+ global_cmd->config.global.features.bits.enable_offload_flip = dc->debug.fams2_config.bits.enable_offload_flip;
- /* construct per-stream configs */
- if (enable) {
- for (i = 0; i < context->bw_ctx.bw.dcn.fams2_stream_count; i++) {
+ /* construct per-stream configs */
+ for (i = 0; i < context->bw_ctx.bw.dcn.fams2_global_config.num_streams; i++) {
struct dmub_rb_cmd_fams2 *stream_cmd = &cmd[i+1].fams2_config;
/* configure command header */
@@ -1702,12 +1726,15 @@ void dc_dmub_srv_fams2_update_config(struct dc *dc,
}
}
- if (enable && context->bw_ctx.bw.dcn.fams2_stream_count) {
+ /* apply feature configuration based on current driver state */
+ global_cmd->config.global.features.bits.enable_visual_confirm = dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS2;
+ global_cmd->config.global.features.bits.enable = enable;
+
+ if (enable && context->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable) {
/* set multi pending for global, and unset for last stream cmd */
- global_cmd->config.global.num_streams = context->bw_ctx.bw.dcn.fams2_stream_count;
global_cmd->header.multi_cmd_pending = 1;
- cmd[context->bw_ctx.bw.dcn.fams2_stream_count].fams2_config.header.multi_cmd_pending = 0;
- num_cmds += context->bw_ctx.bw.dcn.fams2_stream_count;
+ cmd[context->bw_ctx.bw.dcn.fams2_global_config.num_streams].fams2_config.header.multi_cmd_pending = 0;
+ num_cmds += context->bw_ctx.bw.dcn.fams2_global_config.num_streams;
}
dm_execute_dmub_cmd_list(dc->ctx, num_cmds, cmd, DM_DMUB_WAIT_TYPE_WAIT);
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
index 580940222777..42f0cb672d8b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
@@ -109,7 +109,29 @@ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait);
void dc_dmub_srv_apply_idle_power_optimizations(const struct dc *dc, bool allow_idle);
-void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state powerState);
+/**
+ * dc_dmub_srv_set_power_state() - Sets the power state for DMUB service.
+ *
+ * Controls whether messaging the DMCUB or interfacing with it via HW register
+ * interaction is permittable.
+ *
+ * @dc_dmub_srv - The DC DMUB service pointer
+ * @power_state - the DC power state
+ */
+void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state power_state);
+
+/**
+ * dc_dmub_srv_notify_fw_dc_power_state() - Notifies firmware of the DC power state.
+ *
+ * Differs from dc_dmub_srv_set_power_state in that it needs to access HW in order
+ * to message DMCUB of the state transition. Should come after the D0 exit and
+ * before D3 set power state.
+ *
+ * @dc_dmub_srv - The DC DMUB service pointer
+ * @power_state - the DC power state
+ */
+void dc_dmub_srv_notify_fw_dc_power_state(struct dc_dmub_srv *dc_dmub_srv,
+ enum dc_acpi_cm_power_state power_state);
/**
* @dc_dmub_srv_should_detect() - Checks if link detection is required.
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index 959ae0df1e56..c10567ec1c81 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -763,13 +763,6 @@ enum scanning_type {
SCANNING_TYPE_UNDEFINED
};
-enum chroma_cositing {
- CHROMA_COSITING_NONE,
- CHROMA_COSITING_LEFT,
- CHROMA_COSITING_TOPLEFT,
- CHROMA_COSITING_COUNT
-};
-
struct dc_crtc_timing_flags {
uint32_t INTERLACE :1;
uint32_t HSYNC_POSITIVE_POLARITY :1; /* when set to 1,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
index 582606319764..cd6de93eb91c 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
@@ -42,26 +42,26 @@ static void populate_spltaps_from_taps(struct spl_taps *spl_scaling_quality,
static void populate_taps_from_spltaps(struct scaling_taps *scaling_quality,
const struct spl_taps *spl_scaling_quality)
{
- scaling_quality->h_taps_c = spl_scaling_quality->h_taps_c;
- scaling_quality->h_taps = spl_scaling_quality->h_taps;
- scaling_quality->v_taps_c = spl_scaling_quality->v_taps_c;
- scaling_quality->v_taps = spl_scaling_quality->v_taps;
+ scaling_quality->h_taps_c = spl_scaling_quality->h_taps_c + 1;
+ scaling_quality->h_taps = spl_scaling_quality->h_taps + 1;
+ scaling_quality->v_taps_c = spl_scaling_quality->v_taps_c + 1;
+ scaling_quality->v_taps = spl_scaling_quality->v_taps + 1;
}
static void populate_ratios_from_splratios(struct scaling_ratios *ratios,
- const struct spl_ratios *spl_ratios)
+ const struct ratio *spl_ratios)
{
- ratios->horz = spl_ratios->horz;
- ratios->vert = spl_ratios->vert;
- ratios->horz_c = spl_ratios->horz_c;
- ratios->vert_c = spl_ratios->vert_c;
+ ratios->horz = dc_fixpt_from_ux_dy(spl_ratios->h_scale_ratio >> 5, 3, 19);
+ ratios->vert = dc_fixpt_from_ux_dy(spl_ratios->v_scale_ratio >> 5, 3, 19);
+ ratios->horz_c = dc_fixpt_from_ux_dy(spl_ratios->h_scale_ratio_c >> 5, 3, 19);
+ ratios->vert_c = dc_fixpt_from_ux_dy(spl_ratios->v_scale_ratio_c >> 5, 3, 19);
}
static void populate_inits_from_splinits(struct scl_inits *inits,
- const struct spl_inits *spl_inits)
+ const struct init *spl_inits)
{
- inits->h = spl_inits->h;
- inits->v = spl_inits->v;
- inits->h_c = spl_inits->h_c;
- inits->v_c = spl_inits->v_c;
+ inits->h = dc_fixpt_from_int_dy(spl_inits->h_filter_init_int, spl_inits->h_filter_init_frac >> 5, 0, 19);
+ inits->v = dc_fixpt_from_int_dy(spl_inits->v_filter_init_int, spl_inits->v_filter_init_frac >> 5, 0, 19);
+ inits->h_c = dc_fixpt_from_int_dy(spl_inits->h_filter_init_int_c, spl_inits->h_filter_init_frac_c >> 5, 0, 19);
+ inits->v_c = dc_fixpt_from_int_dy(spl_inits->v_filter_init_int_c, spl_inits->v_filter_init_frac_c >> 5, 0, 19);
}
/// @brief Translate SPL input parameters from pipe context
/// @param pipe_ctx
@@ -128,6 +128,7 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
spl_in->basic_out.always_scale = pipe_ctx->stream->ctx->dc->debug.always_scale;
// Make spl input basic output info alpha_en field point to plane res scl_data lb_params alpha_en
spl_in->basic_out.alpha_en = pipe_ctx->plane_res.scl_data.lb_params.alpha_en;
+ spl_in->basic_out.use_two_pixels_per_container = pipe_ctx->stream_res.tg->funcs->is_two_pixels_per_container(&stream->timing);
// Make spl input basic input info scaling quality field point to plane state scaling_quality
populate_spltaps_from_taps(&spl_in->scaling_quality, &plane_state->scaling_quality);
// Translate edge adaptive scaler preference
@@ -138,24 +139,36 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
else if (pipe_ctx->stream->ctx->dc->debug.force_easf == 2)
spl_in->disable_easf = true;
/* Translate adaptive sharpening preference */
- if (pipe_ctx->stream->ctx->dc->debug.force_sharpness > 0) {
- spl_in->adaptive_sharpness.enable = (pipe_ctx->stream->ctx->dc->debug.force_sharpness > 1) ? true : false;
- if (pipe_ctx->stream->ctx->dc->debug.force_sharpness == 2)
- spl_in->adaptive_sharpness.sharpness = SHARPNESS_LOW;
- else if (pipe_ctx->stream->ctx->dc->debug.force_sharpness == 3)
- spl_in->adaptive_sharpness.sharpness = SHARPNESS_MID;
- else if (pipe_ctx->stream->ctx->dc->debug.force_sharpness >= 4)
- spl_in->adaptive_sharpness.sharpness = SHARPNESS_HIGH;
- } else {
- spl_in->adaptive_sharpness.enable = plane_state->adaptive_sharpness_en;
- if (plane_state->sharpnessX1000 == 0)
+ unsigned int sharpness_setting = pipe_ctx->stream->ctx->dc->debug.force_sharpness;
+ unsigned int force_sharpness_level = pipe_ctx->stream->ctx->dc->debug.force_sharpness_level;
+ if (sharpness_setting == SHARPNESS_HW_OFF)
+ spl_in->adaptive_sharpness.enable = false;
+ else if (sharpness_setting == SHARPNESS_ZERO) {
+ spl_in->adaptive_sharpness.enable = true;
+ spl_in->adaptive_sharpness.sharpness_level = 0;
+ } else if (sharpness_setting == SHARPNESS_CUSTOM) {
+ spl_in->adaptive_sharpness.sharpness_range.sdr_rgb_min = 0;
+ spl_in->adaptive_sharpness.sharpness_range.sdr_rgb_max = 1750;
+ spl_in->adaptive_sharpness.sharpness_range.sdr_rgb_mid = 750;
+ spl_in->adaptive_sharpness.sharpness_range.sdr_yuv_min = 0;
+ spl_in->adaptive_sharpness.sharpness_range.sdr_yuv_max = 3500;
+ spl_in->adaptive_sharpness.sharpness_range.sdr_yuv_mid = 1500;
+ spl_in->adaptive_sharpness.sharpness_range.hdr_rgb_min = 0;
+ spl_in->adaptive_sharpness.sharpness_range.hdr_rgb_max = 2750;
+ spl_in->adaptive_sharpness.sharpness_range.hdr_rgb_mid = 1500;
+
+ if (force_sharpness_level > 0) {
+ if (force_sharpness_level > 10)
+ force_sharpness_level = 10;
+ spl_in->adaptive_sharpness.enable = true;
+ spl_in->adaptive_sharpness.sharpness_level = force_sharpness_level;
+ } else if (!plane_state->adaptive_sharpness_en) {
spl_in->adaptive_sharpness.enable = false;
- else if (plane_state->sharpnessX1000 < 999)
- spl_in->adaptive_sharpness.sharpness = SHARPNESS_LOW;
- else if (plane_state->sharpnessX1000 < 1999)
- spl_in->adaptive_sharpness.sharpness = SHARPNESS_MID;
- else // Any other value is high sharpness
- spl_in->adaptive_sharpness.sharpness = SHARPNESS_HIGH;
+ spl_in->adaptive_sharpness.sharpness_level = 0;
+ } else {
+ spl_in->adaptive_sharpness.enable = true;
+ spl_in->adaptive_sharpness.sharpness_level = plane_state->sharpness_level;
+ }
}
// Translate linear light scaling preference
if (pipe_ctx->stream->ctx->dc->debug.force_lls > 0)
@@ -171,6 +184,21 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
spl_in->basic_in.tf_type = (enum spl_transfer_func_type) plane_state->in_transfer_func.type;
spl_in->basic_in.tf_predefined_type = (enum spl_transfer_func_predefined) plane_state->in_transfer_func.tf;
+ spl_in->h_active = pipe_ctx->plane_res.scl_data.h_active;
+ spl_in->v_active = pipe_ctx->plane_res.scl_data.v_active;
+ /* Check if it is stream is in fullscreen and if its HDR.
+ * Use this to determine sharpness levels
+ */
+ spl_in->is_fullscreen = dm_helpers_is_fullscreen(pipe_ctx->stream->ctx, pipe_ctx->stream);
+ spl_in->is_hdr_on = dm_helpers_is_hdr_on(pipe_ctx->stream->ctx, pipe_ctx->stream);
+ spl_in->hdr_multx100 = 0;
+ if (spl_in->is_hdr_on) {
+ spl_in->hdr_multx100 = (uint32_t)dc_fixpt_floor(dc_fixpt_mul(plane_state->hdr_mult,
+ dc_fixpt_from_int(100)));
+ /* Disable sharpness for HDR Mult > 6.0 */
+ if (spl_in->hdr_multx100 > 600)
+ spl_in->adaptive_sharpness.enable = false;
+ }
}
/// @brief Translate SPL output parameters to pipe context
@@ -179,15 +207,15 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
void translate_SPL_out_params_to_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl_out *spl_out)
{
// Make scaler data recout point to spl output field recout
- populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.recout, &spl_out->scl_data.recout);
+ populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.recout, &spl_out->dscl_prog_data->recout);
// Make scaler data ratios point to spl output field ratios
- populate_ratios_from_splratios(&pipe_ctx->plane_res.scl_data.ratios, &spl_out->scl_data.ratios);
+ populate_ratios_from_splratios(&pipe_ctx->plane_res.scl_data.ratios, &spl_out->dscl_prog_data->ratios);
// Make scaler data viewport point to spl output field viewport
- populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport, &spl_out->scl_data.viewport);
+ populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport, &spl_out->dscl_prog_data->viewport);
// Make scaler data viewport_c point to spl output field viewport_c
- populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport_c, &spl_out->scl_data.viewport_c);
+ populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport_c, &spl_out->dscl_prog_data->viewport_c);
// Make scaler data taps point to spl output field scaling taps
- populate_taps_from_spltaps(&pipe_ctx->plane_res.scl_data.taps, &spl_out->scl_data.taps);
+ populate_taps_from_spltaps(&pipe_ctx->plane_res.scl_data.taps, &spl_out->dscl_prog_data->taps);
// Make scaler data init point to spl output field init
- populate_inits_from_splinits(&pipe_ctx->plane_res.scl_data.inits, &spl_out->scl_data.inits);
+ populate_inits_from_splinits(&pipe_ctx->plane_res.scl_data.inits, &spl_out->dscl_prog_data->init);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.h b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.h
index c73d640c3632..eaa5c5373b28 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.h
@@ -6,6 +6,7 @@
#define __DC_SPL_TRANSLATE_H__
#include "dc.h"
#include "resource.h"
+#include "dm_helpers.h"
/* Map SPL input parameters to pipe context
* @pipe_ctx: pipe context
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index 8ebd7e9e776e..14ea47eda0c8 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -142,6 +142,7 @@ union stream_update_flags {
uint32_t mst_bw : 1;
uint32_t crtc_timing_adjust : 1;
uint32_t fams_changed : 1;
+ uint32_t scaler_sharpener : 1;
} bits;
uint32_t raw;
@@ -159,6 +160,12 @@ struct test_pattern {
struct dc_stream_debug_options {
char force_odm_combine_segments;
+ /*
+ * When force_odm_combine_segments is non zero, allow dc to
+ * temporarily transition to ODM bypass when minimal transition state
+ * is required to prevent visual glitches showing on the screen
+ */
+ char allow_transition_for_forced_odm;
};
#define LUMINANCE_DATA_TABLE_SIZE 10
@@ -260,6 +267,8 @@ struct dc_stream_state {
struct dc_cursor_attributes cursor_attributes;
struct dc_cursor_position cursor_position;
+ bool hw_cursor_req;
+
uint32_t sdr_white_level; // for boosting (SDR) cursor in HDR mode
/* from stream struct */
@@ -300,6 +309,7 @@ struct dc_stream_state {
bool is_phantom;
struct luminance_data lumin_data;
+ bool scaler_sharpener_update;
};
#define ABM_LEVEL_IMMEDIATE_DISABLE 255
@@ -344,6 +354,8 @@ struct dc_stream_update {
struct dc_cursor_attributes *cursor_attributes;
struct dc_cursor_position *cursor_position;
+ bool *hw_cursor_req;
+ bool *scaler_sharpener_update;
};
bool dc_is_stream_unchanged(
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index c550e8997033..fd6dca735714 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -590,6 +590,7 @@ enum dc_psr_state {
PSR_STATE5c,
PSR_STATE_HWLOCK_MGR,
PSR_STATE_POLLVUPDATE,
+ PSR_STATE_RELEASE_HWLOCK_MGR_FULL_FRAME,
PSR_STATE_INVALID = 0xFF
};
@@ -1049,6 +1050,23 @@ union replay_error_status {
unsigned char raw;
};
+union replay_low_refresh_rate_enable_options {
+ struct {
+ //BIT[0-3]: Replay Low Hz Support control
+ unsigned int ENABLE_LOW_RR_SUPPORT :1;
+ unsigned int RESERVED_1_3 :3;
+ //BIT[4-15]: Replay Low Hz Enable Scenarios
+ unsigned int ENABLE_STATIC_SCREEN :1;
+ unsigned int ENABLE_FULL_SCREEN_VIDEO :1;
+ unsigned int ENABLE_GENERAL_UI :1;
+ unsigned int RESERVED_7_15 :9;
+ //BIT[16-31]: Replay Low Hz Enable Check
+ unsigned int ENABLE_STATIC_FLICKER_CHECK :1;
+ unsigned int RESERVED_17_31 :15;
+ } bits;
+ unsigned int raw;
+};
+
struct replay_config {
/* Replay feature is supported */
bool replay_supported;
@@ -1072,6 +1090,8 @@ struct replay_config {
bool replay_support_fast_resync_in_ultra_sleep_mode;
/* Replay error status */
union replay_error_status replay_error_status;
+ /* Replay Low Hz enable Options */
+ union replay_low_refresh_rate_enable_options low_rr_enable_options;
};
/* Replay feature flags*/
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
index 1e0292861244..160c299419b7 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
@@ -328,6 +328,17 @@
type DPSTREAMCLK1_GATE_DISABLE;\
type DPSTREAMCLK2_GATE_DISABLE;\
type DPSTREAMCLK3_GATE_DISABLE;\
+ type SYMCLKA_FE_GATE_DISABLE;\
+ type SYMCLKB_FE_GATE_DISABLE;\
+ type SYMCLKC_FE_GATE_DISABLE;\
+ type SYMCLKD_FE_GATE_DISABLE;\
+ type SYMCLKE_FE_GATE_DISABLE;\
+ type SYMCLKA_GATE_DISABLE;\
+ type SYMCLKB_GATE_DISABLE;\
+ type SYMCLKC_GATE_DISABLE;\
+ type SYMCLKD_GATE_DISABLE;\
+ type SYMCLKE_GATE_DISABLE;\
+
#define DCCG401_REG_FIELD_LIST(type) \
type OTG0_TMDS_PIXEL_RATE_DIV;\
@@ -346,11 +357,7 @@
type SYMCLK32_LE3_SRC_SEL;\
type SYMCLK32_LE2_EN;\
type SYMCLK32_LE3_EN;\
- type DP_DTO_ENABLE[MAX_PIPES];\
- type DSCCLK0_DTO_DB_EN;\
- type DSCCLK1_DTO_DB_EN;\
- type DSCCLK2_DTO_DB_EN;\
- type DSCCLK3_DTO_DB_EN;
+ type DP_DTO_ENABLE[MAX_PIPES];
struct dccg_shift {
DCCG_REG_FIELD_LIST(uint8_t)
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c
index 68cd3258f4a9..838d72eaa87f 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c
@@ -24,6 +24,7 @@
#include "reg_helper.h"
#include "core_types.h"
+#include "resource.h"
#include "dcn35_dccg.h"
#define TO_DCN_DCCG(dccg)\
@@ -41,13 +42,1069 @@
#define DC_LOGGER \
dccg->ctx->logger
+enum symclk_fe_source {
+ SYMCLK_FE_SYMCLK_A = 0, // Select functional clock from backend symclk A
+ SYMCLK_FE_SYMCLK_B,
+ SYMCLK_FE_SYMCLK_C,
+ SYMCLK_FE_SYMCLK_D,
+ SYMCLK_FE_SYMCLK_E,
+ SYMCLK_FE_REFCLK = 0xFF, // Arbitrary value to pass refclk selection in software
+};
+
+enum symclk_be_source {
+ SYMCLK_BE_PHYCLK = 0, // Select phy clk when sym_clk_enable = 1
+ SYMCLK_BE_DPIACLK_810 = 4,
+ SYMCLK_BE_DPIACLK_162 = 5,
+ SYMCLK_BE_DPIACLK_540 = 6,
+ SYMCLK_BE_DPIACLK_270 = 7,
+ SYMCLK_BE_REFCLK = 0xFF, // Arbitrary value to pass refclk selection in software
+};
+
+enum physymclk_source {
+ PHYSYMCLK_PHYCLK = 0, // Select symclk as source of clock which is output to PHY through DCIO.
+ PHYSYMCLK_PHYD18CLK, // Select phyd18clk as the source of clock which is output to PHY through DCIO.
+ PHYSYMCLK_PHYD32CLK, // Select phyd32clk as the source of clock which is output to PHY through DCIO.
+ PHYSYMCLK_REFCLK = 0xFF, // Arbitrary value to pass refclk selection in software
+};
+
+enum dtbclk_source {
+ DTBCLK_DPREFCLK = 0, // Selects source for DTBCLK_P# as DPREFCLK (src sel 0 and 1 are same)
+ DTBCLK_DPREFCLK_0, // Selects source for DTBCLK_P# as DPREFCLK (src sel 0 and 1 are same)
+ DTBCLK_DTBCLK0, // Selects source for DTBCLK_P# as DTBCLK0
+ DTBCLK_DTBCLK1, // Selects source for DTBCLK_P# as DTBCLK0
+ DTBCLK_REFCLK = 0xFF, // Arbitrary value to pass refclk selection in software
+};
+
+enum dppclk_clock_source {
+ DPP_REFCLK = 0, // refclk is selected
+ DPP_DCCG_DTO, // Functional clock selected is DTO tuned DPPCLK
+};
+
+enum dp_stream_clk_source {
+ DP_STREAM_DTBCLK_P0 = 0, // Selects functional for DP_STREAM_CLK as DTBCLK_P#
+ DP_STREAM_DTBCLK_P1,
+ DP_STREAM_DTBCLK_P2,
+ DP_STREAM_DTBCLK_P3,
+ DP_STREAM_DTBCLK_P4,
+ DP_STREAM_DTBCLK_P5,
+ DP_STREAM_REFCLK = 0xFF, // Arbitrary value to pass refclk selection in software
+};
+
+enum hdmi_char_clk {
+ HDMI_CHAR_PHYAD18CLK = 0, // Selects functional for hdmi_char_clk as UNIPHYA PHYD18CLK
+ HDMI_CHAR_PHYBD18CLK,
+ HDMI_CHAR_PHYCD18CLK,
+ HDMI_CHAR_PHYDD18CLK,
+ HDMI_CHAR_PHYED18CLK,
+ HDMI_CHAR_REFCLK = 0xFF, // Arbitrary value to pass refclk selection in software
+};
+
+enum hdmi_stream_clk_source {
+ HDMI_STREAM_DTBCLK_P0 = 0, // Selects functional for HDMI_STREAM_CLK as DTBCLK_P#
+ HDMI_STREAM_DTBCLK_P1,
+ HDMI_STREAM_DTBCLK_P2,
+ HDMI_STREAM_DTBCLK_P3,
+ HDMI_STREAM_DTBCLK_P4,
+ HDMI_STREAM_DTBCLK_P5,
+ HDMI_STREAM_REFCLK = 0xFF, // Arbitrary value to pass refclk selection in software
+};
+
+enum symclk32_se_clk_source {
+ SYMCLK32_SE_PHYAD32CLK = 0, // Selects functional for SYMCLK32 as UNIPHYA PHYD32CLK
+ SYMCLK32_SE_PHYBD32CLK,
+ SYMCLK32_SE_PHYCD32CLK,
+ SYMCLK32_SE_PHYDD32CLK,
+ SYMCLK32_SE_PHYED32CLK,
+ SYMCLK32_SE_REFCLK = 0xFF, // Arbitrary value to pass refclk selection in software
+};
+
+enum symclk32_le_clk_source {
+ SYMCLK32_LE_PHYAD32CLK = 0, // Selects functional for SYMCLK32 as UNIPHYA PHYD32CLK
+ SYMCLK32_LE_PHYBD32CLK,
+ SYMCLK32_LE_PHYCD32CLK,
+ SYMCLK32_LE_PHYDD32CLK,
+ SYMCLK32_LE_PHYED32CLK,
+ SYMCLK32_LE_REFCLK = 0xFF, // Arbitrary value to pass refclk selection in software
+};
+
+enum dsc_clk_source {
+ DSC_CLK_REF_CLK = 0, // Ref clock selected for DSC_CLK
+ DSC_DTO_TUNED_CK_GPU_DISCLK_3, // DTO divided clock selected as functional clock
+};
+
+
+static void dccg35_set_dsc_clk_rcg(struct dccg *dccg, int inst, bool enable)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc && enable)
+ return;
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 1:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 2:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 3:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static void dccg35_set_symclk32_se_rcg(
+ struct dccg *dccg,
+ int inst,
+ bool enable)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se && enable)
+ return;
+
+ /* SYMCLK32_ROOT_SE#_GATE_DISABLE will clock gate in DCCG */
+ /* SYMCLK32_SE#_GATE_DISABLE will clock gate in HPO only */
+ switch (inst) {
+ case 0:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE0_GATE_DISABLE, enable ? 0 : 1,
+ SYMCLK32_ROOT_SE0_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 1:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE1_GATE_DISABLE, enable ? 0 : 1,
+ SYMCLK32_ROOT_SE1_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 2:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE2_GATE_DISABLE, enable ? 0 : 1,
+ SYMCLK32_ROOT_SE2_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 3:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE3_GATE_DISABLE, enable ? 0 : 1,
+ SYMCLK32_ROOT_SE3_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static void dccg35_set_symclk32_le_rcg(
+ struct dccg *dccg,
+ int inst,
+ bool enable)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le && enable)
+ return;
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_LE0_GATE_DISABLE, enable ? 0 : 1,
+ SYMCLK32_ROOT_LE0_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 1:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_LE1_GATE_DISABLE, enable ? 0 : 1,
+ SYMCLK32_ROOT_LE1_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static void dccg35_set_physymclk_rcg(
+ struct dccg *dccg,
+ int inst,
+ bool enable)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk && enable)
+ return;
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 1:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 2:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 3:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 4:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static void dccg35_set_symclk_fe_rcg(
+ struct dccg *dccg,
+ int inst,
+ bool enable)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe && enable)
+ return;
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ SYMCLKA_FE_GATE_DISABLE, enable ? 0 : 1);
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKA_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 1:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ SYMCLKB_FE_GATE_DISABLE, enable ? 0 : 1);
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKB_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 2:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ SYMCLKC_FE_GATE_DISABLE, enable ? 0 : 1);
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKC_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 3:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ SYMCLKD_FE_GATE_DISABLE, enable ? 0 : 1);
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKD_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 4:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ SYMCLKE_FE_GATE_DISABLE, enable ? 0 : 1);
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKE_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static void dccg35_set_symclk_be_rcg(
+ struct dccg *dccg,
+ int inst,
+ bool enable)
+{
+
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ /* TBD add symclk_be in rcg control bits */
+ if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe && enable)
+ return;
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ SYMCLKA_GATE_DISABLE, enable ? 0 : 1);
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKA_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 1:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ SYMCLKB_GATE_DISABLE, enable ? 0 : 1);
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKB_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 2:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ SYMCLKC_GATE_DISABLE, enable ? 0 : 1);
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKC_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 3:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ SYMCLKD_GATE_DISABLE, enable ? 0 : 1);
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKD_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 4:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ SYMCLKE_GATE_DISABLE, enable ? 0 : 1);
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKE_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static void dccg35_set_dtbclk_p_rcg(struct dccg *dccg, int inst, bool enable)
+{
+
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable)
+ return;
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 1:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P1_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 2:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P2_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 3:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P3_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ break;
+ }
+}
+
+static void dccg35_set_dppclk_rcg(struct dccg *dccg,
+ int inst, bool enable)
+{
+
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable)
+ return;
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 1:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK1_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 2:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK2_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 3:
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK3_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ break;
+ }
+}
+
+static void dccg35_set_dpstreamclk_rcg(
+ struct dccg *dccg,
+ int inst,
+ bool enable)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream && enable)
+ return;
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
+ DPSTREAMCLK0_GATE_DISABLE, enable ? 0 : 1,
+ DPSTREAMCLK0_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 1:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
+ DPSTREAMCLK1_GATE_DISABLE, enable ? 0 : 1,
+ DPSTREAMCLK1_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 2:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
+ DPSTREAMCLK2_GATE_DISABLE, enable ? 0 : 1,
+ DPSTREAMCLK2_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 3:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
+ DPSTREAMCLK3_GATE_DISABLE, enable ? 0 : 1,
+ DPSTREAMCLK3_ROOT_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static void dccg35_set_smclk32_se_rcg(
+ struct dccg *dccg,
+ int inst,
+ bool enable)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se && enable)
+ return;
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE0_GATE_DISABLE, enable ? 0 : 1,
+ SYMCLK32_ROOT_SE0_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 1:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE1_GATE_DISABLE, enable ? 0 : 1,
+ SYMCLK32_ROOT_SE1_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 2:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE2_GATE_DISABLE, enable ? 0 : 1,
+ SYMCLK32_ROOT_SE2_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ case 3:
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE3_GATE_DISABLE, enable ? 0 : 1,
+ SYMCLK32_ROOT_SE3_GATE_DISABLE, enable ? 0 : 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static void dccg35_set_dsc_clk_src_new(struct dccg *dccg, int inst, enum dsc_clk_source src)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ /* DSCCLK#_EN=0 switches to refclock from functional clock */
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK0_EN, src);
+ break;
+ case 1:
+ REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, src);
+ break;
+ case 2:
+ REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, src);
+ break;
+ case 3:
+ REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, src);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static void dccg35_set_symclk32_se_src_new(
+ struct dccg *dccg,
+ int inst,
+ enum symclk32_se_clk_source src
+ )
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE_2(SYMCLK32_SE_CNTL,
+ SYMCLK32_SE0_SRC_SEL, (src == SYMCLK32_SE_REFCLK) ? 0 : src,
+ SYMCLK32_SE0_EN, (src == SYMCLK32_SE_REFCLK) ? 0 : 1);
+ break;
+ case 1:
+ REG_UPDATE_2(SYMCLK32_SE_CNTL,
+ SYMCLK32_SE1_SRC_SEL, (src == SYMCLK32_SE_REFCLK) ? 0 : src,
+ SYMCLK32_SE1_EN, (src == SYMCLK32_SE_REFCLK) ? 0 : 1);
+ break;
+ case 2:
+ REG_UPDATE_2(SYMCLK32_SE_CNTL,
+ SYMCLK32_SE2_SRC_SEL, (src == SYMCLK32_SE_REFCLK) ? 0 : src,
+ SYMCLK32_SE2_EN, (src == SYMCLK32_SE_REFCLK) ? 0 : 1);
+ break;
+ case 3:
+ REG_UPDATE_2(SYMCLK32_SE_CNTL,
+ SYMCLK32_SE3_SRC_SEL, (src == SYMCLK32_SE_REFCLK) ? 0 : src,
+ SYMCLK32_SE3_EN, (src == SYMCLK32_SE_REFCLK) ? 0 : 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static int
+dccg35_is_symclk32_se_src_functional_le_new(struct dccg *dccg, int symclk_32_se_inst, int symclk_32_le_inst)
+{
+ uint32_t en;
+ uint32_t src_sel;
+
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ REG_GET_2(SYMCLK32_SE_CNTL, SYMCLK32_SE3_SRC_SEL, &src_sel, SYMCLK32_SE3_EN, &en);
+
+ if (en == 1 && src_sel == symclk_32_le_inst)
+ return 1;
+
+ return 0;
+}
+
+
+static void dccg35_set_symclk32_le_src_new(
+ struct dccg *dccg,
+ int inst,
+ enum symclk32_le_clk_source src)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE_2(SYMCLK32_LE_CNTL,
+ SYMCLK32_LE0_SRC_SEL, (src == SYMCLK32_LE_REFCLK) ? 0 : src,
+ SYMCLK32_LE0_EN, (src == SYMCLK32_LE_REFCLK) ? 0 : 1);
+ break;
+ case 1:
+ REG_UPDATE_2(SYMCLK32_LE_CNTL,
+ SYMCLK32_LE1_SRC_SEL, (src == SYMCLK32_LE_REFCLK) ? 0 : src,
+ SYMCLK32_LE1_EN, (src == SYMCLK32_LE_REFCLK) ? 0 : 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static void dcn35_set_dppclk_src_new(struct dccg *dccg,
+ int inst, enum dppclk_clock_source src)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE(DPPCLK_CTRL, DPPCLK0_EN, src);
+ break;
+ case 1:
+ REG_UPDATE(DPPCLK_CTRL, DPPCLK1_EN, src);
+ break;
+ case 2:
+ REG_UPDATE(DPPCLK_CTRL, DPPCLK2_EN, src);
+ break;
+ case 3:
+ REG_UPDATE(DPPCLK_CTRL, DPPCLK3_EN, src);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ break;
+ }
+}
+
+static void dccg35_set_dtbclk_p_src_new(
+ struct dccg *dccg,
+ enum dtbclk_source src,
+ int inst)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ /* If DTBCLK_P#_EN is 0 refclock is selected as functional clock
+ * If DTBCLK_P#_EN is 1 functional clock is selected as DTBCLK_P#_SRC_SEL
+ */
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE_2(DTBCLK_P_CNTL,
+ DTBCLK_P0_SRC_SEL, (src == DTBCLK_REFCLK) ? 0 : src,
+ DTBCLK_P0_EN, (src == DTBCLK_REFCLK) ? 0 : 1);
+ break;
+ case 1:
+ REG_UPDATE_2(DTBCLK_P_CNTL,
+ DTBCLK_P1_SRC_SEL, (src == DTBCLK_REFCLK) ? 0 : src,
+ DTBCLK_P1_EN, (src == DTBCLK_REFCLK) ? 0 : 1);
+ break;
+ case 2:
+ REG_UPDATE_2(DTBCLK_P_CNTL,
+ DTBCLK_P2_SRC_SEL, (src == DTBCLK_REFCLK) ? 0 : src,
+ DTBCLK_P2_EN, (src == DTBCLK_REFCLK) ? 0 : 1);
+ break;
+ case 3:
+ REG_UPDATE_2(DTBCLK_P_CNTL,
+ DTBCLK_P3_SRC_SEL, (src == DTBCLK_REFCLK) ? 0 : src,
+ DTBCLK_P3_EN, (src == DTBCLK_REFCLK) ? 0 : 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static void dccg35_set_dpstreamclk_src_new(
+ struct dccg *dccg,
+ enum dp_stream_clk_source src,
+ int inst)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK0_EN,
+ (src == DP_STREAM_REFCLK) ? 0 : 1,
+ DPSTREAMCLK0_SRC_SEL,
+ (src == DP_STREAM_REFCLK) ? 0 : src);
+ break;
+ case 1:
+ REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK1_EN,
+ (src == DP_STREAM_REFCLK) ? 0 : 1,
+ DPSTREAMCLK1_SRC_SEL,
+ (src == DP_STREAM_REFCLK) ? 0 : src);
+
+ break;
+ case 2:
+ REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK2_EN,
+ (src == DP_STREAM_REFCLK) ? 0 : 1,
+ DPSTREAMCLK2_SRC_SEL,
+ (src == DP_STREAM_REFCLK) ? 0 : src);
+
+ break;
+ case 3:
+ REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK3_EN,
+ (src == DP_STREAM_REFCLK) ? 0 : 1,
+ DPSTREAMCLK3_SRC_SEL,
+ (src == DP_STREAM_REFCLK) ? 0 : src);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static void dccg35_set_physymclk_src_new(
+ struct dccg *dccg,
+ enum physymclk_source src,
+ int inst)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL, PHYASYMCLK_EN,
+ (src == PHYSYMCLK_REFCLK) ? 0 : 1,
+ PHYASYMCLK_SRC_SEL,
+ (src == PHYSYMCLK_REFCLK) ? 0 : src);
+ break;
+ case 1:
+ REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL, PHYBSYMCLK_EN,
+ (src == PHYSYMCLK_REFCLK) ? 0 : 1,
+ PHYBSYMCLK_SRC_SEL,
+ (src == PHYSYMCLK_REFCLK) ? 0 : src);
+ break;
+ case 2:
+ REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL, PHYCSYMCLK_EN,
+ (src == PHYSYMCLK_REFCLK) ? 0 : 1,
+ PHYCSYMCLK_SRC_SEL,
+ (src == PHYSYMCLK_REFCLK) ? 0 : src);
+ break;
+ case 3:
+ REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL, PHYDSYMCLK_EN,
+ (src == PHYSYMCLK_REFCLK) ? 0 : 1,
+ PHYDSYMCLK_SRC_SEL,
+ (src == PHYSYMCLK_REFCLK) ? 0 : src);
+ break;
+ case 4:
+ REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL, PHYESYMCLK_EN,
+ (src == PHYSYMCLK_REFCLK) ? 0 : 1,
+ PHYESYMCLK_SRC_SEL,
+ (src == PHYSYMCLK_REFCLK) ? 0 : src);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+}
+
+static void dccg35_set_symclk_be_src_new(
+ struct dccg *dccg,
+ enum symclk_be_source src,
+ int inst)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,
+ SYMCLKA_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,
+ SYMCLKA_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);
+ break;
+ case 1:
+ REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,
+ SYMCLKB_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,
+ SYMCLKB_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);
+ break;
+ case 2:
+ REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,
+ SYMCLKC_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,
+ SYMCLKC_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);
+ break;
+ case 3:
+ REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,
+ SYMCLKD_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,
+ SYMCLKD_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);
+ break;
+ case 4:
+ REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,
+ SYMCLKE_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,
+ SYMCLKE_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);
+ break;
+ }
+}
+
+static int dccg35_is_symclk_fe_src_functional_be(struct dccg *dccg,
+ int symclk_fe_inst,
+ int symclk_be_inst)
+{
+
+ uint32_t en = 0;
+ uint32_t src_sel = 0;
+
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ switch (symclk_fe_inst) {
+ case 0:
+ REG_GET_2(SYMCLKA_CLOCK_ENABLE, SYMCLKA_FE_SRC_SEL, &src_sel, SYMCLKA_FE_EN, &en);
+ break;
+ case 1:
+ REG_GET_2(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_SRC_SEL, &src_sel, SYMCLKB_FE_EN, &en);
+ break;
+ case 2:
+ REG_GET_2(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_SRC_SEL, &src_sel, SYMCLKC_FE_EN, &en);
+ break;
+ case 3:
+ REG_GET_2(SYMCLKD_CLOCK_ENABLE, SYMCLKD_FE_SRC_SEL, &src_sel, SYMCLKD_FE_EN, &en);
+ break;
+ case 4:
+ REG_GET_2(SYMCLKE_CLOCK_ENABLE, SYMCLKE_FE_SRC_SEL, &src_sel, SYMCLKE_FE_EN, &en);
+ break;
+ }
+
+ if (en == 1 && src_sel == symclk_be_inst)
+ return 1;
+
+ return 0;
+}
+
+static void dccg35_set_symclk_fe_src_new(struct dccg *dccg, enum symclk_fe_source src, int inst)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ switch (inst) {
+ case 0:
+ REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,
+ SYMCLKA_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,
+ SYMCLKA_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);
+ break;
+ case 1:
+ REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,
+ SYMCLKB_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,
+ SYMCLKB_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);
+ break;
+ case 2:
+ REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,
+ SYMCLKC_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,
+ SYMCLKC_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);
+ break;
+ case 3:
+ REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,
+ SYMCLKD_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,
+ SYMCLKD_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);
+ break;
+ case 4:
+ REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,
+ SYMCLKE_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,
+ SYMCLKE_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);
+ break;
+ }
+}
+
+static uint32_t dccg35_is_fe_rcg(struct dccg *dccg, int inst)
+{
+ uint32_t enable = 0;
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ switch (inst) {
+ case 0:
+ REG_GET(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKA_FE_ROOT_GATE_DISABLE, &enable);
+ break;
+ case 1:
+ REG_GET(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKB_FE_ROOT_GATE_DISABLE, &enable);
+ break;
+ case 2:
+ REG_GET(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKC_FE_ROOT_GATE_DISABLE, &enable);
+ break;
+ case 3:
+ REG_GET(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKD_FE_ROOT_GATE_DISABLE, &enable);
+ break;
+ case 4:
+ REG_GET(DCCG_GATE_DISABLE_CNTL5,
+ SYMCLKE_FE_ROOT_GATE_DISABLE, &enable);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ break;
+ }
+ return enable;
+}
+
+static uint32_t dccg35_is_symclk32_se_rcg(struct dccg *dccg, int inst)
+{
+ uint32_t disable_l1 = 0;
+ uint32_t disable_l2 = 0;
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ switch (inst) {
+ case 0:
+ REG_GET_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE0_GATE_DISABLE, &disable_l1,
+ SYMCLK32_ROOT_SE0_GATE_DISABLE, &disable_l2);
+ break;
+ case 1:
+ REG_GET_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE1_GATE_DISABLE, &disable_l1,
+ SYMCLK32_ROOT_SE1_GATE_DISABLE, &disable_l2);
+ break;
+ case 2:
+ REG_GET_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE2_GATE_DISABLE, &disable_l1,
+ SYMCLK32_ROOT_SE2_GATE_DISABLE, &disable_l2);
+ break;
+ case 3:
+ REG_GET_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE3_GATE_DISABLE, &disable_l1,
+ SYMCLK32_ROOT_SE3_GATE_DISABLE, &disable_l2);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return 0;
+ }
+
+ /* return true if either block level or DCCG level gating is active */
+ return (disable_l1 | disable_l2);
+}
+
+static void dccg35_enable_symclk_fe_new(
+ struct dccg *dccg,
+ int inst,
+ enum symclk_fe_source src)
+{
+ dccg35_set_symclk_fe_rcg(dccg, inst, false);
+ dccg35_set_symclk_fe_src_new(dccg, src, inst);
+}
+
+static void dccg35_disable_symclk_fe_new(
+ struct dccg *dccg,
+ int inst)
+{
+ dccg35_set_symclk_fe_src_new(dccg, SYMCLK_FE_REFCLK, inst);
+ dccg35_set_symclk_fe_rcg(dccg, inst, true);
+}
+
+static void dccg35_enable_symclk_be_new(
+ struct dccg *dccg,
+ int inst,
+ enum symclk_be_source src)
+{
+ dccg35_set_symclk_be_rcg(dccg, inst, false);
+ dccg35_set_symclk_be_src_new(dccg, inst, src);
+}
+
+static void dccg35_disable_symclk_be_new(
+ struct dccg *dccg,
+ int inst)
+{
+ int i;
+
+ /* Switch from functional clock to refclock */
+ dccg35_set_symclk_be_src_new(dccg, inst, SYMCLK_BE_REFCLK);
+
+ /* Check if any other SE connected LE and disable them */
+ for (i = 0; i < 4; i++) {
+ /* Make sure FE is not already in RCG */
+ if (dccg35_is_fe_rcg(dccg, i) == 0) {
+ if (dccg35_is_symclk_fe_src_functional_be(dccg, i, inst))
+ dccg35_disable_symclk_fe_new(dccg, i);
+ }
+ }
+ /* Safe to RCG SYMCLK*/
+ dccg35_set_symclk_be_rcg(dccg, inst, true);
+}
+
+static void dccg35_enable_symclk32_se_new(
+ struct dccg *dccg,
+ int inst,
+ enum symclk32_se_clk_source src)
+{
+ dccg35_set_symclk32_se_rcg(dccg, inst, false);
+ dccg35_set_symclk32_se_src_new(dccg, inst, src);
+}
+
+static void dccg35_disable_symclk32_se_new(
+ struct dccg *dccg,
+ int inst)
+{
+ dccg35_set_symclk32_se_src_new(dccg, SYMCLK32_SE_REFCLK, inst);
+ dccg35_set_symclk32_se_rcg(dccg, inst, true);
+}
+
+static void dccg35_enable_symclk32_le_new(
+ struct dccg *dccg,
+ int inst,
+ enum symclk32_le_clk_source src)
+{
+ dccg35_set_symclk32_le_rcg(dccg, inst, false);
+ dccg35_set_symclk32_le_src_new(dccg, inst, src);
+}
+
+static void dccg35_disable_symclk32_le_new(
+ struct dccg *dccg,
+ int inst)
+{
+ int i;
+
+ /* Switch from functional clock to refclock */
+ dccg35_set_symclk32_le_src_new(dccg, inst, SYMCLK32_LE_REFCLK);
+
+ /* Check if any SE are connected and disable SE as well */
+ for (i = 0; i < 4; i++) {
+ /* Make sure FE is not already in RCG */
+ if (dccg35_is_symclk32_se_rcg(dccg, i) == 0) {
+ /* Disable and SE connected to this LE before RCG */
+ if (dccg35_is_symclk32_se_src_functional_le_new(dccg, i, inst))
+ dccg35_disable_symclk32_se_new(dccg, i);
+ }
+ }
+ /* Safe to RCG SYM32_LE*/
+ dccg35_set_symclk32_le_rcg(dccg, inst, true);
+}
+
+static void dccg35_enable_physymclk_new(struct dccg *dccg,
+ int inst,
+ enum physymclk_source src)
+{
+ dccg35_set_physymclk_rcg(dccg, inst, false);
+ dccg35_set_physymclk_src_new(dccg, src, inst);
+}
+
+static void dccg35_disable_physymclk_new(struct dccg *dccg,
+ int inst)
+{
+ dccg35_set_physymclk_src_new(dccg, PHYSYMCLK_REFCLK, inst);
+ dccg35_set_physymclk_rcg(dccg, inst, true);
+}
+
+static void dccg35_enable_dpp_clk_new(
+ struct dccg *dccg,
+ int inst,
+ enum dppclk_clock_source src)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+ /* Sanitize inst before use in array de-ref */
+ if (inst < 0) {
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+ dccg35_set_dppclk_rcg(dccg, inst, false);
+ dcn35_set_dppclk_src_new(dccg, inst, src);
+ /* Switch DPP clock to DTO */
+ REG_SET_2(DPPCLK_DTO_PARAM[inst], 0,
+ DPPCLK0_DTO_PHASE, 0xFF,
+ DPPCLK0_DTO_MODULO, 0xFF);
+}
+
+static void dccg35_disable_dpp_clk_new(
+ struct dccg *dccg,
+ int inst)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+ /* Sanitize inst before use in array de-ref */
+ if (inst < 0) {
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+ dcn35_set_dppclk_src_new(dccg, inst, DPP_REFCLK);
+ REG_SET_2(DPPCLK_DTO_PARAM[inst], 0,
+ DPPCLK0_DTO_PHASE, 0,
+ DPPCLK0_DTO_MODULO, 1);
+ dccg35_set_dppclk_rcg(dccg, inst, true);
+}
+
+static void dccg35_disable_dscclk_new(struct dccg *dccg,
+ int inst)
+{
+ dccg35_set_dsc_clk_src_new(dccg, inst, DSC_CLK_REF_CLK);
+ dccg35_set_dsc_clk_rcg(dccg, inst, true);
+}
+
+static void dccg35_enable_dscclk_new(struct dccg *dccg,
+ int inst,
+ enum dsc_clk_source src)
+{
+ dccg35_set_dsc_clk_rcg(dccg, inst, false);
+ dccg35_set_dsc_clk_src_new(dccg, inst, src);
+}
+
+static void dccg35_enable_dtbclk_p_new(struct dccg *dccg,
+ enum dtbclk_source src,
+ int inst)
+{
+ dccg35_set_dtbclk_p_rcg(dccg, inst, false);
+ dccg35_set_dtbclk_p_src_new(dccg, src, inst);
+}
+
+static void dccg35_disable_dtbclk_p_new(struct dccg *dccg,
+ int inst)
+{
+ dccg35_set_dtbclk_p_src_new(dccg, DTBCLK_REFCLK, inst);
+ dccg35_set_dtbclk_p_rcg(dccg, inst, true);
+}
+
+static void dccg35_disable_dpstreamclk_new(struct dccg *dccg,
+ int inst)
+{
+ dccg35_set_dpstreamclk_src_new(dccg, DP_STREAM_REFCLK, inst);
+ dccg35_set_dpstreamclk_rcg(dccg, inst, true);
+}
+
+static void dccg35_enable_dpstreamclk_new(struct dccg *dccg,
+ enum dp_stream_clk_source src,
+ int inst)
+{
+ dccg35_set_dpstreamclk_rcg(dccg, inst, false);
+ dccg35_set_dpstreamclk_src_new(dccg, src, inst);
+}
+
static void dccg35_trigger_dio_fifo_resync(struct dccg *dccg)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
uint32_t dispclk_rdivider_value = 0;
REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, &dispclk_rdivider_value);
- REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value);
+ if (dispclk_rdivider_value != 0)
+ REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value);
}
static void dcn35_set_dppclk_enable(struct dccg *dccg,
@@ -657,6 +1714,12 @@ static void dccg35_disable_symclk32_se(
}
}
+static void dccg35_init_cb(struct dccg *dccg)
+{
+ (void)dccg;
+ /* Any RCG should be done when driver enter low power mode*/
+}
+
void dccg35_init(struct dccg *dccg)
{
int otg_inst;
@@ -685,10 +1748,6 @@ void dccg35_init(struct dccg *dccg)
dccg35_set_dpstreamclk_root_clock_gating(dccg, otg_inst, false);
}
- if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
- for (otg_inst = 0; otg_inst < 4; otg_inst++)
- dccg35_set_dppclk_root_clock_gating(dccg, otg_inst, 0);
-
/*
dccg35_enable_global_fgcg_rep(
dccg, dccg->ctx->dc->debug.enable_fine_grain_clock_gating.bits
@@ -869,47 +1928,32 @@ static void dccg35_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst,
}
/*get other front end connected to this backend*/
-static uint8_t dccg35_get_other_enabled_symclk_fe(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
+static uint8_t dccg35_get_number_enabled_symclk_fe_connected_to_be(struct dccg *dccg, uint32_t link_enc_inst)
{
uint8_t num_enabled_symclk_fe = 0;
- uint32_t be_clk_en = 0, fe_clk_en[5] = {0}, be_clk_sel[5] = {0};
+ uint32_t fe_clk_en[5] = {0}, be_clk_sel[5] = {0};
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
- switch (link_enc_inst) {
- case 0:
- REG_GET_3(SYMCLKA_CLOCK_ENABLE, SYMCLKA_CLOCK_ENABLE, &be_clk_en,
- SYMCLKA_FE_EN, &fe_clk_en[0],
- SYMCLKA_FE_SRC_SEL, &be_clk_sel[0]);
- break;
- case 1:
- REG_GET_3(SYMCLKB_CLOCK_ENABLE, SYMCLKB_CLOCK_ENABLE, &be_clk_en,
- SYMCLKB_FE_EN, &fe_clk_en[1],
- SYMCLKB_FE_SRC_SEL, &be_clk_sel[1]);
- break;
- case 2:
- REG_GET_3(SYMCLKC_CLOCK_ENABLE, SYMCLKC_CLOCK_ENABLE, &be_clk_en,
- SYMCLKC_FE_EN, &fe_clk_en[2],
- SYMCLKC_FE_SRC_SEL, &be_clk_sel[2]);
- break;
- case 3:
- REG_GET_3(SYMCLKD_CLOCK_ENABLE, SYMCLKD_CLOCK_ENABLE, &be_clk_en,
- SYMCLKD_FE_EN, &fe_clk_en[3],
- SYMCLKD_FE_SRC_SEL, &be_clk_sel[3]);
- break;
- case 4:
- REG_GET_3(SYMCLKE_CLOCK_ENABLE, SYMCLKE_CLOCK_ENABLE, &be_clk_en,
- SYMCLKE_FE_EN, &fe_clk_en[4],
- SYMCLKE_FE_SRC_SEL, &be_clk_sel[4]);
- break;
- }
- if (be_clk_en) {
- /* for DPMST, this backend could be used by multiple front end.
- only disable the backend if this stream_enc_ins is the last active stream enc connected to this back_end*/
- uint8_t i;
- for (i = 0; i != link_enc_inst && i < ARRAY_SIZE(fe_clk_en); i++) {
- if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst)
- num_enabled_symclk_fe++;
- }
+ REG_GET_2(SYMCLKA_CLOCK_ENABLE, SYMCLKA_FE_EN, &fe_clk_en[0],
+ SYMCLKA_FE_SRC_SEL, &be_clk_sel[0]);
+
+ REG_GET_2(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_EN, &fe_clk_en[1],
+ SYMCLKB_FE_SRC_SEL, &be_clk_sel[1]);
+
+ REG_GET_2(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_EN, &fe_clk_en[2],
+ SYMCLKC_FE_SRC_SEL, &be_clk_sel[2]);
+
+ REG_GET_2(SYMCLKD_CLOCK_ENABLE, SYMCLKD_FE_EN, &fe_clk_en[3],
+ SYMCLKD_FE_SRC_SEL, &be_clk_sel[3]);
+
+ REG_GET_2(SYMCLKE_CLOCK_ENABLE, SYMCLKE_FE_EN, &fe_clk_en[4],
+ SYMCLKE_FE_SRC_SEL, &be_clk_sel[4]);
+
+ uint8_t i;
+
+ for (i = 0; i < ARRAY_SIZE(fe_clk_en); i++) {
+ if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst)
+ num_enabled_symclk_fe++;
}
return num_enabled_symclk_fe;
}
@@ -957,9 +2001,9 @@ static void dccg35_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst
break;
}
- /*check other enabled symclk fe */
- num_enabled_symclk_fe = dccg35_get_other_enabled_symclk_fe(dccg, stream_enc_inst, link_enc_inst);
- /*only turn off backend clk if other front end attachecd to this backend are all off,
+ /*check other enabled symclk fe connected to this be */
+ num_enabled_symclk_fe = dccg35_get_number_enabled_symclk_fe_connected_to_be(dccg, link_enc_inst);
+ /*only turn off backend clk if other front end attached to this backend are all off,
for mst, only turn off the backend if this is the last front end*/
if (num_enabled_symclk_fe == 0) {
switch (link_enc_inst) {
@@ -997,6 +2041,336 @@ static void dccg35_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst
}
}
+static void dccg35_set_dpstreamclk_cb(
+ struct dccg *dccg,
+ enum streamclk_source src,
+ int otg_inst,
+ int dp_hpo_inst)
+{
+
+ enum dtbclk_source dtb_clk_src;
+ enum dp_stream_clk_source dp_stream_clk_src;
+
+ switch (src) {
+ case REFCLK:
+ dtb_clk_src = DTBCLK_REFCLK;
+ dp_stream_clk_src = DP_STREAM_REFCLK;
+ break;
+ case DPREFCLK:
+ dtb_clk_src = DTBCLK_DPREFCLK;
+ dp_stream_clk_src = (enum dp_stream_clk_source)otg_inst;
+ break;
+ case DTBCLK0:
+ dtb_clk_src = DTBCLK_DTBCLK0;
+ dp_stream_clk_src = (enum dp_stream_clk_source)otg_inst;
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+
+ if (dtb_clk_src == DTBCLK_REFCLK &&
+ dp_stream_clk_src == DP_STREAM_REFCLK) {
+ dccg35_disable_dtbclk_p_new(dccg, otg_inst);
+ dccg35_disable_dpstreamclk_new(dccg, dp_hpo_inst);
+ } else {
+ dccg35_enable_dtbclk_p_new(dccg, dtb_clk_src, otg_inst);
+ dccg35_enable_dpstreamclk_new(dccg,
+ dp_stream_clk_src,
+ dp_hpo_inst);
+ }
+}
+
+static void dccg35_set_dpstreamclk_root_clock_gating_cb(
+ struct dccg *dccg,
+ int dp_hpo_inst,
+ bool power_on)
+{
+ /* power_on set indicates we need to ungate
+ * Currently called from optimize_bandwidth and prepare_bandwidth calls
+ * Since clock source is not passed restore to refclock on ungate
+ * Instance 0 is implied here since only one streamclock resource
+ * Redundant as gating when enabled is acheived through set_dpstreamclk
+ */
+ if (power_on)
+ dccg35_enable_dpstreamclk_new(dccg,
+ DP_STREAM_REFCLK,
+ dp_hpo_inst);
+ else
+ dccg35_disable_dpstreamclk_new(dccg, dp_hpo_inst);
+}
+
+static void dccg35_update_dpp_dto_cb(struct dccg *dccg, int dpp_inst,
+ int req_dppclk)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ if (dccg->dpp_clock_gated[dpp_inst]) {
+ /*
+ * Do not update the DPPCLK DTO if the clock is stopped.
+ */
+ return;
+ }
+
+ if (dccg->ref_dppclk && req_dppclk) {
+ int ref_dppclk = dccg->ref_dppclk;
+ int modulo, phase;
+
+ // phase / modulo = dpp pipe clk / dpp global clk
+ modulo = 0xff; // use FF at the end
+ phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk;
+
+ if (phase > 0xff) {
+ ASSERT(false);
+ phase = 0xff;
+ }
+
+ /* Enable DPP CLK DTO output */
+ dccg35_enable_dpp_clk_new(dccg, dpp_inst, DPP_DCCG_DTO);
+
+ /* Program DTO */
+ REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
+ DPPCLK0_DTO_PHASE, phase,
+ DPPCLK0_DTO_MODULO, modulo);
+ } else
+ dccg35_disable_dpp_clk_new(dccg, dpp_inst);
+
+ dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
+}
+
+static void dccg35_dpp_root_clock_control_cb(
+ struct dccg *dccg,
+ unsigned int dpp_inst,
+ bool power_on)
+{
+ if (dccg->dpp_clock_gated[dpp_inst] == power_on)
+ return;
+ /* power_on set indicates we need to ungate
+ * Currently called from optimize_bandwidth and prepare_bandwidth calls
+ * Since clock source is not passed restore to refclock on ungate
+ * Redundant as gating when enabled is acheived through update_dpp_dto
+ */
+ dccg35_set_dppclk_rcg(dccg, dpp_inst, !power_on);
+
+ dccg->dpp_clock_gated[dpp_inst] = !power_on;
+}
+
+static void dccg35_enable_symclk32_se_cb(
+ struct dccg *dccg,
+ int inst,
+ enum phyd32clk_clock_source phyd32clk)
+{
+ dccg35_enable_symclk32_se_new(dccg, inst, (enum symclk32_se_clk_source)phyd32clk);
+}
+
+static void dccg35_disable_symclk32_se_cb(struct dccg *dccg, int inst)
+{
+ dccg35_disable_symclk32_se_new(dccg, inst);
+}
+
+static void dccg35_enable_symclk32_le_cb(
+ struct dccg *dccg,
+ int inst,
+ enum phyd32clk_clock_source src)
+{
+ dccg35_enable_symclk32_le_new(dccg, inst, (enum symclk32_le_clk_source) src);
+}
+
+static void dccg35_disable_symclk32_le_cb(struct dccg *dccg, int inst)
+{
+ dccg35_disable_symclk32_le_new(dccg, inst);
+}
+
+static void dccg35_set_symclk32_le_root_clock_gating_cb(
+ struct dccg *dccg,
+ int inst,
+ bool power_on)
+{
+ /* power_on set indicates we need to ungate
+ * Currently called from optimize_bandwidth and prepare_bandwidth calls
+ * Since clock source is not passed restore to refclock on ungate
+ * Redundant as gating when enabled is acheived through disable_symclk32_le
+ */
+ if (power_on)
+ dccg35_enable_symclk32_le_new(dccg, inst, SYMCLK32_LE_REFCLK);
+ else
+ dccg35_disable_symclk32_le_new(dccg, inst);
+}
+
+static void dccg35_set_physymclk_cb(
+ struct dccg *dccg,
+ int inst,
+ enum physymclk_clock_source clk_src,
+ bool force_enable)
+{
+ /* force_enable = 0 indicates we can switch to ref clock */
+ if (force_enable)
+ dccg35_enable_physymclk_new(dccg, inst, (enum physymclk_source)clk_src);
+ else
+ dccg35_disable_physymclk_new(dccg, inst);
+}
+
+static void dccg35_set_physymclk_root_clock_gating_cb(
+ struct dccg *dccg,
+ int inst,
+ bool power_on)
+{
+ /* Redundant RCG already done in disable_physymclk
+ * power_on = 1 indicates we need to ungate
+ */
+ if (power_on)
+ dccg35_enable_physymclk_new(dccg, inst, PHYSYMCLK_REFCLK);
+ else
+ dccg35_disable_physymclk_new(dccg, inst);
+}
+
+static void dccg35_set_symclk32_le_root_clock_gating(
+ struct dccg *dccg,
+ int inst,
+ bool power_on)
+{
+ /* power_on set indicates we need to ungate
+ * Currently called from optimize_bandwidth and prepare_bandwidth calls
+ * Since clock source is not passed restore to refclock on ungate
+ * Redundant as gating when enabled is acheived through disable_symclk32_le
+ */
+ if (power_on)
+ dccg35_enable_symclk32_le_new(dccg, inst, SYMCLK32_LE_REFCLK);
+ else
+ dccg35_disable_symclk32_le_new(dccg, inst);
+}
+
+static void dccg35_set_dtbclk_p_src_cb(
+ struct dccg *dccg,
+ enum streamclk_source src,
+ uint32_t inst)
+{
+ if (src == DTBCLK0)
+ dccg35_enable_dtbclk_p_new(dccg, DTBCLK_DTBCLK0, inst);
+ else
+ dccg35_disable_dtbclk_p_new(dccg, inst);
+}
+
+static void dccg35_set_dtbclk_dto_cb(
+ struct dccg *dccg,
+ const struct dtbclk_dto_params *params)
+{
+ /* set_dtbclk_p_src typ called earlier to switch to DTBCLK
+ * if params->ref_dtbclk_khz and req_dtbclk_khz are 0 switch to ref-clock
+ */
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+ /* DTO Output Rate / Pixel Rate = 1/4 */
+ int req_dtbclk_khz = params->pixclk_khz / 4;
+
+ if (params->ref_dtbclk_khz && req_dtbclk_khz) {
+ uint32_t modulo, phase;
+
+ dccg35_enable_dtbclk_p_new(dccg, DTBCLK_DTBCLK0, params->otg_inst);
+
+ // phase / modulo = dtbclk / dtbclk ref
+ modulo = params->ref_dtbclk_khz * 1000;
+ phase = req_dtbclk_khz * 1000;
+
+ REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
+ REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
+
+ REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+ DTBCLK_DTO_ENABLE[params->otg_inst], 1);
+
+ REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+ DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
+ 1, 100);
+
+ /* program OTG_PIXEL_RATE_DIV for DIVK1 and DIVK2 fields */
+ dccg35_set_pixel_rate_div(dccg, params->otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);
+
+ /* The recommended programming sequence to enable DTBCLK DTO to generate
+ * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
+ * be set only after DTO is enabled
+ */
+ REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+ PIPE_DTO_SRC_SEL[params->otg_inst], 2);
+ } else {
+ dccg35_disable_dtbclk_p_new(dccg, params->otg_inst);
+
+ REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+ DTBCLK_DTO_ENABLE[params->otg_inst], 0,
+ PIPE_DTO_SRC_SEL[params->otg_inst], params->is_hdmi ? 0 : 1);
+
+ REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
+ REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
+ }
+}
+
+static void dccg35_disable_dscclk_cb(struct dccg *dccg,
+ int inst)
+{
+ dccg35_disable_dscclk_new(dccg, inst);
+}
+
+static void dccg35_enable_dscclk_cb(struct dccg *dccg, int inst)
+{
+ dccg35_enable_dscclk_new(dccg, inst, DSC_DTO_TUNED_CK_GPU_DISCLK_3);
+}
+
+static void dccg35_enable_symclk_se_cb(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
+{
+ /* Switch to functional clock if already not selected */
+ dccg35_enable_symclk_be_new(dccg, SYMCLK_BE_PHYCLK, link_enc_inst);
+
+ dccg35_enable_symclk_fe_new(dccg, stream_enc_inst, (enum symclk_fe_source) link_enc_inst);
+
+}
+
+static void dccg35_disable_symclk_se_cb(
+ struct dccg *dccg,
+ uint32_t stream_enc_inst,
+ uint32_t link_enc_inst)
+{
+ dccg35_disable_symclk_fe_new(dccg, stream_enc_inst);
+
+ /* DMU PHY sequence switches SYMCLK_BE (link_enc_inst) to ref clock once PHY is turned off */
+}
+
+void dccg35_root_gate_disable_control(struct dccg *dccg, uint32_t pipe_idx, uint32_t disable_clock_gating)
+{
+
+ if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) {
+ dccg35_set_dppclk_root_clock_gating(dccg, pipe_idx, disable_clock_gating);
+ }
+}
+
+static const struct dccg_funcs dccg35_funcs_new = {
+ .update_dpp_dto = dccg35_update_dpp_dto_cb,
+ .dpp_root_clock_control = dccg35_dpp_root_clock_control_cb,
+ .get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
+ .dccg_init = dccg35_init_cb,
+ .set_dpstreamclk = dccg35_set_dpstreamclk_cb,
+ .set_dpstreamclk_root_clock_gating = dccg35_set_dpstreamclk_root_clock_gating_cb,
+ .enable_symclk32_se = dccg35_enable_symclk32_se_cb,
+ .disable_symclk32_se = dccg35_disable_symclk32_se_cb,
+ .enable_symclk32_le = dccg35_enable_symclk32_le_cb,
+ .disable_symclk32_le = dccg35_disable_symclk32_le_cb,
+ .set_symclk32_le_root_clock_gating = dccg35_set_symclk32_le_root_clock_gating_cb,
+ .set_physymclk = dccg35_set_physymclk_cb,
+ .set_physymclk_root_clock_gating = dccg35_set_physymclk_root_clock_gating_cb,
+ .set_dtbclk_dto = dccg35_set_dtbclk_dto_cb,
+ .set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
+ .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
+ .otg_add_pixel = dccg31_otg_add_pixel,
+ .otg_drop_pixel = dccg31_otg_drop_pixel,
+ .set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
+ .disable_dsc = dccg35_disable_dscclk_cb,
+ .enable_dsc = dccg35_enable_dscclk_cb,
+ .set_pixel_rate_div = dccg35_set_pixel_rate_div,
+ .get_pixel_rate_div = dccg35_get_pixel_rate_div,
+ .trigger_dio_fifo_resync = dccg35_trigger_dio_fifo_resync,
+ .set_valid_pixel_rate = dccg35_set_valid_pixel_rate,
+ .enable_symclk_se = dccg35_enable_symclk_se_cb,
+ .disable_symclk_se = dccg35_disable_symclk_se_cb,
+ .set_dtbclk_p_src = dccg35_set_dtbclk_p_src_cb,
+};
+
static const struct dccg_funcs dccg35_funcs = {
.update_dpp_dto = dccg35_update_dpp_dto,
.dpp_root_clock_control = dccg35_dpp_root_clock_control,
@@ -1026,6 +2400,7 @@ static const struct dccg_funcs dccg35_funcs = {
.enable_symclk_se = dccg35_enable_symclk_se,
.disable_symclk_se = dccg35_disable_symclk_se,
.set_dtbclk_p_src = dccg35_set_dtbclk_p_src,
+ .dccg_root_gate_disable_control = dccg35_root_gate_disable_control,
};
struct dccg *dccg35_create(
@@ -1041,6 +2416,10 @@ struct dccg *dccg35_create(
BREAK_TO_DEBUGGER();
return NULL;
}
+ (void)&dccg35_disable_symclk_be_new;
+ (void)&dccg35_set_symclk32_le_root_clock_gating;
+ (void)&dccg35_set_smclk32_se_rcg;
+ (void)&dccg35_funcs_new;
base = &dccg_dcn->base;
base->ctx = ctx;
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.h
index 1586a45ca3bd..51f98c5c51c4 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.h
@@ -241,6 +241,7 @@ struct dccg *dccg35_create(
void dccg35_init(struct dccg *dccg);
void dccg35_enable_global_fgcg_rep(struct dccg *dccg, bool value);
+void dccg35_root_gate_disable_control(struct dccg *dccg, uint32_t pipe_idx, uint32_t disable_clock_gating);
#endif //__DCN35_DCCG_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
index 07f1f396ba52..0b889004509a 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
@@ -730,35 +730,35 @@ void dccg401_init(struct dccg *dccg)
}
}
-static void dccg401_set_dto_dscclk(struct dccg *dccg, uint32_t inst, bool enable)
+static void dccg401_set_dto_dscclk(struct dccg *dccg, uint32_t inst)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
- uint32_t phase = enable ? 1 : 0;
switch (inst) {
case 0:
- REG_UPDATE_2(DSCCLK_DTO_CTRL, DSCCLK0_EN, 1, DSCCLK0_DTO_DB_EN, 1);
REG_UPDATE_2(DSCCLK0_DTO_PARAM,
- DSCCLK0_DTO_PHASE, phase,
+ DSCCLK0_DTO_PHASE, 1,
DSCCLK0_DTO_MODULO, 1);
+ REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK0_EN, 1);
+
break;
case 1:
- REG_UPDATE_2(DSCCLK_DTO_CTRL, DSCCLK1_EN, 1, DSCCLK1_DTO_DB_EN, 1);
REG_UPDATE_2(DSCCLK1_DTO_PARAM,
- DSCCLK1_DTO_PHASE, phase,
+ DSCCLK1_DTO_PHASE, 1,
DSCCLK1_DTO_MODULO, 1);
+ REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, 1);
break;
case 2:
- REG_UPDATE_2(DSCCLK_DTO_CTRL, DSCCLK2_EN, 1, DSCCLK2_DTO_DB_EN, 1);
REG_UPDATE_2(DSCCLK2_DTO_PARAM,
- DSCCLK2_DTO_PHASE, phase,
+ DSCCLK2_DTO_PHASE, 1,
DSCCLK2_DTO_MODULO, 1);
+ REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, 1);
break;
case 3:
- REG_UPDATE_2(DSCCLK_DTO_CTRL, DSCCLK3_EN, 1, DSCCLK3_DTO_DB_EN, 1);
REG_UPDATE_2(DSCCLK3_DTO_PARAM,
- DSCCLK3_DTO_PHASE, phase,
+ DSCCLK3_DTO_PHASE, 1,
DSCCLK3_DTO_MODULO, 1);
+ REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, 1);
break;
default:
BREAK_TO_DEBUGGER();
@@ -774,15 +774,27 @@ static void dccg401_set_ref_dscclk(struct dccg *dccg,
switch (dsc_inst) {
case 0:
REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK0_EN, 0);
+ REG_UPDATE_2(DSCCLK0_DTO_PARAM,
+ DSCCLK0_DTO_PHASE, 0,
+ DSCCLK0_DTO_MODULO, 0);
break;
case 1:
REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, 0);
+ REG_UPDATE_2(DSCCLK1_DTO_PARAM,
+ DSCCLK1_DTO_PHASE, 0,
+ DSCCLK1_DTO_MODULO, 0);
break;
case 2:
REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, 0);
+ REG_UPDATE_2(DSCCLK2_DTO_PARAM,
+ DSCCLK2_DTO_PHASE, 0,
+ DSCCLK2_DTO_MODULO, 0);
break;
case 3:
REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, 0);
+ REG_UPDATE_2(DSCCLK3_DTO_PARAM,
+ DSCCLK3_DTO_PHASE, 0,
+ DSCCLK3_DTO_MODULO, 0);
break;
default:
return;
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.h
index 8bcddc836347..a196ce9e8127 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.h
@@ -117,10 +117,6 @@
DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK1_EN, mask_sh),\
DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK2_EN, mask_sh),\
DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK3_EN, mask_sh),\
- DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK0_DTO_DB_EN, mask_sh),\
- DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK1_DTO_DB_EN, mask_sh),\
- DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK2_DTO_DB_EN, mask_sh),\
- DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK3_DTO_DB_EN, mask_sh),\
DCCG_SF(DSCCLK0_DTO_PARAM, DSCCLK0_DTO_PHASE, mask_sh),\
DCCG_SF(DSCCLK0_DTO_PARAM, DSCCLK0_DTO_MODULO, mask_sh),\
DCCG_SF(DSCCLK1_DTO_PARAM, DSCCLK1_DTO_PHASE, mask_sh),\
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
index cf5f84fb9c69..eeed840073fe 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
@@ -630,6 +630,11 @@ void dce_aud_az_enable(struct audio *audio)
audio->inst, value);
}
+void dce_aud_az_disable_hbr_audio(struct audio *audio)
+{
+ set_high_bit_rate_capable(audio, false);
+}
+
void dce_aud_az_disable(struct audio *audio)
{
uint32_t value;
@@ -1293,6 +1298,7 @@ static const struct audio_funcs funcs = {
.az_enable = dce_aud_az_enable,
.az_disable = dce_aud_az_disable,
.az_configure = dce_aud_az_configure,
+ .az_disable_hbr_audio = dce_aud_az_disable_hbr_audio,
.destroy = dce_aud_destroy,
};
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h
index 539f881928d1..1b7b8b079af4 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h
@@ -166,6 +166,7 @@ void dce_aud_hw_init(struct audio *audio);
void dce_aud_az_enable(struct audio *audio);
void dce_aud_az_disable(struct audio *audio);
+void dce_aud_az_disable_hbr_audio(struct audio *audio);
void dce_aud_az_configure(struct audio *audio,
enum signal_type signal,
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
index b8996d285f00..bb4ac5042c80 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
@@ -735,7 +735,15 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
(unsigned int) payload->mot);
if (payload->write)
dce_aux_log_payload(" write", payload->data, payload->length, 16);
- ret = dce_aux_transfer_raw(ddc, payload, &operation_result);
+
+ /* Check whether aux to be processed via dmub or dcn directly */
+ if (ddc->ctx->dc->debug.enable_dmub_aux_for_legacy_ddc
+ || ddc->ddc_pin == NULL) {
+ ret = dce_aux_transfer_dmub_raw(ddc, payload, &operation_result);
+ } else {
+ ret = dce_aux_transfer_raw(ddc, payload, &operation_result);
+ }
+
DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION,
LOG_FLAG_I2cAux_DceAux,
"dce_aux_transfer_with_retries: link_index=%u: END: retry %d of %d: address=0x%04x length=%u write=%d mot=%d: ret=%d operation_result=%d payload->reply=%u",
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
index ccf153b7a467..cae18f8c1c9a 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
@@ -94,6 +94,8 @@ static enum dc_psr_state convert_psr_state(uint32_t raw_state)
state = PSR_STATE_HWLOCK_MGR;
else if (raw_state == 0x61)
state = PSR_STATE_POLLVUPDATE;
+ else if (raw_state == 0x62)
+ state = PSR_STATE_RELEASE_HWLOCK_MGR_FULL_FRAME;
else
state = PSR_STATE_INVALID;
@@ -363,6 +365,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
copy_settings_data->debug.bitfields.visual_confirm = dc->dc->debug.visual_confirm == VISUAL_CONFIRM_PSR;
copy_settings_data->debug.bitfields.use_hw_lock_mgr = 1;
copy_settings_data->debug.bitfields.force_full_frame_update = 0;
+ copy_settings_data->debug.bitfields.enable_ips_visual_confirm = dc->dc->debug.enable_ips_visual_confirm;
if (psr_context->su_granularity_required == 0)
copy_settings_data->su_y_granularity = 0;
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
index 4d960dc5ce89..c31e4f26a305 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
@@ -12,6 +12,8 @@
#define MAX_PIPES 6
+#define GPINT_RETRY_NUM 20
+
static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3};
static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5};
@@ -167,6 +169,8 @@ static bool dmub_replay_copy_settings(struct dmub_replay *dmub,
copy_settings_data->smu_optimizations_en = link->replay_settings.replay_smu_opt_enable;
copy_settings_data->replay_timing_sync_supported = link->replay_settings.config.replay_timing_sync_supported;
+ copy_settings_data->debug.bitfields.enable_ips_visual_confirm = dc->dc->debug.enable_ips_visual_confirm;
+
copy_settings_data->flags.u32All = 0;
copy_settings_data->flags.bitfields.fec_enable_status = (link->fec_state == dc_link_fec_enabled);
copy_settings_data->flags.bitfields.dsc_enable_status = (pipe_ctx->stream->timing.flags.DSC == 1);
@@ -220,6 +224,7 @@ static void dmub_replay_residency(struct dmub_replay *dmub, uint8_t panel_inst,
uint32_t *residency, const bool is_start, enum pr_residency_mode mode)
{
uint16_t param = (uint16_t)(panel_inst << 8);
+ uint32_t i = 0;
switch (mode) {
case PR_RESIDENCY_MODE_PHY:
@@ -247,10 +252,17 @@ static void dmub_replay_residency(struct dmub_replay *dmub, uint8_t panel_inst,
if (is_start)
param |= REPLAY_RESIDENCY_ENABLE;
- // Send gpint command and wait for ack
- if (!dc_wake_and_execute_gpint(dmub->ctx, DMUB_GPINT__REPLAY_RESIDENCY, param,
- residency, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
- *residency = 0;
+ for (i = 0; i < GPINT_RETRY_NUM; i++) {
+ // Send gpint command and wait for ack
+ if (dc_wake_and_execute_gpint(dmub->ctx, DMUB_GPINT__REPLAY_RESIDENCY, param,
+ residency, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
+ return;
+
+ udelay(100);
+ }
+
+ // it means gpint retry many times
+ *residency = 0;
}
/*
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
index 49bcfe6ec999..fa422a8cbced 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
@@ -1955,6 +1955,7 @@ void dce110_tg_program_timing(struct timing_generator *tg,
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+ int pstate_keepout,
const enum signal_type signal,
bool use_vbios)
{
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h
index 28c58f1dff2d..ee4de740aceb 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h
@@ -261,6 +261,7 @@ void dce110_tg_program_timing(struct timing_generator *tg,
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+ int pstate_keepout,
const enum signal_type signal,
bool use_vbios);
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
index bf35dc65ca29..9837dec837ff 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
@@ -438,6 +438,7 @@ static void dce110_timing_generator_v_program_timing(struct timing_generator *tg
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+ int pstate_keepout,
const enum signal_type signal,
bool use_vbios)
{
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
index eb3557965781..fcf59348eb62 100644
--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
@@ -697,6 +697,7 @@ static void dce120_tg_program_timing(struct timing_generator *tg,
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+ int pstate_keepout,
const enum signal_type signal,
bool use_vbios)
{
diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c
index c1a85ee374d9..e5fb0e8333e4 100644
--- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c
@@ -111,13 +111,14 @@ static void program_timing(struct timing_generator *tg,
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+ int pstate_keepout,
const enum signal_type signal,
bool use_vbios)
{
if (!use_vbios)
program_pix_dur(tg, timing->pix_clk_100hz);
- dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, use_vbios);
+ dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, 0, use_vbios);
}
static void dce60_timing_generator_enable_advanced_request(
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c
index 2df4654858be..003a9330c286 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c
@@ -111,13 +111,14 @@ static void program_timing(struct timing_generator *tg,
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+ int pstate_keepout,
const enum signal_type signal,
bool use_vbios)
{
if (!use_vbios)
program_pix_dur(tg, timing->pix_clk_100hz);
- dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, use_vbios);
+ dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, 0, use_vbios);
}
static void dce80_timing_generator_enable_advanced_request(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
index 9923d0d620d4..e1f6623d4936 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
@@ -24,8 +24,6 @@
DCN10 = dcn10_ipp.o \
dcn10_hw_sequencer_debug.o \
- dcn10_opp.o \
- dcn10_mpc.o \
dcn10_cm_common.o \
AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10))
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
index 0b49362f71b0..eaed5d1c398a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -591,6 +591,8 @@ bool cm_helper_translate_curve_to_degamma_hw_format(
i += increment) {
if (j == hw_points - 1)
break;
+ if (i >= TRANSFER_FUNC_POINTS)
+ return false;
rgb_resulted[j].red = output_tf->tf_pts.red[i];
rgb_resulted[j].green = output_tf->tf_pts.green[i];
rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
index b3aeabc4d605..25ba0d310d46 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
@@ -1,8 +1,7 @@
# SPDX-License-Identifier: MIT
# Copyright © 2019-2024 Advanced Micro Devices, Inc. All rights reserved.
-DCN20 = dcn20_mpc.o dcn20_opp.o dcn20_mmhubbub.o \
- dcn20_vmid.o dcn20_dwb.o dcn20_dwb_scl.o
+DCN20 = dcn20_vmid.o dcn20_dwb.o dcn20_dwb_scl.o
AMD_DAL_DCN20 = $(addprefix $(AMDDALPATH)/dc/dcn20/,$(DCN20))
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/Makefile b/drivers/gpu/drm/amd/display/dc/dcn30/Makefile
index 4c43af867d86..b17277de0340 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/Makefile
@@ -23,15 +23,11 @@
#
#
-DCN30 := dcn30_mpc.o dcn30_vpg.o \
+DCN30 := dcn30_vpg.o \
dcn30_afmt.o \
- dcn30_dwb.o \
- dcn30_dwb_cm.o \
dcn30_cm_common.o \
dcn30_mmhubbub.o \
-
-
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_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
index b8327237ed44..f31f0e3abfc0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
@@ -28,7 +28,7 @@
#include "reg_helper.h"
#include "dcn30/dcn30_dpp.h"
#include "basics/conversion.h"
-#include "dcn30_cm_common.h"
+#include "dcn30/dcn30_cm_common.h"
#include "custom_float.h"
#define REG(reg) reg
@@ -177,6 +177,8 @@ bool cm3_helper_translate_curve_to_hw_format(
i += increment) {
if (j == hw_points)
break;
+ if (i >= TRANSFER_FUNC_POINTS)
+ return false;
rgb_resulted[j].red = output_tf->tf_pts.red[i];
rgb_resulted[j].green = output_tf->tf_pts.green[i];
rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
@@ -335,6 +337,8 @@ bool cm3_helper_translate_curve_to_degamma_hw_format(
i += increment) {
if (j == hw_points - 1)
break;
+ if (i >= TRANSFER_FUNC_POINTS)
+ return false;
rgb_resulted[j].red = output_tf->tf_pts.red[i];
rgb_resulted[j].green = output_tf->tf_pts.green[i];
rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/Makefile b/drivers/gpu/drm/amd/display/dc/dcn301/Makefile
index dc37dbf870df..fb4814ab3f05 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn301/Makefile
@@ -3,7 +3,7 @@
#
# Makefile for dcn30.
-DCN301 = dcn301_dio_link_encoder.o dcn301_panel_cntl.o
+DCN301 = dcn301_panel_cntl.o
AMD_DAL_DCN301 = $(addprefix $(AMDDALPATH)/dc/dcn301/,$(DCN301))
diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/Makefile b/drivers/gpu/drm/amd/display/dc/dcn303/Makefile
deleted file mode 100644
index a954e316aca2..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dcn303/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: MIT
-#
-# Copyright (C) 2021 Advanced Micro Devices, Inc. All the rights reserved
-#
-# Authors: AMD
-#
-# Makefile for dcn303.
-
-DCN3_03 = dcn303_init.o
-
-AMD_DAL_DCN3_03 = $(addprefix $(AMDDALPATH)/dc/dcn303/,$(DCN3_03))
-
-AMD_DISPLAY_FILES += $(AMD_DAL_DCN3_03)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/Makefile b/drivers/gpu/drm/amd/display/dc/dcn31/Makefile
index e2601d0aba41..d510e4652c18 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/Makefile
@@ -5,7 +5,7 @@
# Makefile for dcn31.
DCN31 = dcn31_panel_cntl.o \
- dcn31_apg.o dcn31_hpo_dp_stream_encoder.o dcn31_hpo_dp_link_encoder.o \
+ dcn31_apg.o \
dcn31_afmt.o dcn31_vpg.o
AMD_DAL_DCN31 = $(addprefix $(AMDDALPATH)/dc/dcn31/,$(DCN31))
diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/Makefile b/drivers/gpu/drm/amd/display/dc/dcn314/Makefile
deleted file mode 100644
index 15fdcf7c6466..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dcn314/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: MIT
-# Copyright © 2024 Advanced Micro Devices, Inc. All rights reserved.
-#
-# Makefile for dcn314.
-
-DCN314 = dcn314_dio_stream_encoder.o
-
-AMD_DAL_DCN314 = $(addprefix $(AMDDALPATH)/dc/dcn314/,$(DCN314))
-
-AMD_DISPLAY_FILES += $(AMD_DAL_DCN314)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn401/Makefile b/drivers/gpu/drm/amd/display/dc/dcn401/Makefile
deleted file mode 100644
index ded1f3140beb..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dcn401/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: MIT
-# Copyright © 2024 Advanced Micro Devices, Inc. All rights reserved.
-
-DCN401 += dcn401_dio_link_encoder.o
-DCN401 += dcn401_dio_stream_encoder.o
-DCN401 += dcn401_mpc.o
-
-AMD_DAL_DCN401 = $(addprefix $(AMDDALPATH)/dc/dcn401/,$(DCN401))
-
-AMD_DISPLAY_FILES += $(AMD_DAL_DCN401)
diff --git a/drivers/gpu/drm/amd/display/dc/dio/Makefile b/drivers/gpu/drm/amd/display/dc/dio/Makefile
index 67840e474d7a..0dfd480976f7 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dio/Makefile
@@ -52,6 +52,15 @@ AMD_DAL_DIO_DCN30 = $(addprefix $(AMDDALPATH)/dc/dio/dcn30/,$(DIO_DCN30))
AMD_DISPLAY_FILES += $(AMD_DAL_DIO_DCN30)
###############################################################################
+# DCN301
+###############################################################################
+DIO_DCN301 = dcn301_dio_link_encoder.o
+
+AMD_DAL_DIO_DCN301 = $(addprefix $(AMDDALPATH)/dc/dio/dcn301/,$(DIO_DCN301))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_DIO_DCN301)
+
+###############################################################################
# DCN31
###############################################################################
DIO_DCN31 = dcn31_dio_link_encoder.o
@@ -61,6 +70,15 @@ AMD_DAL_DIO_DCN31 = $(addprefix $(AMDDALPATH)/dc/dio/dcn31/,$(DIO_DCN31))
AMD_DISPLAY_FILES += $(AMD_DAL_DIO_DCN31)
###############################################################################
+# DCN314
+###############################################################################
+DIO_DCN314 = dcn314_dio_stream_encoder.o
+
+AMD_DAL_DIO_DCN314 = $(addprefix $(AMDDALPATH)/dc/dio/dcn314/,$(DIO_DCN314))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_DIO_DCN314)
+
+###############################################################################
# DCN32
###############################################################################
DIO_DCN32 = dcn32_dio_link_encoder.o dcn32_dio_stream_encoder.o
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/dcn301/dcn301_dio_link_encoder.c
index 1b39a6e8a1ac..1b39a6e8a1ac 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn301/dcn301_dio_link_encoder.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_dio_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dio/dcn301/dcn301_dio_link_encoder.h
index 49f8d91d4951..49f8d91d4951 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_dio_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn301/dcn301_dio_link_encoder.h
diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/dcn314/dcn314_dio_stream_encoder.c
index 5b343f745cf3..5b343f745cf3 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn314/dcn314_dio_stream_encoder.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dio/dcn314/dcn314_dio_stream_encoder.h
index 86548be591be..86548be591be 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn314/dcn314_dio_stream_encoder.h
diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn321/dcn321_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/dcn321/dcn321_dio_link_encoder.c
index 05783daa62ac..2ed382a8e79c 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn321/dcn321_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn321/dcn321_dio_link_encoder.c
@@ -23,7 +23,6 @@
*
*/
-
#include "reg_helper.h"
#include "core_types.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c
index 6a179e5ab417..6ab2a218b769 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c
@@ -22,7 +22,6 @@
*
*/
-
#include "dc_bios_types.h"
#include "dcn30/dcn30_dio_stream_encoder.h"
#include "dcn314/dcn314_dio_stream_encoder.h"
@@ -392,6 +391,14 @@ static void enc35_reset_fifo(struct stream_encoder *enc, bool reset)
udelay(10);
}
+static bool enc35_is_fifo_enabled(struct stream_encoder *enc)
+{
+ struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+ uint32_t reset_val;
+
+ REG_GET(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, &reset_val);
+ return (reset_val == 0) ? false : true;
+}
void enc35_disable_fifo(struct stream_encoder *enc)
{
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
@@ -415,6 +422,24 @@ void enc35_enable_fifo(struct stream_encoder *enc)
REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 1);
}
+static uint32_t enc35_get_pixels_per_cycle(struct stream_encoder *enc)
+{
+ struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+ uint32_t value;
+
+ REG_GET(DIG_FIFO_CTRL0, DIG_FIFO_OUTPUT_PIXEL_MODE, &value);
+
+ switch (value) {
+ case 0:
+ return 1;
+ case 1:
+ return 2;
+ default:
+ ASSERT_CRITICAL(false);
+ return 1;
+ }
+}
+
static const struct stream_encoder_funcs dcn35_str_enc_funcs = {
.dp_set_odm_combine =
enc314_dp_set_odm_combine,
@@ -465,7 +490,9 @@ static const struct stream_encoder_funcs dcn35_str_enc_funcs = {
.set_input_mode = enc314_set_dig_input_mode,
.enable_fifo = enc35_enable_fifo,
.disable_fifo = enc35_disable_fifo,
+ .is_fifo_enabled = enc35_is_fifo_enabled,
.map_stream_to_link = enc35_stream_encoder_map_to_link,
+ .get_pixels_per_cycle = enc35_get_pixels_per_cycle,
};
void dcn35_dio_stream_encoder_construct(
diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
index 34adae7ab6e8..2e4a46f1b499 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
@@ -210,4 +210,7 @@ enum adaptive_sync_type dm_get_adaptive_sync_support_type(struct dc_link *link);
enum dc_edid_status dm_helpers_get_sbios_edid(struct dc_link *link, struct dc_edid *edid);
+bool dm_helpers_is_fullscreen(struct dc_context *ctx, struct dc_stream_state *stream);
+bool dm_helpers_is_hdr_on(struct dc_context *ctx, struct dc_stream_state *stream);
+
#endif /* __DM_HELPERS__ */
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 8a8efe408a9d..e9fea9c2162e 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
@@ -1132,7 +1132,8 @@ static void dcn20_adjust_freesync_v_startup(
patched_crtc_timing.v_addressable -
patched_crtc_timing.v_border_top;
- newVstartup = asic_blank_end + (patched_crtc_timing.v_total - asic_blank_start);
+ /* The newVStartUp is 1 line before vsync point */
+ newVstartup = asic_blank_end + 1;
*vstartup_start = ((newVstartup > *vstartup_start) ? newVstartup : *vstartup_start);
}
@@ -1562,6 +1563,8 @@ int dcn20_populate_dml_pipes_from_context(struct dc *dc,
pipes[pipe_cnt].pipe.src.surface_width_c = pipes[pipe_cnt].pipe.src.viewport_width;
pipes[pipe_cnt].pipe.src.data_pitch = ((pipes[pipe_cnt].pipe.src.viewport_width + 255) / 256) * 256;
pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
+ pipes[pipe_cnt].pipe.src.cur0_src_width = 0;
+ pipes[pipe_cnt].pipe.src.cur1_src_width = 0;
pipes[pipe_cnt].pipe.dest.recout_width = pipes[pipe_cnt].pipe.src.viewport_width; /*vp_width/hratio*/
pipes[pipe_cnt].pipe.dest.recout_height = pipes[pipe_cnt].pipe.src.viewport_height; /*vp_height/vratio*/
pipes[pipe_cnt].pipe.dest.full_recout_width = pipes[pipe_cnt].pipe.dest.recout_width; /*when is_hsplit != 1*/
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
index 7c56ad0f8812..e7019c95ba79 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
@@ -78,7 +78,7 @@ static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
{
- unsigned int ret_val = 0;
+ unsigned int ret_val = 1;
if (source_format == dm_444_16) {
if (!is_chroma)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
index 3d95bfa5aca2..ae5251041728 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
@@ -78,7 +78,7 @@ static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
{
- unsigned int ret_val = 0;
+ unsigned int ret_val = 1;
if (source_format == dm_444_16) {
if (!is_chroma)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
index 98502a4f0567..9e1c18b90805 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
@@ -53,7 +53,7 @@ static void calculate_ttu_cursor(
static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
{
- unsigned int ret_val = 0;
+ unsigned int ret_val = 1;
if (source_format == dm_444_16) {
if (!is_chroma)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index 9d399c4ce957..6f490d8d7038 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -160,8 +160,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = {
.pct_ideal_sdp_bw_after_urgent = 90.0,
.pct_ideal_fabric_bw_after_urgent = 67.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 20.0,
- .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0, // N/A, for now keep as is until DML implemented
- .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0, // N/A, for now keep as is until DML implemented
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
.pct_ideal_dram_bw_after_urgent_strobe = 67.0,
.max_avg_sdp_bw_use_normal_percent = 80.0,
.max_avg_fabric_bw_use_normal_percent = 60.0,
@@ -871,8 +871,9 @@ static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context)
* for VBLANK: (VACTIVE region of the SubVP pipe can fit the MALL prefetch, VBLANK frame time,
* and the max of (VBLANK blanking time, MALL region)).
*/
- if (stretched_drr_us < (1 / (double)drr_timing->min_refresh_in_uhz) * 1000000 * 1000000 &&
- subvp_active_us - prefetch_us - stretched_drr_us - max_vblank_mallregion > 0)
+ if (drr_timing &&
+ stretched_drr_us < (1 / (double)drr_timing->min_refresh_in_uhz) * 1000000 * 1000000 &&
+ subvp_active_us - prefetch_us - stretched_drr_us - max_vblank_mallregion > 0)
schedulable = true;
return schedulable;
@@ -937,7 +938,7 @@ static bool subvp_vblank_schedulable(struct dc *dc, struct dc_state *context)
if (!subvp_pipe && pipe_mall_type == SUBVP_MAIN)
subvp_pipe = pipe;
}
- if (found) {
+ if (found && subvp_pipe) {
phantom_stream = dc_state_get_paired_subvp_stream(context, subvp_pipe->stream);
main_timing = &subvp_pipe->stream->timing;
phantom_timing = &phantom_stream->timing;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
index 4297402bdab3..8839faf42207 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
@@ -139,8 +139,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
.pct_ideal_sdp_bw_after_urgent = 90.0,
.pct_ideal_fabric_bw_after_urgent = 67.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 20.0,
- .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0, // N/A, for now keep as is until DML implemented
- .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0, // N/A, for now keep as is until DML implemented
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
.pct_ideal_dram_bw_after_urgent_strobe = 67.0,
.max_avg_sdp_bw_use_normal_percent = 80.0,
.max_avg_fabric_bw_use_normal_percent = 60.0,
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
index 410e4b671228..641a8cd019cd 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
@@ -523,6 +523,7 @@ struct _vcs_dpi_display_pipe_dest_params_st {
unsigned int vupdate_offset;
unsigned int vupdate_width;
unsigned int vready_offset;
+ unsigned int pstate_keepout;
unsigned char interlaced;
double pixel_rate_mhz;
unsigned char synchronized_vblank_all_planes;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
index dae13f202220..d8bfc85e5dcd 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
@@ -39,7 +39,7 @@
static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
{
- unsigned int ret_val = 0;
+ unsigned int ret_val = 1;
if (source_format == dm_444_16) {
if (!is_chroma)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/Makefile b/drivers/gpu/drm/amd/display/dc/dml2/Makefile
index fea857214c0f..c4378e620cbf 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml2/Makefile
@@ -35,8 +35,6 @@ frame_warn_flag := -Wframe-larger-than=2048
endif
endif
-# DRIVER_BUILD is mostly used in DML2.1 source
-subdir-ccflags-y += -DDRIVER_BUILD=1
subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/dml2
subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/dml2/dml21/src/dml2_core
subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/dml2/dml21/src/dml2_mcg/
@@ -81,13 +79,11 @@ CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_top/dml2_top_optimization := $(dml2_
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.o := $(dml2_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_factory.o := $(dml2_ccflags)
-CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_shared.o := $(dml2_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_factory.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_dcn4.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn3.o := $(dml2_ccflags)
-CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_factory.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_standalone_libraries/lib_float_math.o := $(dml2_ccflags)
@@ -104,13 +100,11 @@ CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_top/dml2_top_optimization.o :
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_factory.o := $(dml2_rcflags)
-CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_shared.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_factory.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_dcn4.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn3.o := $(dml2_rcflags)
-CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_factory.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_standalone_libraries/lib_float_math.o := $(dml2_rcflags)
@@ -126,13 +120,11 @@ DML21 += src/inc/dml2_debug.o
DML21 += src/dml2_core/dml2_core_dcn4.o
DML21 += src/dml2_core/dml2_core_factory.o
DML21 += src/dml2_core/dml2_core_dcn4_calcs.o
-DML21 += src/dml2_core/dml2_core_shared.o
DML21 += src/dml2_dpmm/dml2_dpmm_dcn4.o
DML21 += src/dml2_dpmm/dml2_dpmm_factory.o
DML21 += src/dml2_mcg/dml2_mcg_dcn4.o
DML21 += src/dml2_mcg/dml2_mcg_factory.o
DML21 += src/dml2_pmo/dml2_pmo_dcn3.o
-DML21 += src/dml2_pmo/dml2_pmo_dcn4.o
DML21 += src/dml2_pmo/dml2_pmo_factory.o
DML21 += src/dml2_pmo/dml2_pmo_dcn4_fams2.o
DML21 += src/dml2_standalone_libraries/lib_float_math.o
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
index 06387b8b0aee..b0d9aed0f265 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
@@ -31,7 +31,7 @@ static void dml21_init_socbb_params(struct dml2_initialize_instance_in_out *dml_
else
soc_bb = &dml2_socbb_dcn401;
- qos_params = &dml_dcn401_soc_qos_params;
+ qos_params = &dml_dcn4_variant_a_soc_qos_params;
}
/* patch soc bb */
@@ -516,7 +516,7 @@ static void populate_dml21_stream_overrides_from_stream_state(
if (!stream->ctx->dc->debug.enable_single_display_2to1_odm_policy ||
stream->debug.force_odm_combine_segments > 0)
stream_desc->overrides.disable_dynamic_odm = true;
- stream_desc->overrides.disable_subvp = stream->ctx->dc->debug.force_disable_subvp;
+ stream_desc->overrides.disable_subvp = stream->ctx->dc->debug.force_disable_subvp || stream->hw_cursor_req;
}
static enum dml2_swizzle_mode gfx_addr3_to_dml2_swizzle_mode(enum swizzle_mode_addr3_values addr3_mode)
@@ -725,18 +725,7 @@ static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dm
const struct scaler_data *scaler_data = get_scaler_data_for_plane(dml_ctx, plane_state, context);
struct dc_stream_state *stream = context->streams[stream_index];
- if (stream->cursor_attributes.color_format == CURSOR_MODE_MONO)
- plane->cursor.cursor_bpp = 2;
- else if (stream->cursor_attributes.color_format == CURSOR_MODE_COLOR_1BIT_AND
- || stream->cursor_attributes.color_format == CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA
- || stream->cursor_attributes.color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA) {
- plane->cursor.cursor_bpp = 32;
- } else if (stream->cursor_attributes.color_format == CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED
- || stream->cursor_attributes.color_format == CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED) {
- plane->cursor.cursor_bpp = 64;
- } else
- plane->cursor.cursor_bpp = 32;
-
+ plane->cursor.cursor_bpp = 32;
plane->cursor.cursor_width = 256;
plane->cursor.num_cursors = 1;
@@ -788,6 +777,14 @@ static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dm
* certain cases. Hence do corrective active and disable scaling.
*/
plane->composition.scaler_info.enabled = false;
+ } else if ((plane_state->ctx->dc->config.use_spl == true) &&
+ (plane->composition.scaler_info.enabled == false)) {
+ /* To enable sharpener for 1:1, scaler must be enabled. If use_spl is set, then
+ * allow case where ratio is 1 but taps > 1
+ */
+ if ((scaler_data->taps.h_taps > 1) || (scaler_data->taps.v_taps > 1) ||
+ (scaler_data->taps.h_taps_c > 1) || (scaler_data->taps.v_taps_c > 1))
+ plane->composition.scaler_info.enabled = true;
}
/* always_scale is only used for debug purposes not used in production but has to be
@@ -827,6 +824,7 @@ static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dm
if (plane_state->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
plane->tdlut.setup_for_tdlut = true;
+
switch (plane_state->mcm_luts.lut3d_data.gpu_mem_params.layout) {
case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
@@ -836,6 +834,7 @@ static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dm
plane->tdlut.tdlut_addressing_mode = dml2_tdlut_simple_linear;
break;
}
+
switch (plane_state->mcm_luts.lut3d_data.gpu_mem_params.size) {
case DC_CM2_GPU_MEM_SIZE_171717:
plane->tdlut.tdlut_width_mode = dml2_tdlut_width_17_cube;
@@ -844,8 +843,8 @@ static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dm
//plane->tdlut.tdlut_width_mode = dml2_tdlut_width_flatten; // dml2_tdlut_width_flatten undefined
break;
}
- } else
- plane->tdlut.setup_for_tdlut = false;
+ }
+ plane->tdlut.setup_for_tdlut |= dml_ctx->config.force_tdlut_enable;
plane->dynamic_meta_data.enable = false;
plane->dynamic_meta_data.lines_before_active_required = 0;
@@ -949,6 +948,7 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_s
int stream_index, plane_index;
int disp_cfg_stream_location, disp_cfg_plane_location;
struct dml2_display_cfg *dml_dispcfg = &dml_ctx->v21.display_config;
+ unsigned int plane_count = 0;
memset(&dml_ctx->v21.dml_to_dc_pipe_mapping, 0, sizeof(struct dml2_dml_to_dc_pipe_mapping));
@@ -958,6 +958,11 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_s
dml_dispcfg->minimize_det_reallocation = true;
dml_dispcfg->overrides.enable_subvp_implicit_pmo = true;
+ if (in_dc->debug.disable_unbounded_requesting) {
+ dml_dispcfg->overrides.hw.force_unbounded_requesting.enable = true;
+ dml_dispcfg->overrides.hw.force_unbounded_requesting.value = false;
+ }
+
for (stream_index = 0; stream_index < context->stream_count; stream_index++) {
disp_cfg_stream_location = map_stream_to_dml21_display_cfg(dml_ctx, context->streams[stream_index]);
@@ -1002,33 +1007,39 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_s
dml_dispcfg->plane_descriptors[disp_cfg_plane_location].overrides.uclk_pstate_change_strategy =
dml21_force_pstate_method_to_uclk_state_change_strategy(dml_ctx->config.pmo.force_pstate_method_values[stream_index]);
}
+
+ plane_count++;
}
}
}
+ if (plane_count == 0) {
+ dml_dispcfg->overrides.all_streams_blanked = true;
+ }
+
return true;
}
void dml21_copy_clocks_to_dc_state(struct dml2_context *in_ctx, struct dc_state *context)
{
/* TODO these should be the max of active, svp prefetch and idle should be tracked seperately */
- context->bw_ctx.bw.dcn.clk.dispclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4.dispclk_khz;
- context->bw_ctx.bw.dcn.clk.dcfclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4.active.dcfclk_khz;
- context->bw_ctx.bw.dcn.clk.dramclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4.active.uclk_khz;
- context->bw_ctx.bw.dcn.clk.fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4.active.fclk_khz;
- context->bw_ctx.bw.dcn.clk.idle_dramclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4.idle.uclk_khz;
- context->bw_ctx.bw.dcn.clk.idle_fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4.idle.fclk_khz;
- context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4.deepsleep_dcfclk_khz;
+ context->bw_ctx.bw.dcn.clk.dispclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.dispclk_khz;
+ context->bw_ctx.bw.dcn.clk.dcfclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.active.dcfclk_khz;
+ context->bw_ctx.bw.dcn.clk.dramclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.active.uclk_khz;
+ context->bw_ctx.bw.dcn.clk.fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.active.fclk_khz;
+ context->bw_ctx.bw.dcn.clk.idle_dramclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.idle.uclk_khz;
+ context->bw_ctx.bw.dcn.clk.idle_fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.idle.fclk_khz;
+ context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.deepsleep_dcfclk_khz;
context->bw_ctx.bw.dcn.clk.fclk_p_state_change_support = in_ctx->v21.mode_programming.programming->fclk_pstate_supported;
context->bw_ctx.bw.dcn.clk.p_state_change_support = in_ctx->v21.mode_programming.programming->uclk_pstate_supported;
- context->bw_ctx.bw.dcn.clk.dtbclk_en = in_ctx->v21.mode_programming.programming->min_clocks.dcn4.dtbrefclk_khz > 0;
- context->bw_ctx.bw.dcn.clk.ref_dtbclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4.dtbrefclk_khz;
+ context->bw_ctx.bw.dcn.clk.dtbclk_en = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.dtbrefclk_khz > 0;
+ context->bw_ctx.bw.dcn.clk.ref_dtbclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.dtbrefclk_khz;
}
void dml21_extract_legacy_watermark_set(const struct dc *in_dc, struct dcn_watermarks *watermark, enum dml2_dchub_watermark_reg_set_index reg_set_idx, struct dml2_context *in_ctx)
{
struct dml2_core_internal_display_mode_lib *mode_lib = &in_ctx->v21.dml_init.dml2_instance->core_instance.clean_me_up.mode_lib;
- double refclk_freq_in_mhz = (in_ctx->v21.display_config.overrides.hw.dlg_ref_clk_mhz > 0) ? (double)in_ctx->v21.display_config.overrides.hw.dlg_ref_clk_mhz : mode_lib->soc.dchub_refclk_mhz;;
+ double refclk_freq_in_mhz = (in_ctx->v21.display_config.overrides.hw.dlg_ref_clk_mhz > 0) ? (double)in_ctx->v21.display_config.overrides.hw.dlg_ref_clk_mhz : mode_lib->soc.dchub_refclk_mhz;
if (reg_set_idx >= DML2_DCHUB_WATERMARK_SET_NUM) {
/* invalid register set index */
@@ -1053,16 +1064,16 @@ static struct dml2_dchub_watermark_regs *wm_set_index_to_dc_wm_set(union dcn_wat
switch (wm_index) {
case DML2_DCHUB_WATERMARK_SET_A:
- wm_regs = &watermarks->dcn4.a;
+ wm_regs = &watermarks->dcn4x.a;
break;
case DML2_DCHUB_WATERMARK_SET_B:
- wm_regs = &watermarks->dcn4.b;
+ wm_regs = &watermarks->dcn4x.b;
break;
case DML2_DCHUB_WATERMARK_SET_C:
- wm_regs = &watermarks->dcn4.c;
+ wm_regs = &watermarks->dcn4x.c;
break;
case DML2_DCHUB_WATERMARK_SET_D:
- wm_regs = &watermarks->dcn4.d;
+ wm_regs = &watermarks->dcn4x.d;
break;
case DML2_DCHUB_WATERMARK_SET_NUM:
default:
@@ -1110,10 +1121,11 @@ void dml21_populate_pipe_ctx_dlg_params(struct dml2_context *dml_ctx, struct dc_
global_sync = &stream_programming->phantom_stream.global_sync;
}
- pipe_ctx->pipe_dlg_param.vstartup_start = global_sync->dcn4.vstartup_lines;
- pipe_ctx->pipe_dlg_param.vupdate_offset = global_sync->dcn4.vupdate_offset_pixels;
- pipe_ctx->pipe_dlg_param.vupdate_width = global_sync->dcn4.vupdate_vupdate_width_pixels;
- pipe_ctx->pipe_dlg_param.vready_offset = global_sync->dcn4.vready_offset_pixels;
+ pipe_ctx->pipe_dlg_param.vstartup_start = global_sync->dcn4x.vstartup_lines;
+ pipe_ctx->pipe_dlg_param.vupdate_offset = global_sync->dcn4x.vupdate_offset_pixels;
+ pipe_ctx->pipe_dlg_param.vupdate_width = global_sync->dcn4x.vupdate_vupdate_width_pixels;
+ pipe_ctx->pipe_dlg_param.vready_offset = global_sync->dcn4x.vready_offset_pixels;
+ pipe_ctx->pipe_dlg_param.pstate_keepout = global_sync->dcn4x.pstate_keepout_start_lines;
pipe_ctx->pipe_dlg_param.otg_inst = pipe_ctx->stream_res.tg->inst;
@@ -1164,3 +1176,37 @@ void dml21_get_pipe_mcache_config(
mcache_pipe_config->plane1_enabled =
dml21_is_plane1_enabled(pln_prog->plane_descriptor->pixel_format);
}
+
+void dml21_set_dc_p_state_type(
+ struct pipe_ctx *pipe_ctx,
+ struct dml2_per_stream_programming *stream_programming,
+ bool sub_vp_enabled)
+{
+ switch (stream_programming->uclk_pstate_method) {
+ case dml2_uclk_pstate_support_method_vactive:
+ case dml2_uclk_pstate_support_method_fw_vactive_drr:
+ pipe_ctx->p_state_type = P_STATE_V_ACTIVE;
+ break;
+ case dml2_uclk_pstate_support_method_vblank:
+ case dml2_uclk_pstate_support_method_fw_vblank_drr:
+ if (sub_vp_enabled)
+ pipe_ctx->p_state_type = P_STATE_V_BLANK_SUB_VP;
+ else
+ pipe_ctx->p_state_type = P_STATE_V_BLANK;
+ break;
+ case dml2_uclk_pstate_support_method_fw_subvp_phantom:
+ case dml2_uclk_pstate_support_method_fw_subvp_phantom_drr:
+ pipe_ctx->p_state_type = P_STATE_SUB_VP;
+ break;
+ case dml2_uclk_pstate_support_method_fw_drr:
+ if (sub_vp_enabled)
+ pipe_ctx->p_state_type = P_STATE_DRR_SUB_VP;
+ else
+ pipe_ctx->p_state_type = P_STATE_FPO;
+ break;
+ default:
+ pipe_ctx->p_state_type = P_STATE_UNKNOWN;
+ break;
+ }
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.h
index 4cc0a1fbb93d..476a7f6e4875 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.h
@@ -26,4 +26,5 @@ void dml21_extract_legacy_watermark_set(const struct dc *in_dc, struct dcn_water
void dml21_extract_watermark_sets(const struct dc *in_dc, union dcn_watermark_set *watermarks, struct dml2_context *in_ctx);
void dml21_map_hw_resources(struct dml2_context *dml_ctx);
void dml21_get_pipe_mcache_config(struct dc_state *context, struct pipe_ctx *pipe_ctx, struct dml2_per_plane_programming *pln_prog, struct dml2_pipe_configuration_descriptor *mcache_pipe_config);
+void dml21_set_dc_p_state_type(struct pipe_ctx *pipe_ctx, struct dml2_per_stream_programming *stream_programming, bool sub_vp_enabled);
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c
index d276458e50fd..51d491bffa32 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c
@@ -11,7 +11,6 @@
#include "dml2_core_dcn4_calcs.h"
-
int dml21_helper_find_dml_pipe_idx_by_stream_id(struct dml2_context *ctx, unsigned int stream_id)
{
int i;
@@ -280,6 +279,23 @@ bool check_dp2p0_output_encoder(const struct pipe_ctx *pipe_ctx)
dc_is_dp_signal(pipe_ctx->stream->signal));
}
+
+static bool is_sub_vp_enabled(struct dc *dc, struct dc_state *context)
+{
+ int i;
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+ if (pipe_ctx->stream && dc_state_get_paired_subvp_stream(context, pipe_ctx->stream) &&
+ dc_state_get_pipe_subvp_type(context, pipe_ctx) == SUBVP_MAIN) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
void dml21_program_dc_pipe(struct dml2_context *dml_ctx, struct dc_state *context, struct pipe_ctx *pipe_ctx, struct dml2_per_plane_programming *pln_prog,
struct dml2_per_stream_programming *stream_prog)
{
@@ -310,12 +326,16 @@ void dml21_program_dc_pipe(struct dml2_context *dml_ctx, struct dc_state *contex
pipe_ctx->det_buffer_size_kb = pln_prog->pipe_regs[pipe_reg_index]->det_size * 64;
}
- pipe_ctx->plane_res.bw.dppclk_khz = pln_prog->min_clocks.dcn4.dppclk_khz;
+ pipe_ctx->plane_res.bw.dppclk_khz = pln_prog->min_clocks.dcn4x.dppclk_khz;
if (context->bw_ctx.bw.dcn.clk.dppclk_khz < pipe_ctx->plane_res.bw.dppclk_khz)
context->bw_ctx.bw.dcn.clk.dppclk_khz = pipe_ctx->plane_res.bw.dppclk_khz;
dml21_populate_mall_allocation_size(context, dml_ctx, pln_prog, pipe_ctx);
memcpy(&context->bw_ctx.bw.dcn.mcache_allocations[pipe_ctx->pipe_idx], &pln_prog->mcache_allocation, sizeof(struct dml2_mcache_surface_allocation));
+
+ bool sub_vp_enabled = is_sub_vp_enabled(pipe_ctx->stream->ctx->dc, context);
+
+ dml21_set_dc_p_state_type(pipe_ctx, stream_prog, sub_vp_enabled);
}
static struct dc_stream_state *dml21_add_phantom_stream(struct dml2_context *dml_ctx,
@@ -459,94 +479,103 @@ void dml21_build_fams2_programming(const struct dc *dc,
struct dml2_context *dml_ctx)
{
int i, j, k;
+ unsigned int num_fams2_streams = 0;
/* reset fams2 data */
- context->bw_ctx.bw.dcn.fams2_stream_count = 0;
memset(&context->bw_ctx.bw.dcn.fams2_stream_params, 0, sizeof(struct dmub_fams2_stream_static_state) * DML2_MAX_PLANES);
+ memset(&context->bw_ctx.bw.dcn.fams2_global_config, 0, sizeof(struct dmub_cmd_fams2_global_config));
- if (!dml_ctx->v21.mode_programming.programming->fams2_required)
- return;
+ if (dml_ctx->v21.mode_programming.programming->fams2_required) {
+ for (i = 0; i < context->stream_count; i++) {
+ int dml_stream_idx;
+ struct dc_stream_state *phantom_stream;
+ struct dc_stream_status *phantom_status;
- for (i = 0; i < context->stream_count; i++) {
- int dml_stream_idx;
- struct dc_stream_state *phantom_stream;
- struct dc_stream_status *phantom_status;
-
- struct dmub_fams2_stream_static_state *static_state = &context->bw_ctx.bw.dcn.fams2_stream_params[context->bw_ctx.bw.dcn.fams2_stream_count];
-
- struct dc_stream_state *stream = context->streams[i];
-
- if (context->stream_status[i].plane_count == 0 ||
- dml_ctx->config.svp_pstate.callbacks.get_stream_subvp_type(context, stream) == SUBVP_PHANTOM) {
- /* can ignore blanked or phantom streams */
- continue;
- }
+ struct dmub_fams2_stream_static_state *static_state = &context->bw_ctx.bw.dcn.fams2_stream_params[num_fams2_streams];
- dml_stream_idx = dml21_helper_find_dml_pipe_idx_by_stream_id(dml_ctx, stream->stream_id);
- if (dml_stream_idx < 0) {
- ASSERT(dml_stream_idx >= 0);
- continue;
- }
+ struct dc_stream_state *stream = context->streams[i];
- /* copy static state from PMO */
- memcpy(static_state,
- &dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_params,
- sizeof(struct dmub_fams2_stream_static_state));
-
- /* get information from context */
- static_state->num_planes = context->stream_status[i].plane_count;
- static_state->otg_inst = context->stream_status[i].primary_otg_inst;
-
- /* populate pipe masks for planes */
- for (j = 0; j < context->stream_status[i].plane_count; j++) {
- for (k = 0; k < dc->res_pool->pipe_count; k++) {
- if (context->res_ctx.pipe_ctx[k].stream &&
- context->res_ctx.pipe_ctx[k].stream->stream_id == stream->stream_id &&
- context->res_ctx.pipe_ctx[k].plane_state == context->stream_status[i].plane_states[j]) {
- static_state->pipe_mask |= (1 << k);
- static_state->plane_pipe_masks[j] |= (1 << k);
- }
+ if (context->stream_status[i].plane_count == 0 ||
+ dml_ctx->config.svp_pstate.callbacks.get_stream_subvp_type(context, stream) == SUBVP_PHANTOM) {
+ /* can ignore blanked or phantom streams */
+ continue;
}
- }
- /* get per method programming */
- switch (static_state->type) {
- case FAMS2_STREAM_TYPE_VBLANK:
- case FAMS2_STREAM_TYPE_VACTIVE:
- case FAMS2_STREAM_TYPE_DRR:
- break;
- case FAMS2_STREAM_TYPE_SUBVP:
- phantom_stream = dml_ctx->config.svp_pstate.callbacks.get_paired_subvp_stream(context, stream);
- if (!phantom_stream)
- break;
+ dml_stream_idx = dml21_helper_find_dml_pipe_idx_by_stream_id(dml_ctx, stream->stream_id);
+ if (dml_stream_idx < 0) {
+ ASSERT(dml_stream_idx >= 0);
+ continue;
+ }
- phantom_status = dml_ctx->config.callbacks.get_stream_status(context, phantom_stream);
+ /* copy static state from PMO */
+ memcpy(static_state,
+ &dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_params,
+ sizeof(struct dmub_fams2_stream_static_state));
- /* phantom status should always be present */
- ASSERT(phantom_status);
- static_state->sub_state.subvp.phantom_otg_inst = phantom_status->primary_otg_inst;
+ /* get information from context */
+ static_state->num_planes = context->stream_status[i].plane_count;
+ static_state->otg_inst = context->stream_status[i].primary_otg_inst;
- /* populate pipe masks for phantom planes */
- for (j = 0; j < phantom_status->plane_count; j++) {
+ /* populate pipe masks for planes */
+ for (j = 0; j < context->stream_status[i].plane_count; j++) {
for (k = 0; k < dc->res_pool->pipe_count; k++) {
if (context->res_ctx.pipe_ctx[k].stream &&
- context->res_ctx.pipe_ctx[k].stream->stream_id == phantom_stream->stream_id &&
- context->res_ctx.pipe_ctx[k].plane_state == phantom_status->plane_states[j]) {
- static_state->sub_state.subvp.phantom_pipe_mask |= (1 << k);
- static_state->sub_state.subvp.phantom_plane_pipe_masks[j] |= (1 << k);
+ context->res_ctx.pipe_ctx[k].stream->stream_id == stream->stream_id &&
+ context->res_ctx.pipe_ctx[k].plane_state == context->stream_status[i].plane_states[j]) {
+ static_state->pipe_mask |= (1 << k);
+ static_state->plane_pipe_masks[j] |= (1 << k);
+ }
+ }
+ }
+
+ /* get per method programming */
+ switch (static_state->type) {
+ case FAMS2_STREAM_TYPE_VBLANK:
+ case FAMS2_STREAM_TYPE_VACTIVE:
+ case FAMS2_STREAM_TYPE_DRR:
+ break;
+ case FAMS2_STREAM_TYPE_SUBVP:
+ phantom_stream = dml_ctx->config.svp_pstate.callbacks.get_paired_subvp_stream(context, stream);
+ if (!phantom_stream)
+ break;
+
+ phantom_status = dml_ctx->config.callbacks.get_stream_status(context, phantom_stream);
+
+ /* phantom status should always be present */
+ ASSERT(phantom_status);
+ static_state->sub_state.subvp.phantom_otg_inst = phantom_status->primary_otg_inst;
+
+ /* populate pipe masks for phantom planes */
+ for (j = 0; j < phantom_status->plane_count; j++) {
+ for (k = 0; k < dc->res_pool->pipe_count; k++) {
+ if (context->res_ctx.pipe_ctx[k].stream &&
+ context->res_ctx.pipe_ctx[k].stream->stream_id == phantom_stream->stream_id &&
+ context->res_ctx.pipe_ctx[k].plane_state == phantom_status->plane_states[j]) {
+ static_state->sub_state.subvp.phantom_pipe_mask |= (1 << k);
+ static_state->sub_state.subvp.phantom_plane_pipe_masks[j] |= (1 << k);
+ }
}
}
+ break;
+ default:
+ ASSERT(false);
+ break;
}
- break;
- default:
- ASSERT(false);
- break;
+
+ num_fams2_streams++;
}
+ }
+
+ if (num_fams2_streams > 0) {
+ /* copy FAMS2 configuration */
+ memcpy(&context->bw_ctx.bw.dcn.fams2_global_config,
+ &dml_ctx->v21.mode_programming.programming->fams2_global_config,
+ sizeof(struct dmub_cmd_fams2_global_config));
- context->bw_ctx.bw.dcn.fams2_stream_count++;
+ context->bw_ctx.bw.dcn.fams2_global_config.num_streams = num_fams2_streams;
}
- context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = context->bw_ctx.bw.dcn.fams2_stream_count > 0;
+ context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = context->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable;
}
bool dml21_is_plane1_enabled(enum dml2_source_format_class source_format)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c
index 41ecf00ed196..d35dd507cb9f 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c
@@ -66,7 +66,9 @@ static void dml21_apply_debug_options(const struct dc *in_dc, struct dml2_contex
disable_fams2;
pmo_options->disable_fams2 = disable_fams2;
- pmo_options->disable_drr_var_when_var_active = in_dc->debug.disable_fams_gaming;
+ pmo_options->disable_drr_var_when_var_active = in_dc->debug.disable_fams_gaming == INGAME_FAMS_DISABLE ||
+ in_dc->debug.disable_fams_gaming == INGAME_FAMS_MULTI_DISP_CLAMPED_ONLY;
+ pmo_options->disable_drr_clamped_when_var_active = in_dc->debug.disable_fams_gaming == INGAME_FAMS_DISABLE;
}
static void dml21_init(const struct dc *in_dc, struct dml2_context **dml_ctx, const struct dml2_configuration_options *config)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/bounding_boxes/dcn3_soc_bb.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/bounding_boxes/dcn3_soc_bb.h
index 521f77b8ac44..d82c681a5402 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/bounding_boxes/dcn3_soc_bb.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/bounding_boxes/dcn3_soc_bb.h
@@ -72,7 +72,7 @@ static const struct dml2_soc_qos_parameters dml_dcn31_soc_qos_params = {
.scaling_factor_mhz = 0,
},
.qos_params = {
- .dcn4 = {
+ .dcn4x = {
.df_qos_response_time_fclk_cycles = 300,
.max_round_trip_to_furthest_cs_fclk_cycles = 350,
.mall_overhead_fclk_cycles = 50,
@@ -128,7 +128,7 @@ static const struct dml2_soc_qos_parameters dml_dcn31_soc_qos_params = {
},
},
},
- .qos_type = dml2_qos_param_type_dcn4,
+ .qos_type = dml2_qos_param_type_dcn4x,
};
static const struct dml2_soc_bb dml2_socbb_dcn31 = {
@@ -228,7 +228,7 @@ static const struct dml2_soc_bb dml2_socbb_dcn31 = {
.scaling_factor_mhz = 0,
},
.qos_params = {
- .dcn4 = {
+ .dcn4x = {
.df_qos_response_time_fclk_cycles = 300,
.max_round_trip_to_furthest_cs_fclk_cycles = 350,
.mall_overhead_fclk_cycles = 50,
@@ -332,7 +332,7 @@ static const struct dml2_soc_bb dml2_socbb_dcn31 = {
},
},
},
- .qos_type = dml2_qos_param_type_dcn4,
+ .qos_type = dml2_qos_param_type_dcn4x,
},
.power_management_parameters = {
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/bounding_boxes/dcn4_soc_bb.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/bounding_boxes/dcn4_soc_bb.h
index fe07fcc3d0d5..8ef7977841de 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/bounding_boxes/dcn4_soc_bb.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/bounding_boxes/dcn4_soc_bb.h
@@ -8,7 +8,7 @@
#include "dml_top_soc_parameter_types.h"
-static const struct dml2_soc_qos_parameters dml_dcn401_soc_qos_params = {
+static const struct dml2_soc_qos_parameters dml_dcn4_variant_a_soc_qos_params = {
.derate_table = {
.system_active_urgent = {
.dram_derate_percent_pixel = 22,
@@ -52,7 +52,7 @@ static const struct dml2_soc_qos_parameters dml_dcn401_soc_qos_params = {
.scaling_factor_mhz = 0,
},
.qos_params = {
- .dcn4 = {
+ .dcn4x = {
.df_qos_response_time_fclk_cycles = 300,
.max_round_trip_to_furthest_cs_fclk_cycles = 350,
.mall_overhead_fclk_cycles = 50,
@@ -78,7 +78,7 @@ static const struct dml2_soc_qos_parameters dml_dcn401_soc_qos_params = {
},
},
},
- .qos_type = dml2_qos_param_type_dcn4,
+ .qos_type = dml2_qos_param_type_dcn4x,
};
static const struct dml2_soc_bb dml2_socbb_dcn401 = {
@@ -178,7 +178,7 @@ static const struct dml2_soc_bb dml2_socbb_dcn401 = {
.scaling_factor_mhz = 0,
},
.qos_params = {
- .dcn4 = {
+ .dcn4x = {
.df_qos_response_time_fclk_cycles = 300,
.max_round_trip_to_furthest_cs_fclk_cycles = 350,
.mall_overhead_fclk_cycles = 50,
@@ -282,7 +282,7 @@ static const struct dml2_soc_bb dml2_socbb_dcn401 = {
},
},
},
- .qos_type = dml2_qos_param_type_dcn4,
+ .qos_type = dml2_qos_param_type_dcn4x,
},
.power_management_parameters = {
@@ -344,6 +344,9 @@ static const struct dml2_ip_capabilities dml2_dcn401_max_ip_caps = {
.config_return_buffer_segment_size_in_kbytes = 64,
.meta_fifo_size_in_kentries = 22,
.compressed_buffer_segment_size_in_kbytes = 64,
+ .max_flip_time_us = 80,
+ .max_flip_time_lines = 32,
+ .hostvm_mode = 0,
.subvp_drr_scheduling_margin_us = 100,
.subvp_prefetch_end_to_mall_start_us = 15,
.subvp_fw_processing_delay = 15,
@@ -351,14 +354,18 @@ static const struct dml2_ip_capabilities dml2_dcn401_max_ip_caps = {
.fams2 = {
.max_allow_delay_us = 100 * 1000,
- .scheduling_delay_us = 50,
- .vertical_interrupt_ack_delay_us = 18,
+ .scheduling_delay_us = 125,
+ .vertical_interrupt_ack_delay_us = 40,
.allow_programming_delay_us = 18,
.min_allow_width_us = 20,
.subvp_df_throttle_delay_us = 100,
- .subvp_programming_delay_us = 18,
+ .subvp_programming_delay_us = 200,
.subvp_prefetch_to_mall_delay_us = 18,
- .drr_programming_delay_us = 18,
+ .drr_programming_delay_us = 35,
+
+ .lock_timeout_us = 5000,
+ .recovery_timeout_us = 5000,
+ .flip_programming_delay_us = 300,
},
};
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top.h
index a25f4e5977cf..a64ec4dcf11a 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML_TOP_H__
#define __DML_TOP_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_dchub_registers.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_dchub_registers.h
index 8247289ce7d3..83fc15bf13cf 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_dchub_registers.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_dchub_registers.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __dml2_TOP_DCHUB_REGISTERS_H__
#define __dml2_TOP_DCHUB_REGISTERS_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_display_cfg_types.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_display_cfg_types.h
index daae77f2672b..b132f676a68d 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_display_cfg_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_display_cfg_types.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML_TOP_DISPLAY_CFG_TYPES_H__
#define __DML_TOP_DISPLAY_CFG_TYPES_H__
@@ -411,7 +410,6 @@ struct dml2_stream_parameters {
enum dml2_odm_mode odm_mode;
bool disable_dynamic_odm;
bool disable_subvp;
- bool disable_fams2_drr;
int minimum_vblank_idle_requirement_us;
bool minimize_active_latency_hiding;
@@ -478,6 +476,7 @@ struct dml2_display_cfg {
bool max_outstanding_when_urgent_expected_disable;
bool enable_subvp_implicit_pmo; //enables PMO to switch pipe uclk strategy to subvp, and generate phantom programming
unsigned int best_effort_min_active_latency_hiding_us;
+ bool all_streams_blanked;
} overrides;
};
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_policy_types.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_policy_types.h
index 2f444f448770..8f624a912e78 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_policy_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_policy_types.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML_TOP_POLICY_TYPES_H__
#define __DML_TOP_POLICY_TYPES_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_soc_parameter_types.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_soc_parameter_types.h
index 065b2afab6fb..ebd8abe894a9 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_soc_parameter_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_soc_parameter_types.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML_TOP_SOC_PARAMETER_TYPES_H__
#define __DML_TOP_SOC_PARAMETER_TYPES_H__
@@ -27,7 +26,7 @@ struct dml2_soc_derates {
struct dml2_soc_derate_values system_idle_average;
};
-struct dml2_dcn3_soc_qos_params {
+struct dml2_dcn32x_soc_qos_params {
struct {
unsigned int base_latency_us;
unsigned int base_latency_pixel_vm_us;
@@ -53,7 +52,7 @@ struct dml2_dcn4_uclk_dpm_dependent_qos_params {
unsigned int average_latency_when_non_urgent_uclk_cycles;
};
-struct dml2_dcn4_soc_qos_params {
+struct dml2_dcn4x_soc_qos_params {
unsigned int df_qos_response_time_fclk_cycles;
unsigned int max_round_trip_to_furthest_cs_fclk_cycles;
unsigned int mall_overhead_fclk_cycles;
@@ -69,7 +68,7 @@ struct dml2_dcn4_soc_qos_params {
enum dml2_qos_param_type {
dml2_qos_param_type_dcn3,
- dml2_qos_param_type_dcn4
+ dml2_qos_param_type_dcn4x
};
struct dml2_soc_qos_parameters {
@@ -81,8 +80,8 @@ struct dml2_soc_qos_parameters {
} writeback;
union {
- struct dml2_dcn3_soc_qos_params dcn3;
- struct dml2_dcn4_soc_qos_params dcn4;
+ struct dml2_dcn32x_soc_qos_params dcn32x;
+ struct dml2_dcn4x_soc_qos_params dcn4x;
} qos_params;
enum dml2_qos_param_type qos_type;
@@ -152,6 +151,7 @@ struct dml2_soc_bb {
double phy_downspread_percent;
double dcn_downspread_percent;
double dispclk_dppclk_vco_speed_mhz;
+ bool no_dfs;
bool do_urgent_latency_adjustment;
unsigned int mem_word_bytes;
unsigned int num_dcc_mcaches;
@@ -173,6 +173,7 @@ struct dml2_ip_capabilities {
unsigned int meta_fifo_size_in_kentries;
unsigned int compressed_buffer_segment_size_in_kbytes;
unsigned int max_flip_time_us;
+ unsigned int max_flip_time_lines;
unsigned int hostvm_mode;
unsigned int subvp_drr_scheduling_margin_us;
unsigned int subvp_prefetch_end_to_mall_start_us;
@@ -190,6 +191,10 @@ struct dml2_ip_capabilities {
unsigned int subvp_programming_delay_us;
unsigned int subvp_prefetch_to_mall_delay_us;
unsigned int drr_programming_delay_us;
+
+ unsigned int lock_timeout_us;
+ unsigned int recovery_timeout_us;
+ unsigned int flip_programming_delay_us;
} fams2;
};
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_types.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_types.h
index 8aa77bb190ea..eeb96c455658 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_types.h
@@ -5,7 +5,6 @@
#ifndef __DML_TOP_TYPES_H__
#define __DML_TOP_TYPES_H__
-#include "dml_top_types.h"
#include "dml_top_display_cfg_types.h"
#include "dml_top_soc_parameter_types.h"
#include "dml_top_policy_types.h"
@@ -74,6 +73,7 @@ struct dml2_pmo_options {
bool disable_drr_var;
bool disable_drr_clamped;
bool disable_drr_var_when_var_active;
+ bool disable_drr_clamped_when_var_active;
bool disable_fams2;
bool disable_vactive_det_fill_bw_pad; /* dml2_project_dcn4x_stage2_auto_drr_svp and above only */
bool disable_dyn_odm;
@@ -228,7 +228,7 @@ struct dml2_per_plane_programming {
union {
struct {
unsigned long dppclk_khz;
- } dcn4;
+ } dcn4x;
} min_clocks;
struct dml2_mcache_surface_allocation mcache_allocation;
@@ -262,7 +262,8 @@ union dml2_global_sync_programming {
unsigned int vupdate_offset_pixels;
unsigned int vupdate_vupdate_width_pixels;
unsigned int vready_offset_pixels;
- } dcn4;
+ unsigned int pstate_keepout_start_lines;
+ } dcn4x;
};
struct dml2_per_stream_programming {
@@ -273,7 +274,7 @@ struct dml2_per_stream_programming {
unsigned long dscclk_khz;
unsigned long dtbclk_khz;
unsigned long phyclk_khz;
- } dcn4;
+ } dcn4x;
} min_clocks;
union dml2_global_sync_programming global_sync;
@@ -374,7 +375,7 @@ struct dml2_display_cfg_programming {
unsigned long dispclk_khz;
unsigned long dcfclk_deepsleep_khz;
unsigned long dpp_ref_khz;
- } dcn3;
+ } dcn32x;
struct {
struct {
unsigned long uclk_khz;
@@ -403,7 +404,7 @@ struct dml2_display_cfg_programming {
uint32_t dpprefclk_did;
uint32_t dtbrefclk_did;
} divider_ids;
- } dcn4;
+ } dcn4x;
} min_clocks;
bool uclk_pstate_supported;
@@ -411,6 +412,7 @@ struct dml2_display_cfg_programming {
/* indicates this configuration requires FW to support */
bool fams2_required;
+ struct dmub_cmd_fams2_global_config fams2_global_config;
struct {
bool supported_in_blank; // Changing to configurations where this is false requires stutter to be disabled during the transition
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c
index 04edcde423a9..0aa4e4d343b0 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#include "dml2_internal_shared_types.h"
#include "dml2_core_shared_types.h"
#include "dml2_core_dcn4.h"
@@ -10,7 +9,7 @@
#include "dml2_debug.h"
#include "lib_float_math.h"
-struct dml2_core_ip_params core_dcn4_ip_caps_base = {
+static const struct dml2_core_ip_params core_dcn4_ip_caps_base = {
// Hardcoded values for DCN3x
.vblank_nom_default_us = 668,
.remote_iommu_outstanding_translations = 256,
@@ -70,6 +69,7 @@ struct dml2_core_ip_params core_dcn4_ip_caps_base = {
.max_num_dp2p0_streams = 4,
.imall_supported = 1,
.max_flip_time_us = 80,
+ .max_flip_time_lines = 32,
.words_per_channel = 16,
.subvp_fw_processing_delay_us = 15,
@@ -77,84 +77,6 @@ struct dml2_core_ip_params core_dcn4_ip_caps_base = {
.subvp_swath_height_margin_lines = 16,
};
-struct dml2_core_ip_params core_dcn4sw_ip_caps_base = {
- .vblank_nom_default_us = 668,
- .remote_iommu_outstanding_translations = 256,
- .rob_buffer_size_kbytes = 192,
- .config_return_buffer_size_in_kbytes = 1280,
- .config_return_buffer_segment_size_in_kbytes = 64,
- .compressed_buffer_segment_size_in_kbytes = 64,
- .dpte_buffer_size_in_pte_reqs_luma = 68,
- .dpte_buffer_size_in_pte_reqs_chroma = 36,
- .pixel_chunk_size_kbytes = 8,
- .alpha_pixel_chunk_size_kbytes = 4,
- .min_pixel_chunk_size_bytes = 1024,
- .writeback_chunk_size_kbytes = 8,
- .line_buffer_size_bits = 1171920,
- .max_line_buffer_lines = 32,
- .writeback_interface_buffer_size_kbytes = 90,
-
- //Number of pipes after DCN Pipe harvesting
- .max_num_dpp = 4,
- .max_num_otg = 4,
- .max_num_wb = 1,
- .max_dchub_pscl_bw_pix_per_clk = 4,
- .max_pscl_lb_bw_pix_per_clk = 2,
- .max_lb_vscl_bw_pix_per_clk = 4,
- .max_vscl_hscl_bw_pix_per_clk = 4,
- .max_hscl_ratio = 6,
- .max_vscl_ratio = 6,
- .max_hscl_taps = 8,
- .max_vscl_taps = 8,
- .dispclk_ramp_margin_percent = 1,
- .dppclk_delay_subtotal = 47,
- .dppclk_delay_scl = 50,
- .dppclk_delay_scl_lb_only = 16,
- .dppclk_delay_cnvc_formatter = 28,
- .dppclk_delay_cnvc_cursor = 6,
- .cursor_buffer_size = 24,
- .cursor_chunk_size = 2,
- .dispclk_delay_subtotal = 125,
- .max_inter_dcn_tile_repeaters = 8,
- .writeback_max_hscl_ratio = 1,
- .writeback_max_vscl_ratio = 1,
- .writeback_min_hscl_ratio = 1,
- .writeback_min_vscl_ratio = 1,
- .writeback_max_hscl_taps = 1,
- .writeback_max_vscl_taps = 1,
- .writeback_line_buffer_buffer_size = 0,
- .num_dsc = 4,
- .maximum_dsc_bits_per_component = 12,
- .maximum_pixels_per_line_per_dsc_unit = 5760,
- .dsc422_native_support = true,
- .dcc_supported = true,
- .ptoi_supported = false,
-
- .cursor_64bpp_support = true,
- .dynamic_metadata_vm_enabled = false,
-
- .max_num_hdmi_frl_outputs = 1,
- .max_num_dp2p0_outputs = 4,
- .max_num_dp2p0_streams = 4,
- .imall_supported = 1,
- .max_flip_time_us = 80,
- .words_per_channel = 16,
-
- .subvp_fw_processing_delay_us = 15,
- .subvp_pstate_allow_width_us = 20,
- .subvp_swath_height_margin_lines = 16,
-
- .dcn_mrq_present = 1,
- .zero_size_buffer_entries = 512,
- .compbuf_reserved_space_zs = 64,
- .dcc_meta_buffer_size_bytes = 6272,
- .meta_chunk_size_kbytes = 2,
- .min_meta_chunk_size_bytes = 256,
-
- .dchub_arb_to_ret_delay = 102,
- .hostvm_mode = 1,
-};
-
static void patch_ip_caps_with_explicit_ip_params(struct dml2_ip_capabilities *ip_caps, const struct dml2_core_ip_params *ip_params)
{
ip_caps->pipe_count = ip_params->max_num_dpp;
@@ -169,6 +91,7 @@ static void patch_ip_caps_with_explicit_ip_params(struct dml2_ip_capabilities *i
ip_caps->meta_fifo_size_in_kentries = ip_params->meta_fifo_size_in_kentries;
ip_caps->compressed_buffer_segment_size_in_kbytes = ip_params->compressed_buffer_segment_size_in_kbytes;
ip_caps->max_flip_time_us = ip_params->max_flip_time_us;
+ ip_caps->max_flip_time_lines = ip_params->max_flip_time_lines;
ip_caps->hostvm_mode = ip_params->hostvm_mode;
// FIXME_STAGE2: cleanup after adding all dv override to ip_caps
@@ -192,6 +115,7 @@ static void patch_ip_params_with_ip_caps(struct dml2_core_ip_params *ip_params,
ip_params->meta_fifo_size_in_kentries = ip_caps->meta_fifo_size_in_kentries;
ip_params->compressed_buffer_segment_size_in_kbytes = ip_caps->compressed_buffer_segment_size_in_kbytes;
ip_params->max_flip_time_us = ip_caps->max_flip_time_us;
+ ip_params->max_flip_time_lines = ip_caps->max_flip_time_lines;
ip_params->hostvm_mode = ip_caps->hostvm_mode;
}
@@ -222,6 +146,7 @@ bool core_dcn4_initialize(struct dml2_core_initialize_in_out *in_out)
}
memcpy(&core->clean_me_up.mode_lib.soc, in_out->soc_bb, sizeof(struct dml2_soc_bb));
+ memcpy(&core->clean_me_up.mode_lib.ip_caps, in_out->ip_caps, sizeof(struct dml2_ip_capabilities));
return true;
}
@@ -246,10 +171,12 @@ static void create_phantom_plane_from_main_plane(struct dml2_plane_parameters *p
phantom->stream_index = phantom_stream_index;
phantom->overrides.refresh_from_mall = dml2_refresh_from_mall_mode_override_force_disable;
phantom->overrides.legacy_svp_config = dml2_svp_mode_override_phantom_pipe_no_data_return;
- phantom->composition.viewport.plane0.height = (long int unsigned) math_ceil2(
- (double)phantom->composition.viewport.plane0.height * (double)phantom_stream->timing.v_active / (double)main_stream->timing.v_active, 16.0);
- phantom->composition.viewport.plane1.height = (long int unsigned) math_ceil2(
- (double)phantom->composition.viewport.plane1.height * (double)phantom_stream->timing.v_active / (double)main_stream->timing.v_active, 16.0);
+ phantom->composition.viewport.plane0.height = (long int unsigned) math_min2(math_ceil2(
+ (double)main->composition.scaler_info.plane0.v_ratio * (double)phantom_stream->timing.v_active, 16.0),
+ (double)main->composition.viewport.plane0.height);
+ phantom->composition.viewport.plane1.height = (long int unsigned) math_min2(math_ceil2(
+ (double)main->composition.scaler_info.plane1.v_ratio * (double)phantom_stream->timing.v_active, 16.0),
+ (double)main->composition.viewport.plane1.height);
phantom->immediate_flip = false;
phantom->dynamic_meta_data.enable = false;
phantom->cursor.num_cursors = 0;
@@ -344,6 +271,8 @@ static void pack_mode_programming_params_with_implicit_subvp(struct dml2_core_in
// Check if FAMS2 is required
if (display_cfg->stage3.performed && display_cfg->stage3.success) {
programming->fams2_required = display_cfg->stage3.fams2_required;
+
+ dml2_core_calcs_get_global_fams2_programming(&core->clean_me_up.mode_lib, display_cfg, &programming->fams2_global_config);
}
// Only loop over all the main streams (the implicit svp streams will be packed as part of the main stream)
@@ -621,7 +550,7 @@ bool core_dcn4_mode_programming(struct dml2_core_mode_programming_in_out *in_out
l->mode_programming_ex_params.min_clk_table = in_out->instance->minimum_clock_table;
l->mode_programming_ex_params.cfg_support_info = in_out->cfg_support_info;
l->mode_programming_ex_params.programming = in_out->programming;
- l->mode_programming_ex_params.min_clk_index = lookup_uclk_dpm_index_by_freq(in_out->programming->min_clocks.dcn4.active.uclk_khz,
+ l->mode_programming_ex_params.min_clk_index = lookup_uclk_dpm_index_by_freq(in_out->programming->min_clocks.dcn4x.active.uclk_khz,
&core->clean_me_up.mode_lib.soc);
result = dml2_core_calcs_mode_programming_ex(&l->mode_programming_ex_params);
@@ -641,20 +570,20 @@ bool core_dcn4_mode_programming(struct dml2_core_mode_programming_in_out *in_out
for (plane_index = 0; plane_index < in_out->programming->display_config.num_planes; plane_index++) {
in_out->programming->plane_programming[plane_index].num_dpps_required = core->clean_me_up.mode_lib.mp.NoOfDPP[plane_index];
- if (in_out->programming->display_config.plane_descriptors->overrides.legacy_svp_config == dml2_svp_mode_override_main_pipe)
- in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_fw_subvp_phantom;
- else if (in_out->programming->display_config.plane_descriptors->overrides.legacy_svp_config == dml2_svp_mode_override_phantom_pipe)
- in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_fw_subvp_phantom;
- else if (in_out->programming->display_config.plane_descriptors->overrides.legacy_svp_config == dml2_svp_mode_override_phantom_pipe_no_data_return)
- in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_fw_subvp_phantom;
- else {
- if (core->clean_me_up.mode_lib.mp.MaxActiveDRAMClockChangeLatencySupported[plane_index] >= core->clean_me_up.mode_lib.soc.power_management_parameters.dram_clk_change_blackout_us)
- in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_vactive;
- else if (core->clean_me_up.mode_lib.mp.TWait[plane_index] >= core->clean_me_up.mode_lib.soc.power_management_parameters.dram_clk_change_blackout_us)
- in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_vblank;
- else
- in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_not_supported;
- }
+ if (in_out->programming->display_config.plane_descriptors[plane_index].overrides.legacy_svp_config == dml2_svp_mode_override_main_pipe)
+ in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_fw_subvp_phantom;
+ else if (in_out->programming->display_config.plane_descriptors[plane_index].overrides.legacy_svp_config == dml2_svp_mode_override_phantom_pipe)
+ in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_fw_subvp_phantom;
+ else if (in_out->programming->display_config.plane_descriptors[plane_index].overrides.legacy_svp_config == dml2_svp_mode_override_phantom_pipe_no_data_return)
+ in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_fw_subvp_phantom;
+ else {
+ if (core->clean_me_up.mode_lib.mp.MaxActiveDRAMClockChangeLatencySupported[plane_index] >= core->clean_me_up.mode_lib.soc.power_management_parameters.dram_clk_change_blackout_us)
+ in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_vactive;
+ else if (core->clean_me_up.mode_lib.mp.TWait[plane_index] >= core->clean_me_up.mode_lib.soc.power_management_parameters.dram_clk_change_blackout_us)
+ in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_vblank;
+ else
+ in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_not_supported;
+ }
dml2_core_calcs_get_mall_allocation(&core->clean_me_up.mode_lib, &in_out->programming->plane_programming[plane_index].surface_size_mall_bytes, dml_internal_pipe_index);
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.h
index 235280c6dcf5..e62b2d3eeee6 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_CORE_DCN4_H__
#define __DML2_CORE_DCN4_H__
bool core_dcn4_initialize(struct dml2_core_initialize_in_out *in_out);
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
index 6f4026e396e0..3ea54fd52e46 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
@@ -8,35 +8,55 @@
#include "dml2_debug.h"
#include "lib_float_math.h"
#include "dml_top_types.h"
-#include "dml2_core_shared.h"
-#define DML_VM_PTE_ADL_PATCH_EN
-//#define DML_TVM_UPDATE_EN
-#define DML_TDLUT_ROW_BYTES_FIX_EN
-#define DML_REG_LIMIT_CLAMP_EN
#define DML2_MAX_FMT_420_BUFFER_WIDTH 4096
#define DML_MAX_NUM_OF_SLICES_PER_DSC 4
-static void dml2_print_dml_mode_support_info(const struct dml2_core_internal_mode_support_info *support, bool fail_only)
+const char *dml2_core_internal_bw_type_str(enum dml2_core_internal_bw_type bw_type)
+{
+ switch (bw_type) {
+ case (dml2_core_internal_bw_sdp):
+ return("dml2_core_internal_bw_sdp");
+ case (dml2_core_internal_bw_dram):
+ return("dml2_core_internal_bw_dram");
+ case (dml2_core_internal_bw_max):
+ return("dml2_core_internal_bw_max");
+ default:
+ return("dml2_core_internal_bw_unknown");
+ }
+}
+
+const char *dml2_core_internal_soc_state_type_str(enum dml2_core_internal_soc_state_type dml2_core_internal_soc_state_type)
+{
+ switch (dml2_core_internal_soc_state_type) {
+ case (dml2_core_internal_soc_state_sys_idle):
+ return("dml2_core_internal_soc_state_sys_idle");
+ case (dml2_core_internal_soc_state_sys_active):
+ return("dml2_core_internal_soc_state_sys_active");
+ case (dml2_core_internal_soc_state_svp_prefetch):
+ return("dml2_core_internal_soc_state_svp_prefetch");
+ case dml2_core_internal_soc_state_max:
+ default:
+ return("dml2_core_internal_soc_state_unknown");
+ }
+}
+
+static double dml2_core_div_rem(double dividend, unsigned int divisor, unsigned int *remainder)
+{
+ *remainder = ((dividend / divisor) - (int)(dividend / divisor) > 0);
+ return dividend / divisor;
+}
+
+static void dml2_print_mode_support_info(const struct dml2_core_internal_mode_support_info *support, bool fail_only)
{
dml2_printf("DML: ===================================== \n");
dml2_printf("DML: DML_MODE_SUPPORT_INFO_ST\n");
- if (!fail_only || support->ImmediateFlipSupport == 0)
- dml2_printf("DML: support: ImmediateFlipSupport = %d\n", support->ImmediateFlipSupport);
- if (!fail_only || support->WritebackLatencySupport == 0)
- dml2_printf("DML: support: WritebackLatencySupport = %d\n", support->WritebackLatencySupport);
if (!fail_only || support->ScaleRatioAndTapsSupport == 0)
dml2_printf("DML: support: ScaleRatioAndTapsSupport = %d\n", support->ScaleRatioAndTapsSupport);
if (!fail_only || support->SourceFormatPixelAndScanSupport == 0)
dml2_printf("DML: support: SourceFormatPixelAndScanSupport = %d\n", support->SourceFormatPixelAndScanSupport);
- if (!fail_only || support->P2IWith420 == 1)
- dml2_printf("DML: support: P2IWith420 = %d\n", support->P2IWith420);
- if (!fail_only || support->DSCOnlyIfNecessaryWithBPP == 1)
- dml2_printf("DML: support: DSCOnlyIfNecessaryWithBPP = %d\n", support->DSCOnlyIfNecessaryWithBPP);
- if (!fail_only || support->DSC422NativeNotSupported == 1)
- dml2_printf("DML: support: DSC422NativeNotSupported = %d\n", support->DSC422NativeNotSupported);
- if (!fail_only || support->DSCSlicesODMModeSupported == 0)
- dml2_printf("DML: support: DSCSlicesODMModeSupported = %d\n", support->DSCSlicesODMModeSupported);
+ if (!fail_only || support->ViewportSizeSupport == 0)
+ dml2_printf("DML: support: ViewportSizeSupport = %d\n", support->ViewportSizeSupport);
if (!fail_only || support->LinkRateDoesNotMatchDPVersion == 1)
dml2_printf("DML: support: LinkRateDoesNotMatchDPVersion = %d\n", support->LinkRateDoesNotMatchDPVersion);
if (!fail_only || support->LinkRateForMultistreamNotIndicated == 1)
@@ -45,74 +65,87 @@ static void dml2_print_dml_mode_support_info(const struct dml2_core_internal_mod
dml2_printf("DML: support: BPPForMultistreamNotIndicated = %d\n", support->BPPForMultistreamNotIndicated);
if (!fail_only || support->MultistreamWithHDMIOreDP == 1)
dml2_printf("DML: support: MultistreamWithHDMIOreDP = %d\n", support->MultistreamWithHDMIOreDP);
+ if (!fail_only || support->ExceededMultistreamSlots == 1)
+ dml2_printf("DML: support: ExceededMultistreamSlots = %d\n", support->ExceededMultistreamSlots);
if (!fail_only || support->MSOOrODMSplitWithNonDPLink == 1)
dml2_printf("DML: support: MSOOrODMSplitWithNonDPLink = %d\n", support->MSOOrODMSplitWithNonDPLink);
if (!fail_only || support->NotEnoughLanesForMSO == 1)
dml2_printf("DML: support: NotEnoughLanesForMSO = %d\n", support->NotEnoughLanesForMSO);
- if (!fail_only || support->NumberOfOTGSupport == 0)
- dml2_printf("DML: support: NumberOfOTGSupport = %d\n", support->NumberOfOTGSupport);
- if (!fail_only || support->NumberOfHDMIFRLSupport == 0)
- dml2_printf("DML: support: NumberOfHDMIFRLSupport = %d\n", support->NumberOfHDMIFRLSupport);
- if (!fail_only || support->NumberOfDP2p0Support == 0)
- dml2_printf("DML: support: NumberOfDP2p0Support = %d\n", support->NumberOfDP2p0Support);
- if (!fail_only || support->WritebackScaleRatioAndTapsSupport == 0)
- dml2_printf("DML: support: WritebackScaleRatioAndTapsSupport = %d\n", support->WritebackScaleRatioAndTapsSupport);
- if (!fail_only || support->CursorSupport == 0)
- dml2_printf("DML: support: CursorSupport = %d\n", support->CursorSupport);
- if (!fail_only || support->PitchSupport == 0)
- dml2_printf("DML: support: PitchSupport = %d\n", support->PitchSupport);
- if (!fail_only || support->ViewportExceedsSurface == 1)
- dml2_printf("DML: support: ViewportExceedsSurface = %d\n", support->ViewportExceedsSurface);
- if (!fail_only || support->ExceededMALLSize == 1)
- dml2_printf("DML: support: ExceededMALLSize = %d\n", support->ExceededMALLSize);
- if (!fail_only || support->EnoughWritebackUnits == 0)
- dml2_printf("DML: support: EnoughWritebackUnits = %d\n", support->EnoughWritebackUnits);
- if (!fail_only || support->ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe == 1)
- dml2_printf("DML: support: ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe = %d\n", support->ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe);
- if (!fail_only || support->InvalidCombinationOfMALLUseForPStateAndStaticScreen == 1)
- dml2_printf("DML: support: InvalidCombinationOfMALLUseForPStateAndStaticScreen = %d\n", support->InvalidCombinationOfMALLUseForPStateAndStaticScreen);
- if (!fail_only || support->InvalidCombinationOfMALLUseForPState == 1)
- dml2_printf("DML: support: InvalidCombinationOfMALLUseForPState = %d\n", support->InvalidCombinationOfMALLUseForPState);
- if (!fail_only || support->ExceededMultistreamSlots == 1)
- dml2_printf("DML: support: ExceededMultistreamSlots = %d\n", support->ExceededMultistreamSlots);
+ if (!fail_only || support->P2IWith420 == 1)
+ dml2_printf("DML: support: P2IWith420 = %d\n", support->P2IWith420);
+ if (!fail_only || support->DSC422NativeNotSupported == 1)
+ dml2_printf("DML: support: DSC422NativeNotSupported = %d\n", support->DSC422NativeNotSupported);
+ if (!fail_only || support->DSCSlicesODMModeSupported == 0)
+ dml2_printf("DML: support: DSCSlicesODMModeSupported = %d\n", support->DSCSlicesODMModeSupported);
if (!fail_only || support->NotEnoughDSCUnits == 1)
dml2_printf("DML: support: NotEnoughDSCUnits = %d\n", support->NotEnoughDSCUnits);
if (!fail_only || support->NotEnoughDSCSlices == 1)
dml2_printf("DML: support: NotEnoughDSCSlices = %d\n", support->NotEnoughDSCSlices);
- if (!fail_only || support->PixelsPerLinePerDSCUnitSupport == 0)
- dml2_printf("DML: support: PixelsPerLinePerDSCUnitSupport = %d\n", support->PixelsPerLinePerDSCUnitSupport);
+ if (!fail_only || support->ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe == 1)
+ dml2_printf("DML: support: ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe = %d\n", support->ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe);
+ if (!fail_only || support->InvalidCombinationOfMALLUseForPStateAndStaticScreen == 1)
+ dml2_printf("DML: support: InvalidCombinationOfMALLUseForPStateAndStaticScreen = %d\n", support->InvalidCombinationOfMALLUseForPStateAndStaticScreen);
if (!fail_only || support->DSCCLKRequiredMoreThanSupported == 1)
dml2_printf("DML: support: DSCCLKRequiredMoreThanSupported = %d\n", support->DSCCLKRequiredMoreThanSupported);
+ if (!fail_only || support->PixelsPerLinePerDSCUnitSupport == 0)
+ dml2_printf("DML: support: PixelsPerLinePerDSCUnitSupport = %d\n", support->PixelsPerLinePerDSCUnitSupport);
if (!fail_only || support->DTBCLKRequiredMoreThanSupported == 1)
dml2_printf("DML: support: DTBCLKRequiredMoreThanSupported = %d\n", support->DTBCLKRequiredMoreThanSupported);
- if (!fail_only || support->LinkCapacitySupport == 0)
- dml2_printf("DML: support: LinkCapacitySupport = %d\n", support->LinkCapacitySupport);
+ if (!fail_only || support->InvalidCombinationOfMALLUseForPState == 1)
+ dml2_printf("DML: support: InvalidCombinationOfMALLUseForPState = %d\n", support->InvalidCombinationOfMALLUseForPState);
if (!fail_only || support->ROBSupport == 0)
dml2_printf("DML: support: ROBSupport = %d\n", support->ROBSupport);
if (!fail_only || support->OutstandingRequestsSupport == 0)
dml2_printf("DML: support: OutstandingRequestsSupport = %d\n", support->OutstandingRequestsSupport);
if (!fail_only || support->OutstandingRequestsUrgencyAvoidance == 0)
dml2_printf("DML: support: OutstandingRequestsUrgencyAvoidance = %d\n", support->OutstandingRequestsUrgencyAvoidance);
- if (!fail_only || support->PTEBufferSizeNotExceeded == 0)
- dml2_printf("DML: support: PTEBufferSizeNotExceeded = %d\n", support->PTEBufferSizeNotExceeded);
- if (!fail_only || support->AvgBandwidthSupport == 0)
- dml2_printf("DML: support: AvgBandwidthSupport = %d\n", support->AvgBandwidthSupport);
- if (!fail_only || support->EnoughUrgentLatencyHidingSupport == 0)
- dml2_printf("DML: support: EnoughUrgentLatencyHidingSupport = %d\n", support->EnoughUrgentLatencyHidingSupport);
+ if (!fail_only || support->DISPCLK_DPPCLK_Support == 0)
+ dml2_printf("DML: support: DISPCLK_DPPCLK_Support = %d\n", support->DISPCLK_DPPCLK_Support);
+ if (!fail_only || support->TotalAvailablePipesSupport == 0)
+ dml2_printf("DML: support: TotalAvailablePipesSupport = %d\n", support->TotalAvailablePipesSupport);
+ if (!fail_only || support->NumberOfOTGSupport == 0)
+ dml2_printf("DML: support: NumberOfOTGSupport = %d\n", support->NumberOfOTGSupport);
+ if (!fail_only || support->NumberOfHDMIFRLSupport == 0)
+ dml2_printf("DML: support: NumberOfHDMIFRLSupport = %d\n", support->NumberOfHDMIFRLSupport);
+ if (!fail_only || support->NumberOfDP2p0Support == 0)
+ dml2_printf("DML: support: NumberOfDP2p0Support = %d\n", support->NumberOfDP2p0Support);
+ if (!fail_only || support->EnoughWritebackUnits == 0)
+ dml2_printf("DML: support: EnoughWritebackUnits = %d\n", support->EnoughWritebackUnits);
+ if (!fail_only || support->WritebackScaleRatioAndTapsSupport == 0)
+ dml2_printf("DML: support: WritebackScaleRatioAndTapsSupport = %d\n", support->WritebackScaleRatioAndTapsSupport);
+ if (!fail_only || support->WritebackLatencySupport == 0)
+ dml2_printf("DML: support: WritebackLatencySupport = %d\n", support->WritebackLatencySupport);
+ if (!fail_only || support->CursorSupport == 0)
+ dml2_printf("DML: support: CursorSupport = %d\n", support->CursorSupport);
+ if (!fail_only || support->PitchSupport == 0)
+ dml2_printf("DML: support: PitchSupport = %d\n", support->PitchSupport);
+ if (!fail_only || support->ViewportExceedsSurface == 1)
+ dml2_printf("DML: support: ViewportExceedsSurface = %d\n", support->ViewportExceedsSurface);
if (!fail_only || support->PrefetchSupported == 0)
dml2_printf("DML: support: PrefetchSupported = %d\n", support->PrefetchSupported);
+ if (!fail_only || support->EnoughUrgentLatencyHidingSupport == 0)
+ dml2_printf("DML: support: EnoughUrgentLatencyHidingSupport = %d\n", support->EnoughUrgentLatencyHidingSupport);
+ if (!fail_only || support->AvgBandwidthSupport == 0)
+ dml2_printf("DML: support: AvgBandwidthSupport = %d\n", support->AvgBandwidthSupport);
if (!fail_only || support->DynamicMetadataSupported == 0)
dml2_printf("DML: support: DynamicMetadataSupported = %d\n", support->DynamicMetadataSupported);
if (!fail_only || support->VRatioInPrefetchSupported == 0)
dml2_printf("DML: support: VRatioInPrefetchSupported = %d\n", support->VRatioInPrefetchSupported);
- if (!fail_only || support->DISPCLK_DPPCLK_Support == 0)
- dml2_printf("DML: support: DISPCLK_DPPCLK_Support = %d\n", support->DISPCLK_DPPCLK_Support);
- if (!fail_only || support->TotalAvailablePipesSupport == 0)
- dml2_printf("DML: support: TotalAvailablePipesSupport = %d\n", support->TotalAvailablePipesSupport);
+ if (!fail_only || support->PTEBufferSizeNotExceeded == 1)
+ dml2_printf("DML: support: PTEBufferSizeNotExceeded = %d\n", support->PTEBufferSizeNotExceeded);
+ if (!fail_only || support->DCCMetaBufferSizeNotExceeded == 1)
+ dml2_printf("DML: support: DCCMetaBufferSizeNotExceeded = %d\n", support->DCCMetaBufferSizeNotExceeded);
+ if (!fail_only || support->ExceededMALLSize == 1)
+ dml2_printf("DML: support: ExceededMALLSize = %d\n", support->ExceededMALLSize);
+ if (!fail_only || support->g6_temp_read_support == 0)
+ dml2_printf("DML: support: g6_temp_read_support = %d\n", support->g6_temp_read_support);
+ if (!fail_only || support->ImmediateFlipSupport == 0)
+ dml2_printf("DML: support: ImmediateFlipSupport = %d\n", support->ImmediateFlipSupport);
+ if (!fail_only || support->LinkCapacitySupport == 0)
+ dml2_printf("DML: support: LinkCapacitySupport = %d\n", support->LinkCapacitySupport);
+
if (!fail_only || support->ModeSupport == 0)
dml2_printf("DML: support: ModeSupport = %d\n", support->ModeSupport);
- if (!fail_only || support->ViewportSizeSupport == 0)
- dml2_printf("DML: support: ViewportSizeSupport = %d\n", support->ViewportSizeSupport);
dml2_printf("DML: ===================================== \n");
}
@@ -235,6 +268,7 @@ dml_get_per_pipe_var_func(vstartup_calculated, unsigned int, mode_lib->mp.VStart
dml_get_per_pipe_var_func(vupdate_offset, unsigned int, mode_lib->mp.VUpdateOffsetPix);
dml_get_per_pipe_var_func(vupdate_width, unsigned int, mode_lib->mp.VUpdateWidthPix);
dml_get_per_pipe_var_func(vready_offset, unsigned int, mode_lib->mp.VReadyOffsetPix);
+dml_get_per_pipe_var_func(pstate_keepout_dst_lines, unsigned int, mode_lib->mp.pstate_keepout_dst_lines);
dml_get_per_pipe_var_func(det_stored_buffer_size_l_bytes, unsigned int, mode_lib->mp.DETBufferSizeY);
dml_get_per_pipe_var_func(det_stored_buffer_size_c_bytes, unsigned int, mode_lib->mp.DETBufferSizeC);
dml_get_per_pipe_var_func(det_buffer_size_kbytes, unsigned int, mode_lib->mp.DETBufferSizeInKByte);
@@ -480,7 +514,7 @@ static unsigned int dml_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode
default:
DML2_ASSERT(0);
return 256;
- };
+ }
}
static bool dml_is_vertical_rotation(enum dml2_rotation_angle Scan)
@@ -2051,7 +2085,11 @@ static void CalculateDCCConfiguration(
unsigned int full_swath_bytes_vert_wc_l;
unsigned int full_swath_bytes_vert_wc_c;
- yuv420 = dml_is_420(SourcePixelFormat);
+ if (dml_is_420(SourcePixelFormat))
+ yuv420 = 1;
+ else
+ yuv420 = 0;
+
horz_div_l = 1;
horz_div_c = 1;
vert_div_l = 1;
@@ -2343,16 +2381,16 @@ static void calculate_mcache_row_bytes(
}
if (p->gpuvm_enable) {
- meta_per_mvmpg_per_channel = (float)vmpg_bytes / 256 / p->num_chans;
+ meta_per_mvmpg_per_channel = (float)vmpg_bytes / (float)256 / p->num_chans;
//but using the est_blk_per_vmpg between 2 and 4, to be not as pessimestic
if (p->surf_vert && vmpg_bytes > blk_bytes) {
- meta_per_mvmpg_per_channel = (float)est_blk_per_vmpg * blk_bytes / 256 / p->num_chans;
+ meta_per_mvmpg_per_channel = (float)est_blk_per_vmpg * blk_bytes / (float)256 / p->num_chans;
}
*p->dcc_dram_bw_nom_overhead_factor = 1 + math_max2(1.0 / 256.0, math_ceil2(meta_per_mvmpg_per_channel, p->mem_word_bytes) / (256 * meta_per_mvmpg_per_channel)); // dcc_dr_oh_nom
} else {
- meta_per_mvmpg_per_channel = (float) blk_bytes / 256 / p->num_chans;
+ meta_per_mvmpg_per_channel = (float) blk_bytes / (float)256 / p->num_chans;
if (!p->surf_vert)
*p->dcc_dram_bw_nom_overhead_factor = 1 + 1.0 / 256.0;
@@ -2519,8 +2557,11 @@ static void calculate_mcache_setting(
l->luma_time_factor = (double)l->mvmpg_width_c / l->mvmpg_width_l * 2;
// The algorithm starts with computing a non-integer, avg_mcache_element_size_l/c:
- l->avg_mcache_element_size_l = l->meta_row_width_l / *p->num_mcaches_l;
- if (l->is_dual_plane) {
+ if (*p->num_mcaches_l) {
+ l->avg_mcache_element_size_l = l->meta_row_width_l / *p->num_mcaches_l;
+ }
+
+ if (l->is_dual_plane && *p->num_mcaches_c) {
l->avg_mcache_element_size_c = l->meta_row_width_c / *p->num_mcaches_c;
if (!p->imall_enable || (*p->mall_comb_mcache_l == *p->mall_comb_mcache_c)) {
@@ -2649,9 +2690,9 @@ static double dml_get_return_bandwidth_available(
double ideal_fabric_bandwidth = fclk_mhz * (double)soc->fabric_datapath_to_dcn_data_return_bytes;
double ideal_dram_bandwidth = dram_bw_mbps; //dram_speed_mts * soc->clk_table.dram_config.channel_count * soc->clk_table.dram_config.channel_width_bytes;
- double derate_sdp_factor = 1;
- double derate_fabric_factor = 1;
- double derate_dram_factor = 1;
+ double derate_sdp_factor;
+ double derate_fabric_factor;
+ double derate_dram_factor;
double derate_sdp_bandwidth;
double derate_fabric_bandwidth;
@@ -2851,16 +2892,9 @@ static void CalculateVMRowAndSwath(struct dml2_core_internal_scratch *scratch,
s->HostVMDynamicLevels = CalculateHostVMDynamicLevels(p->display_cfg->gpuvm_enable, p->display_cfg->hostvm_enable, p->HostVMMinPageSize, p->display_cfg->hostvm_max_non_cached_page_table_levels);
for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
- if (p->display_cfg->hostvm_enable == true) {
+ if (p->display_cfg->gpuvm_enable == true) {
p->vm_group_bytes[k] = 512;
p->dpte_group_bytes[k] = 512;
- } else if (p->display_cfg->gpuvm_enable == true) {
- p->vm_group_bytes[k] = 2048;
- if (p->display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes >= 64 && dml_is_vertical_rotation(p->myPipe[k].RotationAngle)) {
- p->dpte_group_bytes[k] = 512;
- } else {
- p->dpte_group_bytes[k] = 2048;
- }
} else {
p->vm_group_bytes[k] = 0;
p->dpte_group_bytes[k] = 0;
@@ -3185,7 +3219,7 @@ static double CalculateUrgentLatency(
double fabric_max_transport_latency_margin)
{
double urgent_latency = 0;
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
urgent_latency = (df_qos_response_time_fclk_cycles + mall_overhead_fclk_cycles) / FabricClock
+ max_round_trip_to_furthest_cs_fclk_cycles / FabricClock * (1 + fabric_max_transport_latency_margin / 100.0)
+ urgent_ramp_uclk_cycles / uclk_freq_mhz * (1 + umc_urgent_ramp_latency_margin / 100.0);
@@ -3196,7 +3230,7 @@ static double CalculateUrgentLatency(
}
}
#ifdef __DML_VBA_DEBUG__
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
dml2_printf("DML::%s: qos_type = %d\n", __func__, qos_type);
dml2_printf("DML::%s: urgent_ramp_uclk_cycles = %d\n", __func__, urgent_ramp_uclk_cycles);
dml2_printf("DML::%s: uclk_freq_mhz = %f\n", __func__, uclk_freq_mhz);
@@ -3226,7 +3260,7 @@ static double CalculateTripToMemory(
double fabric_max_transport_latency_margin)
{
double trip_to_memory_us;
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
trip_to_memory_us = mall_overhead_fclk_cycles / FabricClock
+ max_round_trip_to_furthest_cs_fclk_cycles / FabricClock * (1.0 + fabric_max_transport_latency_margin / 100.0)
+ trip_to_memory_uclk_cycles / uclk_freq_mhz * (1.0 + umc_max_latency_margin / 100.0);
@@ -3235,7 +3269,7 @@ static double CalculateTripToMemory(
}
#ifdef __DML_VBA_DEBUG__
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
dml2_printf("DML::%s: qos_type = %d\n", __func__, qos_type);
dml2_printf("DML::%s: max_round_trip_to_furthest_cs_fclk_cycles = %d\n", __func__, max_round_trip_to_furthest_cs_fclk_cycles);
dml2_printf("DML::%s: mall_overhead_fclk_cycles = %d\n", __func__, mall_overhead_fclk_cycles);
@@ -3265,7 +3299,7 @@ static double CalculateMetaTripToMemory(
double fabric_max_transport_latency_margin)
{
double meta_trip_to_memory_us;
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
meta_trip_to_memory_us = meta_trip_to_memory_fclk_cycles / FabricClock * (1.0 + fabric_max_transport_latency_margin / 100.0)
+ meta_trip_to_memory_uclk_cycles / uclk_freq_mhz * (1.0 + umc_max_latency_margin / 100.0);
} else {
@@ -3273,7 +3307,7 @@ static double CalculateMetaTripToMemory(
}
#ifdef __DML_VBA_DEBUG__
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
dml2_printf("DML::%s: qos_type = %d\n", __func__, qos_type);
dml2_printf("DML::%s: meta_trip_to_memory_fclk_cycles = %d\n", __func__, meta_trip_to_memory_fclk_cycles);
dml2_printf("DML::%s: meta_trip_to_memory_uclk_cycles = %d\n", __func__, meta_trip_to_memory_uclk_cycles);
@@ -3781,8 +3815,8 @@ static void CalculateSwathAndDETConfiguration(struct dml2_core_internal_scratch
p->SwathHeightC[k] = MaximumSwathHeightC[k] / 2;
RoundedUpSwathSizeBytesY[k] = p->full_swath_bytes_l[k] / 2;
RoundedUpSwathSizeBytesC[k] = p->full_swath_bytes_c[k] / 2;
- p->request_size_bytes_luma[k] = ((p->BytePerPixY[k] == 2) == dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) ? 128 : 64;;
- p->request_size_bytes_chroma[k] = ((p->BytePerPixC[k] == 2) == dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) ? 128 : 64;;
+ p->request_size_bytes_luma[k] = ((p->BytePerPixY[k] == 2) == dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) ? 128 : 64;
+ p->request_size_bytes_chroma[k] = ((p->BytePerPixC[k] == 2) == dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) ? 128 : 64;
}
if (p->SwathHeightC[k] == 0)
@@ -3841,7 +3875,7 @@ static void CalculateSwathAndDETConfiguration(struct dml2_core_internal_scratch
*p->compbuf_reserved_space_64b = 2 * p->pixel_chunk_size_kbytes * 1024 / 64;
if (*p->UnboundedRequestEnabled) {
*p->compbuf_reserved_space_64b = (unsigned int)math_ceil2(math_max2(*p->compbuf_reserved_space_64b,
- (double)(p->rob_buffer_size_kbytes * 1024 / 64) - (double)(RoundedUpSwathSizeBytesY[SurfaceDoingUnboundedRequest] * TTUFIFODEPTH / 64)), 1.0);
+ (double)(p->rob_buffer_size_kbytes * 1024 / 64) - (double)(RoundedUpSwathSizeBytesY[SurfaceDoingUnboundedRequest] * TTUFIFODEPTH / (p->mrq_present ? MAXIMUMCOMPRESSION : 1) / 64)), 1.0);
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: RoundedUpSwathSizeBytesY[%d] = %u\n", __func__, SurfaceDoingUnboundedRequest, RoundedUpSwathSizeBytesY[SurfaceDoingUnboundedRequest]);
dml2_printf("DML::%s: rob_buffer_size_kbytes = %u\n", __func__, p->rob_buffer_size_kbytes);
@@ -3852,21 +3886,20 @@ static void CalculateSwathAndDETConfiguration(struct dml2_core_internal_scratch
#endif
*p->hw_debug5 = false;
- if (!p->mrq_present) {
- for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
- if (!(*p->UnboundedRequestEnabled)
- && p->display_cfg->plane_descriptors[k].surface.dcc.enable
- && ((p->rob_buffer_size_kbytes * 1024 + *p->CompressedBufferSizeInkByte * MAXIMUMCOMPRESSION * 1024) > TTUFIFODEPTH * (RoundedUpSwathSizeBytesY[k] + RoundedUpSwathSizeBytesC[k])))
- *p->hw_debug5 = true;
-#ifdef __DML_VBA_DEBUG__
- dml2_printf("DML::%s: k=%u UnboundedRequestEnabled = %u\n", __func__, k, *p->UnboundedRequestEnabled);
- dml2_printf("DML::%s: k=%u MAXIMUMCOMPRESSION = %lu\n", __func__, k, MAXIMUMCOMPRESSION);
- dml2_printf("DML::%s: k=%u TTUFIFODEPTH = %lu\n", __func__, k, TTUFIFODEPTH);
- dml2_printf("DML::%s: k=%u CompressedBufferSizeInkByte = %u\n", __func__, k, *p->CompressedBufferSizeInkByte);
- dml2_printf("DML::%s: k=%u RoundedUpSwathSizeBytesC = %u\n", __func__, k, RoundedUpSwathSizeBytesC[k]);
- dml2_printf("DML::%s: k=%u hw_debug5 = %u\n", __func__, k, *p->hw_debug5);
+ for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
+ if (!(p->mrq_present) && (!(*p->UnboundedRequestEnabled)) && (TotalActiveDPP == 1)
+ && p->display_cfg->plane_descriptors[k].surface.dcc.enable
+ && ((p->rob_buffer_size_kbytes * 1024 * (p->mrq_present ? MAXIMUMCOMPRESSION : 1)
+ + *p->CompressedBufferSizeInkByte * MAXIMUMCOMPRESSION * 1024) > TTUFIFODEPTH * (RoundedUpSwathSizeBytesY[k] + RoundedUpSwathSizeBytesC[k])))
+ *p->hw_debug5 = true;
+#ifdef __DML_VBA_DEBUG__
+ dml2_printf("DML::%s: k=%u UnboundedRequestEnabled = %u\n", __func__, k, *p->UnboundedRequestEnabled);
+ dml2_printf("DML::%s: k=%u MAXIMUMCOMPRESSION = %lu\n", __func__, k, MAXIMUMCOMPRESSION);
+ dml2_printf("DML::%s: k=%u TTUFIFODEPTH = %lu\n", __func__, k, TTUFIFODEPTH);
+ dml2_printf("DML::%s: k=%u CompressedBufferSizeInkByte = %u\n", __func__, k, *p->CompressedBufferSizeInkByte);
+ dml2_printf("DML::%s: k=%u RoundedUpSwathSizeBytesC = %u\n", __func__, k, RoundedUpSwathSizeBytesC[k]);
+ dml2_printf("DML::%s: k=%u hw_debug5 = %u\n", __func__, k, *p->hw_debug5);
#endif
- }
}
}
@@ -4559,15 +4592,6 @@ static void calculate_tdlut_setting(
return;
}
-
- if (!p->setup_for_tdlut) {
- *p->tdlut_groups_per_2row_ub = 0;
- *p->tdlut_opt_time = 0;
- *p->tdlut_drain_time = 0;
- *p->tdlut_bytes_per_group = 0;
- return;
- }
-
if (p->tdlut_mpc_width_flag) {
tdlut_mpc_width = 33;
tdlut_bytes_per_group_simple = 39*256;
@@ -4616,7 +4640,7 @@ static void calculate_tdlut_setting(
*p->tdlut_bytes_per_group = tdlut_bytes_per_line * tdlut_mpc_width;
//the delivery cycles is DispClk cycles per line * number of lines * number of slices
tdlut_delivery_cycles = (unsigned int)math_ceil2(tdlut_mpc_width/2.0, 1) * tdlut_mpc_width * tdlut_mpc_width;
- tdlut_drain_rate = tdlut_bytes_per_line * p->dispclk_mhz / 9.0;
+ tdlut_drain_rate = tdlut_bytes_per_line * p->dispclk_mhz / math_ceil2(tdlut_mpc_width/2.0, 1);
} else {
//tdlut_addressing_mode = tdlut_simple_linear, 3dlut width should be 4*1229=4916 elements
*p->tdlut_bytes_per_frame = (unsigned int)math_ceil2(tdlut_width * tdlut_bpe, 256);
@@ -4627,7 +4651,7 @@ static void calculate_tdlut_setting(
//the tdlut is fetched during the 2 row times of prefetch.
if (p->setup_for_tdlut) {
- *p->tdlut_groups_per_2row_ub = (unsigned int)math_ceil2(*p->tdlut_bytes_per_frame / *p->tdlut_bytes_per_group, 1);
+ *p->tdlut_groups_per_2row_ub = (unsigned int)math_ceil2((double) *p->tdlut_bytes_per_frame / *p->tdlut_bytes_per_group, 1);
*p->tdlut_opt_time = (*p->tdlut_bytes_per_frame - p->cursor_buffer_size * 1024) / tdlut_drain_rate;
*p->tdlut_drain_time = p->cursor_buffer_size * 1024 / tdlut_drain_rate;
}
@@ -4640,7 +4664,7 @@ static void calculate_tdlut_setting(
dml2_printf("DML::%s: dispclk_mhz = %f\n", __func__, p->dispclk_mhz);
dml2_printf("DML::%s: tdlut_width = %u\n", __func__, tdlut_width);
- dml2_printf("DML::%s: tdlut_addressing_mode = %u\n", __func__, p->tdlut_addressing_mode);
+ dml2_printf("DML::%s: tdlut_addressing_mode = %s\n", __func__, (p->tdlut_addressing_mode == dml2_tdlut_sw_linear) ? "sw_linear" : "simple_linear");
dml2_printf("DML::%s: tdlut_pitch_bytes = %u\n", __func__, tdlut_pitch_bytes);
dml2_printf("DML::%s: tdlut_footprint_bytes = %u\n", __func__, tdlut_footprint_bytes);
dml2_printf("DML::%s: tdlut_bytes_per_frame = %u\n", __func__, *p->tdlut_bytes_per_frame);
@@ -4706,11 +4730,12 @@ static void CalculateTarb(
static double CalculateTWait(
long reserved_vblank_time_ns,
double UrgentLatency,
- double Ttrip)
+ double Ttrip,
+ double g6_temp_read_blackout_us)
{
double TWait;
double t_urg_trip = math_max2(UrgentLatency, Ttrip);
- TWait = reserved_vblank_time_ns/1000.0 + t_urg_trip;
+ TWait = math_max2(reserved_vblank_time_ns/1000.0, g6_temp_read_blackout_us) + t_urg_trip;
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: reserved_vblank_time_ns = %d\n", __func__, reserved_vblank_time_ns);
@@ -4858,13 +4883,23 @@ static double get_urgent_bandwidth_required(
}
if (!exclude_this_plane) {
- surface_required_bw[k] = math_max4(NumberOfDPP[k] * prefetch_vmrow_bw[k],
- l->per_plane_flip_bw[k] + ReadBandwidthLuma[k] * l->adj_factor_p0 + ReadBandwidthChroma[k] * l->adj_factor_p1 + cursor_bw[k] * l->adj_factor_cur,
- l->per_plane_flip_bw[k] + NumberOfDPP[k] * (PrefetchBandwidthLuma[k] * l->adj_factor_p0_pre + PrefetchBandwidthChroma[k] * l->adj_factor_p1_pre) + prefetch_cursor_bw[k] * l->adj_factor_cur_pre,
- (ReadBandwidthLuma[k] + excess_vactive_fill_bw_l[k]) * l->tmp_nom_adj_factor_p0 + (ReadBandwidthChroma[k] + excess_vactive_fill_bw_c[k]) * l->tmp_nom_adj_factor_p1 + dpte_row_bw[k] + meta_row_bw[k]);
+ l->vm_row_bw = NumberOfDPP[k] * prefetch_vmrow_bw[k];
+ l->flip_and_active_bw = l->per_plane_flip_bw[k] + ReadBandwidthLuma[k] * l->adj_factor_p0 + ReadBandwidthChroma[k] * l->adj_factor_p1 + cursor_bw[k] * l->adj_factor_cur;
+ l->flip_and_prefetch_bw = l->per_plane_flip_bw[k] + NumberOfDPP[k] * (PrefetchBandwidthLuma[k] * l->adj_factor_p0_pre + PrefetchBandwidthChroma[k] * l->adj_factor_p1_pre) + prefetch_cursor_bw[k] * l->adj_factor_cur_pre;
+ l->active_and_excess_bw = (ReadBandwidthLuma[k] + excess_vactive_fill_bw_l[k]) * l->tmp_nom_adj_factor_p0 + (ReadBandwidthChroma[k] + excess_vactive_fill_bw_c[k]) * l->tmp_nom_adj_factor_p1 + dpte_row_bw[k] + meta_row_bw[k];
+ surface_required_bw[k] = math_max4(l->vm_row_bw, l->flip_and_active_bw, l->flip_and_prefetch_bw, l->active_and_excess_bw);
/* export peak required bandwidth for the surface */
surface_peak_required_bw[k] = math_max2(surface_required_bw[k], surface_peak_required_bw[k]);
+
+#ifdef __DML_VBA_DEBUG__
+ dml2_printf("DML::%s: k=%d, max1: vm_row_bw=%f\n", __func__, k, l->vm_row_bw);
+ dml2_printf("DML::%s: k=%d, max2: flip_and_active_bw=%f\n", __func__, k, l->flip_and_active_bw);
+ dml2_printf("DML::%s: k=%d, max3: flip_and_prefetch_bw=%f\n", __func__, k, l->flip_and_prefetch_bw);
+ dml2_printf("DML::%s: k=%d, max4: active_and_excess_bw=%f\n", __func__, k, l->active_and_excess_bw);
+ dml2_printf("DML::%s: k=%d, surface_required_bw=%f\n", __func__, k, surface_required_bw[k]);
+ dml2_printf("DML::%s: k=%d, surface_peak_required_bw=%f\n", __func__, k, surface_peak_required_bw[k]);
+#endif
} else {
surface_required_bw[k] = 0.0;
}
@@ -4873,6 +4908,8 @@ static double get_urgent_bandwidth_required(
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: k=%d, NumberOfDPP=%d\n", __func__, k, NumberOfDPP[k]);
+ dml2_printf("DML::%s: k=%d, use_qual_row_bw=%d\n", __func__, k, use_qual_row_bw);
+ dml2_printf("DML::%s: k=%d, immediate_flip=%d\n", __func__, k, display_cfg->plane_descriptors[k].immediate_flip);
dml2_printf("DML::%s: k=%d, mall_svp_prefetch_factor=%f\n", __func__, k, l->mall_svp_prefetch_factor);
dml2_printf("DML::%s: k=%d, adj_factor_p0=%f\n", __func__, k, l->adj_factor_p0);
dml2_printf("DML::%s: k=%d, adj_factor_p1=%f\n", __func__, k, l->adj_factor_p1);
@@ -4886,6 +4923,8 @@ static double get_urgent_bandwidth_required(
dml2_printf("DML::%s: k=%d, prefetch_vmrow_bw=%f\n", __func__, k, prefetch_vmrow_bw[k]);
dml2_printf("DML::%s: k=%d, ReadBandwidthLuma=%f\n", __func__, k, ReadBandwidthLuma[k]);
dml2_printf("DML::%s: k=%d, ReadBandwidthChroma=%f\n", __func__, k, ReadBandwidthChroma[k]);
+ dml2_printf("DML::%s: k=%d, excess_vactive_fill_bw_l=%f\n", __func__, k, excess_vactive_fill_bw_l[k]);
+ dml2_printf("DML::%s: k=%d, excess_vactive_fill_bw_c=%f\n", __func__, k, excess_vactive_fill_bw_c[k]);
dml2_printf("DML::%s: k=%d, cursor_bw=%f\n", __func__, k, cursor_bw[k]);
dml2_printf("DML::%s: k=%d, meta_row_bw=%f\n", __func__, k, meta_row_bw[k]);
@@ -4964,7 +5003,7 @@ static void CalculateExtraLatency(
max_request_size_bytes = request_size_bytes_chroma[k];
}
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
*ExtraLatency_sr = dchub_arb_to_ret_delay / DCFCLK;
*ExtraLatency = *ExtraLatency_sr;
if (max_oustanding_when_urgent_expected)
@@ -4980,11 +5019,14 @@ static void CalculateExtraLatency(
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: qos_type=%u\n", __func__, qos_type);
+ dml2_printf("DML::%s: hostvm_mode=%u\n", __func__, hostvm_mode);
+ dml2_printf("DML::%s: Tex_trips=%u\n", __func__, Tex_trips);
dml2_printf("DML::%s: max_oustanding_when_urgent_expected=%u\n", __func__, max_oustanding_when_urgent_expected);
dml2_printf("DML::%s: FabricClock=%f\n", __func__, FabricClock);
dml2_printf("DML::%s: DCFCLK=%f\n", __func__, DCFCLK);
dml2_printf("DML::%s: ReturnBW=%f\n", __func__, ReturnBW);
dml2_printf("DML::%s: RoundTripPingLatencyCycles=%u\n", __func__, RoundTripPingLatencyCycles);
+ dml2_printf("DML::%s: ReorderingBytes=%u\n", __func__, ReorderingBytes);
dml2_printf("DML::%s: Tarb=%f\n", __func__, Tarb);
dml2_printf("DML::%s: ExtraLatency=%f\n", __func__, *ExtraLatency);
dml2_printf("DML::%s: ExtraLatency_sr=%f\n", __func__, *ExtraLatency_sr);
@@ -5021,6 +5063,8 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
s->trip_to_mem = 0.0;
*p->Tvm_trips = 0.0;
*p->Tr0_trips = 0.0;
+ s->Tvm_no_trip_oto = 0.0;
+ s->Tr0_no_trip_oto = 0.0;
s->Tvm_trips_rounded = 0.0;
s->Tr0_trips_rounded = 0.0;
s->max_Tsw = 0.0;
@@ -5037,7 +5081,9 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
s->bytes_pp = 0.0;
s->dep_bytes = 0.0;
s->min_Lsw_oto = 0.0;
+ s->min_Lsw_equ = 0.0;
s->Tsw_est1 = 0.0;
+ s->Tsw_est2 = 0.0;
s->Tsw_est3 = 0.0;
s->cursor_prefetch_bytes = 0;
*p->prefetch_cursor_bw = 0;
@@ -5059,7 +5105,6 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
dml2_printf("DML::%s: GPUVMPageTableLevels = %u\n", __func__, p->display_cfg->gpuvm_max_page_table_levels);
dml2_printf("DML::%s: DCCEnable = %u\n", __func__, p->myPipe->DCCEnable);
dml2_printf("DML::%s: VStartup = %u\n", __func__, p->VStartup);
- dml2_printf("DML::%s: MaxVStartup = %u\n", __func__, p->MaxVStartup);
dml2_printf("DML::%s: HostVMEnable = %u\n", __func__, p->display_cfg->hostvm_enable);
dml2_printf("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, p->HostVMInefficiencyFactor);
dml2_printf("DML::%s: TWait = %f\n", __func__, p->TWait);
@@ -5092,21 +5137,15 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
s->LineTime = p->myPipe->HTotal / p->myPipe->PixelClock;
s->trip_to_mem = p->Ttrip;
-#ifdef DML_TVM_UPDATE_EN
*p->Tvm_trips = p->ExtraLatencyPrefetch + math_max2(s->trip_to_mem * (p->display_cfg->gpuvm_max_page_table_levels * (s->HostVMDynamicLevelsTrips + 1)), p->Turg);
if (dcc_mrq_enable)
*p->Tvm_trips_flip = *p->Tvm_trips;
else
*p->Tvm_trips_flip = *p->Tvm_trips - s->trip_to_mem;
-#else
- *p->Tvm_trips = p->ExtraLatencyPrefetch + s->trip_to_mem * (p->display_cfg->gpuvm_max_page_table_levels * (s->HostVMDynamicLevelsTrips + 1));
- *p->Tvm_trips_flip = *p->Tvm_trips - s->trip_to_mem;
-#endif
*p->Tr0_trips_flip = s->trip_to_mem * (s->HostVMDynamicLevelsTrips + 1);
*p->Tr0_trips = math_max2(*p->Tr0_trips_flip, p->tdlut_opt_time / 2);
-#ifdef DML_TVM_UPDATE_EN
if (p->DynamicMetadataVMEnabled == true) {
*p->Tdmdl_vm = s->TWait_p + *p->Tvm_trips;
*p->Tdmdl = *p->Tdmdl_vm + p->Ttrip;
@@ -5114,15 +5153,6 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
*p->Tdmdl_vm = 0;
*p->Tdmdl = s->TWait_p + p->ExtraLatencyPrefetch + p->Ttrip; // Tex
}
-#else
- if (p->DynamicMetadataVMEnabled == true) {
- *p->Tdmdl_vm = s->TWait_p + *p->Tvm_trips;
- *p->Tdmdl = *p->Tdmdl_vm + p->Ttrip;
- } else {
- *p->Tdmdl_vm = 0;
- *p->Tdmdl = p->TWait + p->ExtraLatencyPrefetch; // Tex
- }
-#endif
if (p->DynamicMetadataEnable == true) {
if (p->VStartup * s->LineTime < *p->TSetup + *p->Tdmdl + s->Tdmbf + s->Tdmec + s->Tdmsks) {
@@ -5186,7 +5216,6 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
dml2_printf("DML::%s: DSTYAfterScaler = %u (final)\n", __func__, *p->DSTYAfterScaler);
#endif
- s->NoTimeToPrefetch = false;
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: Tr0_trips = %f\n", __func__, *p->Tr0_trips);
dml2_printf("DML::%s: Tvm_trips = %f\n", __func__, *p->Tvm_trips);
@@ -5199,14 +5228,10 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
s->Tvm_trips_rounded = math_ceil2(4.0 * *p->Tvm_trips / s->LineTime, 1.0) / 4.0 * s->LineTime;
*p->Tvm_trips_flip_rounded = math_ceil2(4.0 * *p->Tvm_trips_flip / s->LineTime, 1.0) / 4.0 * s->LineTime;
} else {
-#ifdef DML_TVM_UPDATE_EN
if (p->DynamicMetadataEnable || dcc_mrq_enable || p->setup_for_tdlut)
s->Tvm_trips_rounded = math_max2(s->LineTime * math_ceil2(4.0*math_max3(p->ExtraLatencyPrefetch, p->Turg, s->trip_to_mem)/s->LineTime, 1)/4, s->LineTime/4.0);
else
- s->Tvm_trips_rounded = s->LineTime / 4.0;
-#else
- s->Tvm_trips_rounded = s->LineTime / 4.0;
-#endif
+ s->Tvm_trips_rounded = s->LineTime / 4.0;
*p->Tvm_trips_flip_rounded = s->LineTime / 4.0;
}
@@ -5235,16 +5260,10 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
*p->Tno_bw = 0;
}
-#ifdef DML_TVM_UPDATE_EN
if (p->mrq_present || p->display_cfg->gpuvm_max_page_table_levels >= 3)
*p->Tno_bw_flip = *p->Tno_bw;
else
*p->Tno_bw_flip = 0; //because there is no 3DLUT for iFlip
-#else
- *p->Tno_bw_flip = 0;
- if (p->display_cfg->gpuvm_enable == true)
- *p->Tno_bw_flip = *p->Tno_bw;
-#endif
if (dml_is_420(p->myPipe->SourcePixelFormat)) {
s->bytes_pp = p->myPipe->BytePerPixelY + p->myPipe->BytePerPixelC / 4.0;
@@ -5258,64 +5277,63 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
s->max_Tsw = (math_max2(p->PrefetchSourceLinesY, p->PrefetchSourceLinesC) * s->LineTime);
s->prefetch_sw_bytes = p->PrefetchSourceLinesY * p->swath_width_luma_ub * p->myPipe->BytePerPixelY + p->PrefetchSourceLinesC * p->swath_width_chroma_ub * p->myPipe->BytePerPixelC;
-#ifdef DML_TDLUT_ROW_BYTES_FIX_EN
s->prefetch_bw_pr = s->prefetch_bw_pr * p->mall_prefetch_sdp_overhead_factor;
s->prefetch_sw_bytes = s->prefetch_sw_bytes * p->mall_prefetch_sdp_overhead_factor;
-#endif
s->prefetch_bw_oto = math_max2(s->prefetch_bw_pr, s->prefetch_sw_bytes / s->max_Tsw);
s->min_Lsw_oto = math_max2(p->PrefetchSourceLinesY, p->PrefetchSourceLinesC) / __DML2_CALCS_MAX_VRATIO_PRE_OTO__;
s->min_Lsw_oto = math_max2(s->min_Lsw_oto, 2.0);
s->min_Lsw_oto = math_max2(s->min_Lsw_oto, p->tdlut_drain_time / s->LineTime);
+ s->min_Lsw_equ = math_max2(p->PrefetchSourceLinesY, p->PrefetchSourceLinesC) / __DML2_CALCS_MAX_VRATIO_PRE_EQU__;
+ s->min_Lsw_equ = math_max2(s->min_Lsw_equ, 2.0);
+ s->min_Lsw_equ = math_max2(s->min_Lsw_equ, p->tdlut_drain_time / s->LineTime);
+
vm_bytes = p->vm_bytes; // vm_bytes is dpde0_bytes_per_frame_ub_l + dpde0_bytes_per_frame_ub_c + 2*extra_dpde_bytes;
extra_tdpe_bytes = (unsigned int)math_max2(0, (p->display_cfg->gpuvm_max_page_table_levels - 1) * 128);
if (p->setup_for_tdlut)
vm_bytes = vm_bytes + p->tdlut_pte_bytes_per_frame + (p->display_cfg->gpuvm_enable ? extra_tdpe_bytes : 0);
-#ifdef DML_TDLUT_ROW_BYTES_FIX_EN
tdlut_row_bytes = (unsigned long) math_ceil2(p->tdlut_bytes_per_frame/2.0, 1.0);
-#else
- tdlut_row_bytes = p->tdlut_pte_bytes_per_frame;
-#endif
-#ifdef DML_REG_LIMIT_CLAMP_EN
s->prefetch_bw_oto = math_max3(s->prefetch_bw_oto,
p->vm_bytes * p->HostVMInefficiencyFactor / (31 * s->LineTime) - *p->Tno_bw,
(p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / (15 * s->LineTime));
-#endif
s->Lsw_oto = math_ceil2(4.0 * math_max2(s->prefetch_sw_bytes / s->prefetch_bw_oto / s->LineTime, s->min_Lsw_oto), 1.0) / 4.0;
if (p->display_cfg->gpuvm_enable == true) {
- s->Tvm_oto = math_max3(
- *p->Tvm_trips,
+ s->Tvm_no_trip_oto = math_max2(
*p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw_oto,
s->LineTime / 4.0);
+ s->Tvm_oto = math_max2(
+ *p->Tvm_trips,
+ s->Tvm_no_trip_oto);
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: Tvm_oto max0 = %f\n", __func__, *p->Tvm_trips);
dml2_printf("DML::%s: Tvm_oto max1 = %f\n", __func__, *p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw_oto);
dml2_printf("DML::%s: Tvm_oto max2 = %f\n", __func__, s->LineTime / 4.0);
#endif
} else {
-#ifdef DML_TVM_UPDATE_EN
+ s->Tvm_no_trip_oto = s->Tvm_trips_rounded;
s->Tvm_oto = s->Tvm_trips_rounded;
-#else
- s->Tvm_oto = s->LineTime / 4.0;
-#endif
}
if ((p->display_cfg->gpuvm_enable == true || p->setup_for_tdlut || dcc_mrq_enable)) {
- s->Tr0_oto = math_max3(
- *p->Tr0_trips,
+ s->Tr0_no_trip_oto = math_max2(
(p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / s->prefetch_bw_oto,
s->LineTime / 4.0);
+ s->Tr0_oto = math_max2(
+ *p->Tr0_trips,
+ s->Tr0_no_trip_oto);
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: Tr0_oto max0 = %f\n", __func__, *p->Tr0_trips);
dml2_printf("DML::%s: Tr0_oto max1 = %f\n", __func__, (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / s->prefetch_bw_oto);
dml2_printf("DML::%s: Tr0_oto max2 = %f\n", __func__, s->LineTime / 4);
#endif
- } else
- s->Tr0_oto = (s->LineTime - s->Tvm_oto) / 4.0;
+ } else {
+ s->Tr0_no_trip_oto = (s->LineTime - s->Tvm_oto) / 4.0;
+ s->Tr0_oto = s->Tr0_no_trip_oto;
+ }
s->Tvm_oto_lines = math_ceil2(4.0 * s->Tvm_oto / s->LineTime, 1) / 4.0;
s->Tr0_oto_lines = math_ceil2(4.0 * s->Tr0_oto / s->LineTime, 1) / 4.0;
@@ -5325,19 +5343,16 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
Lo = (unsigned int)(*p->DSTYAfterScaler + (double)*p->DSTXAfterScaler / (double)p->myPipe->HTotal);
//Tpre_equ in line time
-#ifdef DML_TVM_UPDATE_EN
if (p->DynamicMetadataVMEnabled && p->DynamicMetadataEnable)
s->dst_y_prefetch_equ = p->VStartup - (*p->TSetup + math_max2(p->TCalc, *p->Tvm_trips) + s->TWait_p) / s->LineTime - Lo;
else
s->dst_y_prefetch_equ = p->VStartup - (*p->TSetup + math_max2(p->TCalc, p->ExtraLatencyPrefetch) + s->TWait_p) / s->LineTime - Lo;
-#else
- s->dst_y_prefetch_equ = p->VStartup - (*p->TSetup + math_max2(s->TWait_p + p->TCalc, *p->Tdmdl - p->Ttrip)) / s->LineTime - Lo;
-#endif
s->dst_y_prefetch_equ = math_min2(s->dst_y_prefetch_equ, 63.75); // limit to the reg limit of U6.2 for DST_Y_PREFETCH
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: HTotal = %u\n", __func__, p->myPipe->HTotal);
dml2_printf("DML::%s: min_Lsw_oto = %f\n", __func__, s->min_Lsw_oto);
+ dml2_printf("DML::%s: min_Lsw_equ = %f\n", __func__, s->min_Lsw_equ);
dml2_printf("DML::%s: Tno_bw = %f\n", __func__, *p->Tno_bw);
dml2_printf("DML::%s: Tno_bw_flip = %f\n", __func__, *p->Tno_bw_flip);
dml2_printf("DML::%s: ExtraLatencyPrefetch = %f\n", __func__, p->ExtraLatencyPrefetch);
@@ -5375,6 +5390,7 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
s->dst_y_prefetch_equ = math_floor2(4.0 * (s->dst_y_prefetch_equ + 0.125), 1) / 4.0;
s->Tpre_rounded = s->dst_y_prefetch_equ * s->LineTime;
+#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: dst_y_prefetch_equ: %f (after round)\n", __func__, s->dst_y_prefetch_equ);
dml2_printf("DML::%s: LineTime: %f\n", __func__, s->LineTime);
dml2_printf("DML::%s: VStartup: %u\n", __func__, p->VStartup);
@@ -5395,18 +5411,12 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
dml2_printf("DML::%s: Ttrip: %fus\n", __func__, p->Ttrip);
dml2_printf("DML::%s: DSTXAfterScaler: %u pixels - number of pixel clocks pipeline and buffer delay after scaler \n", __func__, *p->DSTXAfterScaler);
dml2_printf("DML::%s: DSTYAfterScaler: %u lines - number of lines of pipeline and buffer delay after scaler \n", __func__, *p->DSTYAfterScaler);
-
- s->dep_bytes = math_max2(vm_bytes * p->HostVMInefficiencyFactor, p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes);
-
- dml2_printf("DML::%s: dep_bytes: %f\n", __func__, s->dep_bytes);
- dml2_printf("DML::%s: prefetch_sw_bytes: %f\n", __func__, s->prefetch_sw_bytes);
dml2_printf("DML::%s: vm_bytes: %f (hvm inefficiency scaled)\n", __func__, vm_bytes*p->HostVMInefficiencyFactor);
dml2_printf("DML::%s: row_bytes: %f (hvm inefficiency scaled, 1 row)\n", __func__, p->PixelPTEBytesPerRow*p->HostVMInefficiencyFactor+p->meta_row_bytes+tdlut_row_bytes);
-
- if (s->prefetch_sw_bytes < s->dep_bytes) {
- s->prefetch_sw_bytes = 2 * s->dep_bytes;
- dml2_printf("DML::%s: bump prefetch_sw_bytes to %f\n", __func__, s->prefetch_sw_bytes);
- }
+ dml2_printf("DML::%s: Tno_bw: %f\n", __func__, *p->Tno_bw);
+ dml2_printf("DML::%s: Tpre=%f Tpre_rounded: %f, delta=%f\n", __func__, Tpre, s->Tpre_rounded, (s->Tpre_rounded - Tpre));
+ dml2_printf("DML::%s: Tvm_trips=%f Tvm_trips_rounded: %f, delta=%f\n", __func__, *p->Tvm_trips, s->Tvm_trips_rounded, (s->Tvm_trips_rounded - *p->Tvm_trips));
+#endif
*p->dst_y_per_vm_vblank = 0;
*p->dst_y_per_row_vblank = 0;
@@ -5419,7 +5429,9 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
// Tvm_trips_rounded is Tvm_trips ceiling to 1/4 line time
// Tr0_trips_rounded is Tr0_trips ceiling to 1/4 line time
// So that means prefetch bw calculated can be higher since the total time availabe for prefetch is less
- if (s->dst_y_prefetch_equ > 1) {
+ bool min_Lsw_equ_ok = s->Tpre_rounded >= s->Tvm_trips_rounded + 2.0*s->Tr0_trips_rounded + s->min_Lsw_equ*s->LineTime;
+
+ if (s->dst_y_prefetch_equ > 1 && min_Lsw_equ_ok) {
s->prefetch_bw1 = 0.;
s->prefetch_bw2 = 0.;
s->prefetch_bw3 = 0.;
@@ -5436,28 +5448,35 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
s->prefetch_bw1 = 0;
dml2_printf("DML::%s: prefetch_bw1: %f\n", __func__, s->prefetch_bw1);
- if ((p->VStartup == p->MaxVStartup) && (s->Tsw_est1 / s->LineTime < s->min_Lsw_oto) && (s->Tpre_rounded - s->min_Lsw_oto * s->LineTime - 0.75 * s->LineTime - *p->Tno_bw > 0)) {
+ if ((s->Tsw_est1 < s->min_Lsw_equ * s->LineTime) && (s->Tpre_rounded - s->min_Lsw_equ * s->LineTime - 0.75 * s->LineTime - *p->Tno_bw > 0)) {
s->prefetch_bw1 = (vm_bytes * p->HostVMInefficiencyFactor + 2 * (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes)) /
- (s->Tpre_rounded - s->min_Lsw_oto * s->LineTime - 0.75 * s->LineTime - *p->Tno_bw);
+ (s->Tpre_rounded - s->min_Lsw_equ * s->LineTime - 0.75 * s->LineTime - *p->Tno_bw);
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: vm and 2 rows bytes = %f\n", __func__, (vm_bytes * p->HostVMInefficiencyFactor + 2 * (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes)));
dml2_printf("DML::%s: Tpre_rounded = %f\n", __func__, s->Tpre_rounded);
- dml2_printf("DML::%s: minus term = %f\n", __func__, s->min_Lsw_oto * s->LineTime + 0.75 * s->LineTime + *p->Tno_bw);
- dml2_printf("DML::%s: min_Lsw_oto = %f\n", __func__, s->min_Lsw_oto);
+ dml2_printf("DML::%s: minus term = %f\n", __func__, s->min_Lsw_equ * s->LineTime + 0.75 * s->LineTime + *p->Tno_bw);
+ dml2_printf("DML::%s: min_Lsw_equ = %f\n", __func__, s->min_Lsw_equ);
dml2_printf("DML::%s: LineTime = %f\n", __func__, s->LineTime);
dml2_printf("DML::%s: Tno_bw = %f\n", __func__, *p->Tno_bw);
- dml2_printf("DML::%s: Time to fetch vm and 2 rows = %f\n", __func__, (s->Tpre_rounded - s->min_Lsw_oto * s->LineTime - 0.75 * s->LineTime - *p->Tno_bw));
+ dml2_printf("DML::%s: Time to fetch vm and 2 rows = %f\n", __func__, (s->Tpre_rounded - s->min_Lsw_equ * s->LineTime - 0.75 * s->LineTime - *p->Tno_bw));
dml2_printf("DML::%s: prefetch_bw1: %f (updated)\n", __func__, s->prefetch_bw1);
#endif
}
// prefetch_bw2: VM + SW
- if (s->Tpre_rounded - *p->Tno_bw - 2 * s->Tr0_trips_rounded > 0)
+ if (s->Tpre_rounded - *p->Tno_bw - 2.0 * s->Tr0_trips_rounded > 0) {
s->prefetch_bw2 = (vm_bytes * p->HostVMInefficiencyFactor + s->prefetch_sw_bytes) /
- (s->Tpre_rounded - *p->Tno_bw - 2 * s->Tr0_trips_rounded);
- else
+ (s->Tpre_rounded - *p->Tno_bw - 2.0 * s->Tr0_trips_rounded);
+ s->Tsw_est2 = s->prefetch_sw_bytes / s->prefetch_bw2;
+ } else
s->prefetch_bw2 = 0;
+ dml2_printf("DML::%s: prefetch_bw2: %f\n", __func__, s->prefetch_bw2);
+ if ((s->Tsw_est2 < s->min_Lsw_equ * s->LineTime) && ((s->Tpre_rounded - *p->Tno_bw - 2.0 * s->Tr0_trips_rounded - s->min_Lsw_equ * s->LineTime - 0.25 * s->LineTime) > 0)) {
+ s->prefetch_bw2 = vm_bytes * p->HostVMInefficiencyFactor / (s->Tpre_rounded - *p->Tno_bw - 2.0 * s->Tr0_trips_rounded - s->min_Lsw_equ * s->LineTime - 0.25 * s->LineTime);
+ dml2_printf("DML::%s: prefetch_bw2: %f (updated)\n", __func__, s->prefetch_bw2);
+ }
+
// prefetch_bw3: 2*R0 + SW
if (s->Tpre_rounded - s->Tvm_trips_rounded > 0) {
s->prefetch_bw3 = (2 * (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) + s->prefetch_sw_bytes) /
@@ -5467,8 +5486,8 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
s->prefetch_bw3 = 0;
dml2_printf("DML::%s: prefetch_bw3: %f\n", __func__, s->prefetch_bw3);
- if (p->VStartup == p->MaxVStartup && (s->Tsw_est3 / s->LineTime < s->min_Lsw_oto) && ((s->Tpre_rounded - s->min_Lsw_oto * s->LineTime - 0.5 * s->LineTime - s->Tvm_trips_rounded) > 0)) {
- s->prefetch_bw3 = (2 * (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes)) / (s->Tpre_rounded - s->min_Lsw_oto * s->LineTime - 0.5 * s->LineTime - s->Tvm_trips_rounded);
+ if ((s->Tsw_est3 < s->min_Lsw_equ * s->LineTime) && ((s->Tpre_rounded - s->min_Lsw_equ * s->LineTime - 0.5 * s->LineTime - s->Tvm_trips_rounded) > 0)) {
+ s->prefetch_bw3 = (2 * (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes)) / (s->Tpre_rounded - s->min_Lsw_equ * s->LineTime - 0.5 * s->LineTime - s->Tvm_trips_rounded);
dml2_printf("DML::%s: prefetch_bw3: %f (updated)\n", __func__, s->prefetch_bw3);
}
@@ -5484,6 +5503,7 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
dml2_printf("DML::%s: Tvm_trips=%f Tvm_trips_rounded: %f, delta=%f\n", __func__, *p->Tvm_trips, s->Tvm_trips_rounded, (s->Tvm_trips_rounded - *p->Tvm_trips));
dml2_printf("DML::%s: Tr0_trips=%f Tr0_trips_rounded: %f, delta=%f\n", __func__, *p->Tr0_trips, s->Tr0_trips_rounded, (s->Tr0_trips_rounded - *p->Tr0_trips));
dml2_printf("DML::%s: Tsw_est1: %f\n", __func__, s->Tsw_est1);
+ dml2_printf("DML::%s: Tsw_est2: %f\n", __func__, s->Tsw_est2);
dml2_printf("DML::%s: Tsw_est3: %f\n", __func__, s->Tsw_est3);
dml2_printf("DML::%s: prefetch_bw1: %f (final)\n", __func__, s->prefetch_bw1);
dml2_printf("DML::%s: prefetch_bw2: %f (final)\n", __func__, s->prefetch_bw2);
@@ -5504,9 +5524,18 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
// here is to make sure equ bw wont be more agressive than the latency-based requirement.
// check vm time >= vm_trips
// check r0 time >= r0_trips
+
+ double total_row_bytes = (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes);
+
+ dml2_printf("DML::%s: Tvm_trips_rounded = %f\n", __func__, s->Tvm_trips_rounded);
+ dml2_printf("DML::%s: Tr0_trips_rounded = %f\n", __func__, s->Tr0_trips_rounded);
+
if (s->prefetch_bw1 > 0) {
- if (*p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw1 >= s->Tvm_trips_rounded &&
- (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / s->prefetch_bw1 >= s->Tr0_trips_rounded) {
+ double vm_transfer_time = *p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw1;
+ double row_transfer_time = total_row_bytes / s->prefetch_bw1;
+ dml2_printf("DML::%s: Case1: vm_transfer_time = %f\n", __func__, vm_transfer_time);
+ dml2_printf("DML::%s: Case1: row_transfer_time = %f\n", __func__, row_transfer_time);
+ if (vm_transfer_time >= s->Tvm_trips_rounded && row_transfer_time >= s->Tr0_trips_rounded) {
Case1OK = true;
}
}
@@ -5516,8 +5545,11 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
// check vm time >= vm_trips
// check r0 time < r0_trips
if (s->prefetch_bw2 > 0) {
- if (*p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw2 >= s->Tvm_trips_rounded &&
- (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / s->prefetch_bw2 < s->Tr0_trips_rounded) {
+ double vm_transfer_time = *p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw2;
+ double row_transfer_time = total_row_bytes / s->prefetch_bw2;
+ dml2_printf("DML::%s: Case2: vm_transfer_time = %f\n", __func__, vm_transfer_time);
+ dml2_printf("DML::%s: Case2: row_transfer_time = %f\n", __func__, row_transfer_time);
+ if (vm_transfer_time >= s->Tvm_trips_rounded && row_transfer_time < s->Tr0_trips_rounded) {
Case2OK = true;
}
}
@@ -5526,8 +5558,11 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
// check vm time < vm_trips
// check r0 time >= r0_trips
if (s->prefetch_bw3 > 0) {
- if (*p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw3 < s->Tvm_trips_rounded &&
- (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / s->prefetch_bw3 >= s->Tr0_trips_rounded) {
+ double vm_transfer_time = *p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw3;
+ double row_transfer_time = total_row_bytes / s->prefetch_bw3;
+ dml2_printf("DML::%s: Case3: vm_transfer_time = %f\n", __func__, vm_transfer_time);
+ dml2_printf("DML::%s: Case3: row_transfer_time = %f\n", __func__, row_transfer_time);
+ if (vm_transfer_time < s->Tvm_trips_rounded && row_transfer_time >= s->Tr0_trips_rounded) {
Case3OK = true;
}
}
@@ -5542,11 +5577,9 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
s->prefetch_bw_equ = s->prefetch_bw4;
}
-#ifdef DML_REG_LIMIT_CLAMP_EN
s->prefetch_bw_equ = math_max3(s->prefetch_bw_equ,
p->vm_bytes * p->HostVMInefficiencyFactor / (31 * s->LineTime) - *p->Tno_bw,
(p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / (15 * s->LineTime));
-#endif
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: Case1OK: %u\n", __func__, Case1OK);
dml2_printf("DML::%s: Case2OK: %u\n", __func__, Case2OK);
@@ -5578,6 +5611,9 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
dml2_printf("DML::%s: Tvm_equ = %f\n", __func__, s->Tvm_equ);
dml2_printf("DML::%s: Tr0_equ = %f\n", __func__, s->Tr0_equ);
#endif
+ // Lsw = dst_y_prefetch - (dst_y_per_vm_vblank + 2*dst_y_per_row_vblank)
+ s->Lsw_equ = s->dst_y_prefetch_equ - math_ceil2(4.0 * (s->Tvm_equ + 2 * s->Tr0_equ) / s->LineTime, 1.0) / 4.0;
+
// Use the more stressful prefetch schedule
if (s->dst_y_prefetch_oto < s->dst_y_prefetch_equ) {
*p->dst_y_prefetch = s->dst_y_prefetch_oto;
@@ -5586,29 +5622,28 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
*p->dst_y_per_vm_vblank = math_ceil2(4.0 * s->TimeForFetchingVM / s->LineTime, 1.0) / 4.0;
*p->dst_y_per_row_vblank = math_ceil2(4.0 * s->TimeForFetchingRowInVBlank / s->LineTime, 1.0) / 4.0;
+ s->dst_y_per_vm_no_trip_vblank = math_ceil2(4.0 * s->Tvm_no_trip_oto / s->LineTime, 1.0) / 4.0;
+ s->dst_y_per_row_no_trip_vblank = math_ceil2(4.0 * s->Tr0_no_trip_oto / s->LineTime, 1.0) / 4.0;
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: Using oto scheduling for prefetch\n", __func__);
#endif
-
} else {
*p->dst_y_prefetch = s->dst_y_prefetch_equ;
s->TimeForFetchingVM = s->Tvm_equ;
s->TimeForFetchingRowInVBlank = s->Tr0_equ;
- if (p->VStartup == p->MaxVStartup) {
- *p->dst_y_per_vm_vblank = math_floor2(4.0 * s->TimeForFetchingVM / s->LineTime, 1.0) / 4.0;
- *p->dst_y_per_row_vblank = math_floor2(4.0 * s->TimeForFetchingRowInVBlank / s->LineTime, 1.0) / 4.0;
- } else {
- *p->dst_y_per_vm_vblank = math_ceil2(4.0 * s->TimeForFetchingVM / s->LineTime, 1.0) / 4.0;
- *p->dst_y_per_row_vblank = math_ceil2(4.0 * s->TimeForFetchingRowInVBlank / s->LineTime, 1.0) / 4.0;
- }
+ *p->dst_y_per_vm_vblank = math_ceil2(4.0 * s->TimeForFetchingVM / s->LineTime, 1.0) / 4.0;
+ *p->dst_y_per_row_vblank = math_ceil2(4.0 * s->TimeForFetchingRowInVBlank / s->LineTime, 1.0) / 4.0;
+ s->dst_y_per_vm_no_trip_vblank = *p->dst_y_per_vm_vblank;
+ s->dst_y_per_row_no_trip_vblank = *p->dst_y_per_row_vblank;
+
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: Using equ bw scheduling for prefetch\n", __func__);
#endif
}
- // Lsw = dst_y_prefetch - (dst_y_per_vm_vblank + 2*dst_y_per_row_vblank)
- s->LinesToRequestPrefetchPixelData = *p->dst_y_prefetch - *p->dst_y_per_vm_vblank - 2 * *p->dst_y_per_row_vblank; // Lsw
+ /* take worst case Lsw to calculate bandwidth requirement regardless of schedule */
+ s->LinesToRequestPrefetchPixelData = math_min2(s->Lsw_equ, s->Lsw_oto); // Lsw
s->cursor_prefetch_bytes = (unsigned int)math_max2(p->cursor_bytes_per_chunk, 4 * p->cursor_bytes_per_line);
*p->prefetch_cursor_bw = p->num_cursors * s->cursor_prefetch_bytes / (s->LinesToRequestPrefetchPixelData * s->LineTime);
@@ -5645,7 +5680,7 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
(double)p->MaxNumSwathY * p->SwathHeightY / (s->LinesToRequestPrefetchPixelData - (p->VInitPreFillY - 3.0) / 2.0));
} else {
s->NoTimeToPrefetch = true;
- dml2_printf("DML::%s: MyErr set. LinesToRequestPrefetchPixelData=%f VinitPreFillY=%u\n", __func__, s->LinesToRequestPrefetchPixelData, p->VInitPreFillY);
+ dml2_printf("DML::%s: No time to prefetch!. LinesToRequestPrefetchPixelData=%f VinitPreFillY=%u\n", __func__, s->LinesToRequestPrefetchPixelData, p->VInitPreFillY);
*p->VRatioPrefetchY = 0;
}
#ifdef __DML_VBA_DEBUG__
@@ -5668,7 +5703,7 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
*p->VRatioPrefetchC = math_max2(*p->VRatioPrefetchC, (double)p->MaxNumSwathC * p->SwathHeightC / (s->LinesToRequestPrefetchPixelData - (p->VInitPreFillC - 3.0) / 2.0));
} else {
s->NoTimeToPrefetch = true;
- dml2_printf("DML::%s: MyErr set. LinesToRequestPrefetchPixelData=%f VInitPreFillC=%u\n", __func__, s->LinesToRequestPrefetchPixelData, p->VInitPreFillC);
+ dml2_printf("DML::%s: No time to prefetch!. LinesToRequestPrefetchPixelData=%f VInitPreFillC=%u\n", __func__, s->LinesToRequestPrefetchPixelData, p->VInitPreFillC);
*p->VRatioPrefetchC = 0;
}
#ifdef __DML_VBA_DEBUG__
@@ -5690,14 +5725,13 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
#endif
} else {
s->NoTimeToPrefetch = true;
- dml2_printf("DML::%s: MyErr set, LinesToRequestPrefetchPixelData: %f, should be >= %d\n", __func__, s->LinesToRequestPrefetchPixelData, min_lsw_required);
- dml2_printf("DML::%s: MyErr set, prefetch_bw_equ: %f, should be > 0\n", __func__, s->prefetch_bw_equ);
+ dml2_printf("DML::%s: No time to prefetch!, LinesToRequestPrefetchPixelData: %f, should be >= %d\n", __func__, s->LinesToRequestPrefetchPixelData, min_lsw_required);
+ dml2_printf("DML::%s: No time to prefetch!, prefetch_bw_equ: %f, should be > 0\n", __func__, s->prefetch_bw_equ);
*p->VRatioPrefetchY = 0;
*p->VRatioPrefetchC = 0;
*p->RequiredPrefetchPixelDataBWLuma = 0;
*p->RequiredPrefetchPixelDataBWChroma = 0;
}
-
dml2_printf("DML: Tpre: %fus - sum of time to request 2 x data pte, swaths\n", (double)s->LinesToRequestPrefetchPixelData * s->LineTime + 2.0 * s->TimeForFetchingRowInVBlank + s->TimeForFetchingVM);
dml2_printf("DML: Tvm: %fus - time to fetch vm\n", s->TimeForFetchingVM);
dml2_printf("DML: Tr0: %fus - time to fetch first row of data pagetables\n", s->TimeForFetchingRowInVBlank);
@@ -5708,7 +5742,9 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
dml2_printf("DML: row_bytes = dpte_row_bytes (per_pipe) = PixelPTEBytesPerRow = : %u\n", p->PixelPTEBytesPerRow);
} else {
- dml2_printf("DML::%s: MyErr set, dst_y_prefetch_equ = %f (should be > 1)\n", __func__, s->dst_y_prefetch_equ);
+ dml2_printf("DML::%s: No time to prefetch! dst_y_prefetch_equ = %f (should be > 1)\n", __func__, s->dst_y_prefetch_equ);
+ dml2_printf("DML::%s: No time to prefetch! min_Lsw_equ_ok = %d, Tpre_rounded (%f) should be >= Tvm_trips_rounded (%f) + 2.0*Tr0_trips_rounded (%f) + min_Tsw_equ (%f)\n",
+ __func__, min_Lsw_equ_ok, s->Tpre_rounded, s->Tvm_trips_rounded, 2.0*s->Tr0_trips_rounded, s->min_Lsw_equ*s->LineTime);
s->NoTimeToPrefetch = true;
s->TimeForFetchingVM = 0;
s->TimeForFetchingRowInVBlank = 0;
@@ -5727,26 +5763,26 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
if (vm_bytes == 0) {
prefetch_vm_bw = 0;
- } else if (*p->dst_y_per_vm_vblank > 0) {
+ } else if (s->dst_y_per_vm_no_trip_vblank > 0) {
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, p->HostVMInefficiencyFactor);
dml2_printf("DML::%s: dst_y_per_vm_vblank = %f\n", __func__, *p->dst_y_per_vm_vblank);
dml2_printf("DML::%s: LineTime = %f\n", __func__, s->LineTime);
#endif
- prefetch_vm_bw = vm_bytes * p->HostVMInefficiencyFactor / (*p->dst_y_per_vm_vblank * s->LineTime);
+ prefetch_vm_bw = vm_bytes * p->HostVMInefficiencyFactor / (s->dst_y_per_vm_no_trip_vblank * s->LineTime);
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: prefetch_vm_bw = %f\n", __func__, prefetch_vm_bw);
#endif
} else {
prefetch_vm_bw = 0;
s->NoTimeToPrefetch = true;
- dml2_printf("DML::%s: MyErr set. dst_y_per_vm_vblank=%f (should be > 0)\n", __func__, *p->dst_y_per_vm_vblank);
+ dml2_printf("DML::%s: No time to prefetch!. dst_y_per_vm_vblank=%f (should be > 0)\n", __func__, *p->dst_y_per_vm_vblank);
}
if (p->PixelPTEBytesPerRow == 0 && tdlut_row_bytes == 0) {
prefetch_row_bw = 0;
- } else if (*p->dst_y_per_row_vblank > 0) {
- prefetch_row_bw = (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + tdlut_row_bytes) / (*p->dst_y_per_row_vblank * s->LineTime);
+ } else if (s->dst_y_per_row_no_trip_vblank > 0) {
+ prefetch_row_bw = (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + tdlut_row_bytes) / (s->dst_y_per_row_no_trip_vblank * s->LineTime);
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, p->PixelPTEBytesPerRow);
@@ -5756,7 +5792,7 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
} else {
prefetch_row_bw = 0;
s->NoTimeToPrefetch = true;
- dml2_printf("DML::%s: MyErr set. dst_y_per_row_vblank=%f (should be > 0)\n", __func__, *p->dst_y_per_row_vblank);
+ dml2_printf("DML::%s: No time to prefetch!. dst_y_per_row_vblank=%f (should be > 0)\n", __func__, *p->dst_y_per_row_vblank);
}
*p->prefetch_vmrow_bw = math_max2(prefetch_vm_bw, prefetch_row_bw);
@@ -5773,11 +5809,16 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
*p->VRatioPrefetchC = 0;
*p->RequiredPrefetchPixelDataBWLuma = 0;
*p->RequiredPrefetchPixelDataBWChroma = 0;
+ *p->prefetch_vmrow_bw = 0;
}
dml2_printf("DML::%s: dst_y_per_vm_vblank = %f (final)\n", __func__, *p->dst_y_per_vm_vblank);
dml2_printf("DML::%s: dst_y_per_row_vblank = %f (final)\n", __func__, *p->dst_y_per_row_vblank);
+ dml2_printf("DML::%s: prefetch_vmrow_bw = %f (final)\n", __func__, *p->prefetch_vmrow_bw);
+ dml2_printf("DML::%s: RequiredPrefetchPixelDataBWLuma = %f (final)\n", __func__, *p->RequiredPrefetchPixelDataBWLuma);
+ dml2_printf("DML::%s: RequiredPrefetchPixelDataBWChroma = %f (final)\n", __func__, *p->RequiredPrefetchPixelDataBWChroma);
dml2_printf("DML::%s: NoTimeToPrefetch=%d\n", __func__, s->NoTimeToPrefetch);
+
return s->NoTimeToPrefetch;
}
@@ -6169,6 +6210,7 @@ static void CalculateFlipSchedule(
unsigned int dpte_row_height_chroma,
bool use_one_row_for_frame_flip,
unsigned int max_flip_time_us,
+ unsigned int max_flip_time_lines,
unsigned int per_pipe_flip_bytes,
unsigned int meta_row_bytes,
unsigned int meta_row_height,
@@ -6183,12 +6225,13 @@ static void CalculateFlipSchedule(
{
struct dml2_core_shared_CalculateFlipSchedule_locals *l = &s->CalculateFlipSchedule_locals;
- l->dual_plane = dml2_core_shared_is_420(SourcePixelFormat) || SourcePixelFormat == dml2_rgbe_alpha;
+ l->dual_plane = dml_is_420(SourcePixelFormat) || SourcePixelFormat == dml2_rgbe_alpha;
l->dpte_row_bytes = DPTEBytesPerRow;
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: GPUVMEnable = %u\n", __func__, GPUVMEnable);
dml2_printf("DML::%s: ip.max_flip_time_us = %d\n", __func__, max_flip_time_us);
+ dml2_printf("DML::%s: ip.max_flip_time_lines = %d\n", __func__, max_flip_time_lines);
dml2_printf("DML::%s: BandwidthAvailableForImmediateFlip = %f\n", __func__, BandwidthAvailableForImmediateFlip);
dml2_printf("DML::%s: TotImmediateFlipBytes = %u\n", __func__, TotImmediateFlipBytes);
dml2_printf("DML::%s: use_lb_flip_bw = %u\n", __func__, use_lb_flip_bw);
@@ -6239,7 +6282,8 @@ static void CalculateFlipSchedule(
if (use_lb_flip_bw) {
// For mode check, calculation the flip bw requirement with worst case flip time
- l->max_flip_time = math_min2(l->min_row_time, math_max2(Tvm_trips_flip_rounded + 2 * Tr0_trips_flip_rounded, (double)max_flip_time_us));
+ l->max_flip_time = math_min2(math_min2(l->min_row_time, (double)max_flip_time_lines * LineTime / VRatio),
+ math_max2(Tvm_trips_flip_rounded + 2 * Tr0_trips_flip_rounded, (double)max_flip_time_us));
//The lower bound on flip bandwidth
// Note: The get_urgent_bandwidth_required already consider dpte_row_bw and meta_row_bw in bandwidth calculation, so leave final_flip_bw = 0 if iflip not required
@@ -6257,7 +6301,7 @@ static void CalculateFlipSchedule(
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: max_flip_time = %f\n", __func__, l->max_flip_time);
dml2_printf("DML::%s: total vm bytes (hvm ineff scaled) = %f\n", __func__, l->hvm_scaled_vm_bytes);
- dml2_printf("DML::%s: total row bytes (hvm ineff scaled) = %f\n", __func__, l->hvm_scaled_row_bytes);
+ dml2_printf("DML::%s: total row bytes (%d row, hvm ineff scaled) = %f\n", __func__, l->num_rows, l->hvm_scaled_row_bytes);
dml2_printf("DML::%s: total vm+row bytes (hvm ineff scaled) = %f\n", __func__, l->hvm_scaled_vm_row_bytes);
dml2_printf("DML::%s: lb_flip_bw for vm and row = %f\n", __func__, l->hvm_scaled_vm_row_bytes / (l->max_flip_time - Tno_bw_flip));
dml2_printf("DML::%s: lb_flip_bw for vm = %f\n", __func__, l->hvm_scaled_vm_bytes / (l->max_flip_time - Tno_bw_flip - 2 * Tr0_trips_flip_rounded));
@@ -6268,6 +6312,7 @@ static void CalculateFlipSchedule(
dml2_printf("DML::%s: mode_support est Tr0_flip = %f (bw-based)\n", __func__, l->hvm_scaled_row_bytes / l->lb_flip_bw / l->num_rows);
dml2_printf("DML::%s: mode_support est dst_y_per_vm_flip = %f (bw-based)\n", __func__, Tno_bw_flip + l->hvm_scaled_vm_bytes / l->lb_flip_bw / LineTime);
dml2_printf("DML::%s: mode_support est dst_y_per_row_flip = %f (bw-based)\n", __func__, l->hvm_scaled_row_bytes / l->lb_flip_bw / LineTime / l->num_rows);
+ dml2_printf("DML::%s: Tvm_trips_flip_rounded + 2*Tr0_trips_flip_rounded = %f\n", __func__, (Tvm_trips_flip_rounded + 2 * Tr0_trips_flip_rounded));
}
#endif
l->lb_flip_bw = math_max3(l->lb_flip_bw,
@@ -6284,7 +6329,7 @@ static void CalculateFlipSchedule(
*dst_y_per_vm_flip = 1; // not used
*dst_y_per_row_flip = 1; // not used
- *ImmediateFlipSupportedForPipe = true;
+ *ImmediateFlipSupportedForPipe = l->min_row_time >= (Tvm_trips_flip_rounded + 2 * Tr0_trips_flip_rounded);
} else {
if (iflip_enable) {
l->ImmediateFlipBW = (double)per_pipe_flip_bytes * BandwidthAvailableForImmediateFlip / (double)TotImmediateFlipBytes; // flip_bw(i)
@@ -6350,6 +6395,7 @@ static void CalculateFlipSchedule(
dml2_printf("DML::%s: dst_y_per_row_flip = %f (should be < 16)\n", __func__, *dst_y_per_row_flip);
dml2_printf("DML::%s: Tvm_flip = %f (final)\n", __func__, l->Tvm_flip);
dml2_printf("DML::%s: Tr0_flip = %f (final)\n", __func__, l->Tr0_flip);
+ dml2_printf("DML::%s: Tvm_flip + 2*Tr0_flip = %f (should be <= min_row_time=%f)\n", __func__, l->Tvm_flip + 2 * l->Tr0_flip, l->min_row_time);
}
dml2_printf("DML::%s: final_flip_bw = %f\n", __func__, *final_flip_bw);
dml2_printf("DML::%s: ImmediateFlipSupportedForPipe = %u\n", __func__, *ImmediateFlipSupportedForPipe);
@@ -6380,6 +6426,12 @@ static void CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
p->Watermark->StutterEnterPlusExitWatermark = p->mmSOCParameters.SREnterPlusExitTime + p->mmSOCParameters.ExtraLatency_sr + 10 / p->DCFClkDeepSleep;
p->Watermark->Z8StutterExitWatermark = p->mmSOCParameters.SRExitZ8Time + p->mmSOCParameters.ExtraLatency_sr + 10 / p->DCFClkDeepSleep;
p->Watermark->Z8StutterEnterPlusExitWatermark = p->mmSOCParameters.SREnterPlusExitZ8Time + p->mmSOCParameters.ExtraLatency_sr + 10 / p->DCFClkDeepSleep;
+ if (p->mmSOCParameters.qos_type == dml2_qos_param_type_dcn4x) {
+ p->Watermark->StutterExitWatermark += p->mmSOCParameters.max_urgent_latency_us + p->mmSOCParameters.df_response_time_us;
+ p->Watermark->StutterEnterPlusExitWatermark += p->mmSOCParameters.max_urgent_latency_us + p->mmSOCParameters.df_response_time_us;
+ p->Watermark->Z8StutterExitWatermark += p->mmSOCParameters.max_urgent_latency_us + p->mmSOCParameters.df_response_time_us;
+ p->Watermark->Z8StutterEnterPlusExitWatermark += p->mmSOCParameters.max_urgent_latency_us + p->mmSOCParameters.df_response_time_us;
+ }
p->Watermark->g6_temp_read_watermark_us = p->mmSOCParameters.g6_temp_read_blackout_us + p->Watermark->UrgentWatermark;
#ifdef __DML_VBA_DEBUG__
@@ -6541,7 +6593,8 @@ static void CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
p->DRAMClockChangeSupport[k] = dml2_dram_clock_change_unsupported;
if (uclk_pstate_change_strategy == dml2_uclk_pstate_change_strategy_auto) {
- if (s->ActiveDRAMClockChangeLatencyMargin[k] > 0 && reserved_vblank_time_us >= p->mmSOCParameters.DRAMClockChangeLatency)
+ if (p->display_cfg->overrides.all_streams_blanked ||
+ (s->ActiveDRAMClockChangeLatencyMargin[k] > 0 && reserved_vblank_time_us >= p->mmSOCParameters.DRAMClockChangeLatency))
p->DRAMClockChangeSupport[k] = dml2_dram_clock_change_vblank_and_vactive;
else if (s->ActiveDRAMClockChangeLatencyMargin[k] > 0)
p->DRAMClockChangeSupport[k] = dml2_dram_clock_change_vactive;
@@ -6585,13 +6638,13 @@ static void CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
s->src_y_ahead_c = (unsigned int)(math_floor2(p->DETBufferSizeC[k] / p->BytePerPixelDETC[k] / p->SwathWidthC[k], p->SwathHeightC[k]) + s->LBLatencyHidingSourceLinesC[k]);
s->sub_vp_lines_c = s->src_y_pstate_c + s->src_y_ahead_c + p->meta_row_height_c[k];
- if (dml2_core_shared_is_420(p->display_cfg->plane_descriptors[k].pixel_format))
+ if (dml_is_420(p->display_cfg->plane_descriptors[k].pixel_format))
p->SubViewportLinesNeededInMALL[k] = (unsigned int)(math_max2(s->sub_vp_lines_l, 2 * s->sub_vp_lines_c));
else
p->SubViewportLinesNeededInMALL[k] = (unsigned int)(math_max2(s->sub_vp_lines_l, s->sub_vp_lines_c));
#ifdef __DML_VBA_DEBUG__
- dml2_printf("DML::%s: k=%u, meta_row_height_c = %u\n", __func__, p->meta_row_height_c[k]);
+ dml2_printf("DML::%s: k=%u, meta_row_height_c = %u\n", __func__, k, p->meta_row_height_c[k]);
dml2_printf("DML::%s: k=%u, src_y_pstate_c = %u\n", __func__, k, s->src_y_pstate_c);
dml2_printf("DML::%s: k=%u, src_y_ahead_c = %u\n", __func__, k, s->src_y_ahead_c);
dml2_printf("DML::%s: k=%u, sub_vp_lines_c = %u\n", __func__, k, s->sub_vp_lines_c);
@@ -6856,7 +6909,8 @@ struct dml2_core_internal_g6_temp_read_blackouts_table {
} entries[DML_MAX_CLK_TABLE_SIZE];
};
-struct dml2_core_internal_g6_temp_read_blackouts_table core_dcn4_g6_temp_read_blackout_table = {
+static const struct dml2_core_internal_g6_temp_read_blackouts_table
+ core_dcn4_g6_temp_read_blackout_table = {
.entries = {
{
.uclk_khz = 96000,
@@ -6921,6 +6975,43 @@ static double get_g6_temp_read_blackout_us(
return (double)blackout_us;
}
+static double get_max_urgent_latency_us(
+ struct dml2_dcn4x_soc_qos_params *dcn4x,
+ double uclk_freq_mhz,
+ double FabricClock,
+ unsigned int min_clk_index)
+{
+ double latency;
+ latency = dcn4x->per_uclk_dpm_params[min_clk_index].maximum_latency_when_urgent_uclk_cycles / uclk_freq_mhz
+ * (1 + dcn4x->umc_max_latency_margin / 100.0)
+ + dcn4x->mall_overhead_fclk_cycles / FabricClock
+ + dcn4x->max_round_trip_to_furthest_cs_fclk_cycles / FabricClock
+ * (1 + dcn4x->fabric_max_transport_latency_margin / 100.0);
+ return latency;
+}
+
+static void calculate_pstate_keepout_dst_lines(
+ const struct dml2_display_cfg *display_cfg,
+ const struct dml2_core_internal_watermarks *watermarks,
+ unsigned int pstate_keepout_dst_lines[])
+{
+ const struct dml2_stream_parameters *stream_descriptor;
+ unsigned int i;
+
+ for (i = 0; i < display_cfg->num_planes; i++) {
+ if (!dml_is_phantom_pipe(&display_cfg->plane_descriptors[i])) {
+ stream_descriptor = &display_cfg->stream_descriptors[display_cfg->plane_descriptors[i].stream_index];
+
+ pstate_keepout_dst_lines[i] =
+ (unsigned int)math_ceil(watermarks->DRAMClockChangeWatermark / ((double)stream_descriptor->timing.h_total * 1000.0 / (double)stream_descriptor->timing.pixel_clock_khz));
+
+ if (pstate_keepout_dst_lines[i] > stream_descriptor->timing.v_total - 1) {
+ pstate_keepout_dst_lines[i] = stream_descriptor->timing.v_total - 1;
+ }
+ }
+ }
+}
+
static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out_params)
{
struct dml2_core_internal_display_mode_lib *mode_lib = in_out_params->mode_lib;
@@ -6963,7 +7054,7 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
mode_lib->ms.uclk_freq_mhz = dram_bw_kbps_to_uclk_mhz(min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps, &mode_lib->soc.clk_table.dram_config);
mode_lib->ms.dram_bw_mbps = ((double)min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps / 1000);
mode_lib->ms.max_dram_bw_mbps = ((double)min_clk_table->dram_bw_table.entries[min_clk_table->dram_bw_table.num_entries - 1].pre_derate_dram_bw_kbps / 1000);
- mode_lib->ms.qos_param_index = get_qos_param_index((unsigned int) (mode_lib->ms.uclk_freq_mhz * 1000.0), mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params);
+ mode_lib->ms.qos_param_index = get_qos_param_index((unsigned int) (mode_lib->ms.uclk_freq_mhz * 1000.0), mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params);
mode_lib->ms.active_min_uclk_dpm_index = get_active_min_uclk_dpm_index((unsigned int) (mode_lib->ms.uclk_freq_mhz * 1000.0), &mode_lib->soc.clk_table);
#if defined(__DML_VBA_DEBUG__)
@@ -6981,7 +7072,6 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
dml2_printf("DML::%s: max_dscclk_freq_mhz = %f\n", __func__, mode_lib->ms.max_dscclk_freq_mhz);
dml2_printf("DML::%s: max_dppclk_freq_mhz = %f\n", __func__, mode_lib->ms.max_dppclk_freq_mhz);
dml2_printf("DML::%s: MaxFabricClock = %f\n", __func__, mode_lib->ms.MaxFabricClock);
- dml2_printf("DML::%s: max_dscclk_freq_mhz = %f\n", __func__, mode_lib->ms.max_dscclk_freq_mhz);
dml2_printf("DML::%s: ip.compressed_buffer_segment_size_in_kbytes = %u\n", __func__, mode_lib->ip.compressed_buffer_segment_size_in_kbytes);
dml2_printf("DML::%s: ip.dcn_mrq_present = %u\n", __func__, mode_lib->ip.dcn_mrq_present);
@@ -7126,7 +7216,7 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
mode_lib->ms.support.WritebackLatencySupport = true;
for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.enable == true &&
- (mode_lib->ms.WriteBandwidth[k] > mode_lib->ip.writeback_interface_buffer_size_kbytes * 1024.0 / mode_lib->soc.qos_parameters.writeback.base_latency_us)) {
+ (mode_lib->ms.WriteBandwidth[k] > mode_lib->ip.writeback_interface_buffer_size_kbytes * 1024 / ((double)mode_lib->soc.qos_parameters.writeback.base_latency_us))) {
mode_lib->ms.support.WritebackLatencySupport = false;
}
}
@@ -7202,17 +7292,17 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
#if defined(DV_BUILD)
// Assume a memory config setting of 3 in 420 mode or get a new ip parameter that reflects the programming.
if (mode_lib->ms.BytePerPixelC[k] != 0.0 && display_cfg->plane_descriptors[k].pixel_format != dml2_rgbe_alpha) {
- lb_buffer_size_bits_luma = 34620 * 57;;
+ lb_buffer_size_bits_luma = 34620 * 57;
lb_buffer_size_bits_chroma = 13560 * 57;
}
#endif
*/
- mode_lib->ms.MaximumSwathWidthInLineBufferLuma = lb_buffer_size_bits_luma * math_max2(display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio, 1.0) / 57 /*FIXME_STAGE2 was: LBBitPerPixel*/ /
+ mode_lib->ms.MaximumSwathWidthInLineBufferLuma = lb_buffer_size_bits_luma * math_max2(display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio, 1.0) / 57 /
(display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps + math_max2(math_ceil2(display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio, 1.0) - 2, 0.0));
if (mode_lib->ms.BytePerPixelC[k] == 0.0) {
mode_lib->ms.MaximumSwathWidthInLineBufferChroma = 0;
} else {
- mode_lib->ms.MaximumSwathWidthInLineBufferChroma = lb_buffer_size_bits_chroma * math_max2(display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio, 1.0) / 57 /*FIXME_STAGE2 was: LBBitPerPixel*/ /
+ mode_lib->ms.MaximumSwathWidthInLineBufferChroma = lb_buffer_size_bits_chroma * math_max2(display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio, 1.0) / 57 /
(display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps + math_max2(math_ceil2(display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio, 1.0) - 2, 0.0));
}
@@ -7231,10 +7321,9 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
/* Cursor Support Check */
mode_lib->ms.support.CursorSupport = true;
for (k = 0; k < mode_lib->ms.num_active_planes; k++) {
- if (display_cfg->plane_descriptors[k].cursor.cursor_width > 0.0) {
- if (display_cfg->plane_descriptors[k].cursor.cursor_bpp == 64 && mode_lib->ip.cursor_64bpp_support == false) {
+ if (display_cfg->plane_descriptors[k].cursor.num_cursors > 0) {
+ if (display_cfg->plane_descriptors[k].cursor.cursor_bpp == 64 && mode_lib->ip.cursor_64bpp_support == false)
mode_lib->ms.support.CursorSupport = false;
- }
}
}
@@ -7295,7 +7384,8 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
mode_lib->ms.support.ViewportExceedsSurface = false;
if (!display_cfg->overrides.hw.surface_viewport_size_check_disable) {
for (k = 0; k < mode_lib->ms.num_active_planes; k++) {
- if (display_cfg->plane_descriptors[k].composition.viewport.plane0.width > display_cfg->plane_descriptors[k].surface.plane0.width || display_cfg->plane_descriptors[k].composition.viewport.plane0.height > display_cfg->plane_descriptors[k].surface.plane0.height) {
+ if (display_cfg->plane_descriptors[k].composition.viewport.plane0.width > display_cfg->plane_descriptors[k].surface.plane0.width ||
+ display_cfg->plane_descriptors[k].composition.viewport.plane0.height > display_cfg->plane_descriptors[k].surface.plane0.height) {
mode_lib->ms.support.ViewportExceedsSurface = true;
#if defined(__DML_VBA_DEBUG__)
dml2_printf("DML::%s: k=%u ViewportWidth = %d\n", __func__, k, display_cfg->plane_descriptors[k].composition.viewport.plane0.width);
@@ -7304,11 +7394,11 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
dml2_printf("DML::%s: k=%u SurfaceHeightY = %d\n", __func__, k, display_cfg->plane_descriptors[k].surface.plane0.height);
dml2_printf("DML::%s: k=%u ViewportExceedsSurface = %d\n", __func__, k, mode_lib->ms.support.ViewportExceedsSurface);
#endif
- if (dml_is_420(display_cfg->plane_descriptors[k].pixel_format) || display_cfg->plane_descriptors[k].pixel_format == dml2_rgbe_alpha) {
- if (display_cfg->plane_descriptors[k].composition.viewport.plane1.width > display_cfg->plane_descriptors[k].surface.plane1.width ||
- display_cfg->plane_descriptors[k].composition.viewport.plane1.height > display_cfg->plane_descriptors[k].surface.plane1.height) {
- mode_lib->ms.support.ViewportExceedsSurface = true;
- }
+ }
+ if (dml_is_420(display_cfg->plane_descriptors[k].pixel_format) || display_cfg->plane_descriptors[k].pixel_format == dml2_rgbe_alpha) {
+ if (display_cfg->plane_descriptors[k].composition.viewport.plane1.width > display_cfg->plane_descriptors[k].surface.plane1.width ||
+ display_cfg->plane_descriptors[k].composition.viewport.plane1.height > display_cfg->plane_descriptors[k].surface.plane1.height) {
+ mode_lib->ms.support.ViewportExceedsSurface = true;
}
}
}
@@ -7466,6 +7556,10 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
&mode_lib->ms.OutputRate[k],
&mode_lib->ms.RequiredSlots[k]);
+ if (s->OutputBpp[k] == 0.0) {
+ s->OutputBpp[k] = mode_lib->ms.OutputBpp[k];
+ }
+
if (mode_lib->ms.RequiresDSC[k] == false) {
mode_lib->ms.ODMMode[k] = s->ODMModeNoDSC;
mode_lib->ms.RequiredDISPCLKPerSurface[k] = s->RequiredDISPCLKPerSurfaceNoDSC;
@@ -7580,7 +7674,7 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.h_taps,
display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.v_taps,
display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.input_width,
- display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.output_height,
+ display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.output_width,
display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total,
mode_lib->ip.writeback_line_buffer_buffer_size));
}
@@ -7665,8 +7759,6 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format == dml2_420 && display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced == 1 && mode_lib->ip.ptoi_supported == true)
mode_lib->ms.support.P2IWith420 = true;
- if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.dsc.enable == dml2_dsc_enable_if_necessary && s->OutputBpp[k] != 0)
- mode_lib->ms.support.DSCOnlyIfNecessaryWithBPP = true;
if ((display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.dsc.enable == dml2_dsc_enable || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.dsc.enable == dml2_dsc_enable_if_necessary) && display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format == dml2_n422 && !mode_lib->ip.dsc422_native_support)
mode_lib->ms.support.DSC422NativeNotSupported = true;
@@ -7819,7 +7911,7 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
mode_lib->ms.DSCDelay[k] = DSCDelayRequirement(mode_lib->ms.RequiresDSC[k],
mode_lib->ms.ODMMode[k],
mode_lib->ip.maximum_dsc_bits_per_component,
- mode_lib->ms.OutputBpp[k],
+ s->OutputBpp[k],
display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_active,
display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total,
mode_lib->ms.support.NumberOfDSCSlices[k],
@@ -8059,59 +8151,63 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
mode_lib->ms.excess_vactive_fill_bw_c);
mode_lib->ms.UrgLatency = CalculateUrgentLatency(
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.base_latency_us,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.base_latency_pixel_vm_us,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.base_latency_vm_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.base_latency_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.base_latency_pixel_vm_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.base_latency_vm_us,
mode_lib->soc.do_urgent_latency_adjustment,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.scaling_factor_fclk_us,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.scaling_factor_mhz,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.scaling_factor_fclk_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.scaling_factor_mhz,
mode_lib->ms.FabricClock,
mode_lib->ms.uclk_freq_mhz,
mode_lib->soc.qos_parameters.qos_type,
- mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->ms.qos_param_index].urgent_ramp_uclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.df_qos_response_time_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.max_round_trip_to_furthest_cs_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.mall_overhead_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.umc_urgent_ramp_latency_margin,
- mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin);
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->ms.qos_param_index].urgent_ramp_uclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.df_qos_response_time_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.max_round_trip_to_furthest_cs_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.mall_overhead_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_urgent_ramp_latency_margin,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_max_transport_latency_margin);
mode_lib->ms.TripToMemory = CalculateTripToMemory(
mode_lib->ms.UrgLatency,
mode_lib->ms.FabricClock,
mode_lib->ms.uclk_freq_mhz,
mode_lib->soc.qos_parameters.qos_type,
- mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->ms.qos_param_index].trip_to_memory_uclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.max_round_trip_to_furthest_cs_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.mall_overhead_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.umc_max_latency_margin,
- mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin);
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->ms.qos_param_index].trip_to_memory_uclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.max_round_trip_to_furthest_cs_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.mall_overhead_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_max_latency_margin,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_max_transport_latency_margin);
mode_lib->ms.TripToMemory = math_max2(mode_lib->ms.UrgLatency, mode_lib->ms.TripToMemory);
for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
double line_time_us = (double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
bool cursor_not_enough_urgent_latency_hiding = 0;
- calculate_cursor_req_attributes(
- display_cfg->plane_descriptors[k].cursor.cursor_width,
- display_cfg->plane_descriptors[k].cursor.cursor_bpp,
- // output
- &s->cursor_lines_per_chunk[k],
- &s->cursor_bytes_per_line[k],
- &s->cursor_bytes_per_chunk[k],
- &s->cursor_bytes[k]);
-
- calculate_cursor_urgent_burst_factor(
- mode_lib->ip.cursor_buffer_size,
- display_cfg->plane_descriptors[k].cursor.cursor_width,
- s->cursor_bytes_per_chunk[k],
- s->cursor_lines_per_chunk[k],
- line_time_us,
- mode_lib->ms.UrgLatency,
+ if (display_cfg->plane_descriptors[k].cursor.num_cursors > 0) {
+ calculate_cursor_req_attributes(
+ display_cfg->plane_descriptors[k].cursor.cursor_width,
+ display_cfg->plane_descriptors[k].cursor.cursor_bpp,
+
+ // output
+ &s->cursor_lines_per_chunk[k],
+ &s->cursor_bytes_per_line[k],
+ &s->cursor_bytes_per_chunk[k],
+ &s->cursor_bytes[k]);
+
+ calculate_cursor_urgent_burst_factor(
+ mode_lib->ip.cursor_buffer_size,
+ display_cfg->plane_descriptors[k].cursor.cursor_width,
+ s->cursor_bytes_per_chunk[k],
+ s->cursor_lines_per_chunk[k],
+ line_time_us,
+ mode_lib->ms.UrgLatency,
+
+ // output
+ &mode_lib->ms.UrgentBurstFactorCursor[k],
+ &cursor_not_enough_urgent_latency_hiding);
+ }
- // output
- &mode_lib->ms.UrgentBurstFactorCursor[k],
- &cursor_not_enough_urgent_latency_hiding);
mode_lib->ms.UrgentBurstFactorCursorPre[k] = mode_lib->ms.UrgentBurstFactorCursor[k];
#ifdef __DML_VBA_DEBUG__
@@ -8254,20 +8350,20 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
mode_lib->ms.support.OutstandingRequestsUrgencyAvoidance = true;
mode_lib->ms.support.avg_urgent_latency_us
- = (mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->ms.qos_param_index].average_latency_when_urgent_uclk_cycles / mode_lib->ms.uclk_freq_mhz
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.umc_average_latency_margin / 100.0)
- + mode_lib->soc.qos_parameters.qos_params.dcn4.average_transport_distance_fclk_cycles / mode_lib->ms.FabricClock)
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_average_transport_latency_margin / 100.0);
+ = (mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->ms.qos_param_index].average_latency_when_urgent_uclk_cycles / mode_lib->ms.uclk_freq_mhz
+ * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_average_latency_margin / 100.0)
+ + mode_lib->soc.qos_parameters.qos_params.dcn4x.average_transport_distance_fclk_cycles / mode_lib->ms.FabricClock)
+ * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_average_transport_latency_margin / 100.0);
mode_lib->ms.support.avg_non_urgent_latency_us
- = (mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->ms.qos_param_index].average_latency_when_non_urgent_uclk_cycles / mode_lib->ms.uclk_freq_mhz
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.umc_average_latency_margin / 100.0)
- + mode_lib->soc.qos_parameters.qos_params.dcn4.average_transport_distance_fclk_cycles / mode_lib->ms.FabricClock)
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_average_transport_latency_margin / 100.0);
+ = (mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->ms.qos_param_index].average_latency_when_non_urgent_uclk_cycles / mode_lib->ms.uclk_freq_mhz
+ * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_average_latency_margin / 100.0)
+ + mode_lib->soc.qos_parameters.qos_params.dcn4x.average_transport_distance_fclk_cycles / mode_lib->ms.FabricClock)
+ * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_average_transport_latency_margin / 100.0);
for (k = 0; k < mode_lib->ms.num_active_planes; k++) {
- if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4) {
+ if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4x) {
outstanding_latency_us = (mode_lib->soc.max_outstanding_reqs * mode_lib->ms.support.request_size_bytes_luma[k]
/ (mode_lib->ms.DCFCLK * mode_lib->soc.return_bus_width_bytes));
@@ -8287,7 +8383,7 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
#endif
}
- if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4 && mode_lib->ms.BytePerPixelC[k] > 0) {
+ if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4x && mode_lib->ms.BytePerPixelC[k] > 0) {
outstanding_latency_us = (mode_lib->soc.max_outstanding_reqs * mode_lib->ms.support.request_size_bytes_chroma[k]
/ (mode_lib->ms.DCFCLK * mode_lib->soc.return_bus_width_bytes));
@@ -8460,7 +8556,6 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
{
mode_lib->ms.TimeCalc = 24 / mode_lib->ms.dcfclk_deepsleep;
-
calculate_hostvm_inefficiency_factor(
&s->HostVMInefficiencyFactor,
&s->HostVMInefficiencyFactorPrefetch,
@@ -8501,10 +8596,15 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
min_return_bw_for_latency = mode_lib->ms.support.urg_bandwidth_available_min_latency[dml2_core_internal_soc_state_sys_active];
+ if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn3)
+ s->ReorderingBytes = (unsigned int)(mode_lib->soc.clk_table.dram_config.channel_count * math_max3(mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_out_of_order_return_per_channel_pixel_only_bytes,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_out_of_order_return_per_channel_vm_only_bytes));
+
CalculateExtraLatency(
display_cfg,
mode_lib->ip.rob_buffer_size_kbytes,
- 0, //mode_lib->soc.round_trip_ping_latency_dcfclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.loaded_round_trip_latency_fclk_cycles,
s->ReorderingBytes,
mode_lib->ms.DCFCLK,
mode_lib->ms.FabricClock,
@@ -8540,7 +8640,9 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
mode_lib->ms.TWait[k] = CalculateTWait(
display_cfg->plane_descriptors[k].overrides.reserved_vblank_time_ns,
mode_lib->ms.UrgLatency,
- mode_lib->ms.TripToMemory);
+ mode_lib->ms.TripToMemory,
+ !dml_is_phantom_pipe(&display_cfg->plane_descriptors[k]) && display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.drr_config.enabled ?
+ get_g6_temp_read_blackout_us(&mode_lib->soc, (unsigned int)(mode_lib->ms.uclk_freq_mhz * 1000), in_out_params->min_clk_index) : 0.0);
myPipe->Dppclk = mode_lib->ms.RequiredDPPCLK[k];
myPipe->Dispclk = mode_lib->ms.RequiredDISPCLK;
@@ -8587,7 +8689,6 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
CalculatePrefetchSchedule_params->OutputFormat = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format;
CalculatePrefetchSchedule_params->MaxInterDCNTileRepeaters = mode_lib->ip.max_inter_dcn_tile_repeaters;
CalculatePrefetchSchedule_params->VStartup = s->MaximumVStartup[k];
- CalculatePrefetchSchedule_params->MaxVStartup = s->MaximumVStartup[k];
CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->soc.hostvm_min_page_size_kbytes;
CalculatePrefetchSchedule_params->DynamicMetadataEnable = display_cfg->plane_descriptors[k].dynamic_meta_data.enable;
CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ip.dynamic_metadata_vm_enabled;
@@ -8669,8 +8770,8 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
dml2_printf("DML::%s: k=%d, dst_y_prefetch=%f (should not be < 2)\n", __func__, k, mode_lib->ms.dst_y_prefetch[k]);
dml2_printf("DML::%s: k=%d, LinesForVM=%f (should not be >= 32)\n", __func__, k, mode_lib->ms.LinesForVM[k]);
dml2_printf("DML::%s: k=%d, LinesForDPTERow=%f (should not be >= 16)\n", __func__, k, mode_lib->ms.LinesForDPTERow[k]);
- dml2_printf("DML::%s: k=%d, NoTimeForPrefetch=%d\n", __func__, k, mode_lib->ms.NoTimeForPrefetch[k]);
dml2_printf("DML::%s: k=%d, DSTYAfterScaler=%d (should be <= 8)\n", __func__, k, s->DSTYAfterScaler[k]);
+ dml2_printf("DML::%s: k=%d, NoTimeForPrefetch=%d\n", __func__, k, mode_lib->ms.NoTimeForPrefetch[k]);
}
}
@@ -8683,20 +8784,15 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
mode_lib->ms.support.VRatioInPrefetchSupported = true;
for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
- if (mode_lib->ms.VRatioPreY[k] > __DML2_CALCS_MAX_VRATIO_PRE_ENHANCE_PREFETCH_ACC__ ||
- mode_lib->ms.VRatioPreC[k] > __DML2_CALCS_MAX_VRATIO_PRE_ENHANCE_PREFETCH_ACC__) {
+ if (mode_lib->ms.VRatioPreY[k] > __DML2_CALCS_MAX_VRATIO_PRE__ ||
+ mode_lib->ms.VRatioPreC[k] > __DML2_CALCS_MAX_VRATIO_PRE__) {
mode_lib->ms.support.VRatioInPrefetchSupported = false;
+ dml2_printf("DML::%s: k=%d VRatioPreY = %f (should be <= %f)\n", __func__, k, mode_lib->ms.VRatioPreY[k], __DML2_CALCS_MAX_VRATIO_PRE__);
+ dml2_printf("DML::%s: k=%d VRatioPreC = %f (should be <= %f)\n", __func__, k, mode_lib->ms.VRatioPreC[k], __DML2_CALCS_MAX_VRATIO_PRE__);
dml2_printf("DML::%s: VRatioInPrefetchSupported = %u\n", __func__, mode_lib->ms.support.VRatioInPrefetchSupported);
}
}
- s->AnyLinesForVMOrRowTooLarge = false;
- for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
- if (mode_lib->ms.LinesForDPTERow[k] >= 16 || mode_lib->ms.LinesForVM[k] >= 32) {
- s->AnyLinesForVMOrRowTooLarge = true;
- }
- }
-
// Only do urg vs prefetch bandwidth check, flip schedule check, power saving feature support check IF the Prefetch Schedule Check is ok
if (mode_lib->ms.support.PrefetchSupported) {
for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
@@ -8845,6 +8941,7 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
mode_lib->ms.dpte_row_height_chroma[k],
mode_lib->ms.use_one_row_for_frame_flip[k],
mode_lib->ip.max_flip_time_us,
+ mode_lib->ip.max_flip_time_lines,
s->per_pipe_flip_bytes[k],
mode_lib->ms.meta_row_bytes[k],
s->meta_row_height_luma[k],
@@ -8932,6 +9029,9 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
s->mSOCParameters.USRRetrainingLatency = 0;
s->mSOCParameters.SMNLatency = 0;
s->mSOCParameters.g6_temp_read_blackout_us = get_g6_temp_read_blackout_us(&mode_lib->soc, (unsigned int)(mode_lib->ms.uclk_freq_mhz * 1000), in_out_params->min_clk_index);
+ s->mSOCParameters.max_urgent_latency_us = get_max_urgent_latency_us(&mode_lib->soc.qos_parameters.qos_params.dcn4x, mode_lib->ms.uclk_freq_mhz, mode_lib->ms.FabricClock, in_out_params->min_clk_index);
+ s->mSOCParameters.df_response_time_us = mode_lib->soc.qos_parameters.qos_params.dcn4x.df_qos_response_time_fclk_cycles / mode_lib->ms.FabricClock;
+ s->mSOCParameters.qos_type = mode_lib->soc.qos_parameters.qos_type;
CalculateWatermarks_params->display_cfg = display_cfg;
CalculateWatermarks_params->USRRetrainingRequired = false;
@@ -8951,7 +9051,6 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
CalculateWatermarks_params->DETBufferSizeC = mode_lib->ms.DETBufferSizeC;
CalculateWatermarks_params->SwathHeightY = mode_lib->ms.SwathHeightY;
CalculateWatermarks_params->SwathHeightC = mode_lib->ms.SwathHeightC;
- //CalculateWatermarks_params->LBBitPerPixel = 57; // FIXME_STAGE2, need a new ip param?
CalculateWatermarks_params->SwathWidthY = mode_lib->ms.SwathWidthY;
CalculateWatermarks_params->SwathWidthC = mode_lib->ms.SwathWidthC;
CalculateWatermarks_params->DPPPerSurface = mode_lib->ms.NoOfDPP;
@@ -8979,29 +9078,24 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
CalculateWatermarks_params->VActiveLatencyHidingUs = mode_lib->ms.VActiveLatencyHidingUs;
CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(&mode_lib->scratch, CalculateWatermarks_params);
- }
+ calculate_pstate_keepout_dst_lines(display_cfg, &mode_lib->ms.support.watermarks, s->dummy_integer_array[0]);
+ }
+ dml2_printf("DML::%s: Done prefetch calculation\n", __func__);
// End of Prefetch Check
- dml2_printf("DML::%s: Done prefetch calculation\n", __func__);
+ mode_lib->ms.support.max_urgent_latency_us = s->mSOCParameters.max_urgent_latency_us;
//Re-ordering Buffer Support Check
- mode_lib->ms.support.max_urgent_latency_us
- = mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->ms.qos_param_index].maximum_latency_when_urgent_uclk_cycles / mode_lib->ms.uclk_freq_mhz
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.umc_max_latency_margin / 100.0)
- + mode_lib->soc.qos_parameters.qos_params.dcn4.mall_overhead_fclk_cycles / mode_lib->ms.FabricClock
- + mode_lib->soc.qos_parameters.qos_params.dcn4.max_round_trip_to_furthest_cs_fclk_cycles / mode_lib->ms.FabricClock
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin / 100.0);
-
- if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4) {
+ if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4x) {
if (((mode_lib->ip.rob_buffer_size_kbytes - mode_lib->ip.pixel_chunk_size_kbytes) * 1024
- / mode_lib->ms.support.non_urg_bandwidth_required_flip[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]) >= mode_lib->ms.support.max_urgent_latency_us) {
+ / mode_lib->ms.support.non_urg_bandwidth_required_flip[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]) >= s->mSOCParameters.max_urgent_latency_us) {
mode_lib->ms.support.ROBSupport = true;
} else {
mode_lib->ms.support.ROBSupport = false;
}
} else {
- if (mode_lib->ip.rob_buffer_size_kbytes * 1024 >= mode_lib->soc.qos_parameters.qos_params.dcn3.loaded_round_trip_latency_fclk_cycles * mode_lib->soc.fabric_datapath_to_dcn_data_return_bytes) {
+ if (mode_lib->ip.rob_buffer_size_kbytes * 1024 >= mode_lib->soc.qos_parameters.qos_params.dcn32x.loaded_round_trip_latency_fclk_cycles * mode_lib->soc.fabric_datapath_to_dcn_data_return_bytes) {
mode_lib->ms.support.ROBSupport = true;
} else {
mode_lib->ms.support.ROBSupport = false;
@@ -9024,15 +9118,12 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
mode_lib->ms.dram_change_vactive_det_fill_delay_us);
#ifdef __DML_VBA_DEBUG__
- dml2_printf("DML::%s: max_urgent_latency_us = %f\n", __func__, mode_lib->ms.support.max_urgent_latency_us);
+ dml2_printf("DML::%s: max_urgent_latency_us = %f\n", __func__, s->mSOCParameters.max_urgent_latency_us);
dml2_printf("DML::%s: ROBSupport = %u\n", __func__, mode_lib->ms.support.ROBSupport);
#endif
/*Mode Support, Voltage State and SOC Configuration*/
{
- // s->dram_clock_change_support = 1;
- // s->f_clock_change_support = 1;
-
if (mode_lib->ms.support.ScaleRatioAndTapsSupport
&& mode_lib->ms.support.SourceFormatPixelAndScanSupport
&& mode_lib->ms.support.ViewportSizeSupport
@@ -9043,9 +9134,7 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
&& !mode_lib->ms.support.ExceededMultistreamSlots
&& !mode_lib->ms.support.MSOOrODMSplitWithNonDPLink
&& !mode_lib->ms.support.NotEnoughLanesForMSO
- //&& mode_lib->ms.support.LinkCapacitySupport == true // FIXME_STAGE2
&& !mode_lib->ms.support.P2IWith420
- && !mode_lib->ms.support.DSCOnlyIfNecessaryWithBPP
&& !mode_lib->ms.support.DSC422NativeNotSupported
&& mode_lib->ms.support.DSCSlicesODMModeSupported
&& !mode_lib->ms.support.NotEnoughDSCUnits
@@ -9113,7 +9202,7 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
#if defined(__DML_VBA_DEBUG__)
if (!mode_lib->ms.support.ModeSupport)
- dml2_print_dml_mode_support_info(&mode_lib->ms.support, true);
+ dml2_print_mode_support_info(&mode_lib->ms.support, true);
dml2_printf("DML::%s: --- DONE --- \n", __func__);
#endif
@@ -9132,6 +9221,10 @@ unsigned int dml2_core_calcs_mode_support_ex(struct dml2_core_calcs_mode_support
*in_out_params->out_evaluation_info = in_out_params->mode_lib->ms.support;
dml2_printf("DML::%s: is_mode_support = %u (min_clk_index=%d)\n", __func__, result, in_out_params->min_clk_index);
+
+ for (unsigned int k = 0; k < in_out_params->in_display_cfg->num_planes; k++)
+ dml2_printf("DML::%s: plane_%d: reserved_vblank_time_ns = %u\n", __func__, k, in_out_params->in_display_cfg->plane_descriptors[k].overrides.reserved_vblank_time_ns);
+
dml2_printf("DML::%s: ------------- DONE ----------\n", __func__);
return result;
@@ -9373,11 +9466,9 @@ static void CalculateMetaAndPTETimes(struct dml2_core_shared_CalculateMetaAndPTE
} else {
dpte_groups_per_row_luma_ub = (unsigned int)(math_ceil2((double)p->dpte_row_width_luma_ub[k] / (double)dpte_group_width_luma, 1.0));
}
-#ifdef DML_VM_PTE_ADL_PATCH_EN
if (dpte_groups_per_row_luma_ub <= 2) {
dpte_groups_per_row_luma_ub = dpte_groups_per_row_luma_ub + 1;
}
-#endif
dml2_printf("DML::%s: k=%u, use_one_row_for_frame = %u\n", __func__, k, p->use_one_row_for_frame[k]);
dml2_printf("DML::%s: k=%u, dpte_group_bytes = %u\n", __func__, k, p->dpte_group_bytes[k]);
dml2_printf("DML::%s: k=%u, PTERequestSizeY = %u\n", __func__, k, p->PTERequestSizeY[k]);
@@ -9406,11 +9497,9 @@ static void CalculateMetaAndPTETimes(struct dml2_core_shared_CalculateMetaAndPTE
} else {
dpte_groups_per_row_chroma_ub = (unsigned int)(math_ceil2((double)p->dpte_row_width_chroma_ub[k] / (double)dpte_group_width_chroma, 1.0));
}
-#ifdef DML_VM_PTE_ADL_PATCH_EN
if (dpte_groups_per_row_chroma_ub <= 2) {
dpte_groups_per_row_chroma_ub = dpte_groups_per_row_chroma_ub + 1;
}
-#endif
dml2_printf("DML::%s: k=%u, dpte_row_width_chroma_ub = %u\n", __func__, k, p->dpte_row_width_chroma_ub[k]);
dml2_printf("DML::%s: k=%u, dpte_group_width_chroma = %u\n", __func__, k, dpte_group_width_chroma);
dml2_printf("DML::%s: k=%u, dpte_groups_per_row_chroma_ub = %u\n", __func__, k, dpte_groups_per_row_chroma_ub);
@@ -9535,17 +9624,16 @@ static void CalculateVMGroupAndRequestTimes(
line_time = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz;
-#ifdef DML_VM_PTE_ADL_PATCH_EN
- if (num_group_per_lower_vm_stage_flip <= 2) {
- num_group_per_lower_vm_stage_flip = num_group_per_lower_vm_stage_flip + 1;
- }
+ if (num_group_per_lower_vm_stage_pref > 0)
+ TimePerVMGroupVBlank[k] = dst_y_per_vm_vblank[k] * line_time / num_group_per_lower_vm_stage_pref;
+ else
+ TimePerVMGroupVBlank[k] = 0;
+
+ if (num_group_per_lower_vm_stage_flip > 0)
+ TimePerVMGroupFlip[k] = dst_y_per_vm_flip[k] * line_time / num_group_per_lower_vm_stage_flip;
+ else
+ TimePerVMGroupFlip[k] = 0;
- if (num_group_per_lower_vm_stage_pref <= 2) {
- num_group_per_lower_vm_stage_pref = num_group_per_lower_vm_stage_pref + 1;
- }
-#endif
- TimePerVMGroupVBlank[k] = dst_y_per_vm_vblank[k] * line_time / num_group_per_lower_vm_stage_pref;
- TimePerVMGroupFlip[k] = dst_y_per_vm_flip[k] * line_time / num_group_per_lower_vm_stage_flip;
if (num_req_per_lower_vm_stage_pref > 0)
TimePerVMRequestVBlank[k] = dst_y_per_vm_vblank[k] * line_time / num_req_per_lower_vm_stage_pref;
else
@@ -9599,10 +9687,6 @@ static void CalculateStutterEfficiency(struct dml2_core_internal_scratch *scratc
bool FoundCriticalSurface = false;
double LastZ8StutterPeriod = 0;
- unsigned int SwathSizeCriticalSurface;
- unsigned int LastChunkOfSwathSize;
- unsigned int MissingPartOfLastSwathOfDETSize;
-
memset(l, 0, sizeof(struct dml2_core_calcs_CalculateStutterEfficiency_locals));
for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) {
@@ -9777,7 +9861,7 @@ static void CalculateStutterEfficiency(struct dml2_core_internal_scratch *scratc
l->StutterBurstTime = l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer
/ (p->ReturnBW * (p->hw_debug5 ? 1 : l->AverageDCCCompressionRate)) +
(*p->StutterPeriod * p->TotalDataReadBandwidth - l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer)
- / math_max2(p->DCFCLK * 64, p->ReturnBW * (p->hw_debug5 ? 1 : l->AverageDCCCompressionRate)) +
+ / math_min2(p->DCFCLK * 64, p->ReturnBW * (p->hw_debug5 ? 1 : l->AverageDCCCompressionRate)) +
*p->StutterPeriod * l->TotalRowReadBandwidth / p->ReturnBW;
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: Part 1 = %f\n", __func__, l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer / p->ReturnBW / (p->hw_debug5 ? 1 : l->AverageDCCCompressionRate));
@@ -9871,19 +9955,11 @@ static void CalculateStutterEfficiency(struct dml2_core_internal_scratch *scratc
dml2_printf("DML::%s: Z8NumberOfStutterBurstsPerFrame = %u\n", __func__, *p->Z8NumberOfStutterBurstsPerFrame);
#endif
- SwathSizeCriticalSurface = (unsigned int)(l->BytePerPixelYCriticalSurface * l->SwathHeightYCriticalSurface * math_ceil2(l->SwathWidthYCriticalSurface, l->BlockWidth256BytesYCriticalSurface));
- LastChunkOfSwathSize = SwathSizeCriticalSurface % (p->PixelChunkSizeInKByte * 1024);
- MissingPartOfLastSwathOfDETSize = (unsigned int)(math_ceil2(l->DETBufferSizeYCriticalSurface, SwathSizeCriticalSurface) - l->DETBufferSizeYCriticalSurface);
-
- *p->DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE = !(!p->UnboundedRequestEnabled && (p->NumberOfActiveSurfaces == 1) && l->SinglePlaneCriticalSurface && l->SinglePipeCriticalSurface && (LastChunkOfSwathSize > 0) &&
- (LastChunkOfSwathSize <= 4096) && (MissingPartOfLastSwathOfDETSize > 0) && (MissingPartOfLastSwathOfDETSize <= LastChunkOfSwathSize));
+ *p->DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE = !(!p->UnboundedRequestEnabled && (p->NumberOfActiveSurfaces == 1) && l->SinglePlaneCriticalSurface && l->SinglePipeCriticalSurface);
#ifdef __DML_VBA_DEBUG__
- dml2_printf("DML::%s: SwathSizeCriticalSurface = %u\n", __func__, SwathSizeCriticalSurface);
dml2_printf("DML::%s: DETBufferSizeYCriticalSurface = %u\n", __func__, l->DETBufferSizeYCriticalSurface);
dml2_printf("DML::%s: PixelChunkSizeInKByte = %u\n", __func__, p->PixelChunkSizeInKByte);
- dml2_printf("DML::%s: LastChunkOfSwathSize = %u\n", __func__, LastChunkOfSwathSize);
- dml2_printf("DML::%s: MissingPartOfLastSwathOfDETSize = %u\n", __func__, MissingPartOfLastSwathOfDETSize);
dml2_printf("DML::%s: DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE = %u\n", __func__, *p->DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE);
#endif
}
@@ -9928,14 +10004,14 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
mode_lib->mp.num_active_pipes = dml_get_num_active_pipes(display_cfg->num_planes, cfg_support_info);
dml_calc_pipe_plane_mapping(cfg_support_info, mode_lib->mp.pipe_plane);
- mode_lib->mp.Dcfclk = programming->min_clocks.dcn4.active.dcfclk_khz / 1000.0;
- mode_lib->mp.FabricClock = programming->min_clocks.dcn4.active.fclk_khz / 1000.0;
- mode_lib->mp.dram_bw_mbps = uclk_khz_to_dram_bw_mbps(programming->min_clocks.dcn4.active.uclk_khz, &mode_lib->soc.clk_table.dram_config);
- mode_lib->mp.uclk_freq_mhz = programming->min_clocks.dcn4.active.uclk_khz / 1000.0;
- mode_lib->mp.GlobalDPPCLK = programming->min_clocks.dcn4.dpprefclk_khz / 1000.0;
- s->SOCCLK = (double)programming->min_clocks.dcn4.socclk_khz / 1000;
- mode_lib->mp.qos_param_index = get_qos_param_index(programming->min_clocks.dcn4.active.uclk_khz, mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params);
- mode_lib->mp.active_min_uclk_dpm_index = get_active_min_uclk_dpm_index(programming->min_clocks.dcn4.active.uclk_khz, &mode_lib->soc.clk_table);
+ mode_lib->mp.Dcfclk = programming->min_clocks.dcn4x.active.dcfclk_khz / 1000.0;
+ mode_lib->mp.FabricClock = programming->min_clocks.dcn4x.active.fclk_khz / 1000.0;
+ mode_lib->mp.dram_bw_mbps = uclk_khz_to_dram_bw_mbps(programming->min_clocks.dcn4x.active.uclk_khz, &mode_lib->soc.clk_table.dram_config);
+ mode_lib->mp.uclk_freq_mhz = programming->min_clocks.dcn4x.active.uclk_khz / 1000.0;
+ mode_lib->mp.GlobalDPPCLK = programming->min_clocks.dcn4x.dpprefclk_khz / 1000.0;
+ s->SOCCLK = (double)programming->min_clocks.dcn4x.socclk_khz / 1000;
+ mode_lib->mp.qos_param_index = get_qos_param_index(programming->min_clocks.dcn4x.active.uclk_khz, mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params);
+ mode_lib->mp.active_min_uclk_dpm_index = get_active_min_uclk_dpm_index(programming->min_clocks.dcn4x.active.uclk_khz, &mode_lib->soc.clk_table);
for (k = 0; k < s->num_active_planes; ++k) {
unsigned int stream_index = display_cfg->plane_descriptors[k].stream_index;
@@ -9970,18 +10046,18 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
for (k = 0; k < s->num_active_planes; ++k) {
mode_lib->mp.NoOfDPP[k] = cfg_support_info->plane_support_info[k].dpps_used;
- mode_lib->mp.Dppclk[k] = programming->plane_programming[k].min_clocks.dcn4.dppclk_khz / 1000.0;
+ mode_lib->mp.Dppclk[k] = programming->plane_programming[k].min_clocks.dcn4x.dppclk_khz / 1000.0;
dml2_assert(mode_lib->mp.Dppclk[k] > 0);
}
for (k = 0; k < s->num_active_planes; ++k) {
unsigned int stream_index = display_cfg->plane_descriptors[k].stream_index;
- mode_lib->mp.DSCCLK[k] = programming->stream_programming[stream_index].min_clocks.dcn4.dscclk_khz / 1000.0;
+ mode_lib->mp.DSCCLK[k] = programming->stream_programming[stream_index].min_clocks.dcn4x.dscclk_khz / 1000.0;
dml2_printf("DML::%s: k=%d stream_index=%d, mode_lib->mp.DSCCLK = %f\n", __func__, k, stream_index, mode_lib->mp.DSCCLK[k]);
}
- mode_lib->mp.Dispclk = programming->min_clocks.dcn4.dispclk_khz / 1000.0;
- mode_lib->mp.DCFCLKDeepSleep = programming->min_clocks.dcn4.deepsleep_dcfclk_khz / 1000.0;
+ mode_lib->mp.Dispclk = programming->min_clocks.dcn4x.dispclk_khz / 1000.0;
+ mode_lib->mp.DCFCLKDeepSleep = programming->min_clocks.dcn4x.deepsleep_dcfclk_khz / 1000.0;
dml2_assert(mode_lib->mp.Dcfclk > 0);
dml2_assert(mode_lib->mp.FabricClock > 0);
@@ -10462,11 +10538,16 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
calculate_tdlut_setting(&mode_lib->scratch, calculate_tdlut_setting_params);
}
+ if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn3)
+ s->ReorderingBytes = (unsigned int)(mode_lib->soc.clk_table.dram_config.channel_count * math_max3(mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_out_of_order_return_per_channel_pixel_only_bytes,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_out_of_order_return_per_channel_vm_only_bytes));
+
CalculateExtraLatency(
display_cfg,
mode_lib->ip.rob_buffer_size_kbytes,
- 0, //mode_lib->soc.round_trip_ping_latency_dcfclk_cycles,
- s->ReorderBytes,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.loaded_round_trip_latency_fclk_cycles,
+ s->ReorderingBytes,
mode_lib->mp.Dcfclk,
mode_lib->mp.FabricClock,
mode_lib->ip.pixel_chunk_size_kbytes,
@@ -10551,32 +10632,32 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
mode_lib->mp.excess_vactive_fill_bw_c);
mode_lib->mp.UrgentLatency = CalculateUrgentLatency(
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.base_latency_us,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.base_latency_pixel_vm_us,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.base_latency_vm_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.base_latency_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.base_latency_pixel_vm_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.base_latency_vm_us,
mode_lib->soc.do_urgent_latency_adjustment,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.scaling_factor_fclk_us,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.scaling_factor_mhz,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.scaling_factor_fclk_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.scaling_factor_mhz,
mode_lib->mp.FabricClock,
mode_lib->mp.uclk_freq_mhz,
mode_lib->soc.qos_parameters.qos_type,
- mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->mp.qos_param_index].urgent_ramp_uclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.df_qos_response_time_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.max_round_trip_to_furthest_cs_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.mall_overhead_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.umc_urgent_ramp_latency_margin,
- mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin);
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->mp.qos_param_index].urgent_ramp_uclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.df_qos_response_time_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.max_round_trip_to_furthest_cs_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.mall_overhead_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_urgent_ramp_latency_margin,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_max_transport_latency_margin);
mode_lib->mp.TripToMemory = CalculateTripToMemory(
mode_lib->mp.UrgentLatency,
mode_lib->mp.FabricClock,
mode_lib->mp.uclk_freq_mhz,
mode_lib->soc.qos_parameters.qos_type,
- mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->mp.qos_param_index].trip_to_memory_uclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.max_round_trip_to_furthest_cs_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.mall_overhead_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.umc_max_latency_margin,
- mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin);
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->mp.qos_param_index].trip_to_memory_uclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.max_round_trip_to_furthest_cs_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.mall_overhead_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_max_latency_margin,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_max_transport_latency_margin);
mode_lib->mp.TripToMemory = math_max2(mode_lib->mp.UrgentLatency, mode_lib->mp.TripToMemory);
@@ -10585,38 +10666,40 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
mode_lib->mp.FabricClock,
mode_lib->mp.uclk_freq_mhz,
mode_lib->soc.qos_parameters.qos_type,
- mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->mp.qos_param_index].meta_trip_to_memory_uclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.meta_trip_adder_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.umc_max_latency_margin,
- mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin);
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->mp.qos_param_index].meta_trip_to_memory_uclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.meta_trip_adder_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_max_latency_margin,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_max_transport_latency_margin);
for (k = 0; k < s->num_active_planes; ++k) {
bool cursor_not_enough_urgent_latency_hiding = 0;
- double line_time_us;
+ double line_time_us = 0.0;
- calculate_cursor_req_attributes(
- display_cfg->plane_descriptors[k].cursor.cursor_width,
- display_cfg->plane_descriptors[k].cursor.cursor_bpp,
+ line_time_us = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total /
+ ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
+ if (display_cfg->plane_descriptors[k].cursor.num_cursors > 0) {
+ calculate_cursor_req_attributes(
+ display_cfg->plane_descriptors[k].cursor.cursor_width,
+ display_cfg->plane_descriptors[k].cursor.cursor_bpp,
- // output
- &s->cursor_lines_per_chunk[k],
- &s->cursor_bytes_per_line[k],
- &s->cursor_bytes_per_chunk[k],
- &s->cursor_bytes[k]);
-
- line_time_us = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
-
- calculate_cursor_urgent_burst_factor(
- mode_lib->ip.cursor_buffer_size,
- display_cfg->plane_descriptors[k].cursor.cursor_width,
- s->cursor_bytes_per_chunk[k],
- s->cursor_lines_per_chunk[k],
- line_time_us,
- mode_lib->mp.UrgentLatency,
+ // output
+ &s->cursor_lines_per_chunk[k],
+ &s->cursor_bytes_per_line[k],
+ &s->cursor_bytes_per_chunk[k],
+ &s->cursor_bytes[k]);
+
+ calculate_cursor_urgent_burst_factor(
+ mode_lib->ip.cursor_buffer_size,
+ display_cfg->plane_descriptors[k].cursor.cursor_width,
+ s->cursor_bytes_per_chunk[k],
+ s->cursor_lines_per_chunk[k],
+ line_time_us,
+ mode_lib->mp.UrgentLatency,
- // output
- &mode_lib->mp.UrgentBurstFactorCursor[k],
- &cursor_not_enough_urgent_latency_hiding);
+ // output
+ &mode_lib->mp.UrgentBurstFactorCursor[k],
+ &cursor_not_enough_urgent_latency_hiding);
+ }
mode_lib->mp.UrgentBurstFactorCursorPre[k] = mode_lib->mp.UrgentBurstFactorCursor[k];
CalculateUrgentBurstFactor(
@@ -10676,7 +10759,9 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
mode_lib->mp.TWait[k] = CalculateTWait(
display_cfg->plane_descriptors[k].overrides.reserved_vblank_time_ns,
mode_lib->mp.UrgentLatency,
- mode_lib->mp.TripToMemory);
+ mode_lib->mp.TripToMemory,
+ !dml_is_phantom_pipe(&display_cfg->plane_descriptors[k]) && display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.drr_config.enabled ?
+ get_g6_temp_read_blackout_us(&mode_lib->soc, (unsigned int)(mode_lib->mp.uclk_freq_mhz * 1000), in_out_params->min_clk_index) : 0.0);
myPipe->Dppclk = mode_lib->mp.Dppclk[k];
myPipe->Dispclk = mode_lib->mp.Dispclk;
@@ -10722,7 +10807,6 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
CalculatePrefetchSchedule_params->OutputFormat = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format;
CalculatePrefetchSchedule_params->MaxInterDCNTileRepeaters = mode_lib->ip.max_inter_dcn_tile_repeaters;
CalculatePrefetchSchedule_params->VStartup = s->MaxVStartupLines[k];
- CalculatePrefetchSchedule_params->MaxVStartup = s->MaxVStartupLines[k];
CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->soc.hostvm_min_page_size_kbytes;
CalculatePrefetchSchedule_params->DynamicMetadataEnable = display_cfg->plane_descriptors[k].dynamic_meta_data.enable;
CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ip.dynamic_metadata_vm_enabled;
@@ -10808,9 +10892,13 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
if (mode_lib->mp.dst_y_prefetch[k] < 2)
s->DestinationLineTimesForPrefetchLessThan2 = true;
- if (mode_lib->mp.VRatioPrefetchY[k] > __DML2_CALCS_MAX_VRATIO_PRE_ENHANCE_PREFETCH_ACC__ ||
- mode_lib->mp.VRatioPrefetchC[k] > __DML2_CALCS_MAX_VRATIO_PRE_ENHANCE_PREFETCH_ACC__)
+ if (mode_lib->mp.VRatioPrefetchY[k] > __DML2_CALCS_MAX_VRATIO_PRE__ ||
+ mode_lib->mp.VRatioPrefetchC[k] > __DML2_CALCS_MAX_VRATIO_PRE__) {
s->VRatioPrefetchMoreThanMax = true;
+ dml2_printf("DML::%s: k=%d, VRatioPrefetchY=%f (should not be < %f)\n", __func__, k, mode_lib->mp.VRatioPrefetchY[k], __DML2_CALCS_MAX_VRATIO_PRE__);
+ dml2_printf("DML::%s: k=%d, VRatioPrefetchC=%f (should not be < %f)\n", __func__, k, mode_lib->mp.VRatioPrefetchC[k], __DML2_CALCS_MAX_VRATIO_PRE__);
+ dml2_printf("DML::%s: VRatioPrefetchMoreThanMax = %u\n", __func__, s->VRatioPrefetchMoreThanMax);
+ }
if (mode_lib->mp.NotEnoughUrgentLatencyHiding[k]) {
dml2_printf("DML::%s: k=%u, NotEnoughUrgentLatencyHiding = %u\n", __func__, k, mode_lib->mp.NotEnoughUrgentLatencyHiding[k]);
@@ -10994,6 +11082,7 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
mode_lib->mp.dpte_row_height_chroma[k],
mode_lib->mp.use_one_row_for_frame_flip[k],
mode_lib->ip.max_flip_time_us,
+ mode_lib->ip.max_flip_time_lines,
s->per_pipe_flip_bytes[k],
mode_lib->mp.meta_row_bytes[k],
mode_lib->mp.meta_row_height[k],
@@ -11143,6 +11232,9 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
s->mmSOCParameters.USRRetrainingLatency = 0;
s->mmSOCParameters.SMNLatency = 0;
s->mmSOCParameters.g6_temp_read_blackout_us = get_g6_temp_read_blackout_us(&mode_lib->soc, (unsigned int)(mode_lib->mp.uclk_freq_mhz * 1000), in_out_params->min_clk_index);
+ s->mmSOCParameters.max_urgent_latency_us = get_max_urgent_latency_us(&mode_lib->soc.qos_parameters.qos_params.dcn4x, mode_lib->ms.uclk_freq_mhz, mode_lib->ms.FabricClock, in_out_params->min_clk_index);
+ s->mmSOCParameters.df_response_time_us = mode_lib->soc.qos_parameters.qos_params.dcn4x.df_qos_response_time_fclk_cycles / mode_lib->ms.FabricClock;
+ s->mmSOCParameters.qos_type = mode_lib->soc.qos_parameters.qos_type;
CalculateWatermarks_params->display_cfg = display_cfg;
CalculateWatermarks_params->USRRetrainingRequired = false;
@@ -11162,7 +11254,6 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
CalculateWatermarks_params->DETBufferSizeC = mode_lib->mp.DETBufferSizeC;
CalculateWatermarks_params->SwathHeightY = mode_lib->mp.SwathHeightY;
CalculateWatermarks_params->SwathHeightC = mode_lib->mp.SwathHeightC;
- //CalculateWatermarks_params->LBBitPerPixel = 57; //FIXME_STAGE2
CalculateWatermarks_params->SwathWidthY = mode_lib->mp.SwathWidthY;
CalculateWatermarks_params->SwathWidthC = mode_lib->mp.SwathWidthC;
CalculateWatermarks_params->BytePerPixelDETY = mode_lib->mp.BytePerPixelInDETY;
@@ -11203,6 +11294,8 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
}
}
+ calculate_pstate_keepout_dst_lines(display_cfg, &mode_lib->mp.Watermark, mode_lib->mp.pstate_keepout_dst_lines);
+
dml2_printf("DML::%s: DEBUG stream_index = %0d\n", __func__, display_cfg->plane_descriptors[0].stream_index);
dml2_printf("DML::%s: DEBUG PixelClock = %d kHz\n", __func__, (display_cfg->stream_descriptors[display_cfg->plane_descriptors[0].stream_index].timing.pixel_clock_khz));
@@ -11491,9 +11584,9 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
bool dml2_core_calcs_mode_programming_ex(struct dml2_core_calcs_mode_programming_ex *in_out_params)
{
+ dml2_printf("DML::%s: ------------- START ----------\n", __func__);
bool result = dml_core_mode_programming(in_out_params);
- dml2_printf("DML::%s: ------------- START ----------\n", __func__);
dml2_printf("DML::%s: result = %0d\n", __func__, result);
dml2_printf("DML::%s: ------------- DONE ----------\n", __func__);
return result;
@@ -12186,10 +12279,11 @@ void dml2_core_calcs_get_pipe_regs(const struct dml2_display_cfg *display_cfg,
void dml2_core_calcs_get_global_sync_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, union dml2_global_sync_programming *out, int pipe_index)
{
- out->dcn4.vready_offset_pixels = dml_get_vready_offset(mode_lib, pipe_index);
- out->dcn4.vstartup_lines = dml_get_vstartup_calculated(mode_lib, pipe_index);
- out->dcn4.vupdate_offset_pixels = dml_get_vupdate_offset(mode_lib, pipe_index);
- out->dcn4.vupdate_vupdate_width_pixels = dml_get_vupdate_width(mode_lib, pipe_index);
+ out->dcn4x.vready_offset_pixels = dml_get_vready_offset(mode_lib, pipe_index);
+ out->dcn4x.vstartup_lines = dml_get_vstartup_calculated(mode_lib, pipe_index);
+ out->dcn4x.vupdate_offset_pixels = dml_get_vupdate_offset(mode_lib, pipe_index);
+ out->dcn4x.vupdate_vupdate_width_pixels = dml_get_vupdate_width(mode_lib, pipe_index);
+ out->dcn4x.pstate_keepout_start_lines = dml_get_pstate_keepout_dst_lines(mode_lib, pipe_index);
}
void dml2_core_calcs_get_stream_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_per_stream_programming *out, int pipe_index)
@@ -12197,6 +12291,25 @@ void dml2_core_calcs_get_stream_programming(const struct dml2_core_internal_disp
dml2_core_calcs_get_global_sync_programming(mode_lib, &out->global_sync, pipe_index);
}
+void dml2_core_calcs_get_global_fams2_programming(const struct dml2_core_internal_display_mode_lib *mode_lib,
+ const struct display_configuation_with_meta *display_cfg,
+ struct dmub_cmd_fams2_global_config *fams2_global_config)
+{
+ fams2_global_config->features.bits.enable = display_cfg->stage3.fams2_required;
+
+ if (fams2_global_config->features.bits.enable) {
+ fams2_global_config->features.bits.enable_stall_recovery = true;
+ fams2_global_config->features.bits.allow_delay_check_mode = FAMS2_ALLOW_DELAY_CHECK_FROM_START;
+
+ fams2_global_config->max_allow_delay_us = mode_lib->ip_caps.fams2.max_allow_delay_us;
+ fams2_global_config->lock_wait_time_us = mode_lib->ip_caps.fams2.lock_timeout_us;
+ fams2_global_config->recovery_timeout_us = mode_lib->ip_caps.fams2.recovery_timeout_us;
+ fams2_global_config->hwfq_flip_programming_delay_us = mode_lib->ip_caps.fams2.flip_programming_delay_us;
+
+ fams2_global_config->num_streams = display_cfg->display_config.num_streams;
+ }
+}
+
void dml2_core_calcs_get_stream_fams2_programming(const struct dml2_core_internal_display_mode_lib *mode_lib,
const struct display_configuation_with_meta *display_cfg,
struct dmub_fams2_stream_static_state *fams2_programming,
@@ -12209,6 +12322,11 @@ void dml2_core_calcs_get_stream_fams2_programming(const struct dml2_core_interna
unsigned int i;
+ if (display_cfg->display_config.overrides.all_streams_blanked) {
+ /* stream is blanked, so do nothing */
+ return;
+ }
+
/* from display configuration */
fams2_programming->htotal = (uint16_t)stream_descriptor->timing.h_total;
fams2_programming->vtotal = (uint16_t)stream_descriptor->timing.v_total;
@@ -12368,6 +12486,7 @@ void dml2_core_calcs_get_stream_support_info(const struct dml2_display_cfg *disp
{
double phantom_processing_delay_pix;
unsigned int phantom_processing_delay_lines;
+ unsigned int phantom_min_v_active_lines;
unsigned int phantom_v_active_lines;
unsigned int phantom_v_startup_lines;
unsigned int phantom_v_blank_lines;
@@ -12377,14 +12496,16 @@ void dml2_core_calcs_get_stream_support_info(const struct dml2_display_cfg *disp
phantom_processing_delay_pix = (double)((mode_lib->ip.subvp_fw_processing_delay_us + mode_lib->ip.subvp_pstate_allow_width_us) *
((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[plane_index].stream_index].timing.pixel_clock_khz / 1000));
phantom_processing_delay_lines = (unsigned int)(phantom_processing_delay_pix / (double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[plane_index].stream_index].timing.h_total);
- dml2_core_shared_div_rem(phantom_processing_delay_pix,
+ dml2_core_div_rem(phantom_processing_delay_pix,
display_cfg->stream_descriptors[display_cfg->plane_descriptors[plane_index].stream_index].timing.h_total,
&rem);
if (rem)
phantom_processing_delay_lines++;
phantom_v_startup_lines = dml_get_plane_max_vstartup_lines(mode_lib, plane_index);
- phantom_v_active_lines = phantom_processing_delay_lines + dml_get_plane_subviewport_lines_needed_in_mall(mode_lib, plane_index) + mode_lib->ip.subvp_swath_height_margin_lines;
+ phantom_min_v_active_lines = (unsigned int)math_ceil((double)dml_get_plane_subviewport_lines_needed_in_mall(mode_lib, plane_index) /
+ display_cfg->plane_descriptors[plane_index].composition.scaler_info.plane0.v_ratio);
+ phantom_v_active_lines = phantom_processing_delay_lines + phantom_min_v_active_lines + mode_lib->ip.subvp_swath_height_margin_lines;
// phantom_vblank = max(vbp(vstartup) + vactive + vfp(always 1) + vsync(can be 1), main_vblank)
phantom_v_blank_lines = phantom_v_startup_lines + 1 + 1;
@@ -12396,8 +12517,8 @@ void dml2_core_calcs_get_stream_support_info(const struct dml2_display_cfg *disp
// phantom_vtotal = vactive + vblank
out->phantom_v_total = phantom_v_active_lines + phantom_v_blank_lines;
- out->phantom_min_v_active = dml_get_plane_subviewport_lines_needed_in_mall(mode_lib, plane_index);
- out->phantom_v_startup = dml_get_plane_max_vstartup_lines(mode_lib, plane_index);
+ out->phantom_min_v_active = phantom_min_v_active_lines;
+ out->phantom_v_startup = phantom_v_startup_lines;
out->vblank_reserved_time_us = display_cfg->plane_descriptors[plane_index].overrides.reserved_vblank_time_ns / 1000;
#if defined(__DML_VBA_DEBUG__)
@@ -12418,7 +12539,7 @@ void dml2_core_calcs_get_informative(const struct dml2_core_internal_display_mod
out->informative.mode_support_info.ScaleRatioAndTapsSupport = mode_lib->ms.support.ScaleRatioAndTapsSupport;
out->informative.mode_support_info.SourceFormatPixelAndScanSupport = mode_lib->ms.support.SourceFormatPixelAndScanSupport;
out->informative.mode_support_info.P2IWith420 = mode_lib->ms.support.P2IWith420;
- out->informative.mode_support_info.DSCOnlyIfNecessaryWithBPP = mode_lib->ms.support.DSCOnlyIfNecessaryWithBPP;
+ out->informative.mode_support_info.DSCOnlyIfNecessaryWithBPP = false;
out->informative.mode_support_info.DSC422NativeNotSupported = mode_lib->ms.support.DSC422NativeNotSupported;
out->informative.mode_support_info.LinkRateDoesNotMatchDPVersion = mode_lib->ms.support.LinkRateDoesNotMatchDPVersion;
out->informative.mode_support_info.LinkRateForMultistreamNotIndicated = mode_lib->ms.support.LinkRateForMultistreamNotIndicated;
@@ -12611,7 +12732,7 @@ void dml2_core_calcs_get_informative(const struct dml2_core_internal_display_mod
out->informative.misc.cstate_max_cap_mode = dml_get_cstate_max_cap_mode(mode_lib);
- out->min_clocks.dcn4.dpprefclk_khz = (int unsigned)dml_get_global_dppclk_khz(mode_lib);
+ out->min_clocks.dcn4x.dpprefclk_khz = (int unsigned)dml_get_global_dppclk_khz(mode_lib);
out->informative.qos.max_active_fclk_change_latency_supported = dml_get_fclk_change_latency(mode_lib);
@@ -12724,13 +12845,13 @@ void dml2_core_calcs_get_informative(const struct dml2_core_internal_display_mod
}
}
- out->informative.qos.max_non_urgent_latency_us = mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->mp.qos_param_index].maximum_latency_when_non_urgent_uclk_cycles
- / mode_lib->mp.uclk_freq_mhz * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.umc_max_latency_margin / 100.0)
- + mode_lib->soc.qos_parameters.qos_params.dcn4.mall_overhead_fclk_cycles / mode_lib->mp.FabricClock
- + mode_lib->soc.qos_parameters.qos_params.dcn4.max_round_trip_to_furthest_cs_fclk_cycles / mode_lib->mp.FabricClock
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin / 100.0);
+ out->informative.qos.max_non_urgent_latency_us = mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->mp.qos_param_index].maximum_latency_when_non_urgent_uclk_cycles
+ / mode_lib->mp.uclk_freq_mhz * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_max_latency_margin / 100.0)
+ + mode_lib->soc.qos_parameters.qos_params.dcn4x.mall_overhead_fclk_cycles / mode_lib->mp.FabricClock
+ + mode_lib->soc.qos_parameters.qos_params.dcn4x.max_round_trip_to_furthest_cs_fclk_cycles / mode_lib->mp.FabricClock
+ * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_max_transport_latency_margin / 100.0);
- if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4) {
+ if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4x) {
if (((mode_lib->ip.rob_buffer_size_kbytes - mode_lib->ip.pixel_chunk_size_kbytes) * 1024
/ mode_lib->mp.non_urg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]) >= out->informative.qos.max_non_urgent_latency_us) {
out->informative.misc.ROBUrgencyAvoidance = true;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.h
index b280ab573fbb..df2d1550a14b 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_CORE_DCN4_CALCS_H__
#define __DML2_CORE_DCN4_CALCS_H__
@@ -30,6 +29,7 @@ void dml2_core_calcs_get_informative(const struct dml2_core_internal_display_mod
void dml2_core_calcs_get_stream_support_info(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, struct core_stream_support_info *out, int plane_index);
void dml2_core_calcs_get_mall_allocation(struct dml2_core_internal_display_mode_lib *mode_lib, unsigned int *out, int pipe_index);
void dml2_core_calcs_get_stream_fams2_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, const struct display_configuation_with_meta *display_cfg, struct dmub_fams2_stream_static_state *fams2_programming, enum dml2_uclk_pstate_support_method pstate_method, int plane_index);
+void dml2_core_calcs_get_global_fams2_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, const struct display_configuation_with_meta *display_cfg, struct dmub_cmd_fams2_global_config *fams2_global_config);
void dml2_core_calcs_get_dpte_row_height(unsigned int *dpte_row_height, struct dml2_core_internal_display_mode_lib *mode_lib, bool is_plane1, enum dml2_source_format_class SourcePixelFormat, enum dml2_swizzle_mode SurfaceTiling, enum dml2_rotation_angle ScanDirection, unsigned int pitch, unsigned int GPUVMMinPageSizeKBytes);
void dml2_core_calcs_cursor_dlg_reg(struct dml2_cursor_dlg_regs *cursor_dlg_regs, const struct dml2_get_cursor_dlg_reg *p);
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_factory.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_factory.c
index f56abe9ab919..28394de02885 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_factory.c
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#include "dml2_core_factory.h"
#include "dml2_core_dcn4.h"
#include "dml2_external_lib_deps.h"
@@ -11,7 +10,7 @@ bool dml2_core_create(enum dml2_project_id project_id, struct dml2_core_instance
{
bool result = false;
- if (!out)
+ if (out == 0)
return false;
memset(out, 0, sizeof(struct dml2_core_instance));
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_factory.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_factory.h
index 53636a8f52aa..411c514fe65c 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_factory.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_factory.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_CORE_FACTORY_H__
#define __DML2_CORE_FACTORY_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c
index 81f0a6f19f87..8f3c1c0b1cc1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c
@@ -779,7 +779,7 @@ bool dml2_core_shared_mode_support(struct dml2_core_calcs_mode_support_ex *in_ou
mode_lib->ms.max_dppclk_freq_mhz = (double)min_clk_table->max_clocks_khz.dppclk / 1000;
mode_lib->ms.uclk_freq_mhz = dram_bw_kbps_to_uclk_mhz(min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps, &mode_lib->soc.clk_table.dram_config);
mode_lib->ms.dram_bw_mbps = ((double)min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps / 1000);
- mode_lib->ms.qos_param_index = get_qos_param_index((unsigned int)(mode_lib->ms.uclk_freq_mhz * 1000.0), mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params);
+ mode_lib->ms.qos_param_index = get_qos_param_index((unsigned int)(mode_lib->ms.uclk_freq_mhz * 1000.0), mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params);
mode_lib->ms.active_min_uclk_dpm_index = get_active_min_uclk_dpm_index((unsigned int)(mode_lib->ms.uclk_freq_mhz * 1000.0), &mode_lib->soc.clk_table);
#if defined(__DML_VBA_DEBUG__)
@@ -1776,32 +1776,32 @@ bool dml2_core_shared_mode_support(struct dml2_core_calcs_mode_support_ex *in_ou
#endif
mode_lib->ms.UrgLatency = CalculateUrgentLatency(
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.base_latency_us,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.base_latency_pixel_vm_us,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.base_latency_vm_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.base_latency_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.base_latency_pixel_vm_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.base_latency_vm_us,
mode_lib->soc.do_urgent_latency_adjustment,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.scaling_factor_fclk_us,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.scaling_factor_mhz,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.scaling_factor_fclk_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.scaling_factor_mhz,
mode_lib->ms.FabricClock,
mode_lib->ms.uclk_freq_mhz,
mode_lib->soc.qos_parameters.qos_type,
- mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->ms.qos_param_index].urgent_ramp_uclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.df_qos_response_time_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.max_round_trip_to_furthest_cs_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.mall_overhead_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.umc_urgent_ramp_latency_margin,
- mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin);
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->ms.qos_param_index].urgent_ramp_uclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.df_qos_response_time_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.max_round_trip_to_furthest_cs_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.mall_overhead_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_urgent_ramp_latency_margin,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_max_transport_latency_margin);
mode_lib->ms.TripToMemory = CalculateTripToMemory(
mode_lib->ms.UrgLatency,
mode_lib->ms.FabricClock,
mode_lib->ms.uclk_freq_mhz,
mode_lib->soc.qos_parameters.qos_type,
- mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->ms.qos_param_index].trip_to_memory_uclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.max_round_trip_to_furthest_cs_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.mall_overhead_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.umc_max_latency_margin,
- mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin);
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->ms.qos_param_index].trip_to_memory_uclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.max_round_trip_to_furthest_cs_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.mall_overhead_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_max_latency_margin,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_max_transport_latency_margin);
mode_lib->ms.TripToMemory = math_max2(mode_lib->ms.UrgLatency, mode_lib->ms.TripToMemory);
@@ -1995,21 +1995,21 @@ bool dml2_core_shared_mode_support(struct dml2_core_calcs_mode_support_ex *in_ou
mode_lib->ms.support.OutstandingRequestsUrgencyAvoidance = true;
mode_lib->ms.support.avg_urgent_latency_us
- = (mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->ms.qos_param_index].average_latency_when_urgent_uclk_cycles / mode_lib->ms.uclk_freq_mhz
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.umc_average_latency_margin / 100.0)
- + mode_lib->soc.qos_parameters.qos_params.dcn4.average_transport_distance_fclk_cycles / mode_lib->ms.FabricClock)
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_average_transport_latency_margin / 100.0);
+ = (mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->ms.qos_param_index].average_latency_when_urgent_uclk_cycles / mode_lib->ms.uclk_freq_mhz
+ * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_average_latency_margin / 100.0)
+ + mode_lib->soc.qos_parameters.qos_params.dcn4x.average_transport_distance_fclk_cycles / mode_lib->ms.FabricClock)
+ * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_average_transport_latency_margin / 100.0);
mode_lib->ms.support.avg_non_urgent_latency_us
- = (mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->ms.qos_param_index].average_latency_when_non_urgent_uclk_cycles / mode_lib->ms.uclk_freq_mhz
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.umc_average_latency_margin / 100.0)
- + mode_lib->soc.qos_parameters.qos_params.dcn4.average_transport_distance_fclk_cycles / mode_lib->ms.FabricClock)
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_average_transport_latency_margin / 100.0);
+ = (mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->ms.qos_param_index].average_latency_when_non_urgent_uclk_cycles / mode_lib->ms.uclk_freq_mhz
+ * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_average_latency_margin / 100.0)
+ + mode_lib->soc.qos_parameters.qos_params.dcn4x.average_transport_distance_fclk_cycles / mode_lib->ms.FabricClock)
+ * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_average_transport_latency_margin / 100.0);
double outstanding_latency_us = 0;
for (k = 0; k < mode_lib->ms.num_active_planes; k++) {
- if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4) {
+ if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4x) {
outstanding_latency_us = (mode_lib->soc.max_outstanding_reqs * mode_lib->ms.support.request_size_bytes_luma[k]
/ (mode_lib->ms.DCFCLK * mode_lib->soc.return_bus_width_bytes));
@@ -2029,7 +2029,7 @@ bool dml2_core_shared_mode_support(struct dml2_core_calcs_mode_support_ex *in_ou
#endif
}
- if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4 && mode_lib->ms.BytePerPixelC[k] > 0) {
+ if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4x && mode_lib->ms.BytePerPixelC[k] > 0) {
outstanding_latency_us = (mode_lib->soc.max_outstanding_reqs * mode_lib->ms.support.request_size_bytes_chroma[k]
/ (mode_lib->ms.DCFCLK * mode_lib->soc.return_bus_width_bytes));
@@ -2242,11 +2242,15 @@ bool dml2_core_shared_mode_support(struct dml2_core_calcs_mode_support_ex *in_ou
}
double min_return_bw_for_latency = mode_lib->ms.support.urg_bandwidth_available_min_latency[dml2_core_internal_soc_state_sys_active];
+ if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn3)
+ s->ReorderingBytes = (unsigned int)(mode_lib->soc.clk_table.dram_config.channel_count * math_max3(mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_out_of_order_return_per_channel_pixel_only_bytes,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_out_of_order_return_per_channel_vm_only_bytes));
CalculateExtraLatency(
display_cfg,
mode_lib->ip.rob_buffer_size_kbytes,
- 0, //mode_lib->soc.round_trip_ping_latency_dcfclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.loaded_round_trip_latency_fclk_cycles,
s->ReorderingBytes,
mode_lib->ms.DCFCLK,
mode_lib->ms.FabricClock,
@@ -2713,13 +2717,13 @@ bool dml2_core_shared_mode_support(struct dml2_core_calcs_mode_support_ex *in_ou
//Re-ordering Buffer Support Check
mode_lib->ms.support.max_urgent_latency_us
- = mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->ms.qos_param_index].maximum_latency_when_urgent_uclk_cycles / mode_lib->ms.uclk_freq_mhz
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.umc_max_latency_margin / 100.0)
- + mode_lib->soc.qos_parameters.qos_params.dcn4.mall_overhead_fclk_cycles / mode_lib->ms.FabricClock
- + mode_lib->soc.qos_parameters.qos_params.dcn4.max_round_trip_to_furthest_cs_fclk_cycles / mode_lib->ms.FabricClock
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin / 100.0);
+ = mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->ms.qos_param_index].maximum_latency_when_urgent_uclk_cycles / mode_lib->ms.uclk_freq_mhz
+ * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_max_latency_margin / 100.0)
+ + mode_lib->soc.qos_parameters.qos_params.dcn4x.mall_overhead_fclk_cycles / mode_lib->ms.FabricClock
+ + mode_lib->soc.qos_parameters.qos_params.dcn4x.max_round_trip_to_furthest_cs_fclk_cycles / mode_lib->ms.FabricClock
+ * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_max_transport_latency_margin / 100.0);
- if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4) {
+ if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4x) {
if (((mode_lib->ip.rob_buffer_size_kbytes - mode_lib->ip.pixel_chunk_size_kbytes) * 1024
/ mode_lib->ms.support.non_urg_bandwidth_required_flip[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]) >= mode_lib->ms.support.max_urgent_latency_us) {
mode_lib->ms.support.ROBSupport = true;
@@ -2727,7 +2731,7 @@ bool dml2_core_shared_mode_support(struct dml2_core_calcs_mode_support_ex *in_ou
mode_lib->ms.support.ROBSupport = false;
}
} else {
- if (mode_lib->ip.rob_buffer_size_kbytes * 1024 >= mode_lib->soc.qos_parameters.qos_params.dcn3.loaded_round_trip_latency_fclk_cycles * mode_lib->soc.fabric_datapath_to_dcn_data_return_bytes) {
+ if (mode_lib->ip.rob_buffer_size_kbytes * 1024 >= mode_lib->soc.qos_parameters.qos_params.dcn32x.loaded_round_trip_latency_fclk_cycles * mode_lib->soc.fabric_datapath_to_dcn_data_return_bytes) {
mode_lib->ms.support.ROBSupport = true;
} else {
mode_lib->ms.support.ROBSupport = false;
@@ -5050,7 +5054,7 @@ static void calculate_mcache_row_bytes(
unsigned int meta_per_mvmpg_per_channel_ub = 0;
if (p->gpuvm_enable) {
- meta_per_mvmpg_per_channel = (float)vmpg_bytes / 256 / p->num_chans;
+ meta_per_mvmpg_per_channel = (float)vmpg_bytes / (float)256 / p->num_chans;
//but using the est_blk_per_vmpg between 2 and 4, to be not as pessimestic
if (p->surf_vert && vmpg_bytes > blk_bytes) {
@@ -5059,7 +5063,7 @@ static void calculate_mcache_row_bytes(
*p->dcc_dram_bw_nom_overhead_factor = 1 + math_max2(1.0 / 256.0, math_ceil2(meta_per_mvmpg_per_channel, p->mem_word_bytes) / (256 * meta_per_mvmpg_per_channel)); // dcc_dr_oh_nom
} else {
- meta_per_mvmpg_per_channel = (float)blk_bytes / 256 / p->num_chans;
+ meta_per_mvmpg_per_channel = (float)blk_bytes / (float)256 / p->num_chans;
if (!p->surf_vert)
*p->dcc_dram_bw_nom_overhead_factor = 1 + 1.0 / 256.0;
@@ -5881,7 +5885,7 @@ static double CalculateUrgentLatency(
double fabric_max_transport_latency_margin)
{
double urgent_latency = 0;
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
urgent_latency = (df_qos_response_time_fclk_cycles + mall_overhead_fclk_cycles) / FabricClock
+ max_round_trip_to_furthest_cs_fclk_cycles / FabricClock * (1 + fabric_max_transport_latency_margin / 100.0)
+ urgent_ramp_uclk_cycles / uclk_freq_mhz * (1 + umc_urgent_ramp_latency_margin / 100.0);
@@ -5892,7 +5896,7 @@ static double CalculateUrgentLatency(
}
}
#ifdef __DML_VBA_DEBUG__
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
dml2_printf("DML::%s: qos_type = %d\n", __func__, qos_type);
dml2_printf("DML::%s: urgent_ramp_uclk_cycles = %d\n", __func__, urgent_ramp_uclk_cycles);
dml2_printf("DML::%s: uclk_freq_mhz = %f\n", __func__, uclk_freq_mhz);
@@ -5922,7 +5926,7 @@ static double CalculateTripToMemory(
double fabric_max_transport_latency_margin)
{
double trip_to_memory_us;
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
trip_to_memory_us = mall_overhead_fclk_cycles / FabricClock
+ max_round_trip_to_furthest_cs_fclk_cycles / FabricClock * (1.0 + fabric_max_transport_latency_margin / 100.0)
+ trip_to_memory_uclk_cycles / uclk_freq_mhz * (1.0 + umc_max_latency_margin / 100.0);
@@ -5931,7 +5935,7 @@ static double CalculateTripToMemory(
}
#ifdef __DML_VBA_DEBUG__
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
dml2_printf("DML::%s: qos_type = %d\n", __func__, qos_type);
dml2_printf("DML::%s: max_round_trip_to_furthest_cs_fclk_cycles = %d\n", __func__, max_round_trip_to_furthest_cs_fclk_cycles);
dml2_printf("DML::%s: mall_overhead_fclk_cycles = %d\n", __func__, mall_overhead_fclk_cycles);
@@ -5961,7 +5965,7 @@ static double CalculateMetaTripToMemory(
double fabric_max_transport_latency_margin)
{
double meta_trip_to_memory_us;
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
meta_trip_to_memory_us = meta_trip_to_memory_fclk_cycles / FabricClock * (1.0 + fabric_max_transport_latency_margin / 100.0)
+ meta_trip_to_memory_uclk_cycles / uclk_freq_mhz * (1.0 + umc_max_latency_margin / 100.0);
} else {
@@ -5969,7 +5973,7 @@ static double CalculateMetaTripToMemory(
}
#ifdef __DML_VBA_DEBUG__
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
dml2_printf("DML::%s: qos_type = %d\n", __func__, qos_type);
dml2_printf("DML::%s: meta_trip_to_memory_fclk_cycles = %d\n", __func__, meta_trip_to_memory_fclk_cycles);
dml2_printf("DML::%s: meta_trip_to_memory_uclk_cycles = %d\n", __func__, meta_trip_to_memory_uclk_cycles);
@@ -6460,8 +6464,8 @@ static void CalculateSwathAndDETConfiguration(struct dml2_core_internal_scratch
p->SwathHeightC[k] = l->MaximumSwathHeightC[k] / 2;
l->RoundedUpSwathSizeBytesY[k] = p->full_swath_bytes_l[k] / 2;
l->RoundedUpSwathSizeBytesC[k] = p->full_swath_bytes_c[k] / 2;
- p->request_size_bytes_luma[k] = ((p->BytePerPixY[k] == 2) == dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) ? 128 : 64;;
- p->request_size_bytes_chroma[k] = ((p->BytePerPixC[k] == 2) == dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) ? 128 : 64;;
+ p->request_size_bytes_luma[k] = ((p->BytePerPixY[k] == 2) == dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) ? 128 : 64;
+ p->request_size_bytes_chroma[k] = ((p->BytePerPixC[k] == 2) == dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) ? 128 : 64;
}
if (p->SwathHeightC[k] == 0)
@@ -7165,7 +7169,7 @@ static void calculate_tdlut_setting(
*p->tdlut_bytes_per_group = tdlut_bytes_per_line * tdlut_mpc_width;
//the delivery cycles is DispClk cycles per line * number of lines * number of slices
tdlut_delivery_cycles = (unsigned int)math_ceil2(tdlut_mpc_width / 2.0, 1) * tdlut_mpc_width * tdlut_mpc_width;
- tdlut_drain_rate = tdlut_bytes_per_line * p->dispclk_mhz / 9.0;
+ tdlut_drain_rate = tdlut_bytes_per_line * p->dispclk_mhz / math_ceil2(tdlut_mpc_width/2.0, 1);
} else {
//tdlut_addressing_mode = tdlut_simple_linear, 3dlut width should be 4*1229=4916 elements
*p->tdlut_bytes_per_frame = (unsigned int)math_ceil2(tdlut_width * tdlut_bpe, 256);
@@ -7485,7 +7489,7 @@ static void CalculateExtraLatency(
max_request_size_bytes = request_size_bytes_chroma[k];
}
- if (qos_type == dml2_qos_param_type_dcn4) {
+ if (qos_type == dml2_qos_param_type_dcn4x) {
*ExtraLatency_sr = dchub_arb_to_ret_delay / DCFCLK;
*ExtraLatency = *ExtraLatency_sr;
if (max_oustanding_when_urgent_expected)
@@ -7501,11 +7505,14 @@ static void CalculateExtraLatency(
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: qos_type=%u\n", __func__, qos_type);
+ dml2_printf("DML::%s: hostvm_mode=%u\n", __func__, hostvm_mode);
+ dml2_printf("DML::%s: Tex_trips=%u\n", __func__, Tex_trips);
dml2_printf("DML::%s: max_oustanding_when_urgent_expected=%u\n", __func__, max_oustanding_when_urgent_expected);
dml2_printf("DML::%s: FabricClock=%f\n", __func__, FabricClock);
dml2_printf("DML::%s: DCFCLK=%f\n", __func__, DCFCLK);
dml2_printf("DML::%s: ReturnBW=%f\n", __func__, ReturnBW);
dml2_printf("DML::%s: RoundTripPingLatencyCycles=%u\n", __func__, RoundTripPingLatencyCycles);
+ dml2_printf("DML::%s: ReorderingBytes=%u\n", __func__, ReorderingBytes);
dml2_printf("DML::%s: Tarb=%f\n", __func__, Tarb);
dml2_printf("DML::%s: ExtraLatency=%f\n", __func__, *ExtraLatency);
dml2_printf("DML::%s: ExtraLatency_sr=%f\n", __func__, *ExtraLatency_sr);
@@ -7739,7 +7746,6 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
s->max_Tsw = (math_max2(p->PrefetchSourceLinesY, p->PrefetchSourceLinesC) * s->LineTime);
s->prefetch_sw_bytes = p->PrefetchSourceLinesY * p->swath_width_luma_ub * p->myPipe->BytePerPixelY + p->PrefetchSourceLinesC * p->swath_width_chroma_ub * p->myPipe->BytePerPixelC;
-
s->prefetch_bw_pr = s->prefetch_bw_pr * p->mall_prefetch_sdp_overhead_factor;
s->prefetch_sw_bytes = s->prefetch_sw_bytes * p->mall_prefetch_sdp_overhead_factor;
s->prefetch_bw_oto = math_max2(s->prefetch_bw_pr, s->prefetch_sw_bytes / s->max_Tsw);
@@ -9304,6 +9310,10 @@ static void CalculateMetaAndPTETimes(struct dml2_core_shared_CalculateMetaAndPTE
dpte_groups_per_row_luma_ub = (unsigned int)(math_ceil2((double)p->dpte_row_width_luma_ub[k] / (double)dpte_group_width_luma, 1.0));
}
+ if (dpte_groups_per_row_luma_ub <= 2) {
+ dpte_groups_per_row_luma_ub = dpte_groups_per_row_luma_ub + 1;
+ }
+
dml2_printf("DML::%s: k=%u, use_one_row_for_frame = %u\n", __func__, k, p->use_one_row_for_frame[k]);
dml2_printf("DML::%s: k=%u, dpte_group_bytes = %u\n", __func__, k, p->dpte_group_bytes[k]);
dml2_printf("DML::%s: k=%u, PTERequestSizeY = %u\n", __func__, k, p->PTERequestSizeY[k]);
@@ -9332,6 +9342,9 @@ static void CalculateMetaAndPTETimes(struct dml2_core_shared_CalculateMetaAndPTE
} else {
dpte_groups_per_row_chroma_ub = (unsigned int)(math_ceil2((double)p->dpte_row_width_chroma_ub[k] / (double)dpte_group_width_chroma, 1.0));
}
+ if (dpte_groups_per_row_chroma_ub <= 2) {
+ dpte_groups_per_row_chroma_ub = dpte_groups_per_row_chroma_ub + 1;
+ }
dml2_printf("DML::%s: k=%u, dpte_row_width_chroma_ub = %u\n", __func__, k, p->dpte_row_width_chroma_ub[k]);
dml2_printf("DML::%s: k=%u, dpte_group_width_chroma = %u\n", __func__, k, dpte_group_width_chroma);
dml2_printf("DML::%s: k=%u, dpte_groups_per_row_chroma_ub = %u\n", __func__, k, dpte_groups_per_row_chroma_ub);
@@ -9386,8 +9399,8 @@ static void CalculateVMGroupAndRequestTimes(
double TimePerVMRequestVBlank[],
double TimePerVMRequestFlip[])
{
- unsigned int num_group_per_lower_vm_stage = 0;
- unsigned int num_req_per_lower_vm_stage = 0;
+ unsigned int num_group_per_lower_vm_stage = 1;
+ unsigned int num_req_per_lower_vm_stage = 1;
#ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: NumberOfActiveSurfaces = %u\n", __func__, NumberOfActiveSurfaces);
@@ -9451,6 +9464,14 @@ static void CalculateVMGroupAndRequestTimes(
double line_time = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz;
+ if (num_group_per_lower_vm_stage_flip <= 2) {
+ num_group_per_lower_vm_stage_flip = num_group_per_lower_vm_stage_flip + 1;
+ }
+
+ if (num_group_per_lower_vm_stage_pref <= 2) {
+ num_group_per_lower_vm_stage_pref = num_group_per_lower_vm_stage_pref + 1;
+ }
+
TimePerVMGroupVBlank[k] = dst_y_per_vm_vblank[k] * line_time / num_group_per_lower_vm_stage_pref;
TimePerVMGroupFlip[k] = dst_y_per_vm_flip[k] * line_time / num_group_per_lower_vm_stage_flip;
TimePerVMRequestVBlank[k] = dst_y_per_vm_vblank[k] * line_time / num_req_per_lower_vm_stage_pref;
@@ -9814,14 +9835,14 @@ bool dml2_core_shared_mode_programming(struct dml2_core_calcs_mode_programming_e
mode_lib->mp.num_active_pipes = dml_get_num_active_pipes(display_cfg->num_planes, cfg_support_info);
dml_calc_pipe_plane_mapping(cfg_support_info, mode_lib->mp.pipe_plane);
- mode_lib->mp.Dcfclk = programming->min_clocks.dcn4.active.dcfclk_khz / 1000.0;
- mode_lib->mp.FabricClock = programming->min_clocks.dcn4.active.fclk_khz / 1000.0;
- mode_lib->mp.dram_bw_mbps = uclk_khz_to_dram_bw_mbps(programming->min_clocks.dcn4.active.uclk_khz, &mode_lib->soc.clk_table.dram_config);
- mode_lib->mp.uclk_freq_mhz = programming->min_clocks.dcn4.active.uclk_khz / 1000.0;
- mode_lib->mp.GlobalDPPCLK = programming->min_clocks.dcn4.dpprefclk_khz / 1000.0;
- s->SOCCLK = (double)programming->min_clocks.dcn4.socclk_khz / 1000;
- mode_lib->mp.qos_param_index = get_qos_param_index(programming->min_clocks.dcn4.active.uclk_khz, mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params);
- mode_lib->mp.active_min_uclk_dpm_index = get_active_min_uclk_dpm_index(programming->min_clocks.dcn4.active.uclk_khz, &mode_lib->soc.clk_table);
+ mode_lib->mp.Dcfclk = programming->min_clocks.dcn4x.active.dcfclk_khz / 1000.0;
+ mode_lib->mp.FabricClock = programming->min_clocks.dcn4x.active.fclk_khz / 1000.0;
+ mode_lib->mp.dram_bw_mbps = uclk_khz_to_dram_bw_mbps(programming->min_clocks.dcn4x.active.uclk_khz, &mode_lib->soc.clk_table.dram_config);
+ mode_lib->mp.uclk_freq_mhz = programming->min_clocks.dcn4x.active.uclk_khz / 1000.0;
+ mode_lib->mp.GlobalDPPCLK = programming->min_clocks.dcn4x.dpprefclk_khz / 1000.0;
+ s->SOCCLK = (double)programming->min_clocks.dcn4x.socclk_khz / 1000;
+ mode_lib->mp.qos_param_index = get_qos_param_index(programming->min_clocks.dcn4x.active.uclk_khz, mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params);
+ mode_lib->mp.active_min_uclk_dpm_index = get_active_min_uclk_dpm_index(programming->min_clocks.dcn4x.active.uclk_khz, &mode_lib->soc.clk_table);
for (k = 0; k < s->num_active_planes; ++k) {
unsigned int stream_index = display_cfg->plane_descriptors[k].stream_index;
@@ -9856,18 +9877,18 @@ bool dml2_core_shared_mode_programming(struct dml2_core_calcs_mode_programming_e
for (k = 0; k < s->num_active_planes; ++k) {
mode_lib->mp.NoOfDPP[k] = cfg_support_info->plane_support_info[k].dpps_used;
- mode_lib->mp.Dppclk[k] = programming->plane_programming[k].min_clocks.dcn4.dppclk_khz / 1000.0;
+ mode_lib->mp.Dppclk[k] = programming->plane_programming[k].min_clocks.dcn4x.dppclk_khz / 1000.0;
dml2_assert(mode_lib->mp.Dppclk[k] > 0);
}
for (k = 0; k < s->num_active_planes; ++k) {
unsigned int stream_index = display_cfg->plane_descriptors[k].stream_index;
- mode_lib->mp.DSCCLK[k] = programming->stream_programming[stream_index].min_clocks.dcn4.dscclk_khz / 1000.0;
+ mode_lib->mp.DSCCLK[k] = programming->stream_programming[stream_index].min_clocks.dcn4x.dscclk_khz / 1000.0;
dml2_printf("DML::%s: k=%d stream_index=%d, mode_lib->mp.DSCCLK = %f\n", __func__, k, stream_index, mode_lib->mp.DSCCLK[k]);
}
- mode_lib->mp.Dispclk = programming->min_clocks.dcn4.dispclk_khz / 1000.0;
- mode_lib->mp.DCFCLKDeepSleep = programming->min_clocks.dcn4.deepsleep_dcfclk_khz / 1000.0;
+ mode_lib->mp.Dispclk = programming->min_clocks.dcn4x.dispclk_khz / 1000.0;
+ mode_lib->mp.DCFCLKDeepSleep = programming->min_clocks.dcn4x.deepsleep_dcfclk_khz / 1000.0;
dml2_assert(mode_lib->mp.Dcfclk > 0);
dml2_assert(mode_lib->mp.FabricClock > 0);
@@ -10388,11 +10409,16 @@ bool dml2_core_shared_mode_programming(struct dml2_core_calcs_mode_programming_e
calculate_tdlut_setting(&mode_lib->scratch, calculate_tdlut_setting_params);
}
+ if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn3)
+ s->ReorderingBytes = (unsigned int)(mode_lib->soc.clk_table.dram_config.channel_count * math_max3(mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_out_of_order_return_per_channel_pixel_only_bytes,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_out_of_order_return_per_channel_vm_only_bytes));
+
CalculateExtraLatency(
display_cfg,
mode_lib->ip.rob_buffer_size_kbytes,
- 0, //mode_lib->soc.round_trip_ping_latency_dcfclk_cycles,
- s->ReorderBytes,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.loaded_round_trip_latency_fclk_cycles,
+ s->ReorderingBytes,
mode_lib->mp.Dcfclk,
mode_lib->mp.FabricClock,
mode_lib->ip.pixel_chunk_size_kbytes,
@@ -10465,32 +10491,32 @@ bool dml2_core_shared_mode_programming(struct dml2_core_calcs_mode_programming_e
mode_lib->mp.WritebackDelay[k] = mode_lib->mp.WritebackDelay[j];
mode_lib->mp.UrgentLatency = CalculateUrgentLatency(
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.base_latency_us,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.base_latency_pixel_vm_us,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.base_latency_vm_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.base_latency_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.base_latency_pixel_vm_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.base_latency_vm_us,
mode_lib->soc.do_urgent_latency_adjustment,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.scaling_factor_fclk_us,
- mode_lib->soc.qos_parameters.qos_params.dcn3.urgent_latency_us.scaling_factor_mhz,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.scaling_factor_fclk_us,
+ mode_lib->soc.qos_parameters.qos_params.dcn32x.urgent_latency_us.scaling_factor_mhz,
mode_lib->mp.FabricClock,
mode_lib->mp.uclk_freq_mhz,
mode_lib->soc.qos_parameters.qos_type,
- mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->mp.qos_param_index].urgent_ramp_uclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.df_qos_response_time_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.max_round_trip_to_furthest_cs_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.mall_overhead_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.umc_urgent_ramp_latency_margin,
- mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin);
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->mp.qos_param_index].urgent_ramp_uclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.df_qos_response_time_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.max_round_trip_to_furthest_cs_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.mall_overhead_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_urgent_ramp_latency_margin,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_max_transport_latency_margin);
mode_lib->mp.TripToMemory = CalculateTripToMemory(
mode_lib->mp.UrgentLatency,
mode_lib->mp.FabricClock,
mode_lib->mp.uclk_freq_mhz,
mode_lib->soc.qos_parameters.qos_type,
- mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->mp.qos_param_index].trip_to_memory_uclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.max_round_trip_to_furthest_cs_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.mall_overhead_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.umc_max_latency_margin,
- mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin);
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->mp.qos_param_index].trip_to_memory_uclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.max_round_trip_to_furthest_cs_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.mall_overhead_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_max_latency_margin,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_max_transport_latency_margin);
mode_lib->mp.TripToMemory = math_max2(mode_lib->mp.UrgentLatency, mode_lib->mp.TripToMemory);
@@ -10499,10 +10525,10 @@ bool dml2_core_shared_mode_programming(struct dml2_core_calcs_mode_programming_e
mode_lib->mp.FabricClock,
mode_lib->mp.uclk_freq_mhz,
mode_lib->soc.qos_parameters.qos_type,
- mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->mp.qos_param_index].meta_trip_to_memory_uclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.meta_trip_adder_fclk_cycles,
- mode_lib->soc.qos_parameters.qos_params.dcn4.umc_max_latency_margin,
- mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin);
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->mp.qos_param_index].meta_trip_to_memory_uclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.meta_trip_adder_fclk_cycles,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_max_latency_margin,
+ mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_max_transport_latency_margin);
for (k = 0; k < s->num_active_planes; ++k) {
calculate_cursor_req_attributes(
@@ -11945,14 +11971,14 @@ void dml2_core_shared_get_pipe_regs(const struct dml2_display_cfg *display_cfg,
void dml2_core_shared_get_stream_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_per_stream_programming *out, int pipe_index)
{
- // out->min_clocks.dcn4.dscclk_khz = (unsigned int)(dml_get_dscclk_calculated(mode_lib, pipe_index) * 1000); // FIXME_STAGE2
- // out->min_clocks.dcn4.dtbclk_khz = (unsigned int)(dml_get_dscclk_calculated(mode_lib, pipe_index) * 1000);
- // out->min_clocks.dcn4.phyclk_khz = (unsigned int)(dml_get_dscclk_calculated(mode_lib, pipe_index) * 1000);
-
- out->global_sync.dcn4.vready_offset_pixels = mode_lib->mp.VReadyOffsetPix[mode_lib->mp.pipe_plane[pipe_index]];
- out->global_sync.dcn4.vstartup_lines = mode_lib->mp.VStartup[mode_lib->mp.pipe_plane[pipe_index]];
- out->global_sync.dcn4.vupdate_offset_pixels = mode_lib->mp.VUpdateOffsetPix[mode_lib->mp.pipe_plane[pipe_index]];
- out->global_sync.dcn4.vupdate_vupdate_width_pixels = mode_lib->mp.VUpdateWidthPix[mode_lib->mp.pipe_plane[pipe_index]];
+ // out->min_clocks.dcn4x.dscclk_khz = (unsigned int)(dml_get_dscclk_calculated(mode_lib, pipe_index) * 1000); // FIXME_STAGE2
+ // out->min_clocks.dcn4x.dtbclk_khz = (unsigned int)(dml_get_dscclk_calculated(mode_lib, pipe_index) * 1000);
+ // out->min_clocks.dcn4x.phyclk_khz = (unsigned int)(dml_get_dscclk_calculated(mode_lib, pipe_index) * 1000);
+
+ out->global_sync.dcn4x.vready_offset_pixels = mode_lib->mp.VReadyOffsetPix[mode_lib->mp.pipe_plane[pipe_index]];
+ out->global_sync.dcn4x.vstartup_lines = mode_lib->mp.VStartup[mode_lib->mp.pipe_plane[pipe_index]];
+ out->global_sync.dcn4x.vupdate_offset_pixels = mode_lib->mp.VUpdateOffsetPix[mode_lib->mp.pipe_plane[pipe_index]];
+ out->global_sync.dcn4x.vupdate_vupdate_width_pixels = mode_lib->mp.VUpdateWidthPix[mode_lib->mp.pipe_plane[pipe_index]];
}
void dml2_core_shared_get_mcache_allocation(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_mcache_surface_allocation *out, int plane_idx)
@@ -12255,7 +12281,7 @@ void dml2_core_shared_get_informative(const struct dml2_core_internal_display_mo
out->informative.misc.cstate_max_cap_mode = mode_lib->mp.DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE;
- out->min_clocks.dcn4.dpprefclk_khz = (int unsigned)(mode_lib->mp.GlobalDPPCLK * 1000.0);
+ out->min_clocks.dcn4x.dpprefclk_khz = (int unsigned)(mode_lib->mp.GlobalDPPCLK * 1000.0);
out->informative.qos.max_active_fclk_change_latency_supported = mode_lib->mp.MaxActiveFCLKChangeLatencySupported;
@@ -12368,13 +12394,13 @@ void dml2_core_shared_get_informative(const struct dml2_core_internal_display_mo
}
}
- out->informative.qos.max_non_urgent_latency_us = mode_lib->soc.qos_parameters.qos_params.dcn4.per_uclk_dpm_params[mode_lib->mp.qos_param_index].maximum_latency_when_non_urgent_uclk_cycles
- / mode_lib->mp.uclk_freq_mhz * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.umc_max_latency_margin / 100.0)
- + mode_lib->soc.qos_parameters.qos_params.dcn4.mall_overhead_fclk_cycles / mode_lib->mp.FabricClock
- + mode_lib->soc.qos_parameters.qos_params.dcn4.max_round_trip_to_furthest_cs_fclk_cycles / mode_lib->mp.FabricClock
- * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4.fabric_max_transport_latency_margin / 100.0);
+ out->informative.qos.max_non_urgent_latency_us = mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params[mode_lib->mp.qos_param_index].maximum_latency_when_non_urgent_uclk_cycles
+ / mode_lib->mp.uclk_freq_mhz * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.umc_max_latency_margin / 100.0)
+ + mode_lib->soc.qos_parameters.qos_params.dcn4x.mall_overhead_fclk_cycles / mode_lib->mp.FabricClock
+ + mode_lib->soc.qos_parameters.qos_params.dcn4x.max_round_trip_to_furthest_cs_fclk_cycles / mode_lib->mp.FabricClock
+ * (1 + mode_lib->soc.qos_parameters.qos_params.dcn4x.fabric_max_transport_latency_margin / 100.0);
- if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4) {
+ if (mode_lib->soc.qos_parameters.qos_type == dml2_qos_param_type_dcn4x) {
if (((mode_lib->ip.rob_buffer_size_kbytes - mode_lib->ip.pixel_chunk_size_kbytes) * 1024
/ mode_lib->mp.non_urg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]) >= out->informative.qos.max_non_urgent_latency_us) {
out->informative.misc.ROBUrgencyAvoidance = true;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.h
deleted file mode 100644
index d76bda907ec8..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-License-Identifier: MIT
-//
-// Copyright 2024 Advanced Micro Devices, Inc.
-
-
-#ifndef __DML2_CORE_SHARED_H__
-#define __DML2_CORE_SHARED_H__
-
-#define __DML_VBA_DEBUG__
-#define __DML2_CALCS_MAX_VRATIO_PRE_OTO__ 4.0 //<brief Prefetch schedule max vratio for one to one scheduling calculation for prefetch
-#define __DML2_CALCS_MAX_VRATIO_PRE_ENHANCE_PREFETCH_ACC__ 6.0 //<brief Prefetch schedule max vratio when enhance prefetch schedule acceleration is enabled and vstartup is earliest possible already
-#define __DML2_CALCS_DPP_INVALID__ 0
-#define __DML2_CALCS_DCFCLK_FACTOR__ 1.15 //<brief fudge factor for min dcfclk calclation
-#define __DML2_CALCS_PIPE_NO_PLANE__ 99
-
-#include "dml2_core_shared_types.h"
-#include "dml2_internal_shared_types.h"
-
-double dml2_core_shared_div_rem(double dividend, unsigned int divisor, unsigned int *remainder);
-
-const char *dml2_core_internal_bw_type_str(enum dml2_core_internal_bw_type bw_type);
-const char *dml2_core_internal_soc_state_type_str(enum dml2_core_internal_soc_state_type dml2_core_internal_soc_state_type);
-bool dml2_core_shared_is_420(enum dml2_source_format_class source_format);
-
-bool dml2_core_shared_mode_support(struct dml2_core_calcs_mode_support_ex *in_out_params);
-bool dml2_core_shared_mode_programming(struct dml2_core_calcs_mode_programming_ex *in_out_params);
-void dml2_core_shared_get_watermarks(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_dchub_watermark_regs *out);
-void dml2_core_shared_get_arb_params(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_display_arb_regs *out);
-void dml2_core_shared_get_pipe_regs(const struct dml2_display_cfg *display_cfg, struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_dchub_per_pipe_register_set *out, int pipe_index);
-void dml2_core_shared_get_stream_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_per_stream_programming *out, int pipe_index);
-void dml2_core_shared_get_mcache_allocation(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_mcache_surface_allocation *out, int plane_idx);
-void dml2_core_shared_get_mall_allocation(struct dml2_core_internal_display_mode_lib *mode_lib, unsigned int *out, int pipe_index);
-void dml2_core_shared_get_plane_support_info(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, struct core_plane_support_info *out, int plane_idx);
-void dml2_core_shared_get_stream_support_info(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, struct core_stream_support_info *out, int plane_index);
-void dml2_core_shared_get_informative(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_display_cfg_programming *out);
-void dml2_core_shared_cursor_dlg_reg(struct dml2_cursor_dlg_regs *cursor_dlg_regs, const struct dml2_get_cursor_dlg_reg *p);
-
-#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h
index 1343b744eeb3..cbdfbd5a0bde 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_CORE_SHARED_TYPES_H__
#define __DML2_CORE_SHARED_TYPES_H__
@@ -10,6 +9,15 @@
#include "dml_top_display_cfg_types.h"
#include "dml_top_types.h"
+#define __DML_VBA_DEBUG__
+#define __DML2_CALCS_MAX_VRATIO_PRE_OTO__ 4.0 //<brief max vratio for one-to-one prefetch bw scheduling
+#define __DML2_CALCS_MAX_VRATIO_PRE_EQU__ 6.0 //<brief max vratio for equalized prefetch bw scheduling
+#define __DML2_CALCS_MAX_VRATIO_PRE__ 8.0 //<brief max prefetch vratio register limit
+
+#define __DML2_CALCS_DPP_INVALID__ 0
+#define __DML2_CALCS_DCFCLK_FACTOR__ 1.15 //<brief fudge factor for min dcfclk calclation
+#define __DML2_CALCS_PIPE_NO_PLANE__ 99
+
struct dml2_core_ip_params {
unsigned int vblank_nom_default_us;
unsigned int remote_iommu_outstanding_translations;
@@ -70,6 +78,7 @@ struct dml2_core_ip_params {
unsigned int words_per_channel;
bool imall_supported;
unsigned int max_flip_time_us;
+ unsigned int max_flip_time_lines;
unsigned int subvp_swath_height_margin_lines;
unsigned int subvp_fw_processing_delay_us;
unsigned int subvp_pstate_allow_width_us;
@@ -782,6 +791,7 @@ struct dml2_core_internal_mode_program {
unsigned int VUpdateOffsetPix[DML2_MAX_PLANES];
unsigned int VUpdateWidthPix[DML2_MAX_PLANES];
unsigned int VReadyOffsetPix[DML2_MAX_PLANES];
+ unsigned int pstate_keepout_dst_lines[DML2_MAX_PLANES];
// Latency and Support
double MaxActiveFCLKChangeLatencySupported;
@@ -852,6 +862,9 @@ struct dml2_core_internal_SOCParametersList {
double USRRetrainingLatency;
double SMNLatency;
double g6_temp_read_blackout_us;
+ double max_urgent_latency_us;
+ double df_response_time_us;
+ enum dml2_qos_param_type qos_type;
};
struct dml2_core_calcs_mode_support_locals {
@@ -865,7 +878,7 @@ struct dml2_core_calcs_mode_support_locals {
unsigned int dpte_row_bytes_per_row_l[DML2_MAX_PLANES];
unsigned int dpte_row_bytes_per_row_c[DML2_MAX_PLANES];
- bool dummy_boolean[2];
+ bool dummy_boolean[3];
unsigned int dummy_integer[3];
unsigned int dummy_integer_array[36][DML2_MAX_PLANES];
enum dml2_odm_mode dummy_odm_mode[DML2_MAX_PLANES];
@@ -913,9 +926,7 @@ struct dml2_core_calcs_mode_support_locals {
double HostVMInefficiencyFactor;
double HostVMInefficiencyFactorPrefetch;
- unsigned int NextMaxVStartup;
unsigned int MaxVStartup;
- bool AnyLinesForVMOrRowTooLarge;
double PixelClockBackEndFactor;
unsigned int NumDSCUnitRequired;
@@ -975,7 +986,7 @@ struct dml2_core_calcs_mode_programming_locals {
unsigned int DSCFormatFactor;
struct dml2_core_internal_DmlPipe SurfaceParameters[DML2_MAX_PLANES];
- unsigned int ReorderBytes;
+ unsigned int ReorderingBytes;
double HostVMInefficiencyFactor;
double HostVMInefficiencyFactorPrefetch;
unsigned int TotalDCCActiveDPP;
@@ -1176,11 +1187,15 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_locals {
double prefetch_bw_oto;
double Tvm_oto;
double Tr0_oto;
+ double Tvm_no_trip_oto;
+ double Tr0_no_trip_oto;
double Tvm_oto_lines;
double Tr0_oto_lines;
double dst_y_prefetch_oto;
double TimeForFetchingVM;
double TimeForFetchingRowInVBlank;
+ double dst_y_per_vm_no_trip_vblank;
+ double dst_y_per_row_no_trip_vblank;
double LinesToRequestPrefetchPixelData;
unsigned int HostVMDynamicLevelsTrips;
double trip_to_mem;
@@ -1188,6 +1203,7 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_locals {
double Tr0_trips_rounded;
double max_Tsw;
double Lsw_oto;
+ double Lsw_equ;
double Tpre_rounded;
double prefetch_bw_equ;
double Tvm_equ;
@@ -1196,11 +1212,14 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_locals {
double Tdmec;
double Tdmsks;
double prefetch_sw_bytes;
+ double total_row_bytes;
double prefetch_bw_pr;
double bytes_pp;
double dep_bytes;
double min_Lsw_oto;
+ double min_Lsw_equ;
double Tsw_est1;
+ double Tsw_est2;
double Tsw_est3;
double prefetch_bw1;
double prefetch_bw2;
@@ -1332,6 +1351,10 @@ struct dml2_core_shared_get_urgent_bandwidth_required_locals {
double tmp_nom_adj_factor_p1;
double tmp_pref_adj_factor_p0;
double tmp_pref_adj_factor_p1;
+ double vm_row_bw;
+ double flip_and_active_bw;
+ double flip_and_prefetch_bw;
+ double active_and_excess_bw;
};
struct dml2_core_shared_calculate_peak_bandwidth_required_locals {
@@ -1688,7 +1711,6 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_params {
enum dml2_output_format_class OutputFormat;
unsigned int MaxInterDCNTileRepeaters;
unsigned int VStartup;
- unsigned int MaxVStartup;
unsigned int HostVMMinPageSize;
bool DynamicMetadataEnable;
bool DynamicMetadataVMEnabled;
@@ -2010,6 +2032,7 @@ struct dml2_core_internal_scratch {
struct dml2_core_internal_display_mode_lib {
struct dml2_core_ip_params ip;
struct dml2_soc_bb soc;
+ struct dml2_ip_capabilities ip_caps;
//@brief Mode Support and Mode programming struct
// Used to hold input; intermediate and output of the calculations
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_utils.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_utils.c
new file mode 100644
index 000000000000..ab229e1598ae
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_utils.c
@@ -0,0 +1,631 @@
+// SPDX-License-Identifier: MIT
+//
+// Copyright 2024 Advanced Micro Devices, Inc.
+
+#include "dml2_core_utils.h"
+
+double dml2_core_utils_div_rem(double dividend, unsigned int divisor, unsigned int *remainder)
+{
+ *remainder = ((dividend / divisor) - (int)(dividend / divisor) > 0);
+ return dividend / divisor;
+
+}
+
+const char *dml2_core_utils_internal_bw_type_str(enum dml2_core_internal_bw_type bw_type)
+{
+ switch (bw_type) {
+ case (dml2_core_internal_bw_sdp):
+ return("dml2_core_internal_bw_sdp");
+ case (dml2_core_internal_bw_dram):
+ return("dml2_core_internal_bw_dram");
+ case (dml2_core_internal_bw_max):
+ return("dml2_core_internal_bw_max");
+ default:
+ return("dml2_core_internal_bw_unknown");
+ }
+}
+
+bool dml2_core_utils_is_420(enum dml2_source_format_class source_format)
+{
+ bool val = false;
+
+ switch (source_format) {
+ case dml2_444_8:
+ val = 0;
+ break;
+ case dml2_444_16:
+ val = 0;
+ break;
+ case dml2_444_32:
+ val = 0;
+ break;
+ case dml2_444_64:
+ val = 0;
+ break;
+ case dml2_420_8:
+ val = 1;
+ break;
+ case dml2_420_10:
+ val = 1;
+ break;
+ case dml2_420_12:
+ val = 1;
+ break;
+ case dml2_rgbe_alpha:
+ val = 0;
+ break;
+ case dml2_rgbe:
+ val = 0;
+ break;
+ case dml2_mono_8:
+ val = 0;
+ break;
+ case dml2_mono_16:
+ val = 0;
+ break;
+ default:
+ DML2_ASSERT(0);
+ break;
+ }
+ return val;
+}
+
+void dml2_core_utils_print_mode_support_info(const struct dml2_core_internal_mode_support_info *support, bool fail_only)
+{
+ dml2_printf("DML: ===================================== \n");
+ dml2_printf("DML: DML_MODE_SUPPORT_INFO_ST\n");
+ if (!fail_only || support->ScaleRatioAndTapsSupport == 0)
+ dml2_printf("DML: support: ScaleRatioAndTapsSupport = %d\n", support->ScaleRatioAndTapsSupport);
+ if (!fail_only || support->SourceFormatPixelAndScanSupport == 0)
+ dml2_printf("DML: support: SourceFormatPixelAndScanSupport = %d\n", support->SourceFormatPixelAndScanSupport);
+ if (!fail_only || support->ViewportSizeSupport == 0)
+ dml2_printf("DML: support: ViewportSizeSupport = %d\n", support->ViewportSizeSupport);
+ if (!fail_only || support->LinkRateDoesNotMatchDPVersion == 1)
+ dml2_printf("DML: support: LinkRateDoesNotMatchDPVersion = %d\n", support->LinkRateDoesNotMatchDPVersion);
+ if (!fail_only || support->LinkRateForMultistreamNotIndicated == 1)
+ dml2_printf("DML: support: LinkRateForMultistreamNotIndicated = %d\n", support->LinkRateForMultistreamNotIndicated);
+ if (!fail_only || support->BPPForMultistreamNotIndicated == 1)
+ dml2_printf("DML: support: BPPForMultistreamNotIndicated = %d\n", support->BPPForMultistreamNotIndicated);
+ if (!fail_only || support->MultistreamWithHDMIOreDP == 1)
+ dml2_printf("DML: support: MultistreamWithHDMIOreDP = %d\n", support->MultistreamWithHDMIOreDP);
+ if (!fail_only || support->ExceededMultistreamSlots == 1)
+ dml2_printf("DML: support: ExceededMultistreamSlots = %d\n", support->ExceededMultistreamSlots);
+ if (!fail_only || support->MSOOrODMSplitWithNonDPLink == 1)
+ dml2_printf("DML: support: MSOOrODMSplitWithNonDPLink = %d\n", support->MSOOrODMSplitWithNonDPLink);
+ if (!fail_only || support->NotEnoughLanesForMSO == 1)
+ dml2_printf("DML: support: NotEnoughLanesForMSO = %d\n", support->NotEnoughLanesForMSO);
+ if (!fail_only || support->P2IWith420 == 1)
+ dml2_printf("DML: support: P2IWith420 = %d\n", support->P2IWith420);
+ if (!fail_only || support->DSC422NativeNotSupported == 1)
+ dml2_printf("DML: support: DSC422NativeNotSupported = %d\n", support->DSC422NativeNotSupported);
+ if (!fail_only || support->DSCSlicesODMModeSupported == 0)
+ dml2_printf("DML: support: DSCSlicesODMModeSupported = %d\n", support->DSCSlicesODMModeSupported);
+ if (!fail_only || support->NotEnoughDSCUnits == 1)
+ dml2_printf("DML: support: NotEnoughDSCUnits = %d\n", support->NotEnoughDSCUnits);
+ if (!fail_only || support->NotEnoughDSCSlices == 1)
+ dml2_printf("DML: support: NotEnoughDSCSlices = %d\n", support->NotEnoughDSCSlices);
+ if (!fail_only || support->ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe == 1)
+ dml2_printf("DML: support: ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe = %d\n", support->ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe);
+ if (!fail_only || support->InvalidCombinationOfMALLUseForPStateAndStaticScreen == 1)
+ dml2_printf("DML: support: InvalidCombinationOfMALLUseForPStateAndStaticScreen = %d\n", support->InvalidCombinationOfMALLUseForPStateAndStaticScreen);
+ if (!fail_only || support->DSCCLKRequiredMoreThanSupported == 1)
+ dml2_printf("DML: support: DSCCLKRequiredMoreThanSupported = %d\n", support->DSCCLKRequiredMoreThanSupported);
+ if (!fail_only || support->PixelsPerLinePerDSCUnitSupport == 0)
+ dml2_printf("DML: support: PixelsPerLinePerDSCUnitSupport = %d\n", support->PixelsPerLinePerDSCUnitSupport);
+ if (!fail_only || support->DTBCLKRequiredMoreThanSupported == 1)
+ dml2_printf("DML: support: DTBCLKRequiredMoreThanSupported = %d\n", support->DTBCLKRequiredMoreThanSupported);
+ if (!fail_only || support->InvalidCombinationOfMALLUseForPState == 1)
+ dml2_printf("DML: support: InvalidCombinationOfMALLUseForPState = %d\n", support->InvalidCombinationOfMALLUseForPState);
+ if (!fail_only || support->ROBSupport == 0)
+ dml2_printf("DML: support: ROBSupport = %d\n", support->ROBSupport);
+ if (!fail_only || support->OutstandingRequestsSupport == 0)
+ dml2_printf("DML: support: OutstandingRequestsSupport = %d\n", support->OutstandingRequestsSupport);
+ if (!fail_only || support->OutstandingRequestsUrgencyAvoidance == 0)
+ dml2_printf("DML: support: OutstandingRequestsUrgencyAvoidance = %d\n", support->OutstandingRequestsUrgencyAvoidance);
+ if (!fail_only || support->DISPCLK_DPPCLK_Support == 0)
+ dml2_printf("DML: support: DISPCLK_DPPCLK_Support = %d\n", support->DISPCLK_DPPCLK_Support);
+ if (!fail_only || support->TotalAvailablePipesSupport == 0)
+ dml2_printf("DML: support: TotalAvailablePipesSupport = %d\n", support->TotalAvailablePipesSupport);
+ if (!fail_only || support->NumberOfOTGSupport == 0)
+ dml2_printf("DML: support: NumberOfOTGSupport = %d\n", support->NumberOfOTGSupport);
+ if (!fail_only || support->NumberOfHDMIFRLSupport == 0)
+ dml2_printf("DML: support: NumberOfHDMIFRLSupport = %d\n", support->NumberOfHDMIFRLSupport);
+ if (!fail_only || support->NumberOfDP2p0Support == 0)
+ dml2_printf("DML: support: NumberOfDP2p0Support = %d\n", support->NumberOfDP2p0Support);
+ if (!fail_only || support->EnoughWritebackUnits == 0)
+ dml2_printf("DML: support: EnoughWritebackUnits = %d\n", support->EnoughWritebackUnits);
+ if (!fail_only || support->WritebackScaleRatioAndTapsSupport == 0)
+ dml2_printf("DML: support: WritebackScaleRatioAndTapsSupport = %d\n", support->WritebackScaleRatioAndTapsSupport);
+ if (!fail_only || support->WritebackLatencySupport == 0)
+ dml2_printf("DML: support: WritebackLatencySupport = %d\n", support->WritebackLatencySupport);
+ if (!fail_only || support->CursorSupport == 0)
+ dml2_printf("DML: support: CursorSupport = %d\n", support->CursorSupport);
+ if (!fail_only || support->PitchSupport == 0)
+ dml2_printf("DML: support: PitchSupport = %d\n", support->PitchSupport);
+ if (!fail_only || support->ViewportExceedsSurface == 1)
+ dml2_printf("DML: support: ViewportExceedsSurface = %d\n", support->ViewportExceedsSurface);
+ if (!fail_only || support->PrefetchSupported == 0)
+ dml2_printf("DML: support: PrefetchSupported = %d\n", support->PrefetchSupported);
+ if (!fail_only || support->EnoughUrgentLatencyHidingSupport == 0)
+ dml2_printf("DML: support: EnoughUrgentLatencyHidingSupport = %d\n", support->EnoughUrgentLatencyHidingSupport);
+ if (!fail_only || support->AvgBandwidthSupport == 0)
+ dml2_printf("DML: support: AvgBandwidthSupport = %d\n", support->AvgBandwidthSupport);
+ if (!fail_only || support->DynamicMetadataSupported == 0)
+ dml2_printf("DML: support: DynamicMetadataSupported = %d\n", support->DynamicMetadataSupported);
+ if (!fail_only || support->VRatioInPrefetchSupported == 0)
+ dml2_printf("DML: support: VRatioInPrefetchSupported = %d\n", support->VRatioInPrefetchSupported);
+ if (!fail_only || support->PTEBufferSizeNotExceeded == 1)
+ dml2_printf("DML: support: PTEBufferSizeNotExceeded = %d\n", support->PTEBufferSizeNotExceeded);
+ if (!fail_only || support->DCCMetaBufferSizeNotExceeded == 1)
+ dml2_printf("DML: support: DCCMetaBufferSizeNotExceeded = %d\n", support->DCCMetaBufferSizeNotExceeded);
+ if (!fail_only || support->ExceededMALLSize == 1)
+ dml2_printf("DML: support: ExceededMALLSize = %d\n", support->ExceededMALLSize);
+ if (!fail_only || support->g6_temp_read_support == 0)
+ dml2_printf("DML: support: g6_temp_read_support = %d\n", support->g6_temp_read_support);
+ if (!fail_only || support->ImmediateFlipSupport == 0)
+ dml2_printf("DML: support: ImmediateFlipSupport = %d\n", support->ImmediateFlipSupport);
+ if (!fail_only || support->LinkCapacitySupport == 0)
+ dml2_printf("DML: support: LinkCapacitySupport = %d\n", support->LinkCapacitySupport);
+
+ if (!fail_only || support->ModeSupport == 0)
+ dml2_printf("DML: support: ModeSupport = %d\n", support->ModeSupport);
+ dml2_printf("DML: ===================================== \n");
+}
+
+const char *dml2_core_utils_internal_soc_state_type_str(enum dml2_core_internal_soc_state_type dml2_core_internal_soc_state_type)
+{
+ switch (dml2_core_internal_soc_state_type) {
+ case (dml2_core_internal_soc_state_sys_idle):
+ return("dml2_core_internal_soc_state_sys_idle");
+ case (dml2_core_internal_soc_state_sys_active):
+ return("dml2_core_internal_soc_state_sys_active");
+ case (dml2_core_internal_soc_state_svp_prefetch):
+ return("dml2_core_internal_soc_state_svp_prefetch");
+ case dml2_core_internal_soc_state_max:
+ default:
+ return("dml2_core_internal_soc_state_unknown");
+ }
+}
+
+
+void dml2_core_utils_get_stream_output_bpp(double *out_bpp, const struct dml2_display_cfg *display_cfg)
+{
+ for (unsigned int k = 0; k < display_cfg->num_planes; k++) {
+ double bpc = (double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.bpc;
+ if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.dsc.enable == dml2_dsc_disable) {
+ switch (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format) {
+ case dml2_444:
+ out_bpp[k] = bpc * 3;
+ break;
+ case dml2_s422:
+ out_bpp[k] = bpc * 2;
+ break;
+ case dml2_n422:
+ out_bpp[k] = bpc * 2;
+ break;
+ case dml2_420:
+ default:
+ out_bpp[k] = bpc * 1.5;
+ break;
+ }
+ } else if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.dsc.enable == dml2_dsc_enable) {
+ out_bpp[k] = (double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.dsc.dsc_compressed_bpp_x16 / 16;
+ } else {
+ out_bpp[k] = 0;
+ }
+#ifdef __DML_VBA_DEBUG__
+ dml2_printf("DML::%s: k=%d bpc=%f\n", __func__, k, bpc);
+ dml2_printf("DML::%s: k=%d dsc.enable=%d\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.dsc.enable);
+ dml2_printf("DML::%s: k=%d out_bpp=%f\n", __func__, k, out_bpp[k]);
+#endif
+ }
+}
+
+unsigned int dml2_core_utils_round_to_multiple(unsigned int num, unsigned int multiple, bool up)
+{
+ unsigned int remainder;
+
+ if (multiple == 0)
+ return num;
+
+ remainder = num % multiple;
+ if (remainder == 0)
+ return num;
+
+ if (up)
+ return (num + multiple - remainder);
+ else
+ return (num - remainder);
+}
+
+unsigned int dml2_core_util_get_num_active_pipes(int unsigned num_planes, const struct core_display_cfg_support_info *cfg_support_info)
+{
+ unsigned int num_active_pipes = 0;
+
+ for (unsigned int k = 0; k < num_planes; k++) {
+ num_active_pipes = num_active_pipes + (unsigned int)cfg_support_info->plane_support_info[k].dpps_used;
+ }
+
+#ifdef __DML_VBA_DEBUG__
+ dml2_printf("DML::%s: num_active_pipes = %d\n", __func__, num_active_pipes);
+#endif
+ return num_active_pipes;
+}
+
+void dml2_core_utils_pipe_plane_mapping(const struct core_display_cfg_support_info *cfg_support_info, unsigned int *pipe_plane)
+{
+ unsigned int pipe_idx = 0;
+
+ for (unsigned int k = 0; k < DML2_MAX_PLANES; ++k) {
+ pipe_plane[k] = __DML2_CALCS_PIPE_NO_PLANE__;
+ }
+
+ for (unsigned int plane_idx = 0; plane_idx < DML2_MAX_PLANES; plane_idx++) {
+ for (int i = 0; i < cfg_support_info->plane_support_info[plane_idx].dpps_used; i++) {
+ pipe_plane[pipe_idx] = plane_idx;
+ pipe_idx++;
+ }
+ }
+}
+
+bool dml2_core_utils_is_phantom_pipe(const struct dml2_plane_parameters *plane_cfg)
+{
+ bool is_phantom = false;
+
+ if (plane_cfg->overrides.legacy_svp_config == dml2_svp_mode_override_phantom_pipe ||
+ plane_cfg->overrides.legacy_svp_config == dml2_svp_mode_override_phantom_pipe_no_data_return) {
+ is_phantom = true;
+ }
+
+ return is_phantom;
+}
+
+unsigned int dml2_core_utils_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode)
+{
+ switch (sw_mode) {
+ case (dml2_sw_linear):
+ return 256; break;
+ case (dml2_sw_256b_2d):
+ return 256; break;
+ case (dml2_sw_4kb_2d):
+ return 4096; break;
+ case (dml2_sw_64kb_2d):
+ return 65536; break;
+ case (dml2_sw_256kb_2d):
+ return 262144; break;
+ case (dml2_gfx11_sw_linear):
+ return 256; break;
+ case (dml2_gfx11_sw_64kb_d):
+ return 65536; break;
+ case (dml2_gfx11_sw_64kb_d_t):
+ return 65536; break;
+ case (dml2_gfx11_sw_64kb_d_x):
+ return 65536; break;
+ case (dml2_gfx11_sw_64kb_r_x):
+ return 65536; break;
+ case (dml2_gfx11_sw_256kb_d_x):
+ return 262144; break;
+ case (dml2_gfx11_sw_256kb_r_x):
+ return 262144; break;
+ default:
+ DML2_ASSERT(0);
+ return 256;
+ };
+}
+
+
+bool dml2_core_utils_is_vertical_rotation(enum dml2_rotation_angle Scan)
+{
+ bool is_vert = false;
+ if (Scan == dml2_rotation_90 || Scan == dml2_rotation_270) {
+ is_vert = true;
+ } else {
+ is_vert = false;
+ }
+ return is_vert;
+}
+
+
+int unsigned dml2_core_utils_get_gfx_version(enum dml2_swizzle_mode sw_mode)
+{
+ int unsigned version = 0;
+
+ if (sw_mode == dml2_sw_linear ||
+ sw_mode == dml2_sw_256b_2d ||
+ sw_mode == dml2_sw_4kb_2d ||
+ sw_mode == dml2_sw_64kb_2d ||
+ sw_mode == dml2_sw_256kb_2d) {
+ version = 12;
+ } else if (sw_mode == dml2_gfx11_sw_linear ||
+ sw_mode == dml2_gfx11_sw_64kb_d ||
+ sw_mode == dml2_gfx11_sw_64kb_d_t ||
+ sw_mode == dml2_gfx11_sw_64kb_d_x ||
+ sw_mode == dml2_gfx11_sw_64kb_r_x ||
+ sw_mode == dml2_gfx11_sw_256kb_d_x ||
+ sw_mode == dml2_gfx11_sw_256kb_r_x) {
+ version = 11;
+ } else {
+ dml2_printf("ERROR: Invalid sw_mode setting! val=%u\n", sw_mode);
+ DML2_ASSERT(0);
+ }
+
+ return version;
+}
+
+unsigned int dml2_core_utils_get_qos_param_index(unsigned long uclk_freq_khz, const struct dml2_dcn4_uclk_dpm_dependent_qos_params *per_uclk_dpm_params)
+{
+ unsigned int i;
+ unsigned int index = 0;
+
+ for (i = 0; i < DML_MAX_CLK_TABLE_SIZE; i++) {
+ dml2_printf("DML::%s: per_uclk_dpm_params[%d].minimum_uclk_khz = %d\n", __func__, i, per_uclk_dpm_params[i].minimum_uclk_khz);
+
+ if (i == 0)
+ index = 0;
+ else
+ index = i - 1;
+
+ if (uclk_freq_khz < per_uclk_dpm_params[i].minimum_uclk_khz ||
+ per_uclk_dpm_params[i].minimum_uclk_khz == 0) {
+ break;
+ }
+ }
+#if defined(__DML_VBA_DEBUG__)
+ dml2_printf("DML::%s: uclk_freq_khz = %d\n", __func__, uclk_freq_khz);
+ dml2_printf("DML::%s: index = %d\n", __func__, index);
+#endif
+ return index;
+}
+
+unsigned int dml2_core_utils_get_active_min_uclk_dpm_index(unsigned long uclk_freq_khz, const struct dml2_soc_state_table *clk_table)
+{
+ unsigned int i;
+ bool clk_entry_found = 0;
+
+ for (i = 0; i < clk_table->uclk.num_clk_values; i++) {
+ dml2_printf("DML::%s: clk_table.uclk.clk_values_khz[%d] = %d\n", __func__, i, clk_table->uclk.clk_values_khz[i]);
+
+ if (uclk_freq_khz == clk_table->uclk.clk_values_khz[i]) {
+ clk_entry_found = 1;
+ break;
+ }
+ }
+
+ dml2_assert(clk_entry_found);
+#if defined(__DML_VBA_DEBUG__)
+ dml2_printf("DML::%s: uclk_freq_khz = %ld\n", __func__, uclk_freq_khz);
+ dml2_printf("DML::%s: index = %d\n", __func__, i);
+#endif
+ return i;
+}
+
+bool dml2_core_utils_is_dual_plane(enum dml2_source_format_class source_format)
+{
+ bool ret_val = 0;
+
+ if ((source_format == dml2_420_12) || (source_format == dml2_420_8) || (source_format == dml2_420_10) || (source_format == dml2_rgbe_alpha))
+ ret_val = 1;
+
+ return ret_val;
+}
+
+unsigned int dml2_core_utils_log_and_substract_if_non_zero(unsigned int a, unsigned int subtrahend)
+{
+ if (a == 0)
+ return 0;
+
+ return (math_log2_approx(a) - subtrahend);
+}
+
+static void create_phantom_stream_from_main_stream(struct dml2_stream_parameters *phantom, const struct dml2_stream_parameters *main,
+ const struct dml2_implicit_svp_meta *meta)
+{
+ memcpy(phantom, main, sizeof(struct dml2_stream_parameters));
+
+ phantom->timing.v_total = meta->v_total;
+ phantom->timing.v_active = meta->v_active;
+ phantom->timing.v_front_porch = meta->v_front_porch;
+ phantom->timing.vblank_nom = phantom->timing.v_total - phantom->timing.v_active;
+ phantom->timing.drr_config.enabled = false;
+}
+
+static void create_phantom_plane_from_main_plane(struct dml2_plane_parameters *phantom, const struct dml2_plane_parameters *main,
+ const struct dml2_stream_parameters *phantom_stream, int phantom_stream_index, const struct dml2_stream_parameters *main_stream)
+{
+ memcpy(phantom, main, sizeof(struct dml2_plane_parameters));
+
+ phantom->stream_index = phantom_stream_index;
+ phantom->overrides.refresh_from_mall = dml2_refresh_from_mall_mode_override_force_disable;
+ phantom->overrides.legacy_svp_config = dml2_svp_mode_override_phantom_pipe_no_data_return;
+ phantom->composition.viewport.plane0.height = (long int unsigned) math_min2(math_ceil2(
+ (double)main->composition.scaler_info.plane0.v_ratio * (double)phantom_stream->timing.v_active, 16.0),
+ (double)main->composition.viewport.plane0.height);
+ phantom->composition.viewport.plane1.height = (long int unsigned) math_min2(math_ceil2(
+ (double)main->composition.scaler_info.plane1.v_ratio * (double)phantom_stream->timing.v_active, 16.0),
+ (double)main->composition.viewport.plane1.height);
+ phantom->immediate_flip = false;
+ phantom->dynamic_meta_data.enable = false;
+ phantom->cursor.num_cursors = 0;
+ phantom->cursor.cursor_width = 0;
+ phantom->tdlut.setup_for_tdlut = false;
+}
+
+void dml2_core_utils_expand_implict_subvp(const struct display_configuation_with_meta *display_cfg, struct dml2_display_cfg *svp_expanded_display_cfg,
+ struct dml2_core_scratch *scratch)
+{
+ unsigned int stream_index, plane_index;
+ const struct dml2_plane_parameters *main_plane;
+ const struct dml2_stream_parameters *main_stream;
+ const struct dml2_stream_parameters *phantom_stream;
+
+ memcpy(svp_expanded_display_cfg, &display_cfg->display_config, sizeof(struct dml2_display_cfg));
+ memset(scratch->main_stream_index_from_svp_stream_index, 0, sizeof(int) * DML2_MAX_PLANES);
+ memset(scratch->svp_stream_index_from_main_stream_index, 0, sizeof(int) * DML2_MAX_PLANES);
+ memset(scratch->main_plane_index_to_phantom_plane_index, 0, sizeof(int) * DML2_MAX_PLANES);
+
+ if (!display_cfg->display_config.overrides.enable_subvp_implicit_pmo)
+ return;
+
+ /* disable unbounded requesting for all planes until stage 3 has been performed */
+ if (!display_cfg->stage3.performed) {
+ svp_expanded_display_cfg->overrides.hw.force_unbounded_requesting.enable = true;
+ svp_expanded_display_cfg->overrides.hw.force_unbounded_requesting.value = false;
+ }
+ // Create the phantom streams
+ for (stream_index = 0; stream_index < display_cfg->display_config.num_streams; stream_index++) {
+ main_stream = &display_cfg->display_config.stream_descriptors[stream_index];
+ scratch->main_stream_index_from_svp_stream_index[stream_index] = stream_index;
+ scratch->svp_stream_index_from_main_stream_index[stream_index] = stream_index;
+
+ if (display_cfg->stage3.stream_svp_meta[stream_index].valid) {
+ // Create the phantom stream
+ create_phantom_stream_from_main_stream(&svp_expanded_display_cfg->stream_descriptors[svp_expanded_display_cfg->num_streams],
+ main_stream, &display_cfg->stage3.stream_svp_meta[stream_index]);
+
+ // Associate this phantom stream to the main stream
+ scratch->main_stream_index_from_svp_stream_index[svp_expanded_display_cfg->num_streams] = stream_index;
+ scratch->svp_stream_index_from_main_stream_index[stream_index] = svp_expanded_display_cfg->num_streams;
+
+ // Increment num streams
+ svp_expanded_display_cfg->num_streams++;
+ }
+ }
+
+ // Create the phantom planes
+ for (plane_index = 0; plane_index < display_cfg->display_config.num_planes; plane_index++) {
+ main_plane = &display_cfg->display_config.plane_descriptors[plane_index];
+
+ if (display_cfg->stage3.stream_svp_meta[main_plane->stream_index].valid) {
+ main_stream = &display_cfg->display_config.stream_descriptors[main_plane->stream_index];
+ phantom_stream = &svp_expanded_display_cfg->stream_descriptors[scratch->svp_stream_index_from_main_stream_index[main_plane->stream_index]];
+ create_phantom_plane_from_main_plane(&svp_expanded_display_cfg->plane_descriptors[svp_expanded_display_cfg->num_planes],
+ main_plane, phantom_stream, scratch->svp_stream_index_from_main_stream_index[main_plane->stream_index], main_stream);
+
+ // Associate this phantom plane to the main plane
+ scratch->phantom_plane_index_to_main_plane_index[svp_expanded_display_cfg->num_planes] = plane_index;
+ scratch->main_plane_index_to_phantom_plane_index[plane_index] = svp_expanded_display_cfg->num_planes;
+
+ // Increment num planes
+ svp_expanded_display_cfg->num_planes++;
+
+ // Adjust the main plane settings
+ svp_expanded_display_cfg->plane_descriptors[plane_index].overrides.legacy_svp_config = dml2_svp_mode_override_main_pipe;
+ }
+ }
+}
+
+bool dml2_core_utils_is_stream_encoder_required(const struct dml2_stream_parameters *stream_descriptor)
+{
+ switch (stream_descriptor->output.output_encoder) {
+ case dml2_dp:
+ case dml2_dp2p0:
+ case dml2_edp:
+ case dml2_hdmi:
+ case dml2_hdmifrl:
+ return true;
+ case dml2_none:
+ default:
+ return false;
+ }
+}
+bool dml2_core_utils_is_encoder_dsc_capable(const struct dml2_stream_parameters *stream_descriptor)
+{
+ switch (stream_descriptor->output.output_encoder) {
+ case dml2_dp:
+ case dml2_dp2p0:
+ case dml2_edp:
+ case dml2_hdmifrl:
+ return true;
+ case dml2_hdmi:
+ case dml2_none:
+ default:
+ return false;
+ }
+}
+
+
+bool dml2_core_utils_is_dio_dp_encoder(const struct dml2_stream_parameters *stream_descriptor)
+{
+ switch (stream_descriptor->output.output_encoder) {
+ case dml2_dp:
+ case dml2_edp:
+ return true;
+ case dml2_dp2p0:
+ case dml2_hdmi:
+ case dml2_hdmifrl:
+ case dml2_none:
+ default:
+ return false;
+ }
+}
+
+bool dml2_core_utils_is_hpo_dp_encoder(const struct dml2_stream_parameters *stream_descriptor)
+{
+ switch (stream_descriptor->output.output_encoder) {
+ case dml2_dp2p0:
+ return true;
+ case dml2_dp:
+ case dml2_edp:
+ case dml2_hdmi:
+ case dml2_hdmifrl:
+ case dml2_none:
+ default:
+ return false;
+ }
+}
+
+bool dml2_core_utils_is_dp_encoder(const struct dml2_stream_parameters *stream_descriptor)
+{
+ return dml2_core_utils_is_dio_dp_encoder(stream_descriptor)
+ || dml2_core_utils_is_hpo_dp_encoder(stream_descriptor);
+}
+
+
+bool dml2_core_utils_is_dp_8b_10b_link_rate(enum dml2_output_link_dp_rate rate)
+{
+ switch (rate) {
+ case dml2_dp_rate_hbr:
+ case dml2_dp_rate_hbr2:
+ case dml2_dp_rate_hbr3:
+ return true;
+ case dml2_dp_rate_na:
+ case dml2_dp_rate_uhbr10:
+ case dml2_dp_rate_uhbr13p5:
+ case dml2_dp_rate_uhbr20:
+ default:
+ return false;
+ }
+}
+
+bool dml2_core_utils_is_dp_128b_132b_link_rate(enum dml2_output_link_dp_rate rate)
+{
+ switch (rate) {
+ case dml2_dp_rate_uhbr10:
+ case dml2_dp_rate_uhbr13p5:
+ case dml2_dp_rate_uhbr20:
+ return true;
+ case dml2_dp_rate_hbr:
+ case dml2_dp_rate_hbr2:
+ case dml2_dp_rate_hbr3:
+ case dml2_dp_rate_na:
+ default:
+ return false;
+ }
+}
+
+bool dml2_core_utils_is_odm_split(enum dml2_odm_mode odm_mode)
+{
+ switch (odm_mode) {
+ case dml2_odm_mode_split_1to2:
+ case dml2_odm_mode_mso_1to2:
+ case dml2_odm_mode_mso_1to4:
+ return true;
+ case dml2_odm_mode_auto:
+ case dml2_odm_mode_bypass:
+ case dml2_odm_mode_combine_2to1:
+ case dml2_odm_mode_combine_3to1:
+ case dml2_odm_mode_combine_4to1:
+ default:
+ return false;
+ }
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_utils.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_utils.h
new file mode 100644
index 000000000000..a5cc6a07167a
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_utils.h
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: MIT
+//
+// Copyright 2024 Advanced Micro Devices, Inc.
+
+#ifndef __DML2_CORE_UTILS_H__
+#define __DML2_CORE_UTILS_H__
+#include "dml2_internal_shared_types.h"
+#include "dml2_debug.h"
+#include "lib_float_math.h"
+
+double dml2_core_utils_div_rem(double dividend, unsigned int divisor, unsigned int *remainder);
+const char *dml2_core_utils_internal_bw_type_str(enum dml2_core_internal_bw_type bw_type);
+bool dml2_core_utils_is_420(enum dml2_source_format_class source_format);
+void dml2_core_utils_print_mode_support_info(const struct dml2_core_internal_mode_support_info *support, bool fail_only);
+const char *dml2_core_utils_internal_soc_state_type_str(enum dml2_core_internal_soc_state_type dml2_core_internal_soc_state_type);
+void dml2_core_utils_get_stream_output_bpp(double *out_bpp, const struct dml2_display_cfg *display_cfg);
+unsigned int dml2_core_utils_round_to_multiple(unsigned int num, unsigned int multiple, bool up);
+unsigned int dml2_core_util_get_num_active_pipes(int unsigned num_planes, const struct core_display_cfg_support_info *cfg_support_info);
+void dml2_core_utils_pipe_plane_mapping(const struct core_display_cfg_support_info *cfg_support_info, unsigned int *pipe_plane);
+bool dml2_core_utils_is_phantom_pipe(const struct dml2_plane_parameters *plane_cfg);
+unsigned int dml2_core_utils_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode);
+bool dml2_core_utils_is_vertical_rotation(enum dml2_rotation_angle Scan);
+int unsigned dml2_core_utils_get_gfx_version(enum dml2_swizzle_mode sw_mode);
+unsigned int dml2_core_utils_get_qos_param_index(unsigned long uclk_freq_khz, const struct dml2_dcn4_uclk_dpm_dependent_qos_params *per_uclk_dpm_params);
+unsigned int dml2_core_utils_get_active_min_uclk_dpm_index(unsigned long uclk_freq_khz, const struct dml2_soc_state_table *clk_table);
+bool dml2_core_utils_is_dual_plane(enum dml2_source_format_class source_format);
+unsigned int dml2_core_utils_log_and_substract_if_non_zero(unsigned int a, unsigned int subtrahend);
+void dml2_core_utils_expand_implict_subvp(const struct display_configuation_with_meta *display_cfg, struct dml2_display_cfg *svp_expanded_display_cfg,
+ struct dml2_core_scratch *scratch);
+bool dml2_core_utils_is_stream_encoder_required(const struct dml2_stream_parameters *stream_descriptor);
+bool dml2_core_utils_is_encoder_dsc_capable(const struct dml2_stream_parameters *stream_descriptor);
+bool dml2_core_utils_is_dp_encoder(const struct dml2_stream_parameters *stream_descriptor);
+bool dml2_core_utils_is_dio_dp_encoder(const struct dml2_stream_parameters *stream_descriptor);
+bool dml2_core_utils_is_hpo_dp_encoder(const struct dml2_stream_parameters *stream_descriptor);
+bool dml2_core_utils_is_dp_8b_10b_link_rate(enum dml2_output_link_dp_rate rate);
+bool dml2_core_utils_is_dp_128b_132b_link_rate(enum dml2_output_link_dp_rate rate);
+bool dml2_core_utils_is_odm_split(enum dml2_odm_mode odm_mode);
+
+#endif /* __DML2_CORE_UTILS_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
index c94c4f32c957..8869ea089312 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#include "dml2_dpmm_dcn4.h"
#include "dml2_internal_shared_types.h"
#include "dml_top_types.h"
@@ -83,9 +82,9 @@ static void calculate_system_active_minimums(struct dml2_dpmm_map_mode_to_soc_dp
get_minimum_clocks_for_latency(in_out, &min_uclk_latency, &min_fclk_latency, &min_dcfclk_latency);
- in_out->programming->min_clocks.dcn4.active.uclk_khz = dml_round_up(min_uclk_bw > min_uclk_latency ? min_uclk_bw : min_uclk_latency);
- in_out->programming->min_clocks.dcn4.active.fclk_khz = dml_round_up(min_fclk_bw > min_fclk_latency ? min_fclk_bw : min_fclk_latency);
- in_out->programming->min_clocks.dcn4.active.dcfclk_khz = dml_round_up(min_dcfclk_bw > min_dcfclk_latency ? min_dcfclk_bw : min_dcfclk_latency);
+ in_out->programming->min_clocks.dcn4x.active.uclk_khz = dml_round_up(min_uclk_bw > min_uclk_latency ? min_uclk_bw : min_uclk_latency);
+ in_out->programming->min_clocks.dcn4x.active.fclk_khz = dml_round_up(min_fclk_bw > min_fclk_latency ? min_fclk_bw : min_fclk_latency);
+ in_out->programming->min_clocks.dcn4x.active.dcfclk_khz = dml_round_up(min_dcfclk_bw > min_dcfclk_latency ? min_dcfclk_bw : min_dcfclk_latency);
}
static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out)
@@ -123,9 +122,9 @@ static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm
get_minimum_clocks_for_latency(in_out, &min_uclk_latency, &min_fclk_latency, &min_dcfclk_latency);
- in_out->programming->min_clocks.dcn4.svp_prefetch.uclk_khz = dml_round_up(min_uclk_bw > min_uclk_latency ? min_uclk_bw : min_uclk_latency);
- in_out->programming->min_clocks.dcn4.svp_prefetch.fclk_khz = dml_round_up(min_fclk_bw > min_fclk_latency ? min_fclk_bw : min_fclk_latency);
- in_out->programming->min_clocks.dcn4.svp_prefetch.dcfclk_khz = dml_round_up(min_dcfclk_bw > min_dcfclk_latency ? min_dcfclk_bw : min_dcfclk_latency);
+ in_out->programming->min_clocks.dcn4x.svp_prefetch.uclk_khz = dml_round_up(min_uclk_bw > min_uclk_latency ? min_uclk_bw : min_uclk_latency);
+ in_out->programming->min_clocks.dcn4x.svp_prefetch.fclk_khz = dml_round_up(min_fclk_bw > min_fclk_latency ? min_fclk_bw : min_fclk_latency);
+ in_out->programming->min_clocks.dcn4x.svp_prefetch.dcfclk_khz = dml_round_up(min_dcfclk_bw > min_dcfclk_latency ? min_dcfclk_bw : min_dcfclk_latency);
}
static void calculate_idle_minimums(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out)
@@ -147,9 +146,9 @@ static void calculate_idle_minimums(struct dml2_dpmm_map_mode_to_soc_dpm_params_
get_minimum_clocks_for_latency(in_out, &min_uclk_latency, &min_fclk_latency, &min_dcfclk_latency);
- in_out->programming->min_clocks.dcn4.idle.uclk_khz = dml_round_up(min_uclk_avg > min_uclk_latency ? min_uclk_avg : min_uclk_latency);
- in_out->programming->min_clocks.dcn4.idle.fclk_khz = dml_round_up(min_fclk_avg > min_fclk_latency ? min_fclk_avg : min_fclk_latency);
- in_out->programming->min_clocks.dcn4.idle.dcfclk_khz = dml_round_up(min_dcfclk_avg > min_dcfclk_latency ? min_dcfclk_avg : min_dcfclk_latency);
+ in_out->programming->min_clocks.dcn4x.idle.uclk_khz = dml_round_up(min_uclk_avg > min_uclk_latency ? min_uclk_avg : min_uclk_latency);
+ in_out->programming->min_clocks.dcn4x.idle.fclk_khz = dml_round_up(min_fclk_avg > min_fclk_latency ? min_fclk_avg : min_fclk_latency);
+ in_out->programming->min_clocks.dcn4x.idle.dcfclk_khz = dml_round_up(min_dcfclk_avg > min_dcfclk_latency ? min_dcfclk_avg : min_dcfclk_latency);
}
static bool add_margin_and_round_to_dfs_grainularity(double clock_khz, double margin, unsigned long vco_freq_khz, unsigned long *rounded_khz, uint32_t *divider_id)
@@ -204,6 +203,26 @@ static bool add_margin_and_round_to_dfs_grainularity(double clock_khz, double ma
return true;
}
+static bool round_to_non_dfs_granularity(unsigned long dispclk_khz, unsigned long dpprefclk_khz, unsigned long dtbrefclk_khz,
+ unsigned long *rounded_dispclk_khz, unsigned long *rounded_dpprefclk_khz, unsigned long *rounded_dtbrefclk_khz)
+{
+ unsigned long pll_frequency_khz;
+
+ pll_frequency_khz = (unsigned long) math_max2(600000, math_ceil2(math_max3(dispclk_khz, dpprefclk_khz, dtbrefclk_khz), 1000));
+
+ *rounded_dispclk_khz = pll_frequency_khz / (unsigned long) math_min2(pll_frequency_khz / dispclk_khz, 32);
+
+ *rounded_dpprefclk_khz = pll_frequency_khz / (unsigned long) math_min2(pll_frequency_khz / dpprefclk_khz, 32);
+
+ if (dtbrefclk_khz > 0) {
+ *rounded_dtbrefclk_khz = pll_frequency_khz / (unsigned long) math_min2(pll_frequency_khz / dtbrefclk_khz, 32);
+ } else {
+ *rounded_dtbrefclk_khz = 0;
+ }
+
+ return true;
+}
+
static bool round_up_and_copy_to_next_dpm(unsigned long min_value, unsigned long *rounded_value, const struct dml2_clk_table *clock_table)
{
bool result = false;
@@ -233,25 +252,25 @@ static bool map_soc_min_clocks_to_dpm_fine_grained(struct dml2_display_cfg_progr
{
bool result;
- result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4.active.dcfclk_khz, &state_table->dcfclk);
+ result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.active.dcfclk_khz, &state_table->dcfclk);
if (result)
- result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4.active.fclk_khz, &state_table->fclk);
+ result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.active.fclk_khz, &state_table->fclk);
if (result)
- result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4.active.uclk_khz, &state_table->uclk);
+ result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.active.uclk_khz, &state_table->uclk);
if (result)
- result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4.svp_prefetch.dcfclk_khz, &state_table->dcfclk);
+ result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.svp_prefetch.dcfclk_khz, &state_table->dcfclk);
if (result)
- result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4.svp_prefetch.fclk_khz, &state_table->fclk);
+ result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.svp_prefetch.fclk_khz, &state_table->fclk);
if (result)
- result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4.svp_prefetch.uclk_khz, &state_table->uclk);
+ result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.svp_prefetch.uclk_khz, &state_table->uclk);
if (result)
- result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4.idle.dcfclk_khz, &state_table->dcfclk);
+ result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.idle.dcfclk_khz, &state_table->dcfclk);
if (result)
- result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4.idle.fclk_khz, &state_table->fclk);
+ result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.idle.fclk_khz, &state_table->fclk);
if (result)
- result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4.idle.uclk_khz, &state_table->uclk);
+ result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.idle.uclk_khz, &state_table->uclk);
return result;
}
@@ -263,12 +282,12 @@ static bool map_soc_min_clocks_to_dpm_coarse_grained(struct dml2_display_cfg_pro
result = false;
for (index = 0; index < state_table->uclk.num_clk_values; index++) {
- if (display_cfg->min_clocks.dcn4.active.dcfclk_khz <= state_table->dcfclk.clk_values_khz[index] &&
- display_cfg->min_clocks.dcn4.active.fclk_khz <= state_table->fclk.clk_values_khz[index] &&
- display_cfg->min_clocks.dcn4.active.uclk_khz <= state_table->uclk.clk_values_khz[index]) {
- display_cfg->min_clocks.dcn4.active.dcfclk_khz = state_table->dcfclk.clk_values_khz[index];
- display_cfg->min_clocks.dcn4.active.fclk_khz = state_table->fclk.clk_values_khz[index];
- display_cfg->min_clocks.dcn4.active.uclk_khz = state_table->uclk.clk_values_khz[index];
+ if (display_cfg->min_clocks.dcn4x.active.dcfclk_khz <= state_table->dcfclk.clk_values_khz[index] &&
+ display_cfg->min_clocks.dcn4x.active.fclk_khz <= state_table->fclk.clk_values_khz[index] &&
+ display_cfg->min_clocks.dcn4x.active.uclk_khz <= state_table->uclk.clk_values_khz[index]) {
+ display_cfg->min_clocks.dcn4x.active.dcfclk_khz = state_table->dcfclk.clk_values_khz[index];
+ display_cfg->min_clocks.dcn4x.active.fclk_khz = state_table->fclk.clk_values_khz[index];
+ display_cfg->min_clocks.dcn4x.active.uclk_khz = state_table->uclk.clk_values_khz[index];
result = true;
break;
}
@@ -277,12 +296,12 @@ static bool map_soc_min_clocks_to_dpm_coarse_grained(struct dml2_display_cfg_pro
if (result) {
result = false;
for (index = 0; index < state_table->uclk.num_clk_values; index++) {
- if (display_cfg->min_clocks.dcn4.idle.dcfclk_khz <= state_table->dcfclk.clk_values_khz[index] &&
- display_cfg->min_clocks.dcn4.idle.fclk_khz <= state_table->fclk.clk_values_khz[index] &&
- display_cfg->min_clocks.dcn4.idle.uclk_khz <= state_table->uclk.clk_values_khz[index]) {
- display_cfg->min_clocks.dcn4.idle.dcfclk_khz = state_table->dcfclk.clk_values_khz[index];
- display_cfg->min_clocks.dcn4.idle.fclk_khz = state_table->fclk.clk_values_khz[index];
- display_cfg->min_clocks.dcn4.idle.uclk_khz = state_table->uclk.clk_values_khz[index];
+ if (display_cfg->min_clocks.dcn4x.idle.dcfclk_khz <= state_table->dcfclk.clk_values_khz[index] &&
+ display_cfg->min_clocks.dcn4x.idle.fclk_khz <= state_table->fclk.clk_values_khz[index] &&
+ display_cfg->min_clocks.dcn4x.idle.uclk_khz <= state_table->uclk.clk_values_khz[index]) {
+ display_cfg->min_clocks.dcn4x.idle.dcfclk_khz = state_table->dcfclk.clk_values_khz[index];
+ display_cfg->min_clocks.dcn4x.idle.fclk_khz = state_table->fclk.clk_values_khz[index];
+ display_cfg->min_clocks.dcn4x.idle.uclk_khz = state_table->uclk.clk_values_khz[index];
result = true;
break;
}
@@ -290,9 +309,9 @@ static bool map_soc_min_clocks_to_dpm_coarse_grained(struct dml2_display_cfg_pro
}
// SVP is not supported on any coarse grained SoCs
- display_cfg->min_clocks.dcn4.svp_prefetch.dcfclk_khz = 0;
- display_cfg->min_clocks.dcn4.svp_prefetch.fclk_khz = 0;
- display_cfg->min_clocks.dcn4.svp_prefetch.uclk_khz = 0;
+ display_cfg->min_clocks.dcn4x.svp_prefetch.dcfclk_khz = 0;
+ display_cfg->min_clocks.dcn4x.svp_prefetch.fclk_khz = 0;
+ display_cfg->min_clocks.dcn4x.svp_prefetch.uclk_khz = 0;
return result;
}
@@ -325,30 +344,30 @@ static bool map_min_clocks_to_dpm(const struct dml2_core_mode_support_result *mo
result = map_soc_min_clocks_to_dpm_coarse_grained(display_cfg, state_table);
if (result)
- result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4.dispclk_khz, &state_table->dispclk);
+ result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.dispclk_khz, &state_table->dispclk);
if (result)
- result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4.deepsleep_dcfclk_khz, &state_table->dcfclk);
+ result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.deepsleep_dcfclk_khz, &state_table->dcfclk);
for (i = 0; i < DML2_MAX_DCN_PIPES; i++) {
if (result)
- result = round_up_to_next_dpm(&display_cfg->plane_programming[i].min_clocks.dcn4.dppclk_khz, &state_table->dppclk);
+ result = round_up_to_next_dpm(&display_cfg->plane_programming[i].min_clocks.dcn4x.dppclk_khz, &state_table->dppclk);
}
for (i = 0; i < display_cfg->display_config.num_streams; i++) {
if (result)
- result = round_up_and_copy_to_next_dpm(mode_support_result->per_stream[i].dscclk_khz, &display_cfg->stream_programming[i].min_clocks.dcn4.dscclk_khz, &state_table->dscclk);
+ result = round_up_and_copy_to_next_dpm(mode_support_result->per_stream[i].dscclk_khz, &display_cfg->stream_programming[i].min_clocks.dcn4x.dscclk_khz, &state_table->dscclk);
if (result)
- result = round_up_and_copy_to_next_dpm(mode_support_result->per_stream[i].dtbclk_khz, &display_cfg->stream_programming[i].min_clocks.dcn4.dtbclk_khz, &state_table->dtbclk);
+ result = round_up_and_copy_to_next_dpm(mode_support_result->per_stream[i].dtbclk_khz, &display_cfg->stream_programming[i].min_clocks.dcn4x.dtbclk_khz, &state_table->dtbclk);
if (result)
- result = round_up_and_copy_to_next_dpm(mode_support_result->per_stream[i].phyclk_khz, &display_cfg->stream_programming[i].min_clocks.dcn4.phyclk_khz, &state_table->phyclk);
+ result = round_up_and_copy_to_next_dpm(mode_support_result->per_stream[i].phyclk_khz, &display_cfg->stream_programming[i].min_clocks.dcn4x.phyclk_khz, &state_table->phyclk);
}
if (result)
- result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4.dpprefclk_khz, &state_table->dppclk);
+ result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.dpprefclk_khz, &state_table->dppclk);
if (result)
- result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4.dtbrefclk_khz, &state_table->dtbclk);
+ result = round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.dtbrefclk_khz, &state_table->dtbclk);
return result;
}
@@ -516,15 +535,15 @@ static bool determine_power_management_features_with_fams(struct dml2_dpmm_map_m
static void clamp_uclk_to_max(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out)
{
- in_out->programming->min_clocks.dcn4.active.uclk_khz = in_out->soc_bb->clk_table.uclk.clk_values_khz[in_out->soc_bb->clk_table.uclk.num_clk_values - 1];
- in_out->programming->min_clocks.dcn4.svp_prefetch.uclk_khz = in_out->soc_bb->clk_table.uclk.clk_values_khz[in_out->soc_bb->clk_table.uclk.num_clk_values - 1];
- in_out->programming->min_clocks.dcn4.idle.uclk_khz = in_out->soc_bb->clk_table.uclk.clk_values_khz[in_out->soc_bb->clk_table.uclk.num_clk_values - 1];
+ in_out->programming->min_clocks.dcn4x.active.uclk_khz = in_out->soc_bb->clk_table.uclk.clk_values_khz[in_out->soc_bb->clk_table.uclk.num_clk_values - 1];
+ in_out->programming->min_clocks.dcn4x.svp_prefetch.uclk_khz = in_out->soc_bb->clk_table.uclk.clk_values_khz[in_out->soc_bb->clk_table.uclk.num_clk_values - 1];
+ in_out->programming->min_clocks.dcn4x.idle.uclk_khz = in_out->soc_bb->clk_table.uclk.clk_values_khz[in_out->soc_bb->clk_table.uclk.num_clk_values - 1];
}
static void clamp_fclk_to_max(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out)
{
- in_out->programming->min_clocks.dcn4.active.fclk_khz = in_out->soc_bb->clk_table.fclk.clk_values_khz[in_out->soc_bb->clk_table.fclk.num_clk_values - 1];
- in_out->programming->min_clocks.dcn4.idle.fclk_khz = in_out->soc_bb->clk_table.fclk.clk_values_khz[in_out->soc_bb->clk_table.fclk.num_clk_values - 1];
+ in_out->programming->min_clocks.dcn4x.active.fclk_khz = in_out->soc_bb->clk_table.fclk.clk_values_khz[in_out->soc_bb->clk_table.fclk.num_clk_values - 1];
+ in_out->programming->min_clocks.dcn4x.idle.fclk_khz = in_out->soc_bb->clk_table.fclk.clk_values_khz[in_out->soc_bb->clk_table.fclk.num_clk_values - 1];
}
static bool map_mode_to_soc_dpm(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out)
@@ -540,14 +559,14 @@ static bool map_mode_to_soc_dpm(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_o
// In NV4, there's no support for FCLK or DCFCLK DPM change before SVP prefetch starts, therefore
// active minimums must be boosted to prefetch minimums
- if (in_out->programming->min_clocks.dcn4.svp_prefetch.uclk_khz > in_out->programming->min_clocks.dcn4.active.uclk_khz)
- in_out->programming->min_clocks.dcn4.active.uclk_khz = in_out->programming->min_clocks.dcn4.svp_prefetch.uclk_khz;
+ if (in_out->programming->min_clocks.dcn4x.svp_prefetch.uclk_khz > in_out->programming->min_clocks.dcn4x.active.uclk_khz)
+ in_out->programming->min_clocks.dcn4x.active.uclk_khz = in_out->programming->min_clocks.dcn4x.svp_prefetch.uclk_khz;
- if (in_out->programming->min_clocks.dcn4.svp_prefetch.fclk_khz > in_out->programming->min_clocks.dcn4.active.fclk_khz)
- in_out->programming->min_clocks.dcn4.active.fclk_khz = in_out->programming->min_clocks.dcn4.svp_prefetch.fclk_khz;
+ if (in_out->programming->min_clocks.dcn4x.svp_prefetch.fclk_khz > in_out->programming->min_clocks.dcn4x.active.fclk_khz)
+ in_out->programming->min_clocks.dcn4x.active.fclk_khz = in_out->programming->min_clocks.dcn4x.svp_prefetch.fclk_khz;
- if (in_out->programming->min_clocks.dcn4.svp_prefetch.dcfclk_khz > in_out->programming->min_clocks.dcn4.active.dcfclk_khz)
- in_out->programming->min_clocks.dcn4.active.dcfclk_khz = in_out->programming->min_clocks.dcn4.svp_prefetch.dcfclk_khz;
+ if (in_out->programming->min_clocks.dcn4x.svp_prefetch.dcfclk_khz > in_out->programming->min_clocks.dcn4x.active.dcfclk_khz)
+ in_out->programming->min_clocks.dcn4x.active.dcfclk_khz = in_out->programming->min_clocks.dcn4x.svp_prefetch.dcfclk_khz;
// need some massaging for the dispclk ramping cases:
dispclk_khz = mode_support_result->global.dispclk_khz * (1 + in_out->soc_bb->dcn_downspread_percent / 100.0) * (1.0 + in_out->ip->dispclk_ramp_margin_percent / 100.0);
@@ -556,34 +575,42 @@ static bool map_mode_to_soc_dpm(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_o
// but still the required dispclk can be more than the maximum dispclk speed:
dispclk_khz = math_max2(dispclk_khz, mode_support_result->global.dispclk_khz * (1 + in_out->soc_bb->dcn_downspread_percent / 100.0));
- add_margin_and_round_to_dfs_grainularity(dispclk_khz, 0.0,
- (unsigned long)(in_out->soc_bb->dispclk_dppclk_vco_speed_mhz * 1000), &in_out->programming->min_clocks.dcn4.dispclk_khz, &in_out->programming->min_clocks.dcn4.divider_ids.dispclk_did);
-
// DPP Ref is always set to max of all DPP clocks
for (i = 0; i < DML2_MAX_DCN_PIPES; i++) {
- if (in_out->programming->min_clocks.dcn4.dpprefclk_khz < mode_support_result->per_plane[i].dppclk_khz)
- in_out->programming->min_clocks.dcn4.dpprefclk_khz = mode_support_result->per_plane[i].dppclk_khz;
+ if (in_out->programming->min_clocks.dcn4x.dpprefclk_khz < mode_support_result->per_plane[i].dppclk_khz)
+ in_out->programming->min_clocks.dcn4x.dpprefclk_khz = mode_support_result->per_plane[i].dppclk_khz;
}
+ in_out->programming->min_clocks.dcn4x.dpprefclk_khz = (unsigned long) (in_out->programming->min_clocks.dcn4x.dpprefclk_khz * (1 + in_out->soc_bb->dcn_downspread_percent / 100.0));
- add_margin_and_round_to_dfs_grainularity(in_out->programming->min_clocks.dcn4.dpprefclk_khz, in_out->soc_bb->dcn_downspread_percent / 100.0,
- (unsigned long)(in_out->soc_bb->dispclk_dppclk_vco_speed_mhz * 1000), &in_out->programming->min_clocks.dcn4.dpprefclk_khz, &in_out->programming->min_clocks.dcn4.divider_ids.dpprefclk_did);
-
+ // DTB Ref is always set to max of all DTB clocks
for (i = 0; i < DML2_MAX_DCN_PIPES; i++) {
- in_out->programming->plane_programming[i].min_clocks.dcn4.dppclk_khz = (unsigned long)(in_out->programming->min_clocks.dcn4.dpprefclk_khz / 255.0
- * math_ceil2(in_out->display_cfg->mode_support_result.per_plane[i].dppclk_khz * (1.0 + in_out->soc_bb->dcn_downspread_percent / 100.0) * 255.0 / in_out->programming->min_clocks.dcn4.dpprefclk_khz, 1.0));
+ if (in_out->programming->min_clocks.dcn4x.dtbrefclk_khz < mode_support_result->per_stream[i].dtbclk_khz)
+ in_out->programming->min_clocks.dcn4x.dtbrefclk_khz = mode_support_result->per_stream[i].dtbclk_khz;
}
+ in_out->programming->min_clocks.dcn4x.dtbrefclk_khz = (unsigned long)(in_out->programming->min_clocks.dcn4x.dtbrefclk_khz * (1 + in_out->soc_bb->dcn_downspread_percent / 100.0));
- // DTB Ref is always set to max of all DTB clocks
- for (i = 0; i < DML2_MAX_DCN_PIPES; i++) {
- if (in_out->programming->min_clocks.dcn4.dtbrefclk_khz < mode_support_result->per_stream[i].dtbclk_khz)
- in_out->programming->min_clocks.dcn4.dtbrefclk_khz = mode_support_result->per_stream[i].dtbclk_khz;
+ if (in_out->soc_bb->no_dfs) {
+ round_to_non_dfs_granularity((unsigned long)dispclk_khz, in_out->programming->min_clocks.dcn4x.dpprefclk_khz, in_out->programming->min_clocks.dcn4x.dtbrefclk_khz,
+ &in_out->programming->min_clocks.dcn4x.dispclk_khz, &in_out->programming->min_clocks.dcn4x.dpprefclk_khz, &in_out->programming->min_clocks.dcn4x.dtbrefclk_khz);
+ } else {
+ add_margin_and_round_to_dfs_grainularity(dispclk_khz, 0.0,
+ (unsigned long)(in_out->soc_bb->dispclk_dppclk_vco_speed_mhz * 1000), &in_out->programming->min_clocks.dcn4x.dispclk_khz, &in_out->programming->min_clocks.dcn4x.divider_ids.dispclk_did);
+
+ add_margin_and_round_to_dfs_grainularity(in_out->programming->min_clocks.dcn4x.dpprefclk_khz, 0.0,
+ (unsigned long)(in_out->soc_bb->dispclk_dppclk_vco_speed_mhz * 1000), &in_out->programming->min_clocks.dcn4x.dpprefclk_khz, &in_out->programming->min_clocks.dcn4x.divider_ids.dpprefclk_did);
+
+ add_margin_and_round_to_dfs_grainularity(in_out->programming->min_clocks.dcn4x.dtbrefclk_khz, 0.0,
+ (unsigned long)(in_out->soc_bb->dispclk_dppclk_vco_speed_mhz * 1000), &in_out->programming->min_clocks.dcn4x.dtbrefclk_khz, &in_out->programming->min_clocks.dcn4x.divider_ids.dtbrefclk_did);
}
- add_margin_and_round_to_dfs_grainularity(in_out->programming->min_clocks.dcn4.dtbrefclk_khz, in_out->soc_bb->dcn_downspread_percent / 100.0,
- (unsigned long)(in_out->soc_bb->dispclk_dppclk_vco_speed_mhz * 1000), &in_out->programming->min_clocks.dcn4.dtbrefclk_khz, &in_out->programming->min_clocks.dcn4.divider_ids.dtbrefclk_did);
- in_out->programming->min_clocks.dcn4.deepsleep_dcfclk_khz = mode_support_result->global.dcfclk_deepsleep_khz;
- in_out->programming->min_clocks.dcn4.socclk_khz = mode_support_result->global.socclk_khz;
+ for (i = 0; i < DML2_MAX_DCN_PIPES; i++) {
+ in_out->programming->plane_programming[i].min_clocks.dcn4x.dppclk_khz = (unsigned long)(in_out->programming->min_clocks.dcn4x.dpprefclk_khz / 255.0
+ * math_ceil2(in_out->display_cfg->mode_support_result.per_plane[i].dppclk_khz * (1.0 + in_out->soc_bb->dcn_downspread_percent / 100.0) * 255.0 / in_out->programming->min_clocks.dcn4x.dpprefclk_khz, 1.0));
+ }
+
+ in_out->programming->min_clocks.dcn4x.deepsleep_dcfclk_khz = mode_support_result->global.dcfclk_deepsleep_khz;
+ in_out->programming->min_clocks.dcn4x.socclk_khz = mode_support_result->global.socclk_khz;
result = map_min_clocks_to_dpm(mode_support_result, in_out->programming, &in_out->soc_bb->clk_table);
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.h
index 3afb69dfd040..b165c58dfd11 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_DPMM_DCN4_H__
#define __DML2_DPMM_DCN4_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_factory.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_factory.c
index 2c983daf2dad..3861bc6c9621 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_factory.c
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#include "dml2_dpmm_factory.h"
#include "dml2_dpmm_dcn4.h"
#include "dml2_external_lib_deps.h"
@@ -21,7 +20,7 @@ bool dml2_dpmm_create(enum dml2_project_id project_id, struct dml2_dpmm_instance
{
bool result = false;
- if (!out)
+ if (out == 0)
return false;
memset(out, 0, sizeof(struct dml2_dpmm_instance));
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_factory.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_factory.h
index 80b44b4c2e68..20ba2e446f1d 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_factory.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_factory.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_DPMM_FACTORY_H__
#define __DML2_DPMM_FACTORY_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_dcn4.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_dcn4.c
index 5d8887ac766d..f4b1a7d02d42 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_dcn4.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_dcn4.c
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#include "dml2_mcg_dcn4.h"
#include "dml_top_soc_parameter_types.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_dcn4.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_dcn4.h
index 19d178651435..02da6f45cbf7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_dcn4.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_dcn4.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_MCG_DCN4_H__
#define __DML2_MCG_DCN4_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.c
index 55085b85f8ed..c60b8fe90819 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.c
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#include "dml2_mcg_factory.h"
#include "dml2_mcg_dcn4.h"
#include "dml2_external_lib_deps.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.h
index 5dfdfed04e22..ad307deca3b0 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_MCG_FACTORY_H__
#define __DML2_MCG_FACTORY_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn3.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn3.c
index 671f9ac2627c..a31db5742675 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn3.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn3.c
@@ -2,22 +2,17 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#include "dml2_pmo_factory.h"
#include "dml2_pmo_dcn3.h"
static void sort(double *list_a, int list_a_size)
{
- double temp;
// For all elements b[i] in list_b[]
for (int i = 0; i < list_a_size - 1; i++) {
// Find the first element of list_a that's larger than b[i]
for (int j = i; j < list_a_size - 1; j++) {
- if (list_a[j] > list_a[j + 1]) {
- temp = list_a[j];
- list_a[j] = list_a[j + 1];
- list_a[j + 1] = temp;
- }
+ if (list_a[j] > list_a[j + 1])
+ swap(list_a[j], list_a[j + 1]);
}
}
}
@@ -502,7 +497,6 @@ bool pmo_dcn3_optimize_dcc_mcache(struct dml2_pmo_optimize_dcc_mcache_in_out *in
in_out->cfg_support_info->plane_support_info[i].dpps_used)) {
result = false;
} else {
- free_pipes -= planes_on_stream;
break;
}
} else {
@@ -671,7 +665,7 @@ bool pmo_dcn3_optimize_for_pstate_support(struct dml2_pmo_optimize_for_pstate_su
struct dml2_pmo_instance *pmo = in_out->instance;
unsigned int stream_index;
bool success = false;
- bool reached_end = true;
+ bool reached_end;
memcpy(in_out->optimized_display_config, in_out->base_display_config, sizeof(struct display_configuation_with_meta));
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn3.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn3.h
index cc350f88d4d2..f00bd9e72a86 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn3.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn3.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_PMO_DCN3_H__
#define __DML2_PMO_DCN3_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4.c
deleted file mode 100644
index 8952dd7e36cb..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4.c
+++ /dev/null
@@ -1,1250 +0,0 @@
-// SPDX-License-Identifier: MIT
-//
-// Copyright 2024 Advanced Micro Devices, Inc.
-
-
-#include "dml2_pmo_factory.h"
-#include "dml2_pmo_dcn4.h"
-
-static const int MIN_VACTIVE_MARGIN_US = 100; // We need more than non-zero margin because DET buffer granularity can alter vactive latency hiding
-static const int SUBVP_DRR_MARGIN_US = 100;
-
-static const enum dml2_pmo_pstate_strategy full_strategy_list_1_display[][4] = {
- // VActive Preferred
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
-
- // Then SVP
- { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
-
- // Then VBlank
- { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
-
- // Finally DRR
- { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
-};
-
-static const int full_strategy_list_1_display_size = sizeof(full_strategy_list_1_display) / (sizeof(enum dml2_pmo_pstate_strategy) * 4);
-
-static const enum dml2_pmo_pstate_strategy full_strategy_list_2_display[][4] = {
- // VActive only is preferred
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
-
- // Then VActive + VBlank
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
- { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
-
- // Then VBlank only
- { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
-
- // Then SVP + VBlank
- { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
- { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
-
- // Then SVP + SVP
- { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
-
- // Finally DRR + DRR
- { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
-};
-
-static const int full_strategy_list_2_display_size = sizeof(full_strategy_list_2_display) / (sizeof(enum dml2_pmo_pstate_strategy) * 4);
-
-static const enum dml2_pmo_pstate_strategy full_strategy_list_3_display[][4] = {
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na }, // All VActive
-
- { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na }, // VActive + 1 VBlank
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na },
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na },
-
-// { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na }, // VActive + 2 VBlank
-// { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na },
-// { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na },
-
-// { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na }, // VActive + 3 VBlank
-// { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na },
-// { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na },
-
- { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na }, // All VBlank
-
- { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na }, // All DRR
-};
-
-static const int full_strategy_list_3_display_size = sizeof(full_strategy_list_3_display) / (sizeof(enum dml2_pmo_pstate_strategy) * 4);
-
-static const enum dml2_pmo_pstate_strategy full_strategy_list_4_display[][4] = {
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive }, // All VActive
-
- { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive }, // VActive + 1 VBlank
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive },
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive },
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank },
-
-// { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive }, // VActive + 2 VBlank
-// { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive },
-// { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank },
-// { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive },
-// { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank },
-// { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank },
-
-// { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank }, // VActive + 3 VBlank
-// { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank },
-// { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank },
-// { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive },
-
- { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank }, // All Vblank
-
- { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr }, // All DRR
-};
-
-static const int full_strategy_list_4_display_size = sizeof(full_strategy_list_4_display) / (sizeof(enum dml2_pmo_pstate_strategy) * 4);
-
-static bool increase_odm_combine_factor(enum dml2_odm_mode *odm_mode, int odms_calculated)
-{
- bool result = true;
-
- if (*odm_mode == dml2_odm_mode_auto) {
- switch (odms_calculated) {
- case 1:
- *odm_mode = dml2_odm_mode_bypass;
- break;
- case 2:
- *odm_mode = dml2_odm_mode_combine_2to1;
- break;
- case 3:
- *odm_mode = dml2_odm_mode_combine_3to1;
- break;
- case 4:
- *odm_mode = dml2_odm_mode_combine_4to1;
- break;
- default:
- result = false;
- break;
- }
- }
-
- if (result) {
- if (*odm_mode == dml2_odm_mode_bypass) {
- *odm_mode = dml2_odm_mode_combine_2to1;
- } else if (*odm_mode == dml2_odm_mode_combine_2to1) {
- *odm_mode = dml2_odm_mode_combine_3to1;
- } else if (*odm_mode == dml2_odm_mode_combine_3to1) {
- *odm_mode = dml2_odm_mode_combine_4to1;
- } else {
- result = false;
- }
- }
-
- return result;
-}
-
-static bool increase_mpc_combine_factor(unsigned int *mpc_combine_factor, unsigned int limit)
-{
- if (*mpc_combine_factor < limit) {
- (*mpc_combine_factor)++;
- return true;
- }
-
- return false;
-}
-
-static int count_planes_with_stream_index(const struct dml2_display_cfg *display_cfg, unsigned int stream_index)
-{
- unsigned int i;
- int count;
-
- count = 0;
- for (i = 0; i < display_cfg->num_planes; i++) {
- if (display_cfg->plane_descriptors[i].stream_index == stream_index)
- count++;
- }
-
- return count;
-}
-
-static bool optimize_dcc_mcache_no_odm(struct dml2_pmo_optimize_dcc_mcache_in_out *in_out,
- int free_pipes)
-{
- struct dml2_pmo_instance *pmo = in_out->instance;
-
- unsigned int i;
- bool result = true;
-
- for (i = 0; i < in_out->optimized_display_cfg->num_planes; i++) {
- // For pipes that failed dcc mcache check, we want to increase the pipe count.
- // The logic for doing this depends on how many pipes is already being used,
- // and whether it's mpcc or odm combine.
- if (!in_out->dcc_mcache_supported[i]) {
- // For the general case of "n displays", we can only optimize streams with an ODM combine factor of 1
- if (in_out->cfg_support_info->stream_support_info[in_out->optimized_display_cfg->plane_descriptors[i].stream_index].odms_used == 1) {
- in_out->optimized_display_cfg->plane_descriptors[i].overrides.mpcc_combine_factor =
- in_out->cfg_support_info->plane_support_info[i].dpps_used;
- // For each plane that is not passing mcache validation, just add another pipe to it, up to the limit.
- if (free_pipes > 0) {
- if (!increase_mpc_combine_factor(&in_out->optimized_display_cfg->plane_descriptors[i].overrides.mpcc_combine_factor,
- pmo->mpc_combine_limit)) {
- // We've reached max pipes allocatable to a single plane, so we fail.
- result = false;
- break;
- } else {
- // Successfully added another pipe to this failing plane.
- free_pipes--;
- }
- } else {
- // No free pipes to add.
- result = false;
- break;
- }
- } else {
- // If the stream of this plane needs ODM combine, no further optimization can be done.
- result = false;
- break;
- }
- }
- }
-
- return result;
-}
-
-bool pmo_dcn4_optimize_dcc_mcache(struct dml2_pmo_optimize_dcc_mcache_in_out *in_out)
-{
- struct dml2_pmo_instance *pmo = in_out->instance;
-
- unsigned int i, used_pipes, free_pipes, planes_on_stream;
- bool result;
-
- if (in_out->display_config != in_out->optimized_display_cfg) {
- memcpy(in_out->optimized_display_cfg, in_out->display_config, sizeof(struct dml2_display_cfg));
- }
-
- //Count number of free pipes, and check if any odm combine is in use.
- used_pipes = 0;
- for (i = 0; i < in_out->optimized_display_cfg->num_planes; i++) {
- used_pipes += in_out->cfg_support_info->plane_support_info[i].dpps_used;
- }
- free_pipes = pmo->ip_caps->pipe_count - used_pipes;
-
- // Optimization loop
- // The goal here is to add more pipes to any planes
- // which are failing mcache admissibility
- result = true;
-
- // The optimization logic depends on whether ODM combine is enabled, and the stream count.
- if (in_out->optimized_display_cfg->num_streams > 1) {
- // If there are multiple streams, we are limited to only be able to optimize mcache failures on planes
- // which are not ODM combined.
-
- result = optimize_dcc_mcache_no_odm(in_out, free_pipes);
- } else if (in_out->optimized_display_cfg->num_streams == 1) {
- // In single stream cases, we still optimize mcache failures when there's ODM combine with some
- // additional logic.
-
- if (in_out->cfg_support_info->stream_support_info[0].odms_used > 1) {
- // If ODM combine is enabled, then the logic is to increase ODM combine factor.
-
- // Optimization for streams with > 1 ODM combine factor is only supported for single display.
- planes_on_stream = count_planes_with_stream_index(in_out->optimized_display_cfg, 0);
-
- for (i = 0; i < in_out->optimized_display_cfg->num_planes; i++) {
- // For pipes that failed dcc mcache check, we want to increase the pipe count.
- // The logic for doing this depends on how many pipes is already being used,
- // and whether it's mpcc or odm combine.
- if (!in_out->dcc_mcache_supported[i]) {
- // Increasing ODM combine factor on a stream requires a free pipe for each plane on the stream.
- if (free_pipes >= planes_on_stream) {
- if (!increase_odm_combine_factor(&in_out->optimized_display_cfg->stream_descriptors[i].overrides.odm_mode,
- in_out->cfg_support_info->plane_support_info[i].dpps_used)) {
- result = false;
- } else {
- free_pipes -= planes_on_stream;
- break;
- }
- } else {
- result = false;
- break;
- }
- }
- }
- } else {
- // If ODM combine is not enabled, then we can actually use the same logic as before.
-
- result = optimize_dcc_mcache_no_odm(in_out, free_pipes);
- }
- } else {
- result = true;
- }
-
- return result;
-}
-
-bool pmo_dcn4_initialize(struct dml2_pmo_initialize_in_out *in_out)
-{
- struct dml2_pmo_instance *pmo = in_out->instance;
-
- pmo->soc_bb = in_out->soc_bb;
- pmo->ip_caps = in_out->ip_caps;
- pmo->mpc_combine_limit = 2;
- pmo->odm_combine_limit = 4;
- pmo->mcg_clock_table_size = in_out->mcg_clock_table_size;
-
- pmo->fams_params.v1.subvp.fw_processing_delay_us = 10;
- pmo->fams_params.v1.subvp.prefetch_end_to_mall_start_us = 50;
- pmo->fams_params.v1.subvp.refresh_rate_limit_max = 175;
- pmo->fams_params.v1.subvp.refresh_rate_limit_min = 0;
-
- pmo->options = in_out->options;
-
- return true;
-}
-
-static bool is_h_timing_divisible_by(const struct dml2_timing_cfg *timing, unsigned char denominator)
-{
- /*
- * Htotal, Hblank start/end, and Hsync start/end all must be divisible
- * in order for the horizontal timing params to be considered divisible
- * by 2. Hsync start is always 0.
- */
- unsigned long h_blank_start = timing->h_total - timing->h_front_porch;
-
- return (timing->h_total % denominator == 0) &&
- (h_blank_start % denominator == 0) &&
- (timing->h_blank_end % denominator == 0) &&
- (timing->h_sync_width % denominator == 0);
-}
-
-static bool is_dp_encoder(enum dml2_output_encoder_class encoder_type)
-{
- switch (encoder_type) {
- case dml2_dp:
- case dml2_edp:
- case dml2_dp2p0:
- case dml2_none:
- return true;
- case dml2_hdmi:
- case dml2_hdmifrl:
- default:
- return false;
- }
-}
-
-bool pmo_dcn4_init_for_vmin(struct dml2_pmo_init_for_vmin_in_out *in_out)
-{
- unsigned int i;
- const struct dml2_display_cfg *display_config =
- &in_out->base_display_config->display_config;
- const struct dml2_core_mode_support_result *mode_support_result =
- &in_out->base_display_config->mode_support_result;
-
- if (in_out->instance->options->disable_dyn_odm ||
- (in_out->instance->options->disable_dyn_odm_for_multi_stream && display_config->num_streams > 1))
- return false;
-
- for (i = 0; i < display_config->num_planes; i++)
- /*
- * vmin optimization is required to be seamlessly switched off
- * at any time when the new configuration is no longer
- * supported. However switching from ODM combine to MPC combine
- * is not always seamless. When there not enough free pipes, we
- * will have to use the same secondary OPP heads as secondary
- * DPP pipes in MPC combine in new state. This transition is
- * expected to cause glitches. To avoid the transition, we only
- * allow vmin optimization if the stream's base configuration
- * doesn't require MPC combine. This condition checks if MPC
- * combine is enabled. If so do not optimize the stream.
- */
- if (mode_support_result->cfg_support_info.plane_support_info[i].dpps_used > 1 &&
- mode_support_result->cfg_support_info.stream_support_info[display_config->plane_descriptors[i].stream_index].odms_used == 1)
- in_out->base_display_config->stage4.unoptimizable_streams[display_config->plane_descriptors[i].stream_index] = true;
-
- for (i = 0; i < display_config->num_streams; i++) {
- if (display_config->stream_descriptors[i].overrides.disable_dynamic_odm)
- in_out->base_display_config->stage4.unoptimizable_streams[i] = true;
- else if (in_out->base_display_config->stage3.stream_svp_meta[i].valid &&
- in_out->instance->options->disable_dyn_odm_for_stream_with_svp)
- in_out->base_display_config->stage4.unoptimizable_streams[i] = true;
- /*
- * ODM Combine requires horizontal timing divisible by 2 so each
- * ODM segment has the same size.
- */
- else if (!is_h_timing_divisible_by(&display_config->stream_descriptors[i].timing, 2))
- in_out->base_display_config->stage4.unoptimizable_streams[i] = true;
- /*
- * Our hardware support seamless ODM transitions for DP encoders
- * only.
- */
- else if (!is_dp_encoder(display_config->stream_descriptors[i].output.output_encoder))
- in_out->base_display_config->stage4.unoptimizable_streams[i] = true;
- }
-
- return true;
-}
-
-bool pmo_dcn4_test_for_vmin(struct dml2_pmo_test_for_vmin_in_out *in_out)
-{
- bool is_vmin = true;
-
- if (in_out->vmin_limits->dispclk_khz > 0 &&
- in_out->display_config->mode_support_result.global.dispclk_khz > in_out->vmin_limits->dispclk_khz)
- is_vmin = false;
-
- return is_vmin;
-}
-
-static int find_highest_odm_load_stream_index(
- const struct dml2_display_cfg *display_config,
- const struct dml2_core_mode_support_result *mode_support_result)
-{
- unsigned int i;
- int odm_load, highest_odm_load = -1, highest_odm_load_index = -1;
-
- for (i = 0; i < display_config->num_streams; i++) {
- odm_load = display_config->stream_descriptors[i].timing.pixel_clock_khz
- / mode_support_result->cfg_support_info.stream_support_info[i].odms_used;
- if (odm_load > highest_odm_load) {
- highest_odm_load_index = i;
- highest_odm_load = odm_load;
- }
- }
-
- return highest_odm_load_index;
-}
-
-bool pmo_dcn4_optimize_for_vmin(struct dml2_pmo_optimize_for_vmin_in_out *in_out)
-{
- int stream_index;
- const struct dml2_display_cfg *display_config =
- &in_out->base_display_config->display_config;
- const struct dml2_core_mode_support_result *mode_support_result =
- &in_out->base_display_config->mode_support_result;
- unsigned int odms_used;
- struct dml2_stream_parameters *stream_descriptor;
- bool optimizable = false;
-
- /*
- * highest odm load stream must be optimizable to continue as dispclk is
- * bounded by it.
- */
- stream_index = find_highest_odm_load_stream_index(display_config,
- mode_support_result);
-
- if (stream_index < 0 ||
- in_out->base_display_config->stage4.unoptimizable_streams[stream_index])
- return false;
-
- odms_used = mode_support_result->cfg_support_info.stream_support_info[stream_index].odms_used;
- if ((int)odms_used >= in_out->instance->odm_combine_limit)
- return false;
-
- memcpy(in_out->optimized_display_config,
- in_out->base_display_config,
- sizeof(struct display_configuation_with_meta));
-
- stream_descriptor = &in_out->optimized_display_config->display_config.stream_descriptors[stream_index];
- while (!optimizable && increase_odm_combine_factor(
- &stream_descriptor->overrides.odm_mode,
- odms_used)) {
- switch (stream_descriptor->overrides.odm_mode) {
- case dml2_odm_mode_combine_2to1:
- optimizable = true;
- break;
- case dml2_odm_mode_combine_3to1:
- /*
- * In ODM Combine 3:1 OTG_valid_pixel rate is 1/4 of
- * actual pixel rate. Therefore horizontal timing must
- * be divisible by 4.
- */
- if (is_h_timing_divisible_by(&display_config->stream_descriptors[stream_index].timing, 4)) {
- if (mode_support_result->cfg_support_info.stream_support_info[stream_index].dsc_enable) {
- /*
- * DSC h slice count must be divisible
- * by 3.
- */
- if (mode_support_result->cfg_support_info.stream_support_info[stream_index].num_dsc_slices % 3 == 0)
- optimizable = true;
- } else {
- optimizable = true;
- }
- }
- break;
- case dml2_odm_mode_combine_4to1:
- /*
- * In ODM Combine 4:1 OTG_valid_pixel rate is 1/4 of
- * actual pixel rate. Therefore horizontal timing must
- * be divisible by 4.
- */
- if (is_h_timing_divisible_by(&display_config->stream_descriptors[stream_index].timing, 4)) {
- if (mode_support_result->cfg_support_info.stream_support_info[stream_index].dsc_enable) {
- /*
- * DSC h slice count must be divisible
- * by 4.
- */
- if (mode_support_result->cfg_support_info.stream_support_info[stream_index].num_dsc_slices % 4 == 0)
- optimizable = true;
- } else {
- optimizable = true;
- }
- }
- break;
- case dml2_odm_mode_auto:
- case dml2_odm_mode_bypass:
- case dml2_odm_mode_split_1to2:
- case dml2_odm_mode_mso_1to2:
- case dml2_odm_mode_mso_1to4:
- default:
- break;
- }
- }
-
- return optimizable;
-}
-
-static bool are_timings_trivially_synchronizable(const struct display_configuation_with_meta *display_config, int mask)
-{
- unsigned char i;
- bool identical = true;
- bool contains_drr = false;
- unsigned char remap_array[DML2_MAX_PLANES];
- unsigned char remap_array_size = 0;
-
- // Create a remap array to enable simple iteration through only masked stream indicies
- for (i = 0; i < display_config->display_config.num_streams; i++) {
- if (mask & (0x1 << i)) {
- remap_array[remap_array_size++] = i;
- }
- }
-
- // 0 or 1 display is always trivially synchronizable
- if (remap_array_size <= 1)
- return true;
-
- for (i = 1; i < remap_array_size; i++) {
- if (memcmp(&display_config->display_config.stream_descriptors[remap_array[i - 1]].timing,
- &display_config->display_config.stream_descriptors[remap_array[i]].timing,
- sizeof(struct dml2_timing_cfg))) {
- identical = false;
- break;
- }
- }
-
- for (i = 0; i < remap_array_size; i++) {
- if (display_config->display_config.stream_descriptors[remap_array[i]].timing.drr_config.enabled) {
- contains_drr = true;
- break;
- }
- }
-
- return !contains_drr && identical;
-}
-
-static void set_bit_in_bitfield(unsigned int *bit_field, unsigned int bit_offset)
-{
- *bit_field = *bit_field | (0x1 << bit_offset);
-}
-
-static bool is_bit_set_in_bitfield(unsigned int bit_field, unsigned int bit_offset)
-{
- if (bit_field & (0x1 << bit_offset))
- return true;
-
- return false;
-}
-
-static bool are_all_timings_drr_enabled(const struct display_configuation_with_meta *display_config, int mask)
-{
- unsigned char i;
- for (i = 0; i < DML2_MAX_PLANES; i++) {
- if (is_bit_set_in_bitfield(mask, i)) {
- if (!display_config->display_config.stream_descriptors[i].timing.drr_config.enabled)
- return false;
- }
- }
-
- return true;
-}
-
-static void insert_into_candidate_list(const enum dml2_pmo_pstate_strategy *per_stream_pstate_strategy, int stream_count, struct dml2_pmo_scratch *scratch)
-{
- int stream_index;
-
- scratch->pmo_dcn4.allow_state_increase_for_strategy[scratch->pmo_dcn4.num_pstate_candidates] = true;
-
- for (stream_index = 0; stream_index < stream_count; stream_index++) {
- scratch->pmo_dcn4.per_stream_pstate_strategy[scratch->pmo_dcn4.num_pstate_candidates][stream_index] = per_stream_pstate_strategy[stream_index];
-
- if (per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_vblank)
- scratch->pmo_dcn4.allow_state_increase_for_strategy[scratch->pmo_dcn4.num_pstate_candidates] = false;
- }
-
- scratch->pmo_dcn4.num_pstate_candidates++;
-}
-
-static bool all_planes_match_strategy(const struct display_configuation_with_meta *display_cfg, int plane_mask, enum dml2_pmo_pstate_strategy strategy)
-{
- unsigned char i;
- enum dml2_uclk_pstate_change_strategy matching_strategy = (enum dml2_uclk_pstate_change_strategy) dml2_pmo_pstate_strategy_na;
-
- if (strategy == dml2_pmo_pstate_strategy_vactive)
- matching_strategy = dml2_uclk_pstate_change_strategy_force_vactive;
- else if (strategy == dml2_pmo_pstate_strategy_vblank)
- matching_strategy = dml2_uclk_pstate_change_strategy_force_vblank;
- else if (strategy == dml2_pmo_pstate_strategy_fw_svp)
- matching_strategy = dml2_uclk_pstate_change_strategy_force_mall_svp;
- else if (strategy == dml2_pmo_pstate_strategy_fw_drr)
- matching_strategy = dml2_uclk_pstate_change_strategy_force_drr;
-
- for (i = 0; i < DML2_MAX_PLANES; i++) {
- if (is_bit_set_in_bitfield(plane_mask, i)) {
- if (display_cfg->display_config.plane_descriptors[i].overrides.uclk_pstate_change_strategy != dml2_uclk_pstate_change_strategy_auto &&
- display_cfg->display_config.plane_descriptors[i].overrides.uclk_pstate_change_strategy != matching_strategy)
- return false;
- }
- }
-
- return true;
-}
-
-static bool subvp_subvp_schedulable(struct dml2_pmo_instance *pmo, const struct display_configuation_with_meta *display_cfg,
- unsigned char *svp_stream_indicies, char svp_stream_count)
-{
- struct dml2_pmo_scratch *s = &pmo->scratch;
- int i;
- int microschedule_lines, time_us, refresh_hz;
- int max_microschedule_us = 0;
- int vactive1_us, vactive2_us, vblank1_us, vblank2_us;
-
- const struct dml2_timing_cfg *svp_timing1 = 0;
- const struct dml2_implicit_svp_meta *svp_meta1 = 0;
-
- const struct dml2_timing_cfg *svp_timing2 = 0;
-
- if (svp_stream_count <= 1)
- return true;
- else if (svp_stream_count > 2)
- return false;
-
- /* Loop to calculate the maximum microschedule time between the two SubVP pipes,
- * and also to store the two main SubVP pipe pointers in subvp_pipes[2].
- */
- for (i = 0; i < svp_stream_count; i++) {
- svp_timing1 = &display_cfg->display_config.stream_descriptors[svp_stream_indicies[i]].timing;
- svp_meta1 = &s->pmo_dcn4.stream_svp_meta[svp_stream_indicies[i]];
-
- microschedule_lines = svp_meta1->v_active;
-
- // Round up when calculating microschedule time (+ 1 at the end)
- time_us = (int)((microschedule_lines * svp_timing1->h_total) / (double)(svp_timing1->pixel_clock_khz * 1000) * 1000000 +
- pmo->fams_params.v1.subvp.prefetch_end_to_mall_start_us + pmo->fams_params.v1.subvp.fw_processing_delay_us + 1);
-
- if (time_us > max_microschedule_us)
- max_microschedule_us = time_us;
-
- refresh_hz = (int)((double)(svp_timing1->pixel_clock_khz * 1000) / (svp_timing1->v_total * svp_timing1->h_total));
-
- if (refresh_hz < pmo->fams_params.v1.subvp.refresh_rate_limit_min ||
- refresh_hz > pmo->fams_params.v1.subvp.refresh_rate_limit_max) {
- return false;
- }
- }
-
- svp_timing1 = &display_cfg->display_config.stream_descriptors[svp_stream_indicies[0]].timing;
- svp_meta1 = &s->pmo_dcn4.stream_svp_meta[svp_stream_indicies[0]];
-
- vactive1_us = (int)((svp_timing1->v_active * svp_timing1->h_total) / (double)(svp_timing1->pixel_clock_khz * 1000) * 1000000);
-
- vblank1_us = (int)(((svp_timing1->v_total - svp_timing1->v_active) * svp_timing1->h_total) / (double)(svp_timing1->pixel_clock_khz * 1000) * 1000000);
-
- svp_timing2 = &display_cfg->display_config.stream_descriptors[svp_stream_indicies[1]].timing;
-
- vactive2_us = (int)((svp_timing2->v_active * svp_timing2->h_total) / (double)(svp_timing2->pixel_clock_khz * 1000) * 1000000);
-
- vblank2_us = (int)(((svp_timing2->v_total - svp_timing2->v_active) * svp_timing2->h_total) / (double)(svp_timing2->pixel_clock_khz * 1000) * 1000000);
-
- if ((vactive1_us - vblank2_us) / 2 > max_microschedule_us &&
- (vactive2_us - vblank1_us) / 2 > max_microschedule_us)
- return true;
-
- return false;
-}
-
-static bool validate_svp_cofunctionality(struct dml2_pmo_instance *pmo,
- const struct display_configuation_with_meta *display_cfg, int svp_stream_mask)
-{
- bool result = false;
- unsigned char stream_index;
-
- unsigned char svp_stream_indicies[2] = { 0 };
- unsigned char svp_stream_count = 0;
-
- // Find the SVP streams, store only the first 2, but count all of them
- for (stream_index = 0; stream_index < display_cfg->display_config.num_streams; stream_index++) {
- if (is_bit_set_in_bitfield(svp_stream_mask, stream_index)) {
- if (svp_stream_count < 2)
- svp_stream_indicies[svp_stream_count] = stream_index;
-
- svp_stream_count++;
- }
- }
-
- if (svp_stream_count == 1) {
- result = true; // 1 SVP is always co_functional
- } else if (svp_stream_count == 2) {
- result = subvp_subvp_schedulable(pmo, display_cfg, svp_stream_indicies, svp_stream_count);
- }
-
- return result;
-}
-
-static bool validate_drr_cofunctionality(struct dml2_pmo_instance *pmo,
- const struct display_configuation_with_meta *display_cfg, int drr_stream_mask)
-{
- unsigned char stream_index;
- int drr_stream_count = 0;
-
- // Find the SVP streams and count all of them
- for (stream_index = 0; stream_index < display_cfg->display_config.num_streams; stream_index++) {
- if (is_bit_set_in_bitfield(drr_stream_mask, stream_index)) {
- drr_stream_count++;
- }
- }
-
- return drr_stream_count <= 4;
-}
-
-static bool validate_svp_drr_cofunctionality(struct dml2_pmo_instance *pmo,
- const struct display_configuation_with_meta *display_cfg, int svp_stream_mask, int drr_stream_mask)
-{
- unsigned char stream_index;
- int drr_stream_count = 0;
- int svp_stream_count = 0;
-
- int prefetch_us = 0;
- int mall_region_us = 0;
- int drr_frame_us = 0; // nominal frame time
- int subvp_active_us = 0;
- int stretched_drr_us = 0;
- int drr_stretched_vblank_us = 0;
- int max_vblank_mallregion = 0;
-
- const struct dml2_timing_cfg *svp_timing = 0;
- const struct dml2_timing_cfg *drr_timing = 0;
- const struct dml2_implicit_svp_meta *svp_meta = 0;
-
- bool schedulable = false;
-
- // Find the SVP streams and count all of them
- for (stream_index = 0; stream_index < display_cfg->display_config.num_streams; stream_index++) {
- if (is_bit_set_in_bitfield(svp_stream_mask, stream_index)) {
- svp_timing = &display_cfg->display_config.stream_descriptors[stream_index].timing;
- svp_meta = &pmo->scratch.pmo_dcn4.stream_svp_meta[stream_index];
- svp_stream_count++;
- }
- if (is_bit_set_in_bitfield(drr_stream_mask, stream_index)) {
- drr_timing = &display_cfg->display_config.stream_descriptors[stream_index].timing;
- drr_stream_count++;
- }
- }
-
- if (svp_stream_count == 1 && drr_stream_count == 1 && svp_timing != drr_timing) {
- prefetch_us = (int)((svp_meta->v_total - svp_meta->v_front_porch)
- * svp_timing->h_total / (double)(svp_timing->pixel_clock_khz * 1000) * 1000000 +
- pmo->fams_params.v1.subvp.prefetch_end_to_mall_start_us);
-
- subvp_active_us = (int)(svp_timing->v_active * svp_timing->h_total /
- (double)(svp_timing->pixel_clock_khz * 1000) * 1000000);
-
- drr_frame_us = (int)(drr_timing->v_total * drr_timing->h_total /
- (double)(drr_timing->pixel_clock_khz * 1000) * 1000000);
-
- // P-State allow width and FW delays already included phantom_timing->v_addressable
- mall_region_us = (int)(svp_meta->v_active * svp_timing->h_total /
- (double)(svp_timing->pixel_clock_khz * 1000) * 1000000);
-
- stretched_drr_us = drr_frame_us + mall_region_us + SUBVP_DRR_MARGIN_US;
-
- drr_stretched_vblank_us = (int)((drr_timing->v_total - drr_timing->v_active) * drr_timing->h_total /
- (double)(drr_timing->pixel_clock_khz * 1000) * 1000000 + (stretched_drr_us - drr_frame_us));
-
- max_vblank_mallregion = drr_stretched_vblank_us > mall_region_us ? drr_stretched_vblank_us : mall_region_us;
-
- /* We consider SubVP + DRR schedulable if the stretched frame duration of the DRR display (i.e. the
- * highest refresh rate + margin that can support UCLK P-State switch) passes the static analysis
- * for VBLANK: (VACTIVE region of the SubVP pipe can fit the MALL prefetch, VBLANK frame time,
- * and the max of (VBLANK blanking time, MALL region)).
- */
- if (stretched_drr_us < (1 / (double)drr_timing->drr_config.min_refresh_uhz) * 1000000 * 1000000 &&
- subvp_active_us - prefetch_us - stretched_drr_us - max_vblank_mallregion > 0)
- schedulable = true;
- }
-
- return schedulable;
-}
-
-static bool validate_svp_vblank_cofunctionality(struct dml2_pmo_instance *pmo,
- const struct display_configuation_with_meta *display_cfg, int svp_stream_mask, int vblank_stream_mask)
-{
- unsigned char stream_index;
- int vblank_stream_count = 0;
- int svp_stream_count = 0;
-
- const struct dml2_timing_cfg *svp_timing = 0;
- const struct dml2_timing_cfg *vblank_timing = 0;
- const struct dml2_implicit_svp_meta *svp_meta = 0;
-
- int prefetch_us = 0;
- int mall_region_us = 0;
- int vblank_frame_us = 0;
- int subvp_active_us = 0;
- int vblank_blank_us = 0;
- int max_vblank_mallregion = 0;
-
- bool schedulable = false;
-
- // Find the SVP streams and count all of them
- for (stream_index = 0; stream_index < display_cfg->display_config.num_streams; stream_index++) {
- if (is_bit_set_in_bitfield(svp_stream_mask, stream_index)) {
- svp_timing = &display_cfg->display_config.stream_descriptors[stream_index].timing;
- svp_meta = &pmo->scratch.pmo_dcn4.stream_svp_meta[stream_index];
- svp_stream_count++;
- }
- if (is_bit_set_in_bitfield(vblank_stream_mask, stream_index)) {
- vblank_timing = &display_cfg->display_config.stream_descriptors[stream_index].timing;
- vblank_stream_count++;
- }
- }
-
- if (svp_stream_count == 1 && vblank_stream_count > 0) {
- // Prefetch time is equal to VACTIVE + BP + VSYNC of the phantom pipe
- // Also include the prefetch end to mallstart delay time
- prefetch_us = (int)((svp_meta->v_total - svp_meta->v_front_porch) * svp_timing->h_total
- / (double)(svp_timing->pixel_clock_khz * 1000) * 1000000 +
- pmo->fams_params.v1.subvp.prefetch_end_to_mall_start_us);
-
- // P-State allow width and FW delays already included phantom_timing->v_addressable
- mall_region_us = (int)(svp_meta->v_active * svp_timing->h_total /
- (double)(svp_timing->pixel_clock_khz * 1000) * 1000000);
-
- vblank_frame_us = (int)(vblank_timing->v_total * vblank_timing->h_total /
- (double)(vblank_timing->pixel_clock_khz * 1000) * 1000000);
-
- vblank_blank_us = (int)((vblank_timing->v_total - vblank_timing->v_active) * vblank_timing->h_total /
- (double)(vblank_timing->pixel_clock_khz * 1000) * 1000000);
-
- subvp_active_us = (int)(svp_timing->v_active * svp_timing->h_total /
- (double)(svp_timing->pixel_clock_khz * 1000) * 1000000);
-
- max_vblank_mallregion = vblank_blank_us > mall_region_us ? vblank_blank_us : mall_region_us;
-
- // Schedulable if VACTIVE region of the SubVP pipe can fit the MALL prefetch, VBLANK frame time,
- // and the max of (VBLANK blanking time, MALL region)
- // TODO: Possibly add some margin (i.e. the below conditions should be [...] > X instead of [...] > 0)
- if (subvp_active_us - prefetch_us - vblank_frame_us - max_vblank_mallregion > 0)
- schedulable = true;
- }
- return schedulable;
-}
-
-static bool validate_drr_vblank_cofunctionality(struct dml2_pmo_instance *pmo,
- const struct display_configuation_with_meta *display_cfg, int drr_stream_mask, int vblank_stream_mask)
-{
- return false;
-}
-
-static bool validate_pstate_support_strategy_cofunctionality(struct dml2_pmo_instance *pmo,
- const struct display_configuation_with_meta *display_cfg, const enum dml2_pmo_pstate_strategy per_stream_pstate_strategy[4])
-{
- struct dml2_pmo_scratch *s = &pmo->scratch;
-
- unsigned char stream_index = 0;
-
- unsigned int svp_count = 0;
- unsigned int svp_stream_mask = 0;
- unsigned int drr_count = 0;
- unsigned int drr_stream_mask = 0;
- unsigned int vactive_count = 0;
- unsigned int vactive_stream_mask = 0;
- unsigned int vblank_count = 0;
- unsigned int vblank_stream_mask = 0;
-
- bool strategy_matches_forced_requirements = true;
-
- bool admissible = false;
-
- // Tabulate everything
- for (stream_index = 0; stream_index < display_cfg->display_config.num_streams; stream_index++) {
-
- if (!all_planes_match_strategy(display_cfg, s->pmo_dcn4.stream_plane_mask[stream_index],
- per_stream_pstate_strategy[stream_index])) {
- strategy_matches_forced_requirements = false;
- break;
- }
-
- if (per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_fw_svp) {
- svp_count++;
- set_bit_in_bitfield(&svp_stream_mask, stream_index);
- } else if (per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_fw_drr) {
- drr_count++;
- set_bit_in_bitfield(&drr_stream_mask, stream_index);
- } else if (per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_vactive) {
- vactive_count++;
- set_bit_in_bitfield(&vactive_stream_mask, stream_index);
- } else if (per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_vblank) {
- vblank_count++;
- set_bit_in_bitfield(&vblank_stream_mask, stream_index);
- }
- }
-
- if (!strategy_matches_forced_requirements)
- return false;
-
- // Check for trivial synchronization for vblank
- if (vblank_count > 0 && (pmo->options->disable_vblank || !are_timings_trivially_synchronizable(display_cfg, vblank_stream_mask)))
- return false;
-
- if (svp_count > 0 && pmo->options->disable_svp)
- return false;
-
- if (drr_count > 0 && (pmo->options->disable_drr_var || !are_all_timings_drr_enabled(display_cfg, drr_stream_mask)))
- return false;
-
- // Validate for FAMS admissibiliy
- if (svp_count == 0 && drr_count == 0) {
- // No FAMS
- admissible = true;
- } else {
- admissible = false;
- if (svp_count > 0 && drr_count == 0 && vactive_count == 0 && vblank_count == 0) {
- // All SVP
- admissible = validate_svp_cofunctionality(pmo, display_cfg, svp_stream_mask);
- } else if (svp_count == 0 && drr_count > 0 && vactive_count == 0 && vblank_count == 0) {
- // All DRR
- admissible = validate_drr_cofunctionality(pmo, display_cfg, drr_stream_mask);
- } else if (svp_count > 0 && drr_count > 0 && vactive_count == 0 && vblank_count == 0) {
- // SVP + DRR
- admissible = validate_svp_drr_cofunctionality(pmo, display_cfg, svp_stream_mask, drr_stream_mask);
- } else if (svp_count > 0 && drr_count == 0 && vactive_count == 0 && vblank_count > 0) {
- // SVP + VBlank
- admissible = validate_svp_vblank_cofunctionality(pmo, display_cfg, svp_stream_mask, vblank_stream_mask);
- } else if (svp_count == 0 && drr_count > 0 && vactive_count == 0 && vblank_count > 0) {
- // DRR + VBlank
- admissible = validate_drr_vblank_cofunctionality(pmo, display_cfg, drr_stream_mask, vblank_stream_mask);
- }
- }
-
- return admissible;
-}
-
-static int get_vactive_pstate_margin(const struct display_configuation_with_meta *display_cfg, int plane_mask)
-{
- unsigned char i;
- int min_vactive_margin_us = 0xFFFFFFF;
-
- for (i = 0; i < DML2_MAX_PLANES; i++) {
- if (is_bit_set_in_bitfield(plane_mask, i)) {
- if (display_cfg->mode_support_result.cfg_support_info.plane_support_info[i].dram_change_latency_hiding_margin_in_active < min_vactive_margin_us)
- min_vactive_margin_us = display_cfg->mode_support_result.cfg_support_info.plane_support_info[i].dram_change_latency_hiding_margin_in_active;
- }
- }
-
- return min_vactive_margin_us;
-}
-
-bool pmo_dcn4_init_for_pstate_support(struct dml2_pmo_init_for_pstate_support_in_out *in_out)
-{
- struct dml2_pmo_instance *pmo = in_out->instance;
- struct dml2_optimization_stage3_state *state = &in_out->base_display_config->stage3;
- struct dml2_pmo_scratch *s = &pmo->scratch;
-
- struct display_configuation_with_meta *display_config;
- const struct dml2_plane_parameters *plane_descriptor;
- const enum dml2_pmo_pstate_strategy (*strategy_list)[4] = 0;
- unsigned int strategy_list_size = 0;
- unsigned int plane_index, stream_index, i;
-
- state->performed = true;
-
- display_config = in_out->base_display_config;
- display_config->display_config.overrides.enable_subvp_implicit_pmo = true;
-
- memset(s, 0, sizeof(struct dml2_pmo_scratch));
-
- pmo->scratch.pmo_dcn4.min_latency_index = in_out->base_display_config->stage1.min_clk_index_for_latency;
- pmo->scratch.pmo_dcn4.max_latency_index = pmo->mcg_clock_table_size - 1;
- pmo->scratch.pmo_dcn4.cur_latency_index = in_out->base_display_config->stage1.min_clk_index_for_latency;
-
- // First build the stream plane mask (array of bitfields indexed by stream, indicating plane mapping)
- for (plane_index = 0; plane_index < display_config->display_config.num_planes; plane_index++) {
- plane_descriptor = &display_config->display_config.plane_descriptors[plane_index];
-
- set_bit_in_bitfield(&s->pmo_dcn4.stream_plane_mask[plane_descriptor->stream_index], plane_index);
-
- state->pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_vactive;
- }
-
- // Figure out which streams can do vactive, and also build up implicit SVP meta
- for (stream_index = 0; stream_index < display_config->display_config.num_streams; stream_index++) {
- if (get_vactive_pstate_margin(display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) >=
- MIN_VACTIVE_MARGIN_US)
- set_bit_in_bitfield(&s->pmo_dcn4.stream_vactive_capability_mask, stream_index);
-
- s->pmo_dcn4.stream_svp_meta[stream_index].valid = true;
- s->pmo_dcn4.stream_svp_meta[stream_index].v_active =
- display_config->mode_support_result.cfg_support_info.stream_support_info[stream_index].phantom_v_active;
- s->pmo_dcn4.stream_svp_meta[stream_index].v_total =
- display_config->mode_support_result.cfg_support_info.stream_support_info[stream_index].phantom_v_total;
- s->pmo_dcn4.stream_svp_meta[stream_index].v_front_porch = 1;
- }
-
- switch (display_config->display_config.num_streams) {
- case 1:
- strategy_list = full_strategy_list_1_display;
- strategy_list_size = full_strategy_list_1_display_size;
- break;
- case 2:
- strategy_list = full_strategy_list_2_display;
- strategy_list_size = full_strategy_list_2_display_size;
- break;
- case 3:
- strategy_list = full_strategy_list_3_display;
- strategy_list_size = full_strategy_list_3_display_size;
- break;
- case 4:
- strategy_list = full_strategy_list_4_display;
- strategy_list_size = full_strategy_list_4_display_size;
- break;
- default:
- strategy_list_size = 0;
- break;
- }
-
- if (strategy_list_size == 0)
- return false;
-
- s->pmo_dcn4.num_pstate_candidates = 0;
-
- for (i = 0; i < strategy_list_size && i < DML2_PMO_PSTATE_CANDIDATE_LIST_SIZE; i++) {
- if (validate_pstate_support_strategy_cofunctionality(pmo, display_config, strategy_list[i])) {
- insert_into_candidate_list(strategy_list[i], display_config->display_config.num_streams, s);
- }
- }
-
- if (s->pmo_dcn4.num_pstate_candidates > 0) {
- // There's this funny case...
- // If the first entry in the candidate list is all vactive, then we can consider it "tested", so the current index is 0
- // Otherwise the current index should be -1 because we run the optimization at least once
- s->pmo_dcn4.cur_pstate_candidate = 0;
- for (i = 0; i < display_config->display_config.num_streams; i++) {
- if (s->pmo_dcn4.per_stream_pstate_strategy[0][i] != dml2_pmo_pstate_strategy_vactive) {
- s->pmo_dcn4.cur_pstate_candidate = -1;
- break;
- }
- }
- return true;
- } else {
- return false;
- }
-}
-
-static void reset_display_configuration(struct display_configuation_with_meta *display_config)
-{
- unsigned int plane_index;
- unsigned int stream_index;
- struct dml2_plane_parameters *plane;
-
- for (stream_index = 0; stream_index < display_config->display_config.num_streams; stream_index++) {
- display_config->stage3.stream_svp_meta[stream_index].valid = false;
- }
-
- for (plane_index = 0; plane_index < display_config->display_config.num_planes; plane_index++) {
- plane = &display_config->display_config.plane_descriptors[plane_index];
-
- // Unset SubVP
- plane->overrides.legacy_svp_config = dml2_svp_mode_override_auto;
-
- // Remove reserve time
- plane->overrides.reserved_vblank_time_ns = 0;
-
- // Reset strategy to auto
- plane->overrides.uclk_pstate_change_strategy = dml2_uclk_pstate_change_strategy_auto;
-
- display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_not_supported;
- }
-}
-
-static void setup_planes_for_drr_by_mask(struct display_configuation_with_meta *display_config, int plane_mask)
-{
- unsigned char plane_index;
- struct dml2_plane_parameters *plane;
-
- for (plane_index = 0; plane_index < display_config->display_config.num_planes; plane_index++) {
- if (is_bit_set_in_bitfield(plane_mask, plane_index)) {
- plane = &display_config->display_config.plane_descriptors[plane_index];
-
- // Setup DRR
- plane->overrides.uclk_pstate_change_strategy = dml2_uclk_pstate_change_strategy_force_drr;
-
- display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_fw_drr;
- }
- }
-}
-
-static void setup_planes_for_svp_by_mask(struct display_configuation_with_meta *display_config, int plane_mask)
-{
- unsigned char plane_index;
- int stream_index = -1;
-
- for (plane_index = 0; plane_index < display_config->display_config.num_planes; plane_index++) {
- if (is_bit_set_in_bitfield(plane_mask, plane_index)) {
- stream_index = (char)display_config->display_config.plane_descriptors[plane_index].stream_index;
- display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_fw_subvp_phantom;
- }
- }
-
- if (stream_index >= 0) {
- display_config->stage3.stream_svp_meta[stream_index].valid = true;
- display_config->stage3.stream_svp_meta[stream_index].v_active =
- display_config->mode_support_result.cfg_support_info.stream_support_info[stream_index].phantom_v_active;
- display_config->stage3.stream_svp_meta[stream_index].v_total =
- display_config->mode_support_result.cfg_support_info.stream_support_info[stream_index].phantom_v_total;
- display_config->stage3.stream_svp_meta[stream_index].v_front_porch = 1;
- }
-}
-
-static void setup_planes_for_vblank_by_mask(struct display_configuation_with_meta *display_config, int plane_mask)
-{
- unsigned char plane_index;
- struct dml2_plane_parameters *plane;
-
- for (plane_index = 0; plane_index < display_config->display_config.num_planes; plane_index++) {
- if (is_bit_set_in_bitfield(plane_mask, plane_index)) {
- plane = &display_config->display_config.plane_descriptors[plane_index];
-
- // Setup reserve time
- plane->overrides.reserved_vblank_time_ns = 400 * 1000;
-
- display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_vblank;
- }
- }
-}
-
-static void setup_planes_for_vactive_by_mask(struct display_configuation_with_meta *display_config, int plane_mask)
-{
- unsigned char plane_index;
-
- for (plane_index = 0; plane_index < display_config->display_config.num_planes; plane_index++) {
- if (is_bit_set_in_bitfield(plane_mask, plane_index)) {
- display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_vactive;
- }
- }
-}
-
-static bool setup_display_config(struct display_configuation_with_meta *display_config, struct dml2_pmo_scratch *scratch, int strategy_index)
-{
- bool success = true;
- unsigned char stream_index;
-
- reset_display_configuration(display_config);
-
- for (stream_index = 0; stream_index < display_config->display_config.num_streams; stream_index++) {
- if (scratch->pmo_dcn4.per_stream_pstate_strategy[strategy_index][stream_index] == dml2_pmo_pstate_strategy_na) {
- success = false;
- break;
- } else if (scratch->pmo_dcn4.per_stream_pstate_strategy[strategy_index][stream_index] == dml2_pmo_pstate_strategy_vblank) {
- setup_planes_for_vblank_by_mask(display_config, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
- } else if (scratch->pmo_dcn4.per_stream_pstate_strategy[strategy_index][stream_index] == dml2_pmo_pstate_strategy_fw_svp) {
- setup_planes_for_svp_by_mask(display_config, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
- } else if (scratch->pmo_dcn4.per_stream_pstate_strategy[strategy_index][stream_index] == dml2_pmo_pstate_strategy_fw_drr) {
- setup_planes_for_drr_by_mask(display_config, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
- } else if (scratch->pmo_dcn4.per_stream_pstate_strategy[strategy_index][stream_index] == dml2_pmo_pstate_strategy_vactive) {
- setup_planes_for_vactive_by_mask(display_config, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
- }
- }
-
- return success;
-}
-
-static int get_minimum_reserved_time_us_for_planes(struct display_configuation_with_meta *display_config, int plane_mask)
-{
- int min_time_us = 0xFFFFFF;
- unsigned char plane_index = 0;
-
- for (plane_index = 0; plane_index < display_config->display_config.num_planes; plane_index++) {
- if (is_bit_set_in_bitfield(plane_mask, plane_index)) {
- if (min_time_us > (display_config->display_config.plane_descriptors[plane_index].overrides.reserved_vblank_time_ns / 1000))
- min_time_us = display_config->display_config.plane_descriptors[plane_index].overrides.reserved_vblank_time_ns / 1000;
- }
- }
- return min_time_us;
-}
-
-bool pmo_dcn4_test_for_pstate_support(struct dml2_pmo_test_for_pstate_support_in_out *in_out)
-{
- bool p_state_supported = true;
- unsigned int stream_index;
- struct dml2_pmo_scratch *s = &in_out->instance->scratch;
-
- if (s->pmo_dcn4.cur_pstate_candidate < 0)
- return false;
-
- for (stream_index = 0; stream_index < in_out->base_display_config->display_config.num_streams; stream_index++) {
-
- if (s->pmo_dcn4.per_stream_pstate_strategy[s->pmo_dcn4.cur_pstate_candidate][stream_index] == dml2_pmo_pstate_strategy_vactive) {
- if (get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < MIN_VACTIVE_MARGIN_US) {
- p_state_supported = false;
- break;
- }
- } else if (s->pmo_dcn4.per_stream_pstate_strategy[s->pmo_dcn4.cur_pstate_candidate][stream_index] == dml2_pmo_pstate_strategy_vblank) {
- if (get_minimum_reserved_time_us_for_planes(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) <
- in_out->instance->soc_bb->power_management_parameters.dram_clk_change_blackout_us) {
- p_state_supported = false;
- break;
- }
- } else if (s->pmo_dcn4.per_stream_pstate_strategy[s->pmo_dcn4.cur_pstate_candidate][stream_index] == dml2_pmo_pstate_strategy_fw_svp) {
- if (in_out->base_display_config->stage3.stream_svp_meta[stream_index].valid == false) {
- p_state_supported = false;
- break;
- }
- } else if (s->pmo_dcn4.per_stream_pstate_strategy[s->pmo_dcn4.cur_pstate_candidate][stream_index] == dml2_pmo_pstate_strategy_fw_drr) {
- if (!all_planes_match_strategy(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index], dml2_pmo_pstate_strategy_fw_drr)) {
- p_state_supported = false;
- break;
- }
- } else if (s->pmo_dcn4.per_stream_pstate_strategy[s->pmo_dcn4.cur_pstate_candidate][stream_index] == dml2_pmo_pstate_strategy_na) {
- p_state_supported = false;
- break;
- }
- }
-
- return p_state_supported;
-}
-
-bool pmo_dcn4_optimize_for_pstate_support(struct dml2_pmo_optimize_for_pstate_support_in_out *in_out)
-{
- bool success = false;
- struct dml2_pmo_scratch *s = &in_out->instance->scratch;
-
- memcpy(in_out->optimized_display_config, in_out->base_display_config, sizeof(struct display_configuation_with_meta));
-
- if (in_out->last_candidate_failed) {
- if (s->pmo_dcn4.allow_state_increase_for_strategy[s->pmo_dcn4.cur_pstate_candidate] &&
- s->pmo_dcn4.cur_latency_index < s->pmo_dcn4.max_latency_index) {
- s->pmo_dcn4.cur_latency_index++;
-
- success = true;
- }
- }
-
- if (!success) {
- s->pmo_dcn4.cur_latency_index = s->pmo_dcn4.min_latency_index;
- s->pmo_dcn4.cur_pstate_candidate++;
-
- if (s->pmo_dcn4.cur_pstate_candidate < s->pmo_dcn4.num_pstate_candidates) {
- success = true;
- }
- }
-
- if (success) {
- in_out->optimized_display_config->stage3.min_clk_index_for_latency = s->pmo_dcn4.cur_latency_index;
- setup_display_config(in_out->optimized_display_config, &in_out->instance->scratch, in_out->instance->scratch.pmo_dcn4.cur_pstate_candidate);
- }
-
- return success;
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4.h
deleted file mode 100644
index 09cacc933d21..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// SPDX-License-Identifier: MIT
-//
-// Copyright 2024 Advanced Micro Devices, Inc.
-
-
-#ifndef __DML2_PMO_DCN4_H__
-#define __DML2_PMO_DCN4_H__
-
-#include "dml2_internal_shared_types.h"
-
-bool pmo_dcn4_initialize(struct dml2_pmo_initialize_in_out *in_out);
-
-bool pmo_dcn4_optimize_dcc_mcache(struct dml2_pmo_optimize_dcc_mcache_in_out *in_out);
-
-bool pmo_dcn4_init_for_vmin(struct dml2_pmo_init_for_vmin_in_out *in_out);
-bool pmo_dcn4_test_for_vmin(struct dml2_pmo_test_for_vmin_in_out *in_out);
-bool pmo_dcn4_optimize_for_vmin(struct dml2_pmo_optimize_for_vmin_in_out *in_out);
-
-bool pmo_dcn4_init_for_pstate_support(struct dml2_pmo_init_for_pstate_support_in_out *in_out);
-bool pmo_dcn4_test_for_pstate_support(struct dml2_pmo_test_for_pstate_support_in_out *in_out);
-bool pmo_dcn4_optimize_for_pstate_support(struct dml2_pmo_optimize_for_pstate_support_in_out *in_out);
-
-bool pmo_dcn4_unit_test(void);
-
-#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
index 6547cc2c2a77..d63558ee3135 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
@@ -1,122 +1,181 @@
-/*
-* 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
-*
-*/
+// SPDX-License-Identifier: MIT
+//
+// Copyright 2024 Advanced Micro Devices, Inc.
#include "dml2_pmo_factory.h"
-#include "dml2_pmo_dcn4.h"
#include "dml2_debug.h"
#include "lib_float_math.h"
#include "dml2_pmo_dcn4_fams2.h"
static const double MIN_VACTIVE_MARGIN_PCT = 0.25; // We need more than non-zero margin because DET buffer granularity can alter vactive latency hiding
-static const enum dml2_pmo_pstate_strategy base_strategy_list_1_display[][PMO_DCN4_MAX_DISPLAYS] = {
+static const struct dml2_pmo_pstate_strategy base_strategy_list_1_display[] = {
// VActive Preferred
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = true,
+ },
// Then SVP
- { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = true,
+ },
// Then VBlank
- { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
-
- // Finally DRR
- { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = false,
+ },
+
+ // Then DRR
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = true,
+ },
+
+ // Finally VBlank, but allow base clocks for latency to increase
+ /*
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = true,
+ },
+ */
};
-static const int base_strategy_list_1_display_size = sizeof(base_strategy_list_1_display) / (sizeof(enum dml2_pmo_pstate_strategy) * PMO_DCN4_MAX_DISPLAYS);
+static const int base_strategy_list_1_display_size = sizeof(base_strategy_list_1_display) / sizeof(struct dml2_pmo_pstate_strategy);
-static const enum dml2_pmo_pstate_strategy base_strategy_list_2_display[][PMO_DCN4_MAX_DISPLAYS] = {
+static const struct dml2_pmo_pstate_strategy base_strategy_list_2_display[] = {
// VActive only is preferred
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = true,
+ },
// Then VActive + VBlank
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = false,
+ },
// Then VBlank only
- { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = false,
+ },
// Then SVP + VBlank
- { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = false,
+ },
// Then SVP + DRR
- { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = true,
+ },
// Then SVP + SVP
- { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = true,
+ },
// Then DRR + VActive
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
-
- // Then DRR + VBlank
- //{ dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
-
- // Finally DRR + DRR
- { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = true,
+ },
+
+ // Then DRR + DRR
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = true,
+ },
+
+ // Finally VBlank, but allow base clocks for latency to increase
+ /*
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = true,
+ },
+ */
};
-static const int base_strategy_list_2_display_size = sizeof(base_strategy_list_2_display) / (sizeof(enum dml2_pmo_pstate_strategy) * PMO_DCN4_MAX_DISPLAYS);
-
-static const enum dml2_pmo_pstate_strategy base_strategy_list_3_display[][PMO_DCN4_MAX_DISPLAYS] = {
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na }, // All VActive
-
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na }, // VActive + 1 VBlank
-
- //{ dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na }, // VActive + 2 VBlank
-
- { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na }, // All VBlank
-
- //{ dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na }, // VBlank + 1 DRR
-
- //{ dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na }, // VBlank + 2 DRR
-
- { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na }, // All DRR
+static const int base_strategy_list_2_display_size = sizeof(base_strategy_list_2_display) / sizeof(struct dml2_pmo_pstate_strategy);
+
+static const struct dml2_pmo_pstate_strategy base_strategy_list_3_display[] = {
+ // All VActive
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = true,
+ },
+
+ // VActive + 1 VBlank
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = false,
+ },
+
+ // All VBlank
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = false,
+ },
+
+ // All DRR
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = true,
+ },
+
+ // All VBlank, with state increase allowed
+ /*
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na },
+ .allow_state_increase = true,
+ },
+ */
};
-static const int base_strategy_list_3_display_size = sizeof(base_strategy_list_3_display) / (sizeof(enum dml2_pmo_pstate_strategy) * PMO_DCN4_MAX_DISPLAYS);
-
-static const enum dml2_pmo_pstate_strategy base_strategy_list_4_display[][PMO_DCN4_MAX_DISPLAYS] = {
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive }, // All VActive
-
- { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank }, // VActive + 1 VBlank
-
- //{ dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank }, // VActive + 2 VBlank
-
- //{ dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank }, // VActive + 3 VBlank
-
- { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank }, // All Vblank
-
- //{ dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_fw_drr }, // VBlank + 1 DRR
-
- //{ dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr }, // VBlank + 2 DRR
-
- //{ dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr }, // VBlank + 3 DRR
-
- { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr }, // All DRR
+static const int base_strategy_list_3_display_size = sizeof(base_strategy_list_3_display) / sizeof(struct dml2_pmo_pstate_strategy);
+
+static const struct dml2_pmo_pstate_strategy base_strategy_list_4_display[] = {
+ // All VActive
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive },
+ .allow_state_increase = true,
+ },
+
+ // VActive + 1 VBlank
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank },
+ .allow_state_increase = false,
+ },
+
+ // All Vblank
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank },
+ .allow_state_increase = false,
+ },
+
+ // All DRR
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr },
+ .allow_state_increase = true,
+ },
+
+ // All VBlank, with state increase allowed
+ /*
+ {
+ .per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank },
+ .allow_state_increase = true,
+ },
+ */
};
-static const int base_strategy_list_4_display_size = sizeof(base_strategy_list_4_display) / (sizeof(enum dml2_pmo_pstate_strategy) * PMO_DCN4_MAX_DISPLAYS);
+static const int base_strategy_list_4_display_size = sizeof(base_strategy_list_4_display) / sizeof(struct dml2_pmo_pstate_strategy);
static bool increase_odm_combine_factor(enum dml2_odm_mode *odm_mode, int odms_calculated)
@@ -275,7 +334,6 @@ bool pmo_dcn4_fams2_optimize_dcc_mcache(struct dml2_pmo_optimize_dcc_mcache_in_o
in_out->cfg_support_info->plane_support_info[i].dpps_used)) {
result = false;
} else {
- free_pipes -= planes_on_stream;
break;
}
} else {
@@ -296,9 +354,9 @@ bool pmo_dcn4_fams2_optimize_dcc_mcache(struct dml2_pmo_optimize_dcc_mcache_in_o
return result;
}
-static enum dml2_pmo_pstate_strategy convert_strategy_to_drr_variant(const enum dml2_pmo_pstate_strategy base_strategy)
+static enum dml2_pmo_pstate_method convert_strategy_to_drr_variant(const enum dml2_pmo_pstate_method base_strategy)
{
- enum dml2_pmo_pstate_strategy variant_strategy = 0;
+ enum dml2_pmo_pstate_method variant_strategy = 0;
switch (base_strategy) {
case dml2_pmo_pstate_strategy_vactive:
@@ -327,11 +385,9 @@ static enum dml2_pmo_pstate_strategy convert_strategy_to_drr_variant(const enum
return variant_strategy;
}
-static enum dml2_pmo_pstate_strategy(*get_expanded_strategy_list(
- struct dml2_pmo_init_data *init_data,
- int stream_count))[PMO_DCN4_MAX_DISPLAYS]
+static struct dml2_pmo_pstate_strategy *get_expanded_strategy_list(struct dml2_pmo_init_data *init_data, int stream_count)
{
- enum dml2_pmo_pstate_strategy(*expanded_strategy_list)[PMO_DCN4_MAX_DISPLAYS] = NULL;
+ struct dml2_pmo_pstate_strategy *expanded_strategy_list = NULL;
switch (stream_count) {
case 1:
@@ -361,23 +417,23 @@ static unsigned int get_num_expanded_strategies(
}
static void insert_strategy_into_expanded_list(
- const enum dml2_pmo_pstate_strategy per_stream_pstate_strategy[PMO_DCN4_MAX_DISPLAYS],
+ const struct dml2_pmo_pstate_strategy *per_stream_pstate_strategy,
int stream_count,
struct dml2_pmo_init_data *init_data)
{
- enum dml2_pmo_pstate_strategy(*expanded_strategy_list)[PMO_DCN4_MAX_DISPLAYS] = NULL;
+ struct dml2_pmo_pstate_strategy *expanded_strategy_list = NULL;
expanded_strategy_list = get_expanded_strategy_list(init_data, stream_count);
if (expanded_strategy_list) {
- memcpy(&expanded_strategy_list[init_data->pmo_dcn4.num_expanded_strategies_per_list[stream_count - 1]++],
- per_stream_pstate_strategy,
- sizeof(enum dml2_pmo_pstate_strategy) * PMO_DCN4_MAX_DISPLAYS);
+ memcpy(&expanded_strategy_list[init_data->pmo_dcn4.num_expanded_strategies_per_list[stream_count - 1]], per_stream_pstate_strategy, sizeof(struct dml2_pmo_pstate_strategy));
+
+ init_data->pmo_dcn4.num_expanded_strategies_per_list[stream_count - 1]++;
}
}
static void expand_base_strategy(struct dml2_pmo_instance *pmo,
- const enum dml2_pmo_pstate_strategy base_strategy_list[PMO_DCN4_MAX_DISPLAYS],
+ const struct dml2_pmo_pstate_strategy *base_strategy,
unsigned int stream_count)
{
bool skip_to_next_stream;
@@ -386,19 +442,21 @@ static void expand_base_strategy(struct dml2_pmo_instance *pmo,
unsigned int i, j;
unsigned int num_streams_per_method[PMO_DCN4_MAX_DISPLAYS] = { 0 };
unsigned int stream_iteration_indices[PMO_DCN4_MAX_DISPLAYS] = { 0 };
- enum dml2_pmo_pstate_strategy cur_strategy_list[PMO_DCN4_MAX_DISPLAYS] = { 0 };
+ struct dml2_pmo_pstate_strategy cur_strategy_list = { 0 };
/* determine number of displays per method */
for (i = 0; i < stream_count; i++) {
/* increment the count of the earliest index with the same method */
for (j = 0; j < stream_count; j++) {
- if (base_strategy_list[i] == base_strategy_list[j]) {
+ if (base_strategy->per_stream_pstate_method[i] == base_strategy->per_stream_pstate_method[j]) {
num_streams_per_method[j] = num_streams_per_method[j] + 1;
break;
}
}
}
+ cur_strategy_list.allow_state_increase = base_strategy->allow_state_increase;
+
i = 0;
/* uses a while loop instead of recursion to build permutations of base strategy */
while (stream_iteration_indices[0] < stream_count) {
@@ -409,12 +467,12 @@ static void expand_base_strategy(struct dml2_pmo_instance *pmo,
/* determine what to do for this iteration */
if (stream_iteration_indices[i] < stream_count && num_streams_per_method[stream_iteration_indices[i]] != 0) {
/* decrement count and assign method */
- cur_strategy_list[i] = base_strategy_list[stream_iteration_indices[i]];
+ cur_strategy_list.per_stream_pstate_method[i] = base_strategy->per_stream_pstate_method[stream_iteration_indices[i]];
num_streams_per_method[stream_iteration_indices[i]] -= 1;
if (i >= stream_count - 1) {
/* insert into strategy list */
- insert_strategy_into_expanded_list(cur_strategy_list, stream_count, &pmo->init_data);
+ insert_strategy_into_expanded_list(&cur_strategy_list, stream_count, &pmo->init_data);
expanded_strategy_added = true;
} else {
/* skip to next stream */
@@ -450,55 +508,122 @@ static void expand_base_strategy(struct dml2_pmo_instance *pmo,
}
}
-static void expand_variant_strategy(struct dml2_pmo_instance *pmo,
- const enum dml2_pmo_pstate_strategy base_strategy_list[PMO_DCN4_MAX_DISPLAYS],
+
+static bool is_variant_method_valid(const struct dml2_pmo_pstate_strategy *base_strategy,
+ const struct dml2_pmo_pstate_strategy *variant_strategy,
+ unsigned int num_streams_per_base_method[PMO_DCN4_MAX_DISPLAYS],
+ unsigned int num_streams_per_variant_method[PMO_DCN4_MAX_DISPLAYS],
unsigned int stream_count)
{
+ bool valid = true;
unsigned int i;
- bool variant_found = false;
- enum dml2_pmo_pstate_strategy cur_strategy_list[PMO_DCN4_MAX_DISPLAYS] = { 0 };
+ /* check all restrictions are met */
+ for (i = 0; i < stream_count; i++) {
+ /* vblank + vblank_drr variants are invalid */
+ if (base_strategy->per_stream_pstate_method[i] == dml2_pmo_pstate_strategy_vblank &&
+ ((num_streams_per_base_method[i] > 0 && num_streams_per_variant_method[i] > 0) ||
+ num_streams_per_variant_method[i] > 1)) {
+ valid = false;
+ break;
+ }
+ }
- /* setup variant list as base to start */
- memcpy(cur_strategy_list, base_strategy_list, sizeof(enum dml2_pmo_pstate_strategy) * PMO_DCN4_MAX_DISPLAYS);
+ return valid;
+}
+
+static void expand_variant_strategy(struct dml2_pmo_instance *pmo,
+ const struct dml2_pmo_pstate_strategy *base_strategy,
+ unsigned int stream_count)
+{
+ bool variant_found;
+ unsigned int i, j;
+ unsigned int method_index;
+ unsigned int stream_index;
+ unsigned int num_streams_per_method[PMO_DCN4_MAX_DISPLAYS] = { 0 };
+ unsigned int num_streams_per_base_method[PMO_DCN4_MAX_DISPLAYS] = { 0 };
+ unsigned int num_streams_per_variant_method[PMO_DCN4_MAX_DISPLAYS] = { 0 };
+ enum dml2_pmo_pstate_method per_stream_variant_method[DML2_MAX_PLANES];
+ struct dml2_pmo_pstate_strategy variant_strategy = { 0 };
+ /* determine number of displays per method */
for (i = 0; i < stream_count; i++) {
- cur_strategy_list[i] = convert_strategy_to_drr_variant(base_strategy_list[i]);
+ /* increment the count of the earliest index with the same method */
+ for (j = 0; j < stream_count; j++) {
+ if (base_strategy->per_stream_pstate_method[i] == base_strategy->per_stream_pstate_method[j]) {
+ num_streams_per_method[j] = num_streams_per_method[j] + 1;
+ break;
+ }
+ }
+
+ per_stream_variant_method[i] = convert_strategy_to_drr_variant(base_strategy->per_stream_pstate_method[i]);
+ }
+ memcpy(num_streams_per_base_method, num_streams_per_method, sizeof(unsigned int) * PMO_DCN4_MAX_DISPLAYS);
+
+ memcpy(&variant_strategy, base_strategy, sizeof(struct dml2_pmo_pstate_strategy));
+
+ method_index = 0;
+ /* uses a while loop instead of recursion to build permutations of base strategy */
+ while (num_streams_per_base_method[0] > 0 || method_index != 0) {
+ if (method_index == stream_count) {
+ /* construct variant strategy */
+ variant_found = false;
+ stream_index = 0;
+
+ for (i = 0; i < stream_count; i++) {
+ for (j = 0; j < num_streams_per_base_method[i]; j++) {
+ variant_strategy.per_stream_pstate_method[stream_index++] = base_strategy->per_stream_pstate_method[i];
+ }
+
+ for (j = 0; j < num_streams_per_variant_method[i]; j++) {
+ variant_strategy.per_stream_pstate_method[stream_index++] = per_stream_variant_method[i];
+ if (base_strategy->per_stream_pstate_method[i] != per_stream_variant_method[i]) {
+ variant_found = true;
+ }
+ }
+ }
- if (cur_strategy_list[i] != base_strategy_list[i]) {
- variant_found = true;
+ if (variant_found && is_variant_method_valid(base_strategy, &variant_strategy, num_streams_per_base_method, num_streams_per_variant_method, stream_count)) {
+ expand_base_strategy(pmo, &variant_strategy, stream_count);
+ }
+
+ /* rollback to earliest method with bases remaining */
+ for (method_index = stream_count - 1; method_index > 0; method_index--) {
+ if (num_streams_per_base_method[method_index]) {
+ /* bases remaining */
+ break;
+ } else {
+ /* reset counters */
+ num_streams_per_base_method[method_index] = num_streams_per_method[method_index];
+ num_streams_per_variant_method[method_index] = 0;
+ }
+ }
}
- if (i == stream_count - 1 && variant_found) {
- insert_strategy_into_expanded_list(cur_strategy_list, stream_count, &pmo->init_data);
+ if (num_streams_per_base_method[method_index]) {
+ num_streams_per_base_method[method_index]--;
+ num_streams_per_variant_method[method_index]++;
+
+ method_index++;
+ } else if (method_index != 0) {
+ method_index++;
}
}
}
static void expand_base_strategies(
struct dml2_pmo_instance *pmo,
- const enum dml2_pmo_pstate_strategy(*base_strategies_list)[PMO_DCN4_MAX_DISPLAYS],
+ const struct dml2_pmo_pstate_strategy *base_strategies_list,
const unsigned int num_base_strategies,
unsigned int stream_count)
{
unsigned int i;
- unsigned int num_pre_variant_strategies;
- enum dml2_pmo_pstate_strategy(*expanded_strategy_list)[PMO_DCN4_MAX_DISPLAYS];
/* expand every explicit base strategy (except all DRR) */
- for (i = 0; i < num_base_strategies - 1; i++) {
- expand_base_strategy(pmo, base_strategies_list[i], stream_count);
- }
-
- /* expand base strategies to DRR variants */
- num_pre_variant_strategies = get_num_expanded_strategies(&pmo->init_data, stream_count);
- expanded_strategy_list = get_expanded_strategy_list(&pmo->init_data, stream_count);
- for (i = 0; i < num_pre_variant_strategies; i++) {
- expand_variant_strategy(pmo, expanded_strategy_list[i], stream_count);
+ for (i = 0; i < num_base_strategies; i++) {
+ expand_base_strategy(pmo, &base_strategies_list[i], stream_count);
+ expand_variant_strategy(pmo, &base_strategies_list[i], stream_count);
}
-
- /* add back all DRR */
- insert_strategy_into_expanded_list(base_strategies_list[num_base_strategies - 1], stream_count, &pmo->init_data);
}
bool pmo_dcn4_fams2_initialize(struct dml2_pmo_initialize_in_out *in_out)
@@ -546,8 +671,6 @@ bool pmo_dcn4_fams2_initialize(struct dml2_pmo_initialize_in_out *in_out)
/* populate list */
expand_base_strategies(pmo, base_strategy_list_4_display, base_strategy_list_4_display_size, 4);
break;
- default:
- break;
}
}
@@ -591,6 +714,8 @@ bool pmo_dcn4_fams2_init_for_vmin(struct dml2_pmo_init_for_vmin_in_out *in_out)
&in_out->base_display_config->display_config;
const struct dml2_core_mode_support_result *mode_support_result =
&in_out->base_display_config->mode_support_result;
+ struct dml2_optimization_stage4_state *state =
+ &in_out->base_display_config->stage4;
if (in_out->instance->options->disable_dyn_odm ||
(in_out->instance->options->disable_dyn_odm_for_multi_stream && display_config->num_streams > 1))
@@ -611,28 +736,30 @@ bool pmo_dcn4_fams2_init_for_vmin(struct dml2_pmo_init_for_vmin_in_out *in_out)
*/
if (mode_support_result->cfg_support_info.plane_support_info[i].dpps_used > 1 &&
mode_support_result->cfg_support_info.stream_support_info[display_config->plane_descriptors[i].stream_index].odms_used == 1)
- in_out->base_display_config->stage4.unoptimizable_streams[display_config->plane_descriptors[i].stream_index] = true;
+ state->unoptimizable_streams[display_config->plane_descriptors[i].stream_index] = true;
for (i = 0; i < display_config->num_streams; i++) {
if (display_config->stream_descriptors[i].overrides.disable_dynamic_odm)
- in_out->base_display_config->stage4.unoptimizable_streams[i] = true;
+ state->unoptimizable_streams[i] = true;
else if (in_out->base_display_config->stage3.stream_svp_meta[i].valid &&
in_out->instance->options->disable_dyn_odm_for_stream_with_svp)
- in_out->base_display_config->stage4.unoptimizable_streams[i] = true;
+ state->unoptimizable_streams[i] = true;
/*
* ODM Combine requires horizontal timing divisible by 2 so each
* ODM segment has the same size.
*/
else if (!is_h_timing_divisible_by(&display_config->stream_descriptors[i].timing, 2))
- in_out->base_display_config->stage4.unoptimizable_streams[i] = true;
+ state->unoptimizable_streams[i] = true;
/*
* Our hardware support seamless ODM transitions for DP encoders
* only.
*/
else if (!is_dp_encoder(display_config->stream_descriptors[i].output.output_encoder))
- in_out->base_display_config->stage4.unoptimizable_streams[i] = true;
+ state->unoptimizable_streams[i] = true;
}
+ state->performed = true;
+
return true;
}
@@ -783,6 +910,7 @@ static void build_synchronized_timing_groups(
/* clear all group masks */
memset(s->pmo_dcn4.synchronized_timing_group_masks, 0, sizeof(s->pmo_dcn4.synchronized_timing_group_masks));
memset(s->pmo_dcn4.group_is_drr_enabled, 0, sizeof(s->pmo_dcn4.group_is_drr_enabled));
+ memset(s->pmo_dcn4.group_is_drr_active, 0, sizeof(s->pmo_dcn4.group_is_drr_active));
memset(s->pmo_dcn4.group_line_time_us, 0, sizeof(s->pmo_dcn4.group_line_time_us));
s->pmo_dcn4.num_timing_groups = 0;
@@ -804,6 +932,8 @@ static void build_synchronized_timing_groups(
/* if drr is in use, timing is not sychnronizable */
if (master_timing->drr_config.enabled) {
s->pmo_dcn4.group_is_drr_enabled[timing_group_idx] = true;
+ s->pmo_dcn4.group_is_drr_active[timing_group_idx] = !master_timing->drr_config.disallowed &&
+ (master_timing->drr_config.drr_active_fixed || master_timing->drr_config.drr_active_variable);
continue;
}
@@ -884,7 +1014,7 @@ static bool all_timings_support_drr(const struct dml2_pmo_instance *pmo,
stream_descriptor = &display_config->display_config.stream_descriptors[i];
stream_fams2_meta = &pmo->scratch.pmo_dcn4.stream_fams2_meta[i];
- if (!stream_descriptor->timing.drr_config.enabled || stream_descriptor->overrides.disable_fams2_drr)
+ if (!stream_descriptor->timing.drr_config.enabled)
return false;
/* cannot support required vtotal */
@@ -967,35 +1097,24 @@ static bool all_timings_support_svp(const struct dml2_pmo_instance *pmo,
return true;
}
-static void insert_into_candidate_list(const enum dml2_pmo_pstate_strategy *per_stream_pstate_strategy, int stream_count, struct dml2_pmo_scratch *scratch)
+static void insert_into_candidate_list(const struct dml2_pmo_pstate_strategy *pstate_strategy, int stream_count, struct dml2_pmo_scratch *scratch)
{
- int stream_index;
-
- scratch->pmo_dcn4.allow_state_increase_for_strategy[scratch->pmo_dcn4.num_pstate_candidates] = true;
-
- for (stream_index = 0; stream_index < stream_count; stream_index++) {
- scratch->pmo_dcn4.per_stream_pstate_strategy[scratch->pmo_dcn4.num_pstate_candidates][stream_index] = per_stream_pstate_strategy[stream_index];
-
- if (per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_vblank ||
- per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_fw_vblank_drr)
- scratch->pmo_dcn4.allow_state_increase_for_strategy[scratch->pmo_dcn4.num_pstate_candidates] = false;
- }
-
+ scratch->pmo_dcn4.pstate_strategy_candidates[scratch->pmo_dcn4.num_pstate_candidates] = *pstate_strategy;
scratch->pmo_dcn4.num_pstate_candidates++;
}
-static bool all_planes_match_strategy(const struct display_configuation_with_meta *display_cfg, int plane_mask, enum dml2_pmo_pstate_strategy strategy)
+static bool all_planes_match_method(const struct display_configuation_with_meta *display_cfg, int plane_mask, enum dml2_pmo_pstate_method method)
{
unsigned char i;
enum dml2_uclk_pstate_change_strategy matching_strategy = (enum dml2_uclk_pstate_change_strategy) dml2_pmo_pstate_strategy_na;
- if (strategy == dml2_pmo_pstate_strategy_vactive || strategy == dml2_pmo_pstate_strategy_fw_vactive_drr)
+ if (method == dml2_pmo_pstate_strategy_vactive || method == dml2_pmo_pstate_strategy_fw_vactive_drr)
matching_strategy = dml2_uclk_pstate_change_strategy_force_vactive;
- else if (strategy == dml2_pmo_pstate_strategy_vblank || strategy == dml2_pmo_pstate_strategy_fw_vblank_drr)
+ else if (method == dml2_pmo_pstate_strategy_vblank || method == dml2_pmo_pstate_strategy_fw_vblank_drr)
matching_strategy = dml2_uclk_pstate_change_strategy_force_vblank;
- else if (strategy == dml2_pmo_pstate_strategy_fw_svp)
+ else if (method == dml2_pmo_pstate_strategy_fw_svp)
matching_strategy = dml2_uclk_pstate_change_strategy_force_mall_svp;
- else if (strategy == dml2_pmo_pstate_strategy_fw_drr)
+ else if (method == dml2_pmo_pstate_strategy_fw_drr)
matching_strategy = dml2_uclk_pstate_change_strategy_force_drr;
for (i = 0; i < DML2_MAX_PLANES; i++) {
@@ -1027,12 +1146,12 @@ static void build_method_scheduling_params(
static struct dml2_fams2_per_method_common_meta *get_per_method_common_meta(
struct dml2_pmo_instance *pmo,
- enum dml2_pmo_pstate_strategy stream_pstate_strategy,
+ enum dml2_pmo_pstate_method stream_pstate_method,
int stream_idx)
{
struct dml2_fams2_per_method_common_meta *stream_method_fams2_meta = NULL;
- switch (stream_pstate_strategy) {
+ switch (stream_pstate_method) {
case dml2_pmo_pstate_strategy_vactive:
case dml2_pmo_pstate_strategy_fw_vactive_drr:
stream_method_fams2_meta = &pmo->scratch.pmo_dcn4.stream_fams2_meta[stream_idx].method_vactive.common;
@@ -1063,7 +1182,7 @@ static struct dml2_fams2_per_method_common_meta *get_per_method_common_meta(
static bool is_timing_group_schedulable(
struct dml2_pmo_instance *pmo,
const struct display_configuation_with_meta *display_cfg,
- const enum dml2_pmo_pstate_strategy per_stream_pstate_strategy[PMO_DCN4_MAX_DISPLAYS],
+ const struct dml2_pmo_pstate_strategy *pstate_strategy,
const unsigned int timing_group_idx,
struct dml2_fams2_per_method_common_meta *group_fams2_meta)
{
@@ -1082,7 +1201,7 @@ static bool is_timing_group_schedulable(
}
/* init allow start and end lines for timing group */
- stream_method_fams2_meta = get_per_method_common_meta(pmo, per_stream_pstate_strategy[base_stream_idx], base_stream_idx);
+ stream_method_fams2_meta = get_per_method_common_meta(pmo, pstate_strategy->per_stream_pstate_method[base_stream_idx], base_stream_idx);
if (!stream_method_fams2_meta)
return false;
@@ -1091,9 +1210,9 @@ static bool is_timing_group_schedulable(
group_fams2_meta->period_us = stream_method_fams2_meta->period_us;
for (i = base_stream_idx + 1; i < display_cfg->display_config.num_streams; i++) {
if (is_bit_set_in_bitfield(pmo->scratch.pmo_dcn4.synchronized_timing_group_masks[timing_group_idx], i)) {
- stream_method_fams2_meta = get_per_method_common_meta(pmo, per_stream_pstate_strategy[i], i);
+ stream_method_fams2_meta = get_per_method_common_meta(pmo, pstate_strategy->per_stream_pstate_method[i], i);
if (!stream_method_fams2_meta)
- continue;
+ return false;
if (group_fams2_meta->allow_start_otg_vline < stream_method_fams2_meta->allow_start_otg_vline) {
/* set group allow start to larger otg vline */
@@ -1123,7 +1242,7 @@ static bool is_timing_group_schedulable(
static bool is_config_schedulable(
struct dml2_pmo_instance *pmo,
const struct display_configuation_with_meta *display_cfg,
- const enum dml2_pmo_pstate_strategy per_stream_pstate_strategy[PMO_DCN4_MAX_DISPLAYS])
+ const struct dml2_pmo_pstate_strategy *pstate_strategy)
{
unsigned int i, j;
bool schedulable;
@@ -1146,7 +1265,7 @@ static bool is_config_schedulable(
for (i = 0; i < s->pmo_dcn4.num_timing_groups; i++) {
s->pmo_dcn4.sorted_group_gtl_disallow_index[i] = i;
s->pmo_dcn4.sorted_group_gtl_period_index[i] = i;
- if (!is_timing_group_schedulable(pmo, display_cfg, per_stream_pstate_strategy, i, &s->pmo_dcn4.group_common_fams2_meta[i])) {
+ if (!is_timing_group_schedulable(pmo, display_cfg, pstate_strategy, i, &s->pmo_dcn4.group_common_fams2_meta[i])) {
/* synchronized timing group was not schedulable */
schedulable = false;
break;
@@ -1248,7 +1367,7 @@ static bool is_config_schedulable(
unsigned int sorted_ip1 = s->pmo_dcn4.sorted_group_gtl_period_index[i + 1];
if (s->pmo_dcn4.group_common_fams2_meta[sorted_i].allow_time_us < s->pmo_dcn4.group_common_fams2_meta[sorted_ip1].period_us ||
- s->pmo_dcn4.group_is_drr_enabled[sorted_ip1]) {
+ (s->pmo_dcn4.group_is_drr_enabled[sorted_ip1] && s->pmo_dcn4.group_is_drr_active[sorted_ip1])) {
schedulable = false;
break;
}
@@ -1260,8 +1379,8 @@ static bool is_config_schedulable(
/* STAGE 4: When using HW exclusive modes, check disallow alignments are within allowed threshold */
if (s->pmo_dcn4.num_timing_groups == 2 &&
- !is_bit_set_in_bitfield(PMO_FW_STRATEGY_MASK, per_stream_pstate_strategy[0]) &&
- !is_bit_set_in_bitfield(PMO_FW_STRATEGY_MASK, per_stream_pstate_strategy[1])) {
+ !is_bit_set_in_bitfield(PMO_FW_STRATEGY_MASK, pstate_strategy->per_stream_pstate_method[0]) &&
+ !is_bit_set_in_bitfield(PMO_FW_STRATEGY_MASK, pstate_strategy->per_stream_pstate_method[1])) {
double period_ratio;
double max_shift_us;
double shift_per_period;
@@ -1290,44 +1409,48 @@ static bool is_config_schedulable(
}
static bool stream_matches_drr_policy(struct dml2_pmo_instance *pmo,
- const struct display_configuation_with_meta *display_cfg,
- const enum dml2_pmo_pstate_strategy stream_pstate_strategy,
- unsigned int stream_index)
+ const struct display_configuation_with_meta *display_cfg,
+ const enum dml2_pmo_pstate_method stream_pstate_method,
+ unsigned int stream_index)
{
const struct dml2_stream_parameters *stream_descriptor = &display_cfg->display_config.stream_descriptors[stream_index];
bool strategy_matches_drr_requirements = true;
/* check if strategy is compatible with stream drr capability and strategy */
- if (is_bit_set_in_bitfield(PMO_NO_DRR_STRATEGY_MASK, stream_pstate_strategy) &&
+ if (is_bit_set_in_bitfield(PMO_NO_DRR_STRATEGY_MASK, stream_pstate_method) &&
display_cfg->display_config.num_streams > 1 &&
stream_descriptor->timing.drr_config.enabled &&
(stream_descriptor->timing.drr_config.drr_active_fixed || stream_descriptor->timing.drr_config.drr_active_variable)) {
/* DRR is active, so config may become unschedulable */
strategy_matches_drr_requirements = false;
- } else if (is_bit_set_in_bitfield(PMO_NO_DRR_STRATEGY_MASK, stream_pstate_strategy) &&
- is_bit_set_in_bitfield(PMO_FW_STRATEGY_MASK, stream_pstate_strategy) &&
+ } else if (is_bit_set_in_bitfield(PMO_NO_DRR_STRATEGY_MASK, stream_pstate_method) &&
+ is_bit_set_in_bitfield(PMO_FW_STRATEGY_MASK, stream_pstate_method) &&
stream_descriptor->timing.drr_config.enabled &&
stream_descriptor->timing.drr_config.drr_active_variable) {
/* DRR is variable, fw exclusive methods require DRR to be clamped */
strategy_matches_drr_requirements = false;
- } else if (is_bit_set_in_bitfield(PMO_DRR_VAR_STRATEGY_MASK, stream_pstate_strategy) &&
+ } else if (is_bit_set_in_bitfield(PMO_DRR_VAR_STRATEGY_MASK, stream_pstate_method) &&
pmo->options->disable_drr_var_when_var_active &&
stream_descriptor->timing.drr_config.enabled &&
stream_descriptor->timing.drr_config.drr_active_variable) {
/* DRR variable is active, but policy blocks DRR for p-state when this happens */
strategy_matches_drr_requirements = false;
- } else if (is_bit_set_in_bitfield(PMO_DRR_VAR_STRATEGY_MASK, stream_pstate_strategy) &&
+ } else if (is_bit_set_in_bitfield(PMO_DRR_VAR_STRATEGY_MASK, stream_pstate_method) &&
(pmo->options->disable_drr_var ||
!stream_descriptor->timing.drr_config.enabled ||
stream_descriptor->timing.drr_config.disallowed)) {
/* DRR variable strategies are disallowed due to settings or policy */
strategy_matches_drr_requirements = false;
- } else if (is_bit_set_in_bitfield(PMO_DRR_CLAMPED_STRATEGY_MASK, stream_pstate_strategy) &&
- (pmo->options->disable_drr_clamped ||
- !stream_descriptor->timing.drr_config.enabled)) {
+ } else if (is_bit_set_in_bitfield(PMO_DRR_CLAMPED_STRATEGY_MASK, stream_pstate_method) &&
+ (pmo->options->disable_drr_clamped ||
+ (!stream_descriptor->timing.drr_config.enabled ||
+ (!stream_descriptor->timing.drr_config.drr_active_fixed && !stream_descriptor->timing.drr_config.drr_active_variable)) ||
+ (pmo->options->disable_drr_clamped_when_var_active &&
+ stream_descriptor->timing.drr_config.enabled &&
+ stream_descriptor->timing.drr_config.drr_active_variable))) {
/* DRR fixed strategies are disallowed due to settings or policy */
strategy_matches_drr_requirements = false;
- } else if (is_bit_set_in_bitfield(PMO_FW_STRATEGY_MASK, stream_pstate_strategy) &&
+ } else if (is_bit_set_in_bitfield(PMO_FW_STRATEGY_MASK, stream_pstate_method) &&
pmo->options->disable_fams2) {
/* FW modes require FAMS2 */
strategy_matches_drr_requirements = false;
@@ -1338,7 +1461,7 @@ static bool stream_matches_drr_policy(struct dml2_pmo_instance *pmo,
static bool validate_pstate_support_strategy_cofunctionality(struct dml2_pmo_instance *pmo,
const struct display_configuation_with_meta *display_cfg,
- const enum dml2_pmo_pstate_strategy per_stream_pstate_strategy[PMO_DCN4_MAX_DISPLAYS])
+ const struct dml2_pmo_pstate_strategy *pstate_strategy)
{
struct dml2_pmo_scratch *s = &pmo->scratch;
@@ -1359,28 +1482,28 @@ static bool validate_pstate_support_strategy_cofunctionality(struct dml2_pmo_ins
// Tabulate everything
for (stream_index = 0; stream_index < display_cfg->display_config.num_streams; stream_index++) {
- if (!all_planes_match_strategy(display_cfg, s->pmo_dcn4.stream_plane_mask[stream_index],
- per_stream_pstate_strategy[stream_index])) {
+ if (!all_planes_match_method(display_cfg, s->pmo_dcn4.stream_plane_mask[stream_index],
+ pstate_strategy->per_stream_pstate_method[stream_index])) {
strategy_matches_forced_requirements = false;
break;
}
strategy_matches_drr_requirements &=
- stream_matches_drr_policy(pmo, display_cfg, per_stream_pstate_strategy[stream_index], stream_index);
+ stream_matches_drr_policy(pmo, display_cfg, pstate_strategy->per_stream_pstate_method[stream_index], stream_index);
- if (per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_fw_svp ||
- per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_fw_svp_drr) {
+ if (pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_svp ||
+ pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_svp_drr) {
svp_count++;
set_bit_in_bitfield(&svp_stream_mask, stream_index);
- } else if (per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_fw_drr) {
+ } else if (pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_drr) {
drr_count++;
set_bit_in_bitfield(&drr_stream_mask, stream_index);
- } else if (per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_vactive ||
- per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_fw_vactive_drr) {
+ } else if (pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_vactive ||
+ pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_vactive_drr) {
vactive_count++;
set_bit_in_bitfield(&vactive_stream_mask, stream_index);
- } else if (per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_vblank ||
- per_stream_pstate_strategy[stream_index] == dml2_pmo_pstate_strategy_fw_vblank_drr) {
+ } else if (pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_vblank ||
+ pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_vblank_drr) {
vblank_count++;
set_bit_in_bitfield(&vblank_stream_mask, stream_index);
}
@@ -1389,7 +1512,7 @@ static bool validate_pstate_support_strategy_cofunctionality(struct dml2_pmo_ins
if (!strategy_matches_forced_requirements || !strategy_matches_drr_requirements)
return false;
- if (vactive_count > 0 && (pmo->options->disable_vblank || !all_timings_support_vactive(pmo, display_cfg, vactive_stream_mask)))
+ if (vactive_count > 0 && !all_timings_support_vactive(pmo, display_cfg, vactive_stream_mask))
return false;
if (vblank_count > 0 && (pmo->options->disable_vblank || !all_timings_support_vblank(pmo, display_cfg, vblank_stream_mask)))
@@ -1401,7 +1524,7 @@ static bool validate_pstate_support_strategy_cofunctionality(struct dml2_pmo_ins
if (svp_count > 0 && (pmo->options->disable_svp || !all_timings_support_svp(pmo, display_cfg, svp_stream_mask)))
return false;
- return is_config_schedulable(pmo, display_cfg, per_stream_pstate_strategy);
+ return is_config_schedulable(pmo, display_cfg, pstate_strategy);
}
static int get_vactive_pstate_margin(const struct display_configuation_with_meta *display_cfg, int plane_mask)
@@ -1457,6 +1580,7 @@ static void build_fams2_meta_per_stream(struct dml2_pmo_instance *pmo,
(stream_fams2_meta->nom_vtotal * timing->h_total);
stream_fams2_meta->nom_frame_time_us =
(double)stream_fams2_meta->nom_vtotal * stream_fams2_meta->otg_vline_time_us;
+ stream_fams2_meta->vblank_start = timing->v_blank_end + timing->v_active;
if (stream_descriptor->timing.drr_config.enabled == true) {
if (stream_descriptor->timing.drr_config.min_refresh_uhz != 0.0) {
@@ -1510,7 +1634,7 @@ static void build_fams2_meta_per_stream(struct dml2_pmo_instance *pmo,
stream_fams2_meta->method_vactive.common.allow_start_otg_vline =
timing->v_blank_end + stream_fams2_meta->method_vactive.max_vactive_det_fill_delay_otg_vlines;
stream_fams2_meta->method_vactive.common.allow_end_otg_vline =
- timing->v_blank_end + timing->v_active -
+ stream_fams2_meta->vblank_start -
stream_fams2_meta->dram_clk_change_blackout_otg_vlines;
} else {
stream_fams2_meta->method_vactive.common.allow_start_otg_vline = 0;
@@ -1520,8 +1644,7 @@ static void build_fams2_meta_per_stream(struct dml2_pmo_instance *pmo,
build_method_scheduling_params(&stream_fams2_meta->method_vactive.common, stream_fams2_meta);
/* vblank */
- stream_fams2_meta->method_vblank.common.allow_start_otg_vline =
- timing->v_blank_end + timing->v_active;
+ stream_fams2_meta->method_vblank.common.allow_start_otg_vline = stream_fams2_meta->vblank_start;
stream_fams2_meta->method_vblank.common.allow_end_otg_vline =
stream_fams2_meta->method_vblank.common.allow_start_otg_vline + 1;
stream_fams2_meta->method_vblank.common.period_us = stream_fams2_meta->nom_frame_time_us;
@@ -1555,8 +1678,7 @@ static void build_fams2_meta_per_stream(struct dml2_pmo_instance *pmo,
stream_fams2_meta->method_subvp.prefetch_to_mall_delay_otg_vlines +
stream_fams2_meta->allow_to_target_delay_otg_vlines;
stream_fams2_meta->method_subvp.common.allow_end_otg_vline =
- stream_fams2_meta->nom_vtotal -
- timing->v_front_porch -
+ stream_fams2_meta->vblank_start -
stream_fams2_meta->dram_clk_change_blackout_otg_vlines;
stream_fams2_meta->method_subvp.common.period_us = stream_fams2_meta->nom_frame_time_us;
build_method_scheduling_params(&stream_fams2_meta->method_subvp.common, stream_fams2_meta);
@@ -1565,20 +1687,21 @@ static void build_fams2_meta_per_stream(struct dml2_pmo_instance *pmo,
stream_fams2_meta->method_drr.programming_delay_otg_vlines =
(unsigned int)math_ceil(ip_caps->fams2.drr_programming_delay_us / stream_fams2_meta->otg_vline_time_us);
stream_fams2_meta->method_drr.common.allow_start_otg_vline =
- stream_fams2_meta->nom_vtotal +
+ stream_fams2_meta->vblank_start +
stream_fams2_meta->allow_to_target_delay_otg_vlines;
stream_fams2_meta->method_drr.common.period_us = stream_fams2_meta->nom_frame_time_us;
if (display_config->display_config.num_streams <= 1) {
/* only need to stretch vblank for blackout time */
stream_fams2_meta->method_drr.stretched_vtotal =
- stream_fams2_meta->method_drr.common.allow_start_otg_vline +
+ stream_fams2_meta->nom_vtotal +
+ stream_fams2_meta->allow_to_target_delay_otg_vlines +
stream_fams2_meta->min_allow_width_otg_vlines +
stream_fams2_meta->dram_clk_change_blackout_otg_vlines;
} else {
/* multi display needs to always be schedulable */
stream_fams2_meta->method_drr.stretched_vtotal =
- stream_fams2_meta->method_drr.common.allow_start_otg_vline +
- stream_fams2_meta->nom_vtotal +
+ stream_fams2_meta->nom_vtotal * 2 +
+ stream_fams2_meta->allow_to_target_delay_otg_vlines +
stream_fams2_meta->min_allow_width_otg_vlines +
stream_fams2_meta->dram_clk_change_blackout_otg_vlines;
}
@@ -1611,7 +1734,7 @@ bool pmo_dcn4_fams2_init_for_pstate_support(struct dml2_pmo_init_for_pstate_supp
struct display_configuation_with_meta *display_config;
const struct dml2_plane_parameters *plane_descriptor;
- const enum dml2_pmo_pstate_strategy(*strategy_list)[PMO_DCN4_MAX_DISPLAYS] = NULL;
+ const struct dml2_pmo_pstate_strategy *strategy_list = NULL;
unsigned int strategy_list_size = 0;
unsigned char plane_index, stream_index, i;
@@ -1623,6 +1746,10 @@ bool pmo_dcn4_fams2_init_for_pstate_support(struct dml2_pmo_init_for_pstate_supp
memset(s, 0, sizeof(struct dml2_pmo_scratch));
+ if (display_config->display_config.overrides.all_streams_blanked) {
+ return true;
+ }
+
pmo->scratch.pmo_dcn4.min_latency_index = in_out->base_display_config->stage1.min_clk_index_for_latency;
pmo->scratch.pmo_dcn4.max_latency_index = pmo->mcg_clock_table_size;
pmo->scratch.pmo_dcn4.cur_latency_index = in_out->base_display_config->stage1.min_clk_index_for_latency;
@@ -1652,6 +1779,9 @@ bool pmo_dcn4_fams2_init_for_pstate_support(struct dml2_pmo_init_for_pstate_supp
build_synchronized_timing_groups(pmo, display_config);
strategy_list = get_expanded_strategy_list(&pmo->init_data, display_config->display_config.num_streams);
+ if (!strategy_list)
+ return false;
+
strategy_list_size = get_num_expanded_strategies(&pmo->init_data, display_config->display_config.num_streams);
if (strategy_list_size == 0)
@@ -1660,8 +1790,8 @@ bool pmo_dcn4_fams2_init_for_pstate_support(struct dml2_pmo_init_for_pstate_supp
s->pmo_dcn4.num_pstate_candidates = 0;
for (i = 0; i < strategy_list_size && s->pmo_dcn4.num_pstate_candidates < DML2_PMO_PSTATE_CANDIDATE_LIST_SIZE; i++) {
- if (validate_pstate_support_strategy_cofunctionality(pmo, display_config, strategy_list[i])) {
- insert_into_candidate_list(strategy_list[i], display_config->display_config.num_streams, s);
+ if (validate_pstate_support_strategy_cofunctionality(pmo, display_config, &strategy_list[i])) {
+ insert_into_candidate_list(&strategy_list[i], display_config->display_config.num_streams, s);
}
}
@@ -1778,7 +1908,8 @@ static void setup_planes_for_vblank_by_mask(struct display_configuation_with_met
if (is_bit_set_in_bitfield(plane_mask, plane_index)) {
plane = &display_config->display_config.plane_descriptors[plane_index];
- plane->overrides.reserved_vblank_time_ns = (long)(pmo->soc_bb->power_management_parameters.dram_clk_change_blackout_us * 1000);
+ plane->overrides.reserved_vblank_time_ns = (long)math_max2(pmo->soc_bb->power_management_parameters.dram_clk_change_blackout_us * 1000.0,
+ plane->overrides.reserved_vblank_time_ns);
display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_vblank;
@@ -1857,26 +1988,26 @@ static bool setup_display_config(struct display_configuation_with_meta *display_
for (stream_index = 0; stream_index < display_config->display_config.num_streams; stream_index++) {
- if (pmo->scratch.pmo_dcn4.per_stream_pstate_strategy[strategy_index][stream_index] == dml2_pmo_pstate_strategy_na) {
+ if (pmo->scratch.pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_na) {
success = false;
break;
- } else if (scratch->pmo_dcn4.per_stream_pstate_strategy[strategy_index][stream_index] == dml2_pmo_pstate_strategy_vactive) {
+ } else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_vactive) {
setup_planes_for_vactive_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
- } else if (scratch->pmo_dcn4.per_stream_pstate_strategy[strategy_index][stream_index] == dml2_pmo_pstate_strategy_vblank) {
+ } else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_vblank) {
setup_planes_for_vblank_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
- } else if (scratch->pmo_dcn4.per_stream_pstate_strategy[strategy_index][stream_index] == dml2_pmo_pstate_strategy_fw_svp) {
+ } else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_svp) {
fams2_required = true;
setup_planes_for_svp_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
- } else if (scratch->pmo_dcn4.per_stream_pstate_strategy[strategy_index][stream_index] == dml2_pmo_pstate_strategy_fw_vactive_drr) {
+ } else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_vactive_drr) {
fams2_required = true;
setup_planes_for_vactive_drr_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
- } else if (scratch->pmo_dcn4.per_stream_pstate_strategy[strategy_index][stream_index] == dml2_pmo_pstate_strategy_fw_vblank_drr) {
+ } else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_vblank_drr) {
fams2_required = true;
setup_planes_for_vblank_drr_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
- } else if (scratch->pmo_dcn4.per_stream_pstate_strategy[strategy_index][stream_index] == dml2_pmo_pstate_strategy_fw_svp_drr) {
+ } else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_svp_drr) {
fams2_required = true;
setup_planes_for_svp_drr_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
- } else if (scratch->pmo_dcn4.per_stream_pstate_strategy[strategy_index][stream_index] == dml2_pmo_pstate_strategy_fw_drr) {
+ } else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_drr) {
fams2_required = true;
setup_planes_for_drr_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
}
@@ -1917,6 +2048,10 @@ bool pmo_dcn4_fams2_test_for_pstate_support(struct dml2_pmo_test_for_pstate_supp
int MIN_VACTIVE_MARGIN_DRR = 0;
int REQUIRED_RESERVED_TIME = 0;
+ if (in_out->base_display_config->display_config.overrides.all_streams_blanked) {
+ return true;
+ }
+
MIN_VACTIVE_MARGIN_VBLANK = INT_MIN;
MIN_VACTIVE_MARGIN_DRR = INT_MIN;
REQUIRED_RESERVED_TIME = (int)in_out->instance->soc_bb->power_management_parameters.dram_clk_change_blackout_us;
@@ -1927,34 +2062,34 @@ bool pmo_dcn4_fams2_test_for_pstate_support(struct dml2_pmo_test_for_pstate_supp
for (stream_index = 0; stream_index < in_out->base_display_config->display_config.num_streams; stream_index++) {
struct dml2_fams2_meta *stream_fams2_meta = &s->pmo_dcn4.stream_fams2_meta[stream_index];
- if (s->pmo_dcn4.per_stream_pstate_strategy[s->pmo_dcn4.cur_pstate_candidate][stream_index] == dml2_pmo_pstate_strategy_vactive ||
- s->pmo_dcn4.per_stream_pstate_strategy[s->pmo_dcn4.cur_pstate_candidate][stream_index] == dml2_pmo_pstate_strategy_fw_vactive_drr) {
+ if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_vactive ||
+ s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_vactive_drr) {
if (get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < (MIN_VACTIVE_MARGIN_PCT * in_out->instance->soc_bb->power_management_parameters.dram_clk_change_blackout_us) ||
get_vactive_det_fill_latency_delay_us(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) > stream_fams2_meta->method_vactive.max_vactive_det_fill_delay_us) {
p_state_supported = false;
break;
}
- } else if (s->pmo_dcn4.per_stream_pstate_strategy[s->pmo_dcn4.cur_pstate_candidate][stream_index] == dml2_pmo_pstate_strategy_vblank ||
- s->pmo_dcn4.per_stream_pstate_strategy[s->pmo_dcn4.cur_pstate_candidate][stream_index] == dml2_pmo_pstate_strategy_fw_vblank_drr) {
+ } else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_vblank ||
+ s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_vblank_drr) {
if (get_minimum_reserved_time_us_for_planes(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) <
REQUIRED_RESERVED_TIME ||
get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < MIN_VACTIVE_MARGIN_VBLANK) {
p_state_supported = false;
break;
}
- } else if (s->pmo_dcn4.per_stream_pstate_strategy[s->pmo_dcn4.cur_pstate_candidate][stream_index] == dml2_pmo_pstate_strategy_fw_svp ||
- s->pmo_dcn4.per_stream_pstate_strategy[s->pmo_dcn4.cur_pstate_candidate][stream_index] == dml2_pmo_pstate_strategy_fw_svp_drr) {
+ } else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_svp ||
+ s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_svp_drr) {
if (in_out->base_display_config->stage3.stream_svp_meta[stream_index].valid == false) {
p_state_supported = false;
break;
}
- } else if (s->pmo_dcn4.per_stream_pstate_strategy[s->pmo_dcn4.cur_pstate_candidate][stream_index] == dml2_pmo_pstate_strategy_fw_drr) {
- if (!all_planes_match_strategy(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index], dml2_pmo_pstate_strategy_fw_drr) ||
+ } else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_drr) {
+ if (!all_planes_match_method(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index], dml2_pmo_pstate_strategy_fw_drr) ||
get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < MIN_VACTIVE_MARGIN_DRR) {
p_state_supported = false;
break;
}
- } else if (s->pmo_dcn4.per_stream_pstate_strategy[s->pmo_dcn4.cur_pstate_candidate][stream_index] == dml2_pmo_pstate_strategy_na) {
+ } else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_na) {
p_state_supported = false;
break;
}
@@ -1971,8 +2106,8 @@ bool pmo_dcn4_fams2_optimize_for_pstate_support(struct dml2_pmo_optimize_for_pst
memcpy(in_out->optimized_display_config, in_out->base_display_config, sizeof(struct display_configuation_with_meta));
if (in_out->last_candidate_failed) {
- if (s->pmo_dcn4.allow_state_increase_for_strategy[s->pmo_dcn4.cur_pstate_candidate] &&
- s->pmo_dcn4.cur_latency_index < s->pmo_dcn4.max_latency_index) {
+ if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].allow_state_increase &&
+ s->pmo_dcn4.cur_latency_index < s->pmo_dcn4.max_latency_index - 1) {
s->pmo_dcn4.cur_latency_index++;
success = true;
@@ -2060,15 +2195,15 @@ bool pmo_dcn4_fams2_test_for_stutter(struct dml2_pmo_test_for_stutter_in_out *in
unsigned int i;
- for (i = 0; i < in_out->base_display_config->display_config.num_streams; i++) {
+ for (i = 0; i < in_out->base_display_config->display_config.num_planes; i++) {
if (pmo->soc_bb->power_management_parameters.z8_stutter_exit_latency_us > 0 &&
pmo->scratch.pmo_dcn4.z8_vblank_optimizable &&
- in_out->base_display_config->display_config.stream_descriptors[i].overrides.minimum_vblank_idle_requirement_us < (int)pmo->soc_bb->power_management_parameters.z8_stutter_exit_latency_us) {
+ in_out->base_display_config->display_config.plane_descriptors[i].overrides.reserved_vblank_time_ns < (int)pmo->soc_bb->power_management_parameters.z8_stutter_exit_latency_us * 1000) {
success = false;
break;
}
if (pmo->soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us > 0 &&
- in_out->base_display_config->display_config.stream_descriptors[i].overrides.minimum_vblank_idle_requirement_us < (int)pmo->soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us) {
+ in_out->base_display_config->display_config.plane_descriptors[i].overrides.reserved_vblank_time_ns < (int)pmo->soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us * 1000) {
success = false;
break;
}
@@ -2087,8 +2222,11 @@ bool pmo_dcn4_fams2_optimize_for_stutter(struct dml2_pmo_optimize_for_stutter_in
if (!in_out->last_candidate_failed) {
if (pmo->scratch.pmo_dcn4.cur_stutter_candidate < pmo->scratch.pmo_dcn4.num_stutter_candidates) {
- for (i = 0; i < in_out->optimized_display_config->display_config.num_streams; i++) {
- in_out->optimized_display_config->display_config.stream_descriptors[i].overrides.minimum_vblank_idle_requirement_us = pmo->scratch.pmo_dcn4.optimal_vblank_reserved_time_for_stutter_us[pmo->scratch.pmo_dcn4.cur_stutter_candidate];
+ for (i = 0; i < in_out->optimized_display_config->display_config.num_planes; i++) {
+ /* take the max of the current and the optimal reserved time */
+ in_out->optimized_display_config->display_config.plane_descriptors[i].overrides.reserved_vblank_time_ns =
+ (long)math_max2(pmo->scratch.pmo_dcn4.optimal_vblank_reserved_time_for_stutter_us[pmo->scratch.pmo_dcn4.cur_stutter_candidate] * 1000,
+ in_out->optimized_display_config->display_config.plane_descriptors[i].overrides.reserved_vblank_time_ns);
}
success = true;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.h
index 75175d93add4..0c25bd3e9ac0 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_PMO_FAMS2_DCN4_H__
#define __DML2_PMO_FAMS2_DCN4_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_factory.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_factory.c
index e0b9ece7901d..add51d41a515 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_factory.c
@@ -2,10 +2,8 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#include "dml2_pmo_factory.h"
#include "dml2_pmo_dcn4_fams2.h"
-#include "dml2_pmo_dcn4.h"
#include "dml2_pmo_dcn3.h"
#include "dml2_external_lib_deps.h"
@@ -28,15 +26,15 @@ bool dml2_pmo_create(enum dml2_project_id project_id, struct dml2_pmo_instance *
{
bool result = false;
- if (!out)
+ if (out == 0)
return false;
memset(out, 0, sizeof(struct dml2_pmo_instance));
switch (project_id) {
case dml2_project_dcn4x_stage1:
- out->initialize = pmo_dcn4_initialize;
- out->optimize_dcc_mcache = pmo_dcn4_optimize_dcc_mcache;
+ out->initialize = pmo_dcn4_fams2_initialize;
+ out->optimize_dcc_mcache = pmo_dcn4_fams2_optimize_dcc_mcache;
result = true;
break;
case dml2_project_dcn4x_stage2:
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_factory.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_factory.h
index 9d3dc5e94be1..7218de1824cc 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_factory.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_factory.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_PMO_FACTORY_H__
#define __DML2_PMO_FACTORY_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_standalone_libraries/lib_float_math.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_standalone_libraries/lib_float_math.c
index e73579f1a88e..e17b5ceba447 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_standalone_libraries/lib_float_math.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_standalone_libraries/lib_float_math.c
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#include "lib_float_math.h"
#define ASSERT(condition)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_standalone_libraries/lib_float_math.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_standalone_libraries/lib_float_math.h
index 537cf6fd4c15..e13b0c5939b0 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_standalone_libraries/lib_float_math.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_standalone_libraries/lib_float_math.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __LIB_FLOAT_MATH_H__
#define __LIB_FLOAT_MATH_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_optimization.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_optimization.c
index 1b6dbfaa7ae8..d0e026d981b5 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_optimization.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_optimization.c
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#include "dml2_top_optimization.h"
#include "dml2_internal_shared_types.h"
#include "dml_top_mcache.h"
@@ -220,7 +219,6 @@ bool dml2_top_optimization_perform_optimization_phase_1(struct dml2_optimization
copy_display_configuration_with_meta(&l->cur_candidate_display_cfg, params->display_config);
highest_state = l->cur_candidate_display_cfg.stage1.min_clk_index_for_latency;
lowest_state = 0;
- cur_state = 0;
while (highest_state > lowest_state) {
cur_state = (highest_state + lowest_state) / 2;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_optimization.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_optimization.h
index 1536afcbf73a..9f22ab33eab1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_optimization.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_optimization.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_TOP_OPTIMIZATION_H__
#define __DML2_TOP_OPTIMIZATION_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c
index 2fb3e2f45e07..f9f8869cd8b8 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#include "dml2_internal_shared_types.h"
#include "dml_top.h"
#include "dml2_mcg_factory.h"
@@ -28,6 +27,7 @@ bool dml2_initialize_instance(struct dml2_initialize_instance_in_out *in_out)
bool result = false;
memset(l, 0, sizeof(struct dml2_initialize_instance_locals));
+ memset(dml, 0, sizeof(struct dml2_instance));
memcpy(&dml->ip_caps, &in_out->ip_caps, sizeof(struct dml2_ip_capabilities));
memcpy(&dml->soc_bbox, &in_out->soc_bb, sizeof(struct dml2_soc_bb));
@@ -96,14 +96,12 @@ bool dml2_check_mode_supported(struct dml2_check_mode_supported_in_out *in_out)
{
struct dml2_instance *dml = (struct dml2_instance *)in_out->dml2_instance;
struct dml2_check_mode_supported_locals *l = &dml->scratch.check_mode_supported_locals;
- /* Borrow the build_mode_programming_locals programming struct for DPMM call. */
- struct dml2_display_cfg_programming *dpmm_programming = dml->scratch.build_mode_programming_locals.mode_programming_params.programming;
+ struct dml2_display_cfg_programming *dpmm_programming = &dml->dpmm_instance.dpmm_scratch.programming;
bool result = false;
bool mcache_success = false;
- if (dpmm_programming)
- memset(dpmm_programming, 0, sizeof(struct dml2_display_cfg_programming));
+ memset(dpmm_programming, 0, sizeof(struct dml2_display_cfg_programming));
setup_unoptimized_display_config_with_meta(dml, &l->base_display_config_with_meta, in_out->display_config);
@@ -130,7 +128,7 @@ bool dml2_check_mode_supported(struct dml2_check_mode_supported_in_out *in_out)
/*
* Call DPMM to map all requirements to minimum clock state
*/
- if (result && dpmm_programming) {
+ if (result) {
l->dppm_map_mode_params.min_clk_table = &dml->min_clk_table;
l->dppm_map_mode_params.display_cfg = &l->base_display_config_with_meta;
l->dppm_map_mode_params.programming = dpmm_programming;
@@ -268,9 +266,18 @@ bool dml2_build_mode_programming(struct dml2_build_mode_programming_in_out *in_o
vmin_success = dml2_top_optimization_perform_optimization_phase(&l->optimization_phase_locals, &l->vmin_phase);
- if (vmin_success) {
+ if (l->optimized_display_config_with_meta.stage4.performed) {
+ /*
+ * when performed is true, optimization has applied to
+ * optimized_display_config_with_meta and it has passed mode
+ * support. However it may or may not pass the test function to
+ * reach actual Vmin. As long as voltage is optimized even if it
+ * doesn't reach Vmin level, there is still power benefit so in
+ * this case we will still copy this optimization into base
+ * display config.
+ */
memcpy(&l->base_display_config_with_meta, &l->optimized_display_config_with_meta, sizeof(struct display_configuation_with_meta));
- l->base_display_config_with_meta.stage4.success = true;
+ l->base_display_config_with_meta.stage4.success = vmin_success;
}
/*
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.c
index 7afd417071a5..a342ebfbe4e7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.c
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#include "dml2_debug.h"
#include "dml_top_mcache.h"
@@ -143,12 +142,12 @@ static unsigned int count_elements_in_span(int *array, unsigned int array_size,
while (span_start_index < array_size) {
for (i = span_start_index; i < array_size; i++) {
- if (array[i] - span_start_value > span) {
+ if (array[i] - span_start_value <= span) {
if (i - span_start_index + 1 > greatest_element_count) {
greatest_element_count = i - span_start_index + 1;
}
+ } else
break;
- }
}
span_start_index++;
@@ -208,9 +207,9 @@ bool dml2_top_mcache_validate_admissability(struct top_mcache_validate_admissabi
int temp, p0shift, p1shift;
unsigned int plane_index = 0;
unsigned int i;
- char odm_combine_factor = 1;
- char mpc_combine_factor = 1;
- char num_dpps;
+ unsigned int odm_combine_factor;
+ unsigned int mpc_combine_factor;
+ unsigned int num_dpps;
unsigned int num_boundaries;
enum dml2_scaling_transform scaling_transform;
const struct dml2_plane_parameters *plane;
@@ -227,10 +226,10 @@ bool dml2_top_mcache_validate_admissability(struct top_mcache_validate_admissabi
plane = &params->display_cfg->plane_descriptors[plane_index];
stream = &params->display_cfg->stream_descriptors[plane->stream_index];
- odm_combine_factor = (char)params->cfg_support_info->stream_support_info[plane->stream_index].odms_used;
+ num_dpps = odm_combine_factor = params->cfg_support_info->stream_support_info[plane->stream_index].odms_used;
if (odm_combine_factor == 1)
- mpc_combine_factor = (char)params->cfg_support_info->plane_support_info[plane_index].dpps_used;
+ num_dpps = mpc_combine_factor = (unsigned int)params->cfg_support_info->plane_support_info[plane_index].dpps_used;
else
mpc_combine_factor = 1;
@@ -260,13 +259,13 @@ bool dml2_top_mcache_validate_admissability(struct top_mcache_validate_admissabi
// The last element in the unshifted boundary array will always be the first pixel outside the
// plane, which means theres no mcache associated with it, so -1
num_boundaries = params->mcache_allocations[plane_index].num_mcaches_plane0 == 0 ? 0 : params->mcache_allocations[plane_index].num_mcaches_plane0 - 1;
- if (count_elements_in_span(params->mcache_allocations[plane_index].mcache_x_offsets_plane0,
- num_boundaries, max_per_pipe_vp_p0) <= 1) {
+ if ((count_elements_in_span(params->mcache_allocations[plane_index].mcache_x_offsets_plane0,
+ num_boundaries, max_per_pipe_vp_p0) <= 1) && (num_boundaries <= num_dpps)) {
p0pass = true;
}
num_boundaries = params->mcache_allocations[plane_index].num_mcaches_plane1 == 0 ? 0 : params->mcache_allocations[plane_index].num_mcaches_plane1 - 1;
- if (count_elements_in_span(params->mcache_allocations[plane_index].mcache_x_offsets_plane1,
- num_boundaries, max_per_pipe_vp_p1) <= 1) {
+ if ((count_elements_in_span(params->mcache_allocations[plane_index].mcache_x_offsets_plane1,
+ num_boundaries, max_per_pipe_vp_p1) <= 1) && (num_boundaries <= num_dpps)) {
p1pass = true;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.h
index bb12e4c30690..7b1f6f7143d0 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML_TOP_MCACHE_H__
#define __DML_TOP_MCACHE_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_debug.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_debug.c
index de7d8a6a2d3d..e9b8e10695ae 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_debug.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_debug.c
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#include "dml2_debug.h"
int dml2_printf(const char *format, ...)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_debug.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_debug.h
index 0403238df107..d51a1b6c62f2 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_debug.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_debug.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_DEBUG_H__
#define __DML2_DEBUG_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_internal_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_internal_shared_types.h
index 5632cdacb7f4..aeac9f159fa5 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_internal_shared_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_internal_shared_types.h
@@ -2,7 +2,6 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-
#ifndef __DML2_INTERNAL_SHARED_TYPES_H__
#define __DML2_INTERNAL_SHARED_TYPES_H__
@@ -107,10 +106,16 @@ struct dml2_dpmm_map_watermarks_params_in_out {
struct dml2_display_cfg_programming *programming;
};
+struct dml2_dpmm_scratch {
+ struct dml2_display_cfg_programming programming;
+};
+
struct dml2_dpmm_instance {
bool (*map_mode_to_soc_dpm)(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out);
bool (*map_watermarks)(struct dml2_dpmm_map_watermarks_params_in_out *in_out);
bool (*unit_test)(void);
+
+ struct dml2_dpmm_scratch dpmm_scratch;
};
/*
@@ -266,6 +271,7 @@ struct dml2_fams2_meta {
unsigned int contention_delay_otg_vlines;
unsigned int min_allow_width_otg_vlines;
unsigned int nom_vtotal;
+ unsigned int vblank_start;
double nom_refresh_rate_hz;
double nom_frame_time_us;
unsigned int max_vtotal;
@@ -594,7 +600,7 @@ struct dml2_pmo_optimize_for_stutter_in_out {
struct display_configuation_with_meta *optimized_display_config;
};
-enum dml2_pmo_pstate_strategy {
+enum dml2_pmo_pstate_method {
dml2_pmo_pstate_strategy_na = 0,
/* hw exclusive modes */
dml2_pmo_pstate_strategy_vactive = 1,
@@ -612,6 +618,11 @@ enum dml2_pmo_pstate_strategy {
dml2_pmo_pstate_strategy_reserved_fw_drr_var = 22,
};
+struct dml2_pmo_pstate_strategy {
+ enum dml2_pmo_pstate_method per_stream_pstate_method[DML2_MAX_PLANES];
+ bool allow_state_increase;
+};
+
#define PMO_NO_DRR_STRATEGY_MASK (((1 << (dml2_pmo_pstate_strategy_reserved_fw - dml2_pmo_pstate_strategy_na + 1)) - 1) << dml2_pmo_pstate_strategy_na)
#define PMO_DRR_STRATEGY_MASK (((1 << (dml2_pmo_pstate_strategy_reserved_fw_drr_var - dml2_pmo_pstate_strategy_fw_vactive_drr + 1)) - 1) << dml2_pmo_pstate_strategy_fw_vactive_drr)
#define PMO_DRR_CLAMPED_STRATEGY_MASK (((1 << (dml2_pmo_pstate_strategy_reserved_fw_drr_clamped - dml2_pmo_pstate_strategy_fw_vactive_drr + 1)) - 1) << dml2_pmo_pstate_strategy_fw_vactive_drr)
@@ -634,8 +645,7 @@ struct dml2_pmo_scratch {
int stream_mask;
} pmo_dcn3;
struct {
- enum dml2_pmo_pstate_strategy per_stream_pstate_strategy[DML2_MAX_PLANES][DML2_PMO_PSTATE_CANDIDATE_LIST_SIZE];
- bool allow_state_increase_for_strategy[DML2_PMO_PSTATE_CANDIDATE_LIST_SIZE];
+ struct dml2_pmo_pstate_strategy pstate_strategy_candidates[DML2_PMO_PSTATE_CANDIDATE_LIST_SIZE];
int num_pstate_candidates;
int cur_pstate_candidate;
@@ -661,6 +671,7 @@ struct dml2_pmo_scratch {
unsigned int num_timing_groups;
unsigned int synchronized_timing_group_masks[DML2_MAX_PLANES];
bool group_is_drr_enabled[DML2_MAX_PLANES];
+ bool group_is_drr_active[DML2_MAX_PLANES];
double group_line_time_us[DML2_MAX_PLANES];
/* scheduling check locals */
@@ -676,10 +687,10 @@ struct dml2_pmo_init_data {
union {
struct {
/* populated once during initialization */
- enum dml2_pmo_pstate_strategy expanded_strategy_list_1_display[PMO_DCN4_MAX_BASE_STRATEGIES * 2][PMO_DCN4_MAX_DISPLAYS];
- enum dml2_pmo_pstate_strategy expanded_strategy_list_2_display[PMO_DCN4_MAX_BASE_STRATEGIES * 2 * 2][PMO_DCN4_MAX_DISPLAYS];
- enum dml2_pmo_pstate_strategy expanded_strategy_list_3_display[PMO_DCN4_MAX_BASE_STRATEGIES * 6 * 2][PMO_DCN4_MAX_DISPLAYS];
- enum dml2_pmo_pstate_strategy expanded_strategy_list_4_display[PMO_DCN4_MAX_BASE_STRATEGIES * 24 * 2][PMO_DCN4_MAX_DISPLAYS];
+ struct dml2_pmo_pstate_strategy expanded_strategy_list_1_display[PMO_DCN4_MAX_BASE_STRATEGIES * 2];
+ struct dml2_pmo_pstate_strategy expanded_strategy_list_2_display[PMO_DCN4_MAX_BASE_STRATEGIES * 4 * 4];
+ struct dml2_pmo_pstate_strategy expanded_strategy_list_3_display[PMO_DCN4_MAX_BASE_STRATEGIES * 6 * 6 * 6];
+ struct dml2_pmo_pstate_strategy expanded_strategy_list_4_display[PMO_DCN4_MAX_BASE_STRATEGIES * 8 * 8 * 8 * 8];
unsigned int num_expanded_strategies_per_list[PMO_DCN4_MAX_DISPLAYS];
} pmo_dcn4;
};
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h b/drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h
index b566f53608c6..140ec01545db 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h
@@ -101,6 +101,7 @@ struct dml2_wrapper_scratch {
struct dml2_dml_to_dc_pipe_mapping dml_to_dc_pipe_mapping;
bool enable_flexible_pipe_mapping;
bool plane_duplicate_exists;
+ int hpo_stream_to_link_encoder_mapping[MAX_HPO_DP2_ENCODERS];
};
struct dml2_helper_det_policy_scratch {
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
index 8b9dcee77266..bde4250853b1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
@@ -733,7 +733,7 @@ static void populate_dml_timing_cfg_from_stream_state(struct dml_timing_cfg_st *
}
static void populate_dml_output_cfg_from_stream_state(struct dml_output_cfg_st *out, unsigned int location,
- const struct dc_stream_state *in, const struct pipe_ctx *pipe)
+ const struct dc_stream_state *in, const struct pipe_ctx *pipe, struct dml2_context *dml2)
{
unsigned int output_bpc;
@@ -746,8 +746,8 @@ static void populate_dml_output_cfg_from_stream_state(struct dml_output_cfg_st *
case SIGNAL_TYPE_DISPLAY_PORT_MST:
case SIGNAL_TYPE_DISPLAY_PORT:
out->OutputEncoder[location] = dml_dp;
- if (is_dp2p0_output_encoder(pipe))
- out->OutputEncoder[location] = dml_dp2p0;
+ if (dml2->v20.scratch.hpo_stream_to_link_encoder_mapping[location] != -1)
+ out->OutputEncoder[dml2->v20.scratch.hpo_stream_to_link_encoder_mapping[location]] = dml_dp2p0;
break;
case SIGNAL_TYPE_EDP:
out->OutputEncoder[location] = dml_edp;
@@ -953,7 +953,9 @@ static void get_scaler_data_for_plane(const struct dc_plane_state *in, struct dc
memcpy(out, &temp_pipe->plane_res.scl_data, sizeof(*out));
}
-static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned int location, const struct dc_stream_state *in)
+static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned int location,
+ const struct dc_stream_state *in,
+ const struct soc_bounding_box_st *soc)
{
dml_uint_t width, height;
@@ -970,7 +972,7 @@ static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned
out->CursorBPP[location] = dml_cur_32bit;
out->CursorWidth[location] = 256;
- out->GPUVMMinPageSizeKBytes[location] = 256;
+ out->GPUVMMinPageSizeKBytes[location] = soc->gpuvm_min_page_size_kbytes;
out->ViewportWidth[location] = width;
out->ViewportHeight[location] = height;
@@ -1007,7 +1009,9 @@ static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned
out->ScalerEnabled[location] = false;
}
-static void populate_dml_plane_cfg_from_plane_state(struct dml_plane_cfg_st *out, unsigned int location, const struct dc_plane_state *in, struct dc_state *context)
+static void populate_dml_plane_cfg_from_plane_state(struct dml_plane_cfg_st *out, unsigned int location,
+ const struct dc_plane_state *in, struct dc_state *context,
+ const struct soc_bounding_box_st *soc)
{
struct scaler_data *scaler_data = kzalloc(sizeof(*scaler_data), GFP_KERNEL);
if (!scaler_data)
@@ -1018,7 +1022,7 @@ static void populate_dml_plane_cfg_from_plane_state(struct dml_plane_cfg_st *out
out->CursorBPP[location] = dml_cur_32bit;
out->CursorWidth[location] = 256;
- out->GPUVMMinPageSizeKBytes[location] = 256;
+ out->GPUVMMinPageSizeKBytes[location] = soc->gpuvm_min_page_size_kbytes;
out->ViewportWidth[location] = scaler_data->viewport.width;
out->ViewportHeight[location] = scaler_data->viewport.height;
@@ -1193,6 +1197,7 @@ static void dml2_populate_pipe_to_plane_index_mapping(struct dml2_context *dml2,
plane_index = 0;
}
}
+
static void populate_dml_writeback_cfg_from_stream_state(struct dml_writeback_cfg_st *out,
unsigned int location, const struct dc_stream_state *in)
{
@@ -1233,6 +1238,30 @@ static void populate_dml_writeback_cfg_from_stream_state(struct dml_writeback_cf
}
}
}
+
+static void dml2_map_hpo_stream_encoder_to_hpo_link_encoder_index(struct dml2_context *dml2, struct dc_state *context)
+{
+ int i;
+ struct pipe_ctx *current_pipe_context;
+
+ /* Scratch gets reset to zero in dml, but link encoder instance can be zero, so reset to -1 */
+ for (i = 0; i < MAX_HPO_DP2_ENCODERS; i++) {
+ dml2->v20.scratch.hpo_stream_to_link_encoder_mapping[i] = -1;
+ }
+
+ /* If an HPO stream encoder is allocated to a pipe, get the instance of it's allocated HPO Link encoder */
+ for (i = 0; i < MAX_PIPES; i++) {
+ current_pipe_context = &context->res_ctx.pipe_ctx[i];
+ if (current_pipe_context->stream &&
+ current_pipe_context->stream_res.hpo_dp_stream_enc &&
+ current_pipe_context->link_res.hpo_dp_link_enc &&
+ dc_is_dp_signal(current_pipe_context->stream->signal)) {
+ dml2->v20.scratch.hpo_stream_to_link_encoder_mapping[current_pipe_context->stream_res.hpo_dp_stream_enc->inst] =
+ current_pipe_context->link_res.hpo_dp_link_enc->inst;
+ }
+ }
+}
+
void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_state *context, struct dml_display_cfg_st *dml_dispcfg)
{
int i = 0, j = 0, k = 0;
@@ -1256,6 +1285,7 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat
dml2->v20.dml_core_ctx.policy.AllowForPStateChangeOrStutterInVBlankFinal = dml_prefetch_support_uclk_fclk_and_stutter;
dml2_populate_pipe_to_plane_index_mapping(dml2, context);
+ dml2_map_hpo_stream_encoder_to_hpo_link_encoder_index(dml2, context);
for (i = 0; i < context->stream_count; i++) {
current_pipe_context = NULL;
@@ -1276,7 +1306,7 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat
ASSERT(disp_cfg_stream_location >= 0 && disp_cfg_stream_location <= __DML2_WRAPPER_MAX_STREAMS_PLANES__);
populate_dml_timing_cfg_from_stream_state(&dml_dispcfg->timing, disp_cfg_stream_location, context->streams[i]);
- populate_dml_output_cfg_from_stream_state(&dml_dispcfg->output, disp_cfg_stream_location, context->streams[i], current_pipe_context);
+ populate_dml_output_cfg_from_stream_state(&dml_dispcfg->output, disp_cfg_stream_location, context->streams[i], current_pipe_context, dml2);
/*Call site for populate_dml_writeback_cfg_from_stream_state*/
populate_dml_writeback_cfg_from_stream_state(&dml_dispcfg->writeback,
disp_cfg_stream_location, context->streams[i]);
@@ -1299,7 +1329,8 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat
disp_cfg_plane_location = dml_dispcfg->num_surfaces++;
populate_dummy_dml_surface_cfg(&dml_dispcfg->surface, disp_cfg_plane_location, context->streams[i]);
- populate_dummy_dml_plane_cfg(&dml_dispcfg->plane, disp_cfg_plane_location, context->streams[i]);
+ populate_dummy_dml_plane_cfg(&dml_dispcfg->plane, disp_cfg_plane_location,
+ context->streams[i], &dml2->v20.dml_core_ctx.soc);
dml_dispcfg->plane.BlendingAndTiming[disp_cfg_plane_location] = disp_cfg_stream_location;
@@ -1315,7 +1346,10 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat
ASSERT(disp_cfg_plane_location >= 0 && disp_cfg_plane_location <= __DML2_WRAPPER_MAX_STREAMS_PLANES__);
populate_dml_surface_cfg_from_plane_state(dml2->v20.dml_core_ctx.project, &dml_dispcfg->surface, disp_cfg_plane_location, context->stream_status[i].plane_states[j]);
- populate_dml_plane_cfg_from_plane_state(&dml_dispcfg->plane, disp_cfg_plane_location, context->stream_status[i].plane_states[j], context);
+ populate_dml_plane_cfg_from_plane_state(
+ &dml_dispcfg->plane, disp_cfg_plane_location,
+ context->stream_status[i].plane_states[j], context,
+ &dml2->v20.dml_core_ctx.soc);
if (stream_mall_type == SUBVP_MAIN) {
dml_dispcfg->plane.UseMALLForPStateChange[disp_cfg_plane_location] = dml_use_mall_pstate_change_sub_viewport;
@@ -1337,7 +1371,7 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat
if (j >= 1) {
populate_dml_timing_cfg_from_stream_state(&dml_dispcfg->timing, disp_cfg_plane_location, context->streams[i]);
- populate_dml_output_cfg_from_stream_state(&dml_dispcfg->output, disp_cfg_plane_location, context->streams[i], current_pipe_context);
+ populate_dml_output_cfg_from_stream_state(&dml_dispcfg->output, disp_cfg_plane_location, context->streams[i], current_pipe_context, dml2);
switch (context->streams[i]->debug.force_odm_combine_segments) {
case 2:
dml2->v20.dml_core_ctx.policy.ODMUse[disp_cfg_plane_location] = dml_odm_use_policy_combine_2to1;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c
index 92238ff333a4..9a33158b63bf 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c
@@ -161,14 +161,6 @@ bool is_dp2p0_output_encoder(const struct pipe_ctx *pipe_ctx)
/* If this assert is hit then we have a link encoder dynamic management issue */
ASSERT(pipe_ctx->stream_res.hpo_dp_stream_enc ? pipe_ctx->link_res.hpo_dp_link_enc != NULL : true);
- /* Count MST hubs once by treating only 1st remote sink in topology as an encoder */
- if (pipe_ctx->stream->link && pipe_ctx->stream->link->remote_sinks[0]) {
- return (pipe_ctx->stream_res.hpo_dp_stream_enc &&
- pipe_ctx->link_res.hpo_dp_link_enc &&
- dc_is_dp_signal(pipe_ctx->stream->signal) &&
- (pipe_ctx->stream->link->remote_sinks[0]->sink_id == pipe_ctx->stream->sink->sink_id));
- }
-
return (pipe_ctx->stream_res.hpo_dp_stream_enc &&
pipe_ctx->link_res.hpo_dp_link_enc &&
dc_is_dp_signal(pipe_ctx->stream->signal));
@@ -421,7 +413,7 @@ unsigned int dml2_calc_max_scaled_time(
void dml2_extract_writeback_wm(struct dc_state *context, struct display_mode_lib_st *dml_core_ctx)
{
- int i, j = 0;;
+ int i, j = 0;
struct mcif_arb_params *wb_arb_params = NULL;
struct dcn_bw_writeback *bw_writeback = NULL;
enum mmhubbub_wbif_mode wbif_mode = PACKED_444_FP16; /*for now*/
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
index d5dcc8b77281..866b0abcff1b 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
@@ -575,7 +575,7 @@ static bool dml2_validate_and_build_resource(const struct dc *in_dc, struct dc_s
unsigned int lowest_state_idx = 0;
out_clks.p_state_supported = true;
- out_clks.dispclk_khz = (unsigned int)dml2->v20.dml_core_ctx.states.state_array[lowest_state_idx].dispclk_mhz * 1000;
+ out_clks.dispclk_khz = 0; /* No requirement, and lowest index will generally be maximum dispclk. */
out_clks.dcfclk_khz = (unsigned int)dml2->v20.dml_core_ctx.states.state_array[lowest_state_idx].dcfclk_mhz * 1000;
out_clks.fclk_khz = (unsigned int)dml2->v20.dml_core_ctx.states.state_array[lowest_state_idx].fabricclk_mhz * 1000;
out_clks.uclk_mts = (unsigned int)dml2->v20.dml_core_ctx.states.state_array[lowest_state_idx].dram_speed_mts;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
index 023325e8f6e2..0f944fcfd5a5 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
@@ -236,6 +236,7 @@ struct dml2_configuration_options {
bool use_clock_dc_limits;
bool gpuvm_enable;
+ bool force_tdlut_enable;
struct dml2_soc_bb *bb_from_dmub;
};
diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp_cm.c
index f2a2d53e9689..f8f6019d8304 100644
--- a/drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp_cm.c
@@ -684,9 +684,6 @@ void dpp1_set_degamma(
BREAK_TO_DEBUGGER();
break;
}
-
- REG_SEQ_SUBMIT();
- REG_SEQ_WAIT_DONE();
}
void dpp1_degamma_ram_select(
diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c
index e16274fee31d..8473c694bfdc 100644
--- a/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c
@@ -59,6 +59,31 @@ void dpp35_dppclk_control(
DISPCLK_R_GATE_DISABLE, 0);
}
+void dpp35_program_bias_and_scale_fcnv(
+ struct dpp *dpp_base,
+ struct dc_bias_and_scale *params)
+{
+ struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
+
+ if (!params->bias_and_scale_valid) {
+ REG_SET(FCNV_FP_BIAS_R, 0, FCNV_FP_BIAS_R, 0);
+ REG_SET(FCNV_FP_BIAS_G, 0, FCNV_FP_BIAS_G, 0);
+ REG_SET(FCNV_FP_BIAS_B, 0, FCNV_FP_BIAS_B, 0);
+
+ REG_SET(FCNV_FP_SCALE_R, 0, FCNV_FP_SCALE_R, 0x1F000);
+ REG_SET(FCNV_FP_SCALE_G, 0, FCNV_FP_SCALE_G, 0x1F000);
+ REG_SET(FCNV_FP_SCALE_B, 0, FCNV_FP_SCALE_B, 0x1F000);
+ } else {
+ REG_SET(FCNV_FP_BIAS_R, 0, FCNV_FP_BIAS_R, params->bias_red);
+ REG_SET(FCNV_FP_BIAS_G, 0, FCNV_FP_BIAS_G, params->bias_green);
+ REG_SET(FCNV_FP_BIAS_B, 0, FCNV_FP_BIAS_B, params->bias_blue);
+
+ REG_SET(FCNV_FP_SCALE_R, 0, FCNV_FP_SCALE_R, params->scale_red);
+ REG_SET(FCNV_FP_SCALE_G, 0, FCNV_FP_SCALE_G, params->scale_green);
+ REG_SET(FCNV_FP_SCALE_B, 0, FCNV_FP_SCALE_B, params->scale_blue);
+ }
+}
+
static struct dpp_funcs dcn35_dpp_funcs = {
.dpp_program_gamcor_lut = dpp3_program_gamcor_lut,
.dpp_read_state = dpp30_read_state,
@@ -81,7 +106,7 @@ static struct dpp_funcs dcn35_dpp_funcs = {
.dpp_program_shaper_lut = NULL, // CM SHAPER block is removed in DCN3.2 DPP, (it is in MPCC, programmable before or after BLND)
.dpp_program_3dlut = NULL, // CM 3DLUT block is removed in DCN3.2 DPP, (it is in MPCC, programmable before or after BLND)
- .dpp_program_bias_and_scale = NULL,
+ .dpp_program_bias_and_scale = dpp35_program_bias_and_scale_fcnv,
.dpp_cnv_set_alpha_keyer = dpp2_cnv_set_alpha_keyer,
.set_cursor_attributes = dpp3_set_cursor_attributes,
.set_cursor_position = dpp1_set_cursor_position,
diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.h b/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.h
index 135872d88219..3ca339a16e5b 100644
--- a/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.h
@@ -61,4 +61,7 @@ bool dpp35_construct(struct dcn3_dpp *dpp3, struct dc_context *ctx,
void dpp35_set_fgcg(struct dcn3_dpp *dpp, bool enable);
+void dpp35_program_bias_and_scale_fcnv(struct dpp *dpp_base,
+ struct dc_bias_and_scale *bias_and_scale);
+
#endif // __DCN35_DPP_H
diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.c
index 7cae18fd7be9..97bf26fa3573 100644
--- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.c
@@ -30,6 +30,7 @@
#include "basics/conversion.h"
#include "dcn30/dcn30_cm_common.h"
#include "dcn32/dcn32_dpp.h"
+#include "dcn35/dcn35_dpp.h"
#define REG(reg)\
dpp->tf_regs->reg
@@ -240,7 +241,7 @@ static struct dpp_funcs dcn401_dpp_funcs = {
.dpp_program_shaper_lut = NULL, // CM SHAPER block is removed in DCN3.2 DPP, (it is in MPCC, programmable before or after BLND)
.dpp_program_3dlut = NULL, // CM 3DLUT block is removed in DCN3.2 DPP, (it is in MPCC, programmable before or after BLND)
- .dpp_program_bias_and_scale = NULL,
+ .dpp_program_bias_and_scale = dpp35_program_bias_and_scale_fcnv,
.dpp_cnv_set_alpha_keyer = dpp2_cnv_set_alpha_keyer,
.set_cursor_attributes = dpp401_set_cursor_attributes,
.set_cursor_position = dpp401_set_cursor_position,
diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c
index d0f8c9ff5232..3b6ca7974e18 100644
--- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c
@@ -120,11 +120,10 @@ void dpp401_set_cursor_attributes(
enum dc_cursor_color_format color_format = cursor_attributes->color_format;
int cur_rom_en = 0;
+ // DCN4 should always do Cursor degamma for Cursor Color modes
if (color_format == CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA ||
color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA) {
- if (cursor_attributes->attribute_flags.bits.ENABLE_CURSOR_DEGAMMA) {
- cur_rom_en = 1;
- }
+ cur_rom_en = 1;
}
REG_UPDATE_3(CURSOR0_CONTROL,
@@ -246,16 +245,6 @@ void dpp401_set_cursor_matrix(
enum dc_color_space color_space,
struct dc_csc_transform cursor_csc_color_matrix)
{
- struct dpp_input_csc_matrix cursor_tbl_entry;
- unsigned int i;
-
- if (cursor_csc_color_matrix.enable_adjustment == true) {
- for (i = 0; i < 12; i++)
- cursor_tbl_entry.regval[i] = cursor_csc_color_matrix.matrix[i];
-
- cursor_tbl_entry.color_space = color_space;
- dpp401_program_cursor_csc(dpp_base, color_space, &cursor_tbl_entry);
- } else {
- dpp401_program_cursor_csc(dpp_base, color_space, NULL);
- }
+ //Since we don't have cursor matrix information, force bypass mode by passing in unknown color space
+ dpp401_program_cursor_csc(dpp_base, COLOR_SPACE_UNKNOWN, NULL);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c
index 505929800426..5105fd580017 100644
--- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c
+++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c
@@ -280,7 +280,8 @@ static void dpp401_dscl_set_scaler_filter(
static void dpp401_dscl_set_scl_filter(
struct dcn401_dpp *dpp,
const struct scaler_data *scl_data,
- bool chroma_coef_mode)
+ bool chroma_coef_mode,
+ bool force_coeffs_update)
{
bool h_2tap_hardcode_coef_en = false;
bool v_2tap_hardcode_coef_en = false;
@@ -343,7 +344,7 @@ static void dpp401_dscl_set_scl_filter(
|| (filter_v_c && (filter_v_c != dpp->filter_v_c));
}
- if (filter_updated) {
+ if ((filter_updated) || (force_coeffs_update)) {
uint32_t scl_mode = REG_READ(SCL_MODE);
if (!h_2tap_hardcode_coef_en && filter_h) {
@@ -656,274 +657,252 @@ static void dpp401_dscl_set_recout(struct dcn401_dpp *dpp,
RECOUT_HEIGHT, recout->height);
}
/**
- * dpp401_dscl_program_easf - Program EASF
+ * dpp401_dscl_program_easf_v - Program EASF_V
*
* @dpp_base: High level DPP struct
* @scl_data: scalaer_data info
*
- * This is the primary function to program EASF
+ * This is the primary function to program vertical EASF registers
*
*/
-static void dpp401_dscl_program_easf(struct dpp *dpp_base, const struct scaler_data *scl_data)
+static void dpp401_dscl_program_easf_v(struct dpp *dpp_base, const struct scaler_data *scl_data)
{
struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
PERF_TRACE();
- REG_UPDATE(DSCL_SC_MODE,
- SCL_SC_MATRIX_MODE, scl_data->dscl_prog_data.easf_matrix_mode);
- REG_UPDATE(DSCL_SC_MODE,
- SCL_SC_LTONL_EN, scl_data->dscl_prog_data.easf_ltonl_en);
/* DSCL_EASF_V_MODE */
- REG_UPDATE(DSCL_EASF_V_MODE,
- SCL_EASF_V_EN, scl_data->dscl_prog_data.easf_v_en);
- REG_UPDATE(DSCL_EASF_V_MODE,
- SCL_EASF_V_2TAP_SHARP_FACTOR, scl_data->dscl_prog_data.easf_v_sharp_factor);
- REG_UPDATE(DSCL_EASF_V_MODE,
+ REG_SET_3(DSCL_EASF_V_MODE, 0,
+ SCL_EASF_V_EN, scl_data->dscl_prog_data.easf_v_en,
+ SCL_EASF_V_2TAP_SHARP_FACTOR, scl_data->dscl_prog_data.easf_v_sharp_factor,
SCL_EASF_V_RINGEST_FORCE_EN, scl_data->dscl_prog_data.easf_v_ring);
- REG_UPDATE(DSCL_EASF_V_BF_CNTL,
- SCL_EASF_V_BF1_EN, scl_data->dscl_prog_data.easf_v_bf1_en);
- REG_UPDATE(DSCL_EASF_V_BF_CNTL,
- SCL_EASF_V_BF2_MODE, scl_data->dscl_prog_data.easf_v_bf2_mode);
- REG_UPDATE(DSCL_EASF_V_BF_CNTL,
- SCL_EASF_V_BF3_MODE, scl_data->dscl_prog_data.easf_v_bf3_mode);
- REG_UPDATE(DSCL_EASF_V_BF_CNTL,
- SCL_EASF_V_BF2_FLAT1_GAIN, scl_data->dscl_prog_data.easf_v_bf2_flat1_gain);
- REG_UPDATE(DSCL_EASF_V_BF_CNTL,
- SCL_EASF_V_BF2_FLAT2_GAIN, scl_data->dscl_prog_data.easf_v_bf2_flat2_gain);
- REG_UPDATE(DSCL_EASF_V_BF_CNTL,
+
+ if (!scl_data->dscl_prog_data.easf_v_en) {
+ PERF_TRACE();
+ return;
+ }
+
+ /* DSCL_EASF_V_BF_CNTL */
+ REG_SET_6(DSCL_EASF_V_BF_CNTL, 0,
+ SCL_EASF_V_BF1_EN, scl_data->dscl_prog_data.easf_v_bf1_en,
+ SCL_EASF_V_BF2_MODE, scl_data->dscl_prog_data.easf_v_bf2_mode,
+ SCL_EASF_V_BF3_MODE, scl_data->dscl_prog_data.easf_v_bf3_mode,
+ SCL_EASF_V_BF2_FLAT1_GAIN, scl_data->dscl_prog_data.easf_v_bf2_flat1_gain,
+ SCL_EASF_V_BF2_FLAT2_GAIN, scl_data->dscl_prog_data.easf_v_bf2_flat2_gain,
SCL_EASF_V_BF2_ROC_GAIN, scl_data->dscl_prog_data.easf_v_bf2_roc_gain);
- REG_UPDATE(DSCL_EASF_V_RINGEST_3TAP_CNTL1,
- SCL_EASF_V_RINGEST_3TAP_DNTILT_UPTILT, scl_data->dscl_prog_data.easf_v_ringest_3tap_dntilt_uptilt);
- REG_UPDATE(DSCL_EASF_V_RINGEST_3TAP_CNTL1,
+ /* DSCL_EASF_V_RINGEST_3TAP_CNTLn */
+ REG_SET_2(DSCL_EASF_V_RINGEST_3TAP_CNTL1, 0,
+ SCL_EASF_V_RINGEST_3TAP_DNTILT_UPTILT, scl_data->dscl_prog_data.easf_v_ringest_3tap_dntilt_uptilt,
SCL_EASF_V_RINGEST_3TAP_UPTILT_MAXVAL, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt_max);
- REG_UPDATE(DSCL_EASF_V_RINGEST_3TAP_CNTL2,
- SCL_EASF_V_RINGEST_3TAP_DNTILT_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_dntilt_slope);
- REG_UPDATE(DSCL_EASF_V_RINGEST_3TAP_CNTL2,
+ REG_SET_2(DSCL_EASF_V_RINGEST_3TAP_CNTL2, 0,
+ SCL_EASF_V_RINGEST_3TAP_DNTILT_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_dntilt_slope,
SCL_EASF_V_RINGEST_3TAP_UPTILT1_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt1_slope);
- REG_UPDATE(DSCL_EASF_V_RINGEST_3TAP_CNTL3,
- SCL_EASF_V_RINGEST_3TAP_UPTILT2_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt2_slope);
- REG_UPDATE(DSCL_EASF_V_RINGEST_3TAP_CNTL3,
+ REG_SET_2(DSCL_EASF_V_RINGEST_3TAP_CNTL3, 0,
+ SCL_EASF_V_RINGEST_3TAP_UPTILT2_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt2_slope,
SCL_EASF_V_RINGEST_3TAP_UPTILT2_OFFSET, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt2_offset);
- REG_UPDATE(DSCL_EASF_V_RINGEST_EVENTAP_REDUCE,
- SCL_EASF_V_RINGEST_EVENTAP_REDUCEG1, scl_data->dscl_prog_data.easf_v_ringest_eventap_reduceg1);
- REG_UPDATE(DSCL_EASF_V_RINGEST_EVENTAP_REDUCE,
+ /* DSCL_EASF_V_RINGEST_EVENTAP_REDUCE */
+ REG_SET_2(DSCL_EASF_V_RINGEST_EVENTAP_REDUCE, 0,
+ SCL_EASF_V_RINGEST_EVENTAP_REDUCEG1, scl_data->dscl_prog_data.easf_v_ringest_eventap_reduceg1,
SCL_EASF_V_RINGEST_EVENTAP_REDUCEG2, scl_data->dscl_prog_data.easf_v_ringest_eventap_reduceg2);
- REG_UPDATE(DSCL_EASF_V_RINGEST_EVENTAP_GAIN,
- SCL_EASF_V_RINGEST_EVENTAP_GAIN1, scl_data->dscl_prog_data.easf_v_ringest_eventap_gain1);
- REG_UPDATE(DSCL_EASF_V_RINGEST_EVENTAP_GAIN,
+ /* DSCL_EASF_V_RINGEST_EVENTAP_GAIN */
+ REG_SET_2(DSCL_EASF_V_RINGEST_EVENTAP_GAIN, 0,
+ SCL_EASF_V_RINGEST_EVENTAP_GAIN1, scl_data->dscl_prog_data.easf_v_ringest_eventap_gain1,
SCL_EASF_V_RINGEST_EVENTAP_GAIN2, scl_data->dscl_prog_data.easf_v_ringest_eventap_gain2);
- REG_UPDATE(DSCL_EASF_V_BF_FINAL_MAX_MIN,
- SCL_EASF_V_BF_MAXA, scl_data->dscl_prog_data.easf_v_bf_maxa);
- REG_UPDATE(DSCL_EASF_V_BF_FINAL_MAX_MIN,
- SCL_EASF_V_BF_MAXB, scl_data->dscl_prog_data.easf_v_bf_maxb);
- REG_UPDATE(DSCL_EASF_V_BF_FINAL_MAX_MIN,
- SCL_EASF_V_BF_MINA, scl_data->dscl_prog_data.easf_v_bf_mina);
- REG_UPDATE(DSCL_EASF_V_BF_FINAL_MAX_MIN,
+ /* DSCL_EASF_V_BF_FINAL_MAX_MIN */
+ REG_SET_4(DSCL_EASF_V_BF_FINAL_MAX_MIN, 0,
+ SCL_EASF_V_BF_MAXA, scl_data->dscl_prog_data.easf_v_bf_maxa,
+ SCL_EASF_V_BF_MAXB, scl_data->dscl_prog_data.easf_v_bf_maxb,
+ SCL_EASF_V_BF_MINA, scl_data->dscl_prog_data.easf_v_bf_mina,
SCL_EASF_V_BF_MINB, scl_data->dscl_prog_data.easf_v_bf_minb);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG0,
- SCL_EASF_V_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg0);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG0,
- SCL_EASF_V_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg0);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG0,
+ /* DSCL_EASF_V_BF1_PWL_SEGn */
+ REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG0, 0,
+ SCL_EASF_V_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg0,
+ SCL_EASF_V_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg0,
SCL_EASF_V_BF1_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg0);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG1,
- SCL_EASF_V_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg1);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG1,
- SCL_EASF_V_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg1);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG1,
+ REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG1, 0,
+ SCL_EASF_V_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg1,
+ SCL_EASF_V_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg1,
SCL_EASF_V_BF1_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg1);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG2,
- SCL_EASF_V_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg2);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG2,
- SCL_EASF_V_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg2);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG2,
+ REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG2, 0,
+ SCL_EASF_V_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg2,
+ SCL_EASF_V_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg2,
SCL_EASF_V_BF1_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg2);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG3,
- SCL_EASF_V_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg3);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG3,
- SCL_EASF_V_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg3);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG3,
+ REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG3, 0,
+ SCL_EASF_V_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg3,
+ SCL_EASF_V_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg3,
SCL_EASF_V_BF1_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg3);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG4,
- SCL_EASF_V_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg4);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG4,
- SCL_EASF_V_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg4);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG4,
+ REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG4, 0,
+ SCL_EASF_V_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg4,
+ SCL_EASF_V_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg4,
SCL_EASF_V_BF1_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg4);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG5,
- SCL_EASF_V_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg5);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG5,
- SCL_EASF_V_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg5);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG5,
+ REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG5, 0,
+ SCL_EASF_V_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg5,
+ SCL_EASF_V_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg5,
SCL_EASF_V_BF1_PWL_SLOPE_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg5);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG6,
- SCL_EASF_V_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg6);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG6,
- SCL_EASF_V_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg6);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG6,
+ REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG6, 0,
+ SCL_EASF_V_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg6,
+ SCL_EASF_V_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg6,
SCL_EASF_V_BF1_PWL_SLOPE_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg6);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG7,
- SCL_EASF_V_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg7);
- REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG7,
+ REG_SET_2(DSCL_EASF_V_BF1_PWL_SEG7, 0,
+ SCL_EASF_V_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg7,
SCL_EASF_V_BF1_PWL_BASE_SEG7, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg7);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG0,
- SCL_EASF_V_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set0);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG0,
- SCL_EASF_V_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set0);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG0,
+ /* DSCL_EASF_V_BF3_PWL_SEGn */
+ REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG0, 0,
+ SCL_EASF_V_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set0,
+ SCL_EASF_V_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set0,
SCL_EASF_V_BF3_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set0);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG1,
- SCL_EASF_V_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set1);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG1,
- SCL_EASF_V_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set1);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG1,
+ REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG1, 0,
+ SCL_EASF_V_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set1,
+ SCL_EASF_V_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set1,
SCL_EASF_V_BF3_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set1);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG2,
- SCL_EASF_V_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set2);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG2,
- SCL_EASF_V_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set2);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG2,
+ REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG2, 0,
+ SCL_EASF_V_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set2,
+ SCL_EASF_V_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set2,
SCL_EASF_V_BF3_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set2);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG3,
- SCL_EASF_V_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set3);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG3,
- SCL_EASF_V_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set3);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG3,
+ REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG3, 0,
+ SCL_EASF_V_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set3,
+ SCL_EASF_V_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set3,
SCL_EASF_V_BF3_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set3);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG4,
- SCL_EASF_V_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set4);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG4,
- SCL_EASF_V_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set4);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG4,
+ REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG4, 0,
+ SCL_EASF_V_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set4,
+ SCL_EASF_V_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set4,
SCL_EASF_V_BF3_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set4);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG5,
- SCL_EASF_V_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set5);
- REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG5,
+ REG_SET_2(DSCL_EASF_V_BF3_PWL_SEG5, 0,
+ SCL_EASF_V_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set5,
SCL_EASF_V_BF3_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set5);
+ PERF_TRACE();
+}
+/**
+ * dpp401_dscl_program_easf_h - Program EASF_H
+ *
+ * @dpp_base: High level DPP struct
+ * @scl_data: scalaer_data info
+ *
+ * This is the primary function to program horizontal EASF registers
+ *
+ */
+static void dpp401_dscl_program_easf_h(struct dpp *dpp_base, const struct scaler_data *scl_data)
+{
+ struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
+
+ PERF_TRACE();
/* DSCL_EASF_H_MODE */
- REG_UPDATE(DSCL_EASF_H_MODE,
- SCL_EASF_H_EN, scl_data->dscl_prog_data.easf_h_en);
- REG_UPDATE(DSCL_EASF_H_MODE,
- SCL_EASF_H_2TAP_SHARP_FACTOR, scl_data->dscl_prog_data.easf_h_sharp_factor);
- REG_UPDATE(DSCL_EASF_H_MODE,
+ REG_SET_3(DSCL_EASF_H_MODE, 0,
+ SCL_EASF_H_EN, scl_data->dscl_prog_data.easf_h_en,
+ SCL_EASF_H_2TAP_SHARP_FACTOR, scl_data->dscl_prog_data.easf_h_sharp_factor,
SCL_EASF_H_RINGEST_FORCE_EN, scl_data->dscl_prog_data.easf_h_ring);
- REG_UPDATE(DSCL_EASF_H_BF_CNTL,
- SCL_EASF_H_BF1_EN, scl_data->dscl_prog_data.easf_h_bf1_en);
- REG_UPDATE(DSCL_EASF_H_BF_CNTL,
- SCL_EASF_H_BF2_MODE, scl_data->dscl_prog_data.easf_h_bf2_mode);
- REG_UPDATE(DSCL_EASF_H_BF_CNTL,
- SCL_EASF_H_BF3_MODE, scl_data->dscl_prog_data.easf_h_bf3_mode);
- REG_UPDATE(DSCL_EASF_H_BF_CNTL,
- SCL_EASF_H_BF2_FLAT1_GAIN, scl_data->dscl_prog_data.easf_h_bf2_flat1_gain);
- REG_UPDATE(DSCL_EASF_H_BF_CNTL,
- SCL_EASF_H_BF2_FLAT2_GAIN, scl_data->dscl_prog_data.easf_h_bf2_flat2_gain);
- REG_UPDATE(DSCL_EASF_H_BF_CNTL,
+
+ if (!scl_data->dscl_prog_data.easf_h_en) {
+ PERF_TRACE();
+ return;
+ }
+
+ /* DSCL_EASF_H_BF_CNTL */
+ REG_SET_6(DSCL_EASF_H_BF_CNTL, 0,
+ SCL_EASF_H_BF1_EN, scl_data->dscl_prog_data.easf_h_bf1_en,
+ SCL_EASF_H_BF2_MODE, scl_data->dscl_prog_data.easf_h_bf2_mode,
+ SCL_EASF_H_BF3_MODE, scl_data->dscl_prog_data.easf_h_bf3_mode,
+ SCL_EASF_H_BF2_FLAT1_GAIN, scl_data->dscl_prog_data.easf_h_bf2_flat1_gain,
+ SCL_EASF_H_BF2_FLAT2_GAIN, scl_data->dscl_prog_data.easf_h_bf2_flat2_gain,
SCL_EASF_H_BF2_ROC_GAIN, scl_data->dscl_prog_data.easf_h_bf2_roc_gain);
- REG_UPDATE(DSCL_EASF_H_RINGEST_EVENTAP_REDUCE,
- SCL_EASF_H_RINGEST_EVENTAP_REDUCEG1, scl_data->dscl_prog_data.easf_h_ringest_eventap_reduceg1);
- REG_UPDATE(DSCL_EASF_H_RINGEST_EVENTAP_REDUCE,
+ /* DSCL_EASF_H_RINGEST_EVENTAP_REDUCE */
+ REG_SET_2(DSCL_EASF_H_RINGEST_EVENTAP_REDUCE, 0,
+ SCL_EASF_H_RINGEST_EVENTAP_REDUCEG1, scl_data->dscl_prog_data.easf_h_ringest_eventap_reduceg1,
SCL_EASF_H_RINGEST_EVENTAP_REDUCEG2, scl_data->dscl_prog_data.easf_h_ringest_eventap_reduceg2);
- REG_UPDATE(DSCL_EASF_H_RINGEST_EVENTAP_GAIN,
- SCL_EASF_H_RINGEST_EVENTAP_GAIN1, scl_data->dscl_prog_data.easf_h_ringest_eventap_gain1);
- REG_UPDATE(DSCL_EASF_H_RINGEST_EVENTAP_GAIN,
+ /* DSCL_EASF_H_RINGEST_EVENTAP_GAIN */
+ REG_SET_2(DSCL_EASF_H_RINGEST_EVENTAP_GAIN, 0,
+ SCL_EASF_H_RINGEST_EVENTAP_GAIN1, scl_data->dscl_prog_data.easf_h_ringest_eventap_gain1,
SCL_EASF_H_RINGEST_EVENTAP_GAIN2, scl_data->dscl_prog_data.easf_h_ringest_eventap_gain2);
- REG_UPDATE(DSCL_EASF_H_BF_FINAL_MAX_MIN,
- SCL_EASF_H_BF_MAXA, scl_data->dscl_prog_data.easf_h_bf_maxa);
- REG_UPDATE(DSCL_EASF_H_BF_FINAL_MAX_MIN,
- SCL_EASF_H_BF_MAXB, scl_data->dscl_prog_data.easf_h_bf_maxb);
- REG_UPDATE(DSCL_EASF_H_BF_FINAL_MAX_MIN,
- SCL_EASF_H_BF_MINA, scl_data->dscl_prog_data.easf_h_bf_mina);
- REG_UPDATE(DSCL_EASF_H_BF_FINAL_MAX_MIN,
+ /* DSCL_EASF_H_BF_FINAL_MAX_MIN */
+ REG_SET_4(DSCL_EASF_H_BF_FINAL_MAX_MIN, 0,
+ SCL_EASF_H_BF_MAXA, scl_data->dscl_prog_data.easf_h_bf_maxa,
+ SCL_EASF_H_BF_MAXB, scl_data->dscl_prog_data.easf_h_bf_maxb,
+ SCL_EASF_H_BF_MINA, scl_data->dscl_prog_data.easf_h_bf_mina,
SCL_EASF_H_BF_MINB, scl_data->dscl_prog_data.easf_h_bf_minb);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG0,
- SCL_EASF_H_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg0);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG0,
- SCL_EASF_H_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg0);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG0,
+ /* DSCL_EASF_H_BF1_PWL_SEGn */
+ REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG0, 0,
+ SCL_EASF_H_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg0,
+ SCL_EASF_H_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg0,
SCL_EASF_H_BF1_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg0);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG1,
- SCL_EASF_H_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg1);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG1,
- SCL_EASF_H_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg1);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG1,
+ REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG1, 0,
+ SCL_EASF_H_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg1,
+ SCL_EASF_H_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg1,
SCL_EASF_H_BF1_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg1);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG2,
- SCL_EASF_H_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg2);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG2,
- SCL_EASF_H_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg2);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG2,
+ REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG2, 0,
+ SCL_EASF_H_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg2,
+ SCL_EASF_H_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg2,
SCL_EASF_H_BF1_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg2);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG3,
- SCL_EASF_H_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg3);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG3,
- SCL_EASF_H_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg3);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG3,
+ REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG3, 0,
+ SCL_EASF_H_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg3,
+ SCL_EASF_H_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg3,
SCL_EASF_H_BF1_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg3);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG4,
- SCL_EASF_H_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg4);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG4,
- SCL_EASF_H_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg4);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG4,
+ REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG4, 0,
+ SCL_EASF_H_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg4,
+ SCL_EASF_H_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg4,
SCL_EASF_H_BF1_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg4);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG5,
- SCL_EASF_H_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg5);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG5,
- SCL_EASF_H_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg5);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG5,
+ REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG5, 0,
+ SCL_EASF_H_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg5,
+ SCL_EASF_H_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg5,
SCL_EASF_H_BF1_PWL_SLOPE_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg5);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG6,
- SCL_EASF_H_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg6);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG6,
- SCL_EASF_H_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg6);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG6,
+ REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG6, 0,
+ SCL_EASF_H_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg6,
+ SCL_EASF_H_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg6,
SCL_EASF_H_BF1_PWL_SLOPE_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg6);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG7,
- SCL_EASF_H_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg7);
- REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG7,
+ REG_SET_2(DSCL_EASF_H_BF1_PWL_SEG7, 0,
+ SCL_EASF_H_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg7,
SCL_EASF_H_BF1_PWL_BASE_SEG7, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg7);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG0,
- SCL_EASF_H_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set0);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG0,
- SCL_EASF_H_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set0);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG0,
+ /* DSCL_EASF_H_BF3_PWL_SEGn */
+ REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG0, 0,
+ SCL_EASF_H_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set0,
+ SCL_EASF_H_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set0,
SCL_EASF_H_BF3_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set0);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG1,
- SCL_EASF_H_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set1);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG1,
- SCL_EASF_H_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set1);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG1,
+ REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG1, 0,
+ SCL_EASF_H_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set1,
+ SCL_EASF_H_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set1,
SCL_EASF_H_BF3_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set1);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG2,
- SCL_EASF_H_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set2);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG2,
- SCL_EASF_H_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set2);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG2,
+ REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG2, 0,
+ SCL_EASF_H_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set2,
+ SCL_EASF_H_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set2,
SCL_EASF_H_BF3_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set2);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG3,
- SCL_EASF_H_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set3);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG3,
- SCL_EASF_H_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set3);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG3,
+ REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG3, 0,
+ SCL_EASF_H_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set3,
+ SCL_EASF_H_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set3,
SCL_EASF_H_BF3_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set3);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG4,
- SCL_EASF_H_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set4);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG4,
- SCL_EASF_H_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set4);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG4,
+ REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG4, 0,
+ SCL_EASF_H_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set4,
+ SCL_EASF_H_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set4,
SCL_EASF_H_BF3_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set4);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG5,
- SCL_EASF_H_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set5);
- REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG5,
+ REG_SET_2(DSCL_EASF_H_BF3_PWL_SEG5, 0,
+ SCL_EASF_H_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set5,
SCL_EASF_H_BF3_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set5);
+ PERF_TRACE();
+}
+/**
+ * dpp401_dscl_program_easf - Program EASF
+ *
+ * @dpp_base: High level DPP struct
+ * @scl_data: scalaer_data info
+ *
+ * This is the primary function to program EASF
+ *
+ */
+static void dpp401_dscl_program_easf(struct dpp *dpp_base, const struct scaler_data *scl_data)
+{
+ struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
+
+ PERF_TRACE();
+ /* DSCL_SC_MODE */
+ REG_SET_2(DSCL_SC_MODE, 0,
+ SCL_SC_MATRIX_MODE, scl_data->dscl_prog_data.easf_matrix_mode,
+ SCL_SC_LTONL_EN, scl_data->dscl_prog_data.easf_ltonl_en);
/* DSCL_EASF_SC_MATRIX_C0C1, DSCL_EASF_SC_MATRIX_C2C3 */
- REG_UPDATE(DSCL_SC_MATRIX_C0C1,
- SCL_SC_MATRIX_C0, scl_data->dscl_prog_data.easf_matrix_c0);
- REG_UPDATE(DSCL_SC_MATRIX_C0C1,
+ REG_SET_2(DSCL_SC_MATRIX_C0C1, 0,
+ SCL_SC_MATRIX_C0, scl_data->dscl_prog_data.easf_matrix_c0,
SCL_SC_MATRIX_C1, scl_data->dscl_prog_data.easf_matrix_c1);
- REG_UPDATE(DSCL_SC_MATRIX_C2C3,
- SCL_SC_MATRIX_C2, scl_data->dscl_prog_data.easf_matrix_c2);
- REG_UPDATE(DSCL_SC_MATRIX_C2C3,
+ REG_SET_2(DSCL_SC_MATRIX_C2C3, 0,
+ SCL_SC_MATRIX_C2, scl_data->dscl_prog_data.easf_matrix_c2,
SCL_SC_MATRIX_C3, scl_data->dscl_prog_data.easf_matrix_c3);
+ dpp401_dscl_program_easf_v(dpp_base, scl_data);
+ dpp401_dscl_program_easf_h(dpp_base, scl_data);
PERF_TRACE();
}
/**
@@ -958,10 +937,11 @@ static void dpp401_dscl_set_isharp_filter(
REG_UPDATE(ISHARP_DELTA_CTRL,
ISHARP_DELTA_LUT_HOST_SELECT, 0);
+ /* LUT data write is auto-indexed. Write index once */
+ REG_SET(ISHARP_DELTA_INDEX, 0,
+ ISHARP_DELTA_INDEX, 0);
for (level = 0; level < NUM_LEVELS; level++) {
filter_data = filter[level];
- REG_SET(ISHARP_DELTA_INDEX, 0,
- ISHARP_DELTA_INDEX, level);
REG_SET(ISHARP_DELTA_DATA, 0,
ISHARP_DELTA_DATA, filter_data);
}
@@ -971,112 +951,83 @@ static void dpp401_dscl_set_isharp_filter(
*
* @dpp_base: High level DPP struct
* @scl_data: scalaer_data info
+ * @program_isharp_1dlut: flag to program isharp 1D LUT
+ * @bs_coeffs_updated: Blur and Scale Coefficients update flag
*
* This is the primary function to program isharp
*
*/
static void dpp401_dscl_program_isharp(struct dpp *dpp_base,
- const struct scaler_data *scl_data)
+ const struct scaler_data *scl_data,
+ bool program_isharp_1dlut,
+ bool *bs_coeffs_updated)
{
struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
+ *bs_coeffs_updated = false;
PERF_TRACE();
- /* ISHARP_EN */
- REG_UPDATE(ISHARP_MODE,
- ISHARP_EN, scl_data->dscl_prog_data.isharp_en);
- /* ISHARP_NOISEDET_EN */
- REG_UPDATE(ISHARP_MODE,
- ISHARP_NOISEDET_EN, scl_data->dscl_prog_data.isharp_noise_det.enable);
- /* ISHARP_NOISEDET_MODE */
- REG_UPDATE(ISHARP_MODE,
- ISHARP_NOISEDET_MODE, scl_data->dscl_prog_data.isharp_noise_det.mode);
- /* ISHARP_NOISEDET_UTHRE */
- REG_UPDATE(ISHARP_NOISEDET_THRESHOLD,
- ISHARP_NOISEDET_UTHRE, scl_data->dscl_prog_data.isharp_noise_det.uthreshold);
- /* ISHARP_NOISEDET_DTHRE */
- REG_UPDATE(ISHARP_NOISEDET_THRESHOLD,
- ISHARP_NOISEDET_DTHRE, scl_data->dscl_prog_data.isharp_noise_det.dthreshold);
- REG_UPDATE(ISHARP_MODE,
- ISHARP_NOISEDET_MODE, scl_data->dscl_prog_data.isharp_noise_det.mode);
- /* ISHARP_NOISEDET_UTHRE */
- REG_UPDATE(ISHARP_NOISEDET_THRESHOLD,
- ISHARP_NOISEDET_UTHRE, scl_data->dscl_prog_data.isharp_noise_det.uthreshold);
- /* ISHARP_NOISEDET_DTHRE */
- REG_UPDATE(ISHARP_NOISEDET_THRESHOLD,
+ /* ISHARP_MODE */
+ REG_SET_6(ISHARP_MODE, 0,
+ ISHARP_EN, scl_data->dscl_prog_data.isharp_en,
+ ISHARP_NOISEDET_EN, scl_data->dscl_prog_data.isharp_noise_det.enable,
+ ISHARP_NOISEDET_MODE, scl_data->dscl_prog_data.isharp_noise_det.mode,
+ ISHARP_LBA_MODE, scl_data->dscl_prog_data.isharp_lba.mode,
+ ISHARP_FMT_MODE, scl_data->dscl_prog_data.isharp_fmt.mode,
+ ISHARP_FMT_NORM, scl_data->dscl_prog_data.isharp_fmt.norm);
+
+ /* Skip remaining register programming if ISHARP is disabled */
+ if (!scl_data->dscl_prog_data.isharp_en) {
+ PERF_TRACE();
+ return;
+ }
+
+ /* ISHARP_NOISEDET_THRESHOLD */
+ REG_SET_2(ISHARP_NOISEDET_THRESHOLD, 0,
+ ISHARP_NOISEDET_UTHRE, scl_data->dscl_prog_data.isharp_noise_det.uthreshold,
ISHARP_NOISEDET_DTHRE, scl_data->dscl_prog_data.isharp_noise_det.dthreshold);
- /* ISHARP_NOISEDET_PWL_START_IN */
- REG_UPDATE(ISHARP_NOISE_GAIN_PWL,
- ISHARP_NOISEDET_PWL_START_IN, scl_data->dscl_prog_data.isharp_noise_det.pwl_start_in);
- /* ISHARP_NOISEDET_PWL_END_IN */
- REG_UPDATE(ISHARP_NOISE_GAIN_PWL,
- ISHARP_NOISEDET_PWL_END_IN, scl_data->dscl_prog_data.isharp_noise_det.pwl_end_in);
- /* ISHARP_NOISEDET_PWL_SLOPE */
- REG_UPDATE(ISHARP_NOISE_GAIN_PWL,
+
+ /* ISHARP_NOISE_GAIN_PWL */
+ REG_SET_3(ISHARP_NOISE_GAIN_PWL, 0,
+ ISHARP_NOISEDET_PWL_START_IN, scl_data->dscl_prog_data.isharp_noise_det.pwl_start_in,
+ ISHARP_NOISEDET_PWL_END_IN, scl_data->dscl_prog_data.isharp_noise_det.pwl_end_in,
ISHARP_NOISEDET_PWL_SLOPE, scl_data->dscl_prog_data.isharp_noise_det.pwl_slope);
- /* ISHARP_LBA_MODE */
- REG_UPDATE(ISHARP_MODE,
- ISHARP_LBA_MODE, scl_data->dscl_prog_data.isharp_lba.mode);
+
/* ISHARP_LBA: IN_SEG, BASE_SEG, SLOPE_SEG */
- REG_UPDATE(ISHARP_LBA_PWL_SEG0,
- ISHARP_LBA_PWL_IN_SEG0, scl_data->dscl_prog_data.isharp_lba.in_seg[0]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG0,
- ISHARP_LBA_PWL_BASE_SEG0, scl_data->dscl_prog_data.isharp_lba.base_seg[0]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG0,
+ REG_SET_3(ISHARP_LBA_PWL_SEG0, 0,
+ ISHARP_LBA_PWL_IN_SEG0, scl_data->dscl_prog_data.isharp_lba.in_seg[0],
+ ISHARP_LBA_PWL_BASE_SEG0, scl_data->dscl_prog_data.isharp_lba.base_seg[0],
ISHARP_LBA_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.isharp_lba.slope_seg[0]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG1,
- ISHARP_LBA_PWL_IN_SEG1, scl_data->dscl_prog_data.isharp_lba.in_seg[1]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG1,
- ISHARP_LBA_PWL_BASE_SEG1, scl_data->dscl_prog_data.isharp_lba.base_seg[1]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG1,
+ REG_SET_3(ISHARP_LBA_PWL_SEG1, 0,
+ ISHARP_LBA_PWL_IN_SEG1, scl_data->dscl_prog_data.isharp_lba.in_seg[1],
+ ISHARP_LBA_PWL_BASE_SEG1, scl_data->dscl_prog_data.isharp_lba.base_seg[1],
ISHARP_LBA_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.isharp_lba.slope_seg[1]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG2,
- ISHARP_LBA_PWL_IN_SEG2, scl_data->dscl_prog_data.isharp_lba.in_seg[2]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG2,
- ISHARP_LBA_PWL_BASE_SEG2, scl_data->dscl_prog_data.isharp_lba.base_seg[2]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG2,
+ REG_SET_3(ISHARP_LBA_PWL_SEG2, 0,
+ ISHARP_LBA_PWL_IN_SEG2, scl_data->dscl_prog_data.isharp_lba.in_seg[2],
+ ISHARP_LBA_PWL_BASE_SEG2, scl_data->dscl_prog_data.isharp_lba.base_seg[2],
ISHARP_LBA_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.isharp_lba.slope_seg[2]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG3,
- ISHARP_LBA_PWL_IN_SEG3, scl_data->dscl_prog_data.isharp_lba.in_seg[3]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG3,
- ISHARP_LBA_PWL_BASE_SEG3, scl_data->dscl_prog_data.isharp_lba.base_seg[3]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG3,
+ REG_SET_3(ISHARP_LBA_PWL_SEG3, 0,
+ ISHARP_LBA_PWL_IN_SEG3, scl_data->dscl_prog_data.isharp_lba.in_seg[3],
+ ISHARP_LBA_PWL_BASE_SEG3, scl_data->dscl_prog_data.isharp_lba.base_seg[3],
ISHARP_LBA_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.isharp_lba.slope_seg[3]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG4,
- ISHARP_LBA_PWL_IN_SEG4, scl_data->dscl_prog_data.isharp_lba.in_seg[4]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG4,
- ISHARP_LBA_PWL_BASE_SEG4, scl_data->dscl_prog_data.isharp_lba.base_seg[4]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG4,
+ REG_SET_3(ISHARP_LBA_PWL_SEG4, 0,
+ ISHARP_LBA_PWL_IN_SEG4, scl_data->dscl_prog_data.isharp_lba.in_seg[4],
+ ISHARP_LBA_PWL_BASE_SEG4, scl_data->dscl_prog_data.isharp_lba.base_seg[4],
ISHARP_LBA_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.isharp_lba.slope_seg[4]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG5,
- ISHARP_LBA_PWL_IN_SEG5, scl_data->dscl_prog_data.isharp_lba.in_seg[5]);
- REG_UPDATE(ISHARP_LBA_PWL_SEG5,
+ REG_SET_2(ISHARP_LBA_PWL_SEG5, 0,
+ ISHARP_LBA_PWL_IN_SEG5, scl_data->dscl_prog_data.isharp_lba.in_seg[5],
ISHARP_LBA_PWL_BASE_SEG5, scl_data->dscl_prog_data.isharp_lba.base_seg[5]);
- /* ISHARP_FMT_MODE */
- REG_UPDATE(ISHARP_MODE,
- ISHARP_FMT_MODE, scl_data->dscl_prog_data.isharp_fmt.mode);
- /* ISHARP_FMT_NORM */
- REG_UPDATE(ISHARP_MODE,
- ISHARP_FMT_NORM, scl_data->dscl_prog_data.isharp_fmt.norm);
/* ISHARP_DELTA_LUT */
- dpp401_dscl_set_isharp_filter(dpp, scl_data->dscl_prog_data.isharp_delta);
- /* ISHARP_NLDELTA_SCLIP_EN_P */
- REG_UPDATE(ISHARP_NLDELTA_SOFT_CLIP,
- ISHARP_NLDELTA_SCLIP_EN_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.enable_p);
- /* ISHARP_NLDELTA_SCLIP_PIVOT_P */
- REG_UPDATE(ISHARP_NLDELTA_SOFT_CLIP,
- ISHARP_NLDELTA_SCLIP_PIVOT_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.pivot_p);
- /* ISHARP_NLDELTA_SCLIP_SLOPE_P */
- REG_UPDATE(ISHARP_NLDELTA_SOFT_CLIP,
- ISHARP_NLDELTA_SCLIP_SLOPE_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.slope_p);
- /* ISHARP_NLDELTA_SCLIP_EN_N */
- REG_UPDATE(ISHARP_NLDELTA_SOFT_CLIP,
- ISHARP_NLDELTA_SCLIP_EN_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.enable_n);
- /* ISHARP_NLDELTA_SCLIP_PIVOT_N */
- REG_UPDATE(ISHARP_NLDELTA_SOFT_CLIP,
- ISHARP_NLDELTA_SCLIP_PIVOT_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.pivot_n);
- /* ISHARP_NLDELTA_SCLIP_SLOPE_N */
- REG_UPDATE(ISHARP_NLDELTA_SOFT_CLIP,
+ if (!program_isharp_1dlut)
+ dpp401_dscl_set_isharp_filter(dpp, scl_data->dscl_prog_data.isharp_delta);
+
+ /* ISHARP_NLDELTA_SOFT_CLIP */
+ REG_SET_6(ISHARP_NLDELTA_SOFT_CLIP, 0,
+ ISHARP_NLDELTA_SCLIP_EN_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.enable_p,
+ ISHARP_NLDELTA_SCLIP_PIVOT_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.pivot_p,
+ ISHARP_NLDELTA_SCLIP_SLOPE_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.slope_p,
+ ISHARP_NLDELTA_SCLIP_EN_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.enable_n,
+ ISHARP_NLDELTA_SCLIP_PIVOT_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.pivot_n,
ISHARP_NLDELTA_SCLIP_SLOPE_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.slope_n);
/* Blur and Scale Coefficients - SCL_COEF_RAM_TAP_SELECT */
@@ -1086,12 +1037,14 @@ static void dpp401_dscl_program_isharp(struct dpp *dpp_base,
dpp, scl_data->taps.v_taps,
SCL_COEF_VERTICAL_BLUR_SCALE,
scl_data->dscl_prog_data.filter_blur_scale_v);
+ *bs_coeffs_updated = true;
}
if (scl_data->dscl_prog_data.filter_blur_scale_h) {
dpp401_dscl_set_scaler_filter(
dpp, scl_data->taps.h_taps,
SCL_COEF_HORIZONTAL_BLUR_SCALE,
scl_data->dscl_prog_data.filter_blur_scale_h);
+ *bs_coeffs_updated = true;
}
}
PERF_TRACE();
@@ -1122,12 +1075,29 @@ void dpp401_dscl_set_scaler_manual_scale(struct dpp *dpp_base,
dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale);
bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN
&& scl_data->format <= PIXEL_FORMAT_VIDEO_END;
+ bool program_isharp_1dlut = false;
+ bool bs_coeffs_updated = false;
+
if (memcmp(&dpp->scl_data, scl_data, sizeof(*scl_data)) == 0)
return;
PERF_TRACE();
+ /* If only sharpness has changed, then only update 1dlut, then return */
+ if (scl_data->dscl_prog_data.isharp_en &&
+ (dpp->scl_data.dscl_prog_data.sharpness_level
+ != scl_data->dscl_prog_data.sharpness_level)) {
+ /* ISHARP_DELTA_LUT */
+ dpp401_dscl_set_isharp_filter(dpp, scl_data->dscl_prog_data.isharp_delta);
+ dpp->scl_data.dscl_prog_data.sharpness_level = scl_data->dscl_prog_data.sharpness_level;
+ dpp->scl_data.dscl_prog_data.isharp_delta = scl_data->dscl_prog_data.isharp_delta;
+
+ if (memcmp(&dpp->scl_data, scl_data, sizeof(*scl_data)) == 0)
+ return;
+ program_isharp_1dlut = true;
+ }
+
dpp->scl_data = *scl_data;
if ((dpp->base.ctx->dc->config.use_spl) && (!dpp->base.ctx->dc->debug.disable_spl)) {
@@ -1181,7 +1151,7 @@ void dpp401_dscl_set_scaler_manual_scale(struct dpp *dpp_base,
if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) {
if (dpp->base.ctx->dc->config.prefer_easf)
dpp401_dscl_disable_easf(dpp_base, scl_data);
- dpp401_dscl_program_isharp(dpp_base, scl_data);
+ dpp401_dscl_program_isharp(dpp_base, scl_data, program_isharp_1dlut, &bs_coeffs_updated);
return;
}
@@ -1208,12 +1178,18 @@ void dpp401_dscl_set_scaler_manual_scale(struct dpp *dpp_base,
SCL_V_NUM_TAPS_C, v_num_taps_c,
SCL_H_NUM_TAPS_C, h_num_taps_c);
- dpp401_dscl_set_scl_filter(dpp, scl_data, ycbcr);
+ /* ISharp configuration
+ * - B&S coeffs are written to same coeff RAM as WB scaler coeffs
+ * - coeff RAM toggle is in EASF programming
+ * - if we are only programming B&S coeffs, then need to reprogram
+ * WB scaler coeffs and toggle coeff RAM together
+ */
+ //if (dpp->base.ctx->dc->config.prefer_easf)
+ dpp401_dscl_program_isharp(dpp_base, scl_data, program_isharp_1dlut, &bs_coeffs_updated);
+
+ dpp401_dscl_set_scl_filter(dpp, scl_data, ycbcr, bs_coeffs_updated);
/* Edge adaptive scaler function configuration */
if (dpp->base.ctx->dc->config.prefer_easf)
dpp401_dscl_program_easf(dpp_base, scl_data);
- /* isharp configuration */
- //if (dpp->base.ctx->dc->config.prefer_easf)
- dpp401_dscl_program_isharp(dpp_base, scl_data);
PERF_TRACE();
}
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c
index 6acb6699f146..61678b0a5a1e 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c
@@ -27,7 +27,7 @@ static void dsc401_disconnect(struct display_stream_compressor *dsc);
static void dsc401_wait_disconnect_pending_clear(struct display_stream_compressor *dsc);
static void dsc401_get_enc_caps(struct dsc_enc_caps *dsc_enc_caps, int pixel_clock_100Hz);
-const struct dsc_funcs dcn401_dsc_funcs = {
+static const struct dsc_funcs dcn401_dsc_funcs = {
.dsc_get_enc_caps = dsc401_get_enc_caps,
.dsc_read_state = dsc401_read_state,
.dsc_validate_stream = dsc401_validate_stream,
diff --git a/drivers/gpu/drm/amd/display/dc/dwb/Makefile b/drivers/gpu/drm/amd/display/dc/dwb/Makefile
index 16f7a454fed9..3952ba4cd508 100644
--- a/drivers/gpu/drm/amd/display/dc/dwb/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dwb/Makefile
@@ -25,6 +25,15 @@
ifdef CONFIG_DRM_AMD_DC_FP
###############################################################################
+# DCN30
+###############################################################################
+DWB_DCN30 = dcn30_dwb.o dcn30_dwb_cm.o
+
+AMD_DAL_DWB_DCN30 = $(addprefix $(AMDDALPATH)/dc/dwb/dcn30/,$(DWB_DCN30))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_DWB_DCN30)
+
+###############################################################################
# DCN35
###############################################################################
DWB_DCN35 = dcn35_dwb.o
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.h b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_cm_common.h
index bd98b327a6c7..bd98b327a6c7 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.h
+++ b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_cm_common.h
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb.c
index fae98cf52020..fae98cf52020 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c
+++ b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb.h
index 0f3f7c5fbaec..0f3f7c5fbaec 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h
+++ b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb.h
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb_cm.c
index 03a50c32fcfe..03a50c32fcfe 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb_cm.c
diff --git a/drivers/gpu/drm/amd/display/dc/dwb/dcn35/dcn35_dwb.c b/drivers/gpu/drm/amd/display/dc/dwb/dcn35/dcn35_dwb.c
index b23a809999ed..d5e8294f5a16 100644
--- a/drivers/gpu/drm/amd/display/dc/dwb/dcn35/dcn35_dwb.c
+++ b/drivers/gpu/drm/amd/display/dc/dwb/dcn35/dcn35_dwb.c
@@ -21,7 +21,6 @@
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "reg_helper.h"
#include "dcn35_dwb.h"
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn401/hw_factory_dcn401.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn401/hw_factory_dcn401.c
index 46415cab23ab..928abca18a18 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn401/hw_factory_dcn401.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn401/hw_factory_dcn401.c
@@ -86,7 +86,13 @@ static const struct ddc_registers ddc_data_regs_dcn[] = {
ddc_data_regs_dcn2(2),
ddc_data_regs_dcn2(3),
ddc_data_regs_dcn2(4),
-// ddc_data_regs_dcn2(5),
+ {
+ // add a dummy entry for cases no such port
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
+ .ddc_setup = 0,
+ .phy_aux_cntl = 0,
+ .dc_gpio_aux_ctrl_5 = 0
+ },
{
// add a dummy entry for cases no such port
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
@@ -107,7 +113,13 @@ static const struct ddc_registers ddc_clk_regs_dcn[] = {
ddc_clk_regs_dcn2(2),
ddc_clk_regs_dcn2(3),
ddc_clk_regs_dcn2(4),
-// ddc_clk_regs_dcn2(5),
+ {
+ // add a dummy entry for cases no such port
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
+ .ddc_setup = 0,
+ .phy_aux_cntl = 0,
+ .dc_gpio_aux_ctrl_5 = 0
+ },
{
// add a dummy entry for cases no such port
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
diff --git a/drivers/gpu/drm/amd/display/dc/hpo/Makefile b/drivers/gpu/drm/amd/display/dc/hpo/Makefile
index c248bd86b477..7f2c9ee0dff1 100644
--- a/drivers/gpu/drm/amd/display/dc/hpo/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/hpo/Makefile
@@ -25,6 +25,21 @@
ifdef CONFIG_DRM_AMD_DC_FP
###############################################################################
+# DCN30
+###############################################################################
+
+AMD_DAL_HPO_DCN30 = $(addprefix $(AMDDALPATH)/dc/hpo/dcn30/,$(HPO_DCN30))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HPO_DCN30)
+###############################################################################
+# DCN31
+###############################################################################
+HPO_DCN31 = dcn31_hpo_dp_stream_encoder.o dcn31_hpo_dp_link_encoder.o
+
+AMD_DAL_HPO_DCN31 = $(addprefix $(AMDDALPATH)/dc/hpo/dcn31/,$(HPO_DCN31))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_HPO_DCN31)
+###############################################################################
# DCN32
###############################################################################
HPO_DCN32 = dcn32_hpo_dp_link_encoder.o
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.c
index 03b4ac2f1991..03b4ac2f1991 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.h b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.h
index 51f5781325e8..51f5781325e8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.h
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.c
index 678db949cfe3..678db949cfe3 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.h
index 82c3b3ac1f0d..82c3b3ac1f0d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.h
diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c
index 181041d6d177..37d26fa0b6fb 100644
--- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c
@@ -75,108 +75,108 @@ bool hubbub401_program_urgent_watermarks(
/* Repeat for water mark set A and B */
/* clock state A */
- if (safe_to_lower || watermarks->dcn4.a.urgent > hubbub2->watermarks.dcn4.a.urgent) {
- hubbub2->watermarks.dcn4.a.urgent = watermarks->dcn4.a.urgent;
+ if (safe_to_lower || watermarks->dcn4x.a.urgent > hubbub2->watermarks.dcn4x.a.urgent) {
+ hubbub2->watermarks.dcn4x.a.urgent = watermarks->dcn4x.a.urgent;
REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0,
- DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, watermarks->dcn4.a.urgent);
+ DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, watermarks->dcn4x.a.urgent);
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
- watermarks->dcn4.a.urgent, watermarks->dcn4.a.urgent);
- } else if (watermarks->dcn4.a.urgent < hubbub2->watermarks.dcn4.a.urgent)
+ watermarks->dcn4x.a.urgent, watermarks->dcn4x.a.urgent);
+ } else if (watermarks->dcn4x.a.urgent < hubbub2->watermarks.dcn4x.a.urgent)
wm_pending = true;
/* determine the transfer time for a quantity of data for a particular requestor.*/
- if (safe_to_lower || watermarks->dcn4.a.frac_urg_bw_flip
- > hubbub2->watermarks.dcn4.a.frac_urg_bw_flip) {
- hubbub2->watermarks.dcn4.a.frac_urg_bw_flip = watermarks->dcn4.a.frac_urg_bw_flip;
+ if (safe_to_lower || watermarks->dcn4x.a.frac_urg_bw_flip
+ > hubbub2->watermarks.dcn4x.a.frac_urg_bw_flip) {
+ hubbub2->watermarks.dcn4x.a.frac_urg_bw_flip = watermarks->dcn4x.a.frac_urg_bw_flip;
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, 0,
- DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, watermarks->dcn4.a.frac_urg_bw_flip);
- } else if (watermarks->dcn4.a.frac_urg_bw_flip
- < hubbub2->watermarks.dcn4.a.frac_urg_bw_flip)
+ DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, watermarks->dcn4x.a.frac_urg_bw_flip);
+ } else if (watermarks->dcn4x.a.frac_urg_bw_flip
+ < hubbub2->watermarks.dcn4x.a.frac_urg_bw_flip)
wm_pending = true;
- if (safe_to_lower || watermarks->dcn4.a.frac_urg_bw_nom
- > hubbub2->watermarks.dcn4.a.frac_urg_bw_nom) {
- hubbub2->watermarks.dcn4.a.frac_urg_bw_nom = watermarks->dcn4.a.frac_urg_bw_nom;
+ if (safe_to_lower || watermarks->dcn4x.a.frac_urg_bw_nom
+ > hubbub2->watermarks.dcn4x.a.frac_urg_bw_nom) {
+ hubbub2->watermarks.dcn4x.a.frac_urg_bw_nom = watermarks->dcn4x.a.frac_urg_bw_nom;
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0,
- DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->dcn4.a.frac_urg_bw_nom);
- } else if (watermarks->dcn4.a.frac_urg_bw_nom
- < hubbub2->watermarks.dcn4.a.frac_urg_bw_nom)
+ DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->dcn4x.a.frac_urg_bw_nom);
+ } else if (watermarks->dcn4x.a.frac_urg_bw_nom
+ < hubbub2->watermarks.dcn4x.a.frac_urg_bw_nom)
wm_pending = true;
- if (safe_to_lower || watermarks->dcn4.a.frac_urg_bw_mall
- > hubbub2->watermarks.dcn4.a.frac_urg_bw_mall) {
- hubbub2->watermarks.dcn4.a.frac_urg_bw_mall = watermarks->dcn4.a.frac_urg_bw_mall;
+ if (safe_to_lower || watermarks->dcn4x.a.frac_urg_bw_mall
+ > hubbub2->watermarks.dcn4x.a.frac_urg_bw_mall) {
+ hubbub2->watermarks.dcn4x.a.frac_urg_bw_mall = watermarks->dcn4x.a.frac_urg_bw_mall;
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_MALL_A, 0,
- DCHUBBUB_ARB_FRAC_URG_BW_MALL_A, watermarks->dcn4.a.frac_urg_bw_mall);
- } else if (watermarks->dcn4.a.frac_urg_bw_mall < hubbub2->watermarks.dcn4.a.frac_urg_bw_mall)
+ DCHUBBUB_ARB_FRAC_URG_BW_MALL_A, watermarks->dcn4x.a.frac_urg_bw_mall);
+ } else if (watermarks->dcn4x.a.frac_urg_bw_mall < hubbub2->watermarks.dcn4x.a.frac_urg_bw_mall)
wm_pending = true;
- if (safe_to_lower || watermarks->dcn4.a.refcyc_per_trip_to_mem > hubbub2->watermarks.dcn4.a.refcyc_per_trip_to_mem) {
- hubbub2->watermarks.dcn4.a.refcyc_per_trip_to_mem = watermarks->dcn4.a.refcyc_per_trip_to_mem;
+ if (safe_to_lower || watermarks->dcn4x.a.refcyc_per_trip_to_mem > hubbub2->watermarks.dcn4x.a.refcyc_per_trip_to_mem) {
+ hubbub2->watermarks.dcn4x.a.refcyc_per_trip_to_mem = watermarks->dcn4x.a.refcyc_per_trip_to_mem;
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0,
- DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, watermarks->dcn4.a.refcyc_per_trip_to_mem);
- } else if (watermarks->dcn4.a.refcyc_per_trip_to_mem < hubbub2->watermarks.dcn4.a.refcyc_per_trip_to_mem)
+ DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, watermarks->dcn4x.a.refcyc_per_trip_to_mem);
+ } else if (watermarks->dcn4x.a.refcyc_per_trip_to_mem < hubbub2->watermarks.dcn4x.a.refcyc_per_trip_to_mem)
wm_pending = true;
- if (safe_to_lower || watermarks->dcn4.a.refcyc_per_meta_trip_to_mem > hubbub2->watermarks.dcn4.a.refcyc_per_meta_trip_to_mem) {
- hubbub2->watermarks.dcn4.a.refcyc_per_meta_trip_to_mem = watermarks->dcn4.a.refcyc_per_meta_trip_to_mem;
+ if (safe_to_lower || watermarks->dcn4x.a.refcyc_per_meta_trip_to_mem > hubbub2->watermarks.dcn4x.a.refcyc_per_meta_trip_to_mem) {
+ hubbub2->watermarks.dcn4x.a.refcyc_per_meta_trip_to_mem = watermarks->dcn4x.a.refcyc_per_meta_trip_to_mem;
REG_SET(DCHUBBUB_ARB_REFCYC_PER_META_TRIP_A, 0,
- DCHUBBUB_ARB_REFCYC_PER_META_TRIP_A, watermarks->dcn4.a.refcyc_per_meta_trip_to_mem);
- } else if (watermarks->dcn4.a.refcyc_per_meta_trip_to_mem < hubbub2->watermarks.dcn4.a.refcyc_per_meta_trip_to_mem)
+ DCHUBBUB_ARB_REFCYC_PER_META_TRIP_A, watermarks->dcn4x.a.refcyc_per_meta_trip_to_mem);
+ } else if (watermarks->dcn4x.a.refcyc_per_meta_trip_to_mem < hubbub2->watermarks.dcn4x.a.refcyc_per_meta_trip_to_mem)
wm_pending = true;
/* clock state B */
- if (safe_to_lower || watermarks->dcn4.b.urgent > hubbub2->watermarks.dcn4.b.urgent) {
- hubbub2->watermarks.dcn4.b.urgent = watermarks->dcn4.b.urgent;
+ if (safe_to_lower || watermarks->dcn4x.b.urgent > hubbub2->watermarks.dcn4x.b.urgent) {
+ hubbub2->watermarks.dcn4x.b.urgent = watermarks->dcn4x.b.urgent;
REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0,
- DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, watermarks->dcn4.b.urgent);
+ DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, watermarks->dcn4x.b.urgent);
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
- watermarks->dcn4.b.urgent, watermarks->dcn4.b.urgent);
- } else if (watermarks->dcn4.b.urgent < hubbub2->watermarks.dcn4.b.urgent)
+ watermarks->dcn4x.b.urgent, watermarks->dcn4x.b.urgent);
+ } else if (watermarks->dcn4x.b.urgent < hubbub2->watermarks.dcn4x.b.urgent)
wm_pending = true;
/* determine the transfer time for a quantity of data for a particular requestor.*/
- if (safe_to_lower || watermarks->dcn4.b.frac_urg_bw_flip
- > hubbub2->watermarks.dcn4.b.frac_urg_bw_flip) {
- hubbub2->watermarks.dcn4.b.frac_urg_bw_flip = watermarks->dcn4.b.frac_urg_bw_flip;
+ if (safe_to_lower || watermarks->dcn4x.b.frac_urg_bw_flip
+ > hubbub2->watermarks.dcn4x.b.frac_urg_bw_flip) {
+ hubbub2->watermarks.dcn4x.b.frac_urg_bw_flip = watermarks->dcn4x.b.frac_urg_bw_flip;
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, 0,
- DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, watermarks->dcn4.b.frac_urg_bw_flip);
- } else if (watermarks->dcn4.b.frac_urg_bw_flip
- < hubbub2->watermarks.dcn4.b.frac_urg_bw_flip)
+ DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, watermarks->dcn4x.b.frac_urg_bw_flip);
+ } else if (watermarks->dcn4x.b.frac_urg_bw_flip
+ < hubbub2->watermarks.dcn4x.b.frac_urg_bw_flip)
wm_pending = true;
- if (safe_to_lower || watermarks->dcn4.b.frac_urg_bw_nom
- > hubbub2->watermarks.dcn4.b.frac_urg_bw_nom) {
- hubbub2->watermarks.dcn4.b.frac_urg_bw_nom = watermarks->dcn4.b.frac_urg_bw_nom;
+ if (safe_to_lower || watermarks->dcn4x.b.frac_urg_bw_nom
+ > hubbub2->watermarks.dcn4x.b.frac_urg_bw_nom) {
+ hubbub2->watermarks.dcn4x.b.frac_urg_bw_nom = watermarks->dcn4x.b.frac_urg_bw_nom;
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, 0,
- DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->dcn4.b.frac_urg_bw_nom);
- } else if (watermarks->dcn4.b.frac_urg_bw_nom
- < hubbub2->watermarks.dcn4.b.frac_urg_bw_nom)
+ DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->dcn4x.b.frac_urg_bw_nom);
+ } else if (watermarks->dcn4x.b.frac_urg_bw_nom
+ < hubbub2->watermarks.dcn4x.b.frac_urg_bw_nom)
wm_pending = true;
- if (safe_to_lower || watermarks->dcn4.b.frac_urg_bw_mall
- > hubbub2->watermarks.dcn4.b.frac_urg_bw_mall) {
- hubbub2->watermarks.dcn4.b.frac_urg_bw_mall = watermarks->dcn4.b.frac_urg_bw_mall;
+ if (safe_to_lower || watermarks->dcn4x.b.frac_urg_bw_mall
+ > hubbub2->watermarks.dcn4x.b.frac_urg_bw_mall) {
+ hubbub2->watermarks.dcn4x.b.frac_urg_bw_mall = watermarks->dcn4x.b.frac_urg_bw_mall;
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_MALL_B, 0,
- DCHUBBUB_ARB_FRAC_URG_BW_MALL_B, watermarks->dcn4.b.frac_urg_bw_mall);
- } else if (watermarks->dcn4.b.frac_urg_bw_mall < hubbub2->watermarks.dcn4.b.frac_urg_bw_mall)
+ DCHUBBUB_ARB_FRAC_URG_BW_MALL_B, watermarks->dcn4x.b.frac_urg_bw_mall);
+ } else if (watermarks->dcn4x.b.frac_urg_bw_mall < hubbub2->watermarks.dcn4x.b.frac_urg_bw_mall)
wm_pending = true;
- if (safe_to_lower || watermarks->dcn4.b.refcyc_per_trip_to_mem > hubbub2->watermarks.dcn4.b.refcyc_per_trip_to_mem) {
- hubbub2->watermarks.dcn4.b.refcyc_per_trip_to_mem = watermarks->dcn4.b.refcyc_per_trip_to_mem;
+ if (safe_to_lower || watermarks->dcn4x.b.refcyc_per_trip_to_mem > hubbub2->watermarks.dcn4x.b.refcyc_per_trip_to_mem) {
+ hubbub2->watermarks.dcn4x.b.refcyc_per_trip_to_mem = watermarks->dcn4x.b.refcyc_per_trip_to_mem;
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0,
- DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, watermarks->dcn4.b.refcyc_per_trip_to_mem);
- } else if (watermarks->dcn4.b.refcyc_per_trip_to_mem < hubbub2->watermarks.dcn4.b.refcyc_per_trip_to_mem)
+ DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, watermarks->dcn4x.b.refcyc_per_trip_to_mem);
+ } else if (watermarks->dcn4x.b.refcyc_per_trip_to_mem < hubbub2->watermarks.dcn4x.b.refcyc_per_trip_to_mem)
wm_pending = true;
- if (safe_to_lower || watermarks->dcn4.b.refcyc_per_meta_trip_to_mem > hubbub2->watermarks.dcn4.b.refcyc_per_meta_trip_to_mem) {
- hubbub2->watermarks.dcn4.b.refcyc_per_meta_trip_to_mem = watermarks->dcn4.b.refcyc_per_meta_trip_to_mem;
+ if (safe_to_lower || watermarks->dcn4x.b.refcyc_per_meta_trip_to_mem > hubbub2->watermarks.dcn4x.b.refcyc_per_meta_trip_to_mem) {
+ hubbub2->watermarks.dcn4x.b.refcyc_per_meta_trip_to_mem = watermarks->dcn4x.b.refcyc_per_meta_trip_to_mem;
REG_SET(DCHUBBUB_ARB_REFCYC_PER_META_TRIP_B, 0,
- DCHUBBUB_ARB_REFCYC_PER_META_TRIP_B, watermarks->dcn4.b.refcyc_per_meta_trip_to_mem);
- } else if (watermarks->dcn4.b.refcyc_per_meta_trip_to_mem < hubbub2->watermarks.dcn4.b.refcyc_per_meta_trip_to_mem)
+ DCHUBBUB_ARB_REFCYC_PER_META_TRIP_B, watermarks->dcn4x.b.refcyc_per_meta_trip_to_mem);
+ } else if (watermarks->dcn4x.b.refcyc_per_meta_trip_to_mem < hubbub2->watermarks.dcn4x.b.refcyc_per_meta_trip_to_mem)
wm_pending = true;
return wm_pending;
@@ -192,89 +192,89 @@ bool hubbub401_program_stutter_watermarks(
bool wm_pending = false;
/* clock state A */
- if (safe_to_lower || watermarks->dcn4.a.sr_enter
- > hubbub2->watermarks.dcn4.a.sr_enter) {
- hubbub2->watermarks.dcn4.a.sr_enter =
- watermarks->dcn4.a.sr_enter;
+ if (safe_to_lower || watermarks->dcn4x.a.sr_enter
+ > hubbub2->watermarks.dcn4x.a.sr_enter) {
+ hubbub2->watermarks.dcn4x.a.sr_enter =
+ watermarks->dcn4x.a.sr_enter;
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0,
- DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, watermarks->dcn4.a.sr_enter);
+ DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, watermarks->dcn4x.a.sr_enter);
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
- watermarks->dcn4.a.sr_enter, watermarks->dcn4.a.sr_enter);
+ watermarks->dcn4x.a.sr_enter, watermarks->dcn4x.a.sr_enter);
// On dGPU Z states are N/A, so program all other 3 Stutter Enter wm A with the same value
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK1_A, 0,
- DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK1_A, watermarks->dcn4.a.sr_enter);
+ DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK1_A, watermarks->dcn4x.a.sr_enter);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK2_A, 0,
- DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK2_A, watermarks->dcn4.a.sr_enter);
+ DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK2_A, watermarks->dcn4x.a.sr_enter);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK3_A, 0,
- DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK3_A, watermarks->dcn4.a.sr_enter);
+ DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK3_A, watermarks->dcn4x.a.sr_enter);
- } else if (watermarks->dcn4.a.sr_enter
- < hubbub2->watermarks.dcn4.a.sr_enter)
+ } else if (watermarks->dcn4x.a.sr_enter
+ < hubbub2->watermarks.dcn4x.a.sr_enter)
wm_pending = true;
- if (safe_to_lower || watermarks->dcn4.a.sr_exit
- > hubbub2->watermarks.dcn4.a.sr_exit) {
- hubbub2->watermarks.dcn4.a.sr_exit =
- watermarks->dcn4.a.sr_exit;
+ if (safe_to_lower || watermarks->dcn4x.a.sr_exit
+ > hubbub2->watermarks.dcn4x.a.sr_exit) {
+ hubbub2->watermarks.dcn4x.a.sr_exit =
+ watermarks->dcn4x.a.sr_exit;
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0,
- DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, watermarks->dcn4.a.sr_exit);
+ DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, watermarks->dcn4x.a.sr_exit);
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
- watermarks->dcn4.a.sr_exit, watermarks->dcn4.a.sr_exit);
+ watermarks->dcn4x.a.sr_exit, watermarks->dcn4x.a.sr_exit);
// On dGPU Z states are N/A, so program all other 3 Stutter Exit wm A with the same value
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK1_A, 0,
- DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK1_A, watermarks->dcn4.a.sr_exit);
+ DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK1_A, watermarks->dcn4x.a.sr_exit);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK2_A, 0,
- DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK2_A, watermarks->dcn4.a.sr_exit);
+ DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK2_A, watermarks->dcn4x.a.sr_exit);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK3_A, 0,
- DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK3_A, watermarks->dcn4.a.sr_exit);
+ DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK3_A, watermarks->dcn4x.a.sr_exit);
- } else if (watermarks->dcn4.a.sr_exit
- < hubbub2->watermarks.dcn4.a.sr_exit)
+ } else if (watermarks->dcn4x.a.sr_exit
+ < hubbub2->watermarks.dcn4x.a.sr_exit)
wm_pending = true;
/* clock state B */
- if (safe_to_lower || watermarks->dcn4.b.sr_enter
- > hubbub2->watermarks.dcn4.b.sr_enter) {
- hubbub2->watermarks.dcn4.b.sr_enter =
- watermarks->dcn4.b.sr_enter;
+ if (safe_to_lower || watermarks->dcn4x.b.sr_enter
+ > hubbub2->watermarks.dcn4x.b.sr_enter) {
+ hubbub2->watermarks.dcn4x.b.sr_enter =
+ watermarks->dcn4x.b.sr_enter;
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0,
- DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, watermarks->dcn4.b.sr_enter);
+ DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, watermarks->dcn4x.b.sr_enter);
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
- watermarks->dcn4.b.sr_enter, watermarks->dcn4.b.sr_enter);
+ watermarks->dcn4x.b.sr_enter, watermarks->dcn4x.b.sr_enter);
// On dGPU Z states are N/A, so program all other 3 Stutter Enter wm A with the same value
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK1_B, 0,
- DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK1_B, watermarks->dcn4.b.sr_enter);
+ DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK1_B, watermarks->dcn4x.b.sr_enter);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK2_B, 0,
- DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK2_B, watermarks->dcn4.b.sr_enter);
+ DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK2_B, watermarks->dcn4x.b.sr_enter);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK3_B, 0,
- DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK3_B, watermarks->dcn4.b.sr_enter);
+ DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK3_B, watermarks->dcn4x.b.sr_enter);
- } else if (watermarks->dcn4.b.sr_enter
- < hubbub2->watermarks.dcn4.b.sr_enter)
+ } else if (watermarks->dcn4x.b.sr_enter
+ < hubbub2->watermarks.dcn4x.b.sr_enter)
wm_pending = true;
- if (safe_to_lower || watermarks->dcn4.b.sr_exit
- > hubbub2->watermarks.dcn4.b.sr_exit) {
- hubbub2->watermarks.dcn4.b.sr_exit =
- watermarks->dcn4.b.sr_exit;
+ if (safe_to_lower || watermarks->dcn4x.b.sr_exit
+ > hubbub2->watermarks.dcn4x.b.sr_exit) {
+ hubbub2->watermarks.dcn4x.b.sr_exit =
+ watermarks->dcn4x.b.sr_exit;
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0,
- DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, watermarks->dcn4.b.sr_exit);
+ DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, watermarks->dcn4x.b.sr_exit);
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
- watermarks->dcn4.b.sr_exit, watermarks->dcn4.b.sr_exit);
+ watermarks->dcn4x.b.sr_exit, watermarks->dcn4x.b.sr_exit);
// On dGPU Z states are N/A, so program all other 3 Stutter Exit wm A with the same value
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK1_B, 0,
- DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK1_B, watermarks->dcn4.b.sr_exit);
+ DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK1_B, watermarks->dcn4x.b.sr_exit);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK2_B, 0,
- DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK2_B, watermarks->dcn4.b.sr_exit);
+ DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK2_B, watermarks->dcn4x.b.sr_exit);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK3_B, 0,
- DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK3_B, watermarks->dcn4.b.sr_exit);
+ DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK3_B, watermarks->dcn4x.b.sr_exit);
- } else if (watermarks->dcn4.b.sr_exit
- < hubbub2->watermarks.dcn4.b.sr_exit)
+ } else if (watermarks->dcn4x.b.sr_exit
+ < hubbub2->watermarks.dcn4x.b.sr_exit)
wm_pending = true;
return wm_pending;
@@ -292,116 +292,116 @@ bool hubbub401_program_pstate_watermarks(
/* Section for UCLK_PSTATE_CHANGE_WATERMARKS */
/* clock state A */
- if (safe_to_lower || watermarks->dcn4.a.uclk_pstate
- > hubbub2->watermarks.dcn4.a.uclk_pstate) {
- hubbub2->watermarks.dcn4.a.uclk_pstate =
- watermarks->dcn4.a.uclk_pstate;
+ if (safe_to_lower || watermarks->dcn4x.a.uclk_pstate
+ > hubbub2->watermarks.dcn4x.a.uclk_pstate) {
+ hubbub2->watermarks.dcn4x.a.uclk_pstate =
+ watermarks->dcn4x.a.uclk_pstate;
REG_SET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A, 0,
- DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A, watermarks->dcn4.a.uclk_pstate);
+ DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A, watermarks->dcn4x.a.uclk_pstate);
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n\n",
- watermarks->dcn4.a.uclk_pstate, watermarks->dcn4.a.uclk_pstate);
- } else if (watermarks->dcn4.a.uclk_pstate
- < hubbub2->watermarks.dcn4.a.uclk_pstate)
+ watermarks->dcn4x.a.uclk_pstate, watermarks->dcn4x.a.uclk_pstate);
+ } else if (watermarks->dcn4x.a.uclk_pstate
+ < hubbub2->watermarks.dcn4x.a.uclk_pstate)
wm_pending = true;
/* clock state B */
- if (safe_to_lower || watermarks->dcn4.b.uclk_pstate
- > hubbub2->watermarks.dcn4.b.uclk_pstate) {
- hubbub2->watermarks.dcn4.b.uclk_pstate =
- watermarks->dcn4.b.uclk_pstate;
+ if (safe_to_lower || watermarks->dcn4x.b.uclk_pstate
+ > hubbub2->watermarks.dcn4x.b.uclk_pstate) {
+ hubbub2->watermarks.dcn4x.b.uclk_pstate =
+ watermarks->dcn4x.b.uclk_pstate;
REG_SET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, 0,
- DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, watermarks->dcn4.b.uclk_pstate);
+ DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, watermarks->dcn4x.b.uclk_pstate);
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n\n",
- watermarks->dcn4.b.uclk_pstate, watermarks->dcn4.b.uclk_pstate);
- } else if (watermarks->dcn4.b.uclk_pstate
- < hubbub2->watermarks.dcn4.b.uclk_pstate)
+ watermarks->dcn4x.b.uclk_pstate, watermarks->dcn4x.b.uclk_pstate);
+ } else if (watermarks->dcn4x.b.uclk_pstate
+ < hubbub2->watermarks.dcn4x.b.uclk_pstate)
wm_pending = true;
/* Section for UCLK_PSTATE_CHANGE_WATERMARKS1 (DUMMY_PSTATE/TEMP_READ/PPT) */
- if (safe_to_lower || watermarks->dcn4.a.temp_read_or_ppt
- > hubbub2->watermarks.dcn4.a.temp_read_or_ppt) {
- hubbub2->watermarks.dcn4.a.temp_read_or_ppt =
- watermarks->dcn4.a.temp_read_or_ppt;
+ if (safe_to_lower || watermarks->dcn4x.a.temp_read_or_ppt
+ > hubbub2->watermarks.dcn4x.a.temp_read_or_ppt) {
+ hubbub2->watermarks.dcn4x.a.temp_read_or_ppt =
+ watermarks->dcn4x.a.temp_read_or_ppt;
REG_SET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK1_A, 0,
- DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK1_A, watermarks->dcn4.a.temp_read_or_ppt);
+ DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK1_A, watermarks->dcn4x.a.temp_read_or_ppt);
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK1_A calculated =%d\n"
"HW register value = 0x%x\n\n",
- watermarks->dcn4.a.temp_read_or_ppt, watermarks->dcn4.a.temp_read_or_ppt);
- } else if (watermarks->dcn4.a.temp_read_or_ppt
- < hubbub2->watermarks.dcn4.a.temp_read_or_ppt)
+ watermarks->dcn4x.a.temp_read_or_ppt, watermarks->dcn4x.a.temp_read_or_ppt);
+ } else if (watermarks->dcn4x.a.temp_read_or_ppt
+ < hubbub2->watermarks.dcn4x.a.temp_read_or_ppt)
wm_pending = true;
/* clock state B */
- if (safe_to_lower || watermarks->dcn4.b.temp_read_or_ppt
- > hubbub2->watermarks.dcn4.b.temp_read_or_ppt) {
- hubbub2->watermarks.dcn4.b.temp_read_or_ppt =
- watermarks->dcn4.b.temp_read_or_ppt;
+ if (safe_to_lower || watermarks->dcn4x.b.temp_read_or_ppt
+ > hubbub2->watermarks.dcn4x.b.temp_read_or_ppt) {
+ hubbub2->watermarks.dcn4x.b.temp_read_or_ppt =
+ watermarks->dcn4x.b.temp_read_or_ppt;
REG_SET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK1_B, 0,
- DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK1_B, watermarks->dcn4.b.temp_read_or_ppt);
+ DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK1_B, watermarks->dcn4x.b.temp_read_or_ppt);
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK1_B calculated =%d\n"
"HW register value = 0x%x\n\n",
- watermarks->dcn4.b.temp_read_or_ppt, watermarks->dcn4.b.temp_read_or_ppt);
- } else if (watermarks->dcn4.b.temp_read_or_ppt
- < hubbub2->watermarks.dcn4.b.temp_read_or_ppt)
+ watermarks->dcn4x.b.temp_read_or_ppt, watermarks->dcn4x.b.temp_read_or_ppt);
+ } else if (watermarks->dcn4x.b.temp_read_or_ppt
+ < hubbub2->watermarks.dcn4x.b.temp_read_or_ppt)
wm_pending = true;
/* Section for FCLK_PSTATE_CHANGE_WATERMARKS */
/* clock state A */
- if (safe_to_lower || watermarks->dcn4.a.fclk_pstate
- > hubbub2->watermarks.dcn4.a.fclk_pstate) {
- hubbub2->watermarks.dcn4.a.fclk_pstate =
- watermarks->dcn4.a.fclk_pstate;
+ if (safe_to_lower || watermarks->dcn4x.a.fclk_pstate
+ > hubbub2->watermarks.dcn4x.a.fclk_pstate) {
+ hubbub2->watermarks.dcn4x.a.fclk_pstate =
+ watermarks->dcn4x.a.fclk_pstate;
REG_SET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A, 0,
- DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A, watermarks->dcn4.a.fclk_pstate);
+ DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A, watermarks->dcn4x.a.fclk_pstate);
DC_LOG_BANDWIDTH_CALCS("FCLK_CHANGE_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n\n",
- watermarks->dcn4.a.fclk_pstate, watermarks->dcn4.a.fclk_pstate);
- } else if (watermarks->dcn4.a.fclk_pstate
- < hubbub2->watermarks.dcn4.a.fclk_pstate)
+ watermarks->dcn4x.a.fclk_pstate, watermarks->dcn4x.a.fclk_pstate);
+ } else if (watermarks->dcn4x.a.fclk_pstate
+ < hubbub2->watermarks.dcn4x.a.fclk_pstate)
wm_pending = true;
/* clock state B */
- if (safe_to_lower || watermarks->dcn4.b.fclk_pstate
- > hubbub2->watermarks.dcn4.b.fclk_pstate) {
- hubbub2->watermarks.dcn4.b.fclk_pstate =
- watermarks->dcn4.b.fclk_pstate;
+ if (safe_to_lower || watermarks->dcn4x.b.fclk_pstate
+ > hubbub2->watermarks.dcn4x.b.fclk_pstate) {
+ hubbub2->watermarks.dcn4x.b.fclk_pstate =
+ watermarks->dcn4x.b.fclk_pstate;
REG_SET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, 0,
- DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, watermarks->dcn4.b.fclk_pstate);
+ DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, watermarks->dcn4x.b.fclk_pstate);
DC_LOG_BANDWIDTH_CALCS("FCLK_CHANGE_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n\n",
- watermarks->dcn4.b.fclk_pstate, watermarks->dcn4.b.fclk_pstate);
- } else if (watermarks->dcn4.b.fclk_pstate
- < hubbub2->watermarks.dcn4.b.fclk_pstate)
+ watermarks->dcn4x.b.fclk_pstate, watermarks->dcn4x.b.fclk_pstate);
+ } else if (watermarks->dcn4x.b.fclk_pstate
+ < hubbub2->watermarks.dcn4x.b.fclk_pstate)
wm_pending = true;
/* Section for FCLK_CHANGE_WATERMARKS1 (DUMMY_PSTATE/TEMP_READ/PPT) */
- if (safe_to_lower || watermarks->dcn4.a.temp_read_or_ppt
- > hubbub2->watermarks.dcn4.a.temp_read_or_ppt) {
- hubbub2->watermarks.dcn4.a.temp_read_or_ppt =
- watermarks->dcn4.a.temp_read_or_ppt;
+ if (safe_to_lower || watermarks->dcn4x.a.temp_read_or_ppt
+ > hubbub2->watermarks.dcn4x.a.temp_read_or_ppt) {
+ hubbub2->watermarks.dcn4x.a.temp_read_or_ppt =
+ watermarks->dcn4x.a.temp_read_or_ppt;
REG_SET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK1_A, 0,
- DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK1_A, watermarks->dcn4.a.temp_read_or_ppt);
+ DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK1_A, watermarks->dcn4x.a.temp_read_or_ppt);
DC_LOG_BANDWIDTH_CALCS("FCLK_CHANGE_WATERMARK1_A calculated =%d\n"
"HW register value = 0x%x\n\n",
- watermarks->dcn4.a.temp_read_or_ppt, watermarks->dcn4.a.temp_read_or_ppt);
- } else if (watermarks->dcn4.a.temp_read_or_ppt
- < hubbub2->watermarks.dcn4.a.temp_read_or_ppt)
+ watermarks->dcn4x.a.temp_read_or_ppt, watermarks->dcn4x.a.temp_read_or_ppt);
+ } else if (watermarks->dcn4x.a.temp_read_or_ppt
+ < hubbub2->watermarks.dcn4x.a.temp_read_or_ppt)
wm_pending = true;
/* clock state B */
- if (safe_to_lower || watermarks->dcn4.b.temp_read_or_ppt
- > hubbub2->watermarks.dcn4.b.temp_read_or_ppt) {
- hubbub2->watermarks.dcn4.b.temp_read_or_ppt =
- watermarks->dcn4.b.temp_read_or_ppt;
+ if (safe_to_lower || watermarks->dcn4x.b.temp_read_or_ppt
+ > hubbub2->watermarks.dcn4x.b.temp_read_or_ppt) {
+ hubbub2->watermarks.dcn4x.b.temp_read_or_ppt =
+ watermarks->dcn4x.b.temp_read_or_ppt;
REG_SET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK1_B, 0,
- DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK1_B, watermarks->dcn4.b.temp_read_or_ppt);
+ DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK1_B, watermarks->dcn4x.b.temp_read_or_ppt);
DC_LOG_BANDWIDTH_CALCS("FCLK_CHANGE_WATERMARK1_B calculated =%d\n"
"HW register value = 0x%x\n\n",
- watermarks->dcn4.b.temp_read_or_ppt, watermarks->dcn4.b.temp_read_or_ppt);
- } else if (watermarks->dcn4.b.temp_read_or_ppt
- < hubbub2->watermarks.dcn4.b.temp_read_or_ppt)
+ watermarks->dcn4x.b.temp_read_or_ppt, watermarks->dcn4x.b.temp_read_or_ppt);
+ } else if (watermarks->dcn4x.b.temp_read_or_ppt
+ < hubbub2->watermarks.dcn4x.b.temp_read_or_ppt)
wm_pending = true;
return wm_pending;
@@ -418,29 +418,29 @@ bool hubbub401_program_usr_watermarks(
bool wm_pending = false;
/* clock state A */
- if (safe_to_lower || watermarks->dcn4.a.usr
- > hubbub2->watermarks.dcn4.a.usr) {
- hubbub2->watermarks.dcn4.a.usr = watermarks->dcn4.a.usr;
+ if (safe_to_lower || watermarks->dcn4x.a.usr
+ > hubbub2->watermarks.dcn4x.a.usr) {
+ hubbub2->watermarks.dcn4x.a.usr = watermarks->dcn4x.a.usr;
REG_SET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A, 0,
- DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A, watermarks->dcn4.a.usr);
+ DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A, watermarks->dcn4x.a.usr);
DC_LOG_BANDWIDTH_CALCS("USR_RETRAINING_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n\n",
- watermarks->dcn4.a.usr, watermarks->dcn4.a.usr);
- } else if (watermarks->dcn4.a.usr
- < hubbub2->watermarks.dcn4.a.usr)
+ watermarks->dcn4x.a.usr, watermarks->dcn4x.a.usr);
+ } else if (watermarks->dcn4x.a.usr
+ < hubbub2->watermarks.dcn4x.a.usr)
wm_pending = true;
/* clock state B */
- if (safe_to_lower || watermarks->dcn4.b.usr
- > hubbub2->watermarks.dcn4.b.usr) {
- hubbub2->watermarks.dcn4.b.usr = watermarks->dcn4.b.usr;
+ if (safe_to_lower || watermarks->dcn4x.b.usr
+ > hubbub2->watermarks.dcn4x.b.usr) {
+ hubbub2->watermarks.dcn4x.b.usr = watermarks->dcn4x.b.usr;
REG_SET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, 0,
- DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, watermarks->dcn4.b.usr);
+ DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, watermarks->dcn4x.b.usr);
DC_LOG_BANDWIDTH_CALCS("USR_RETRAINING_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n\n",
- watermarks->dcn4.b.usr, watermarks->dcn4.b.usr);
- } else if (watermarks->dcn4.b.usr
- < hubbub2->watermarks.dcn4.b.usr)
+ watermarks->dcn4x.b.usr, watermarks->dcn4x.b.usr);
+ } else if (watermarks->dcn4x.b.usr
+ < hubbub2->watermarks.dcn4x.b.usr)
wm_pending = true;
return wm_pending;
@@ -1170,6 +1170,28 @@ static void dcn401_program_compbuf_segments(struct hubbub *hubbub, unsigned comp
}
}
+static void dcn401_wait_for_det_update(struct hubbub *hubbub, int hubp_inst)
+{
+ struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
+
+ switch (hubp_inst) {
+ case 0:
+ REG_WAIT(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT, hubbub2->det0_size, 1, 100000); /* 1 vupdate at 10hz */
+ break;
+ case 1:
+ REG_WAIT(DCHUBBUB_DET1_CTRL, DET1_SIZE_CURRENT, hubbub2->det1_size, 1, 100000);
+ break;
+ case 2:
+ REG_WAIT(DCHUBBUB_DET2_CTRL, DET2_SIZE_CURRENT, hubbub2->det2_size, 1, 100000);
+ break;
+ case 3:
+ REG_WAIT(DCHUBBUB_DET3_CTRL, DET3_SIZE_CURRENT, hubbub2->det3_size, 1, 100000);
+ break;
+ default:
+ break;
+ }
+}
+
static const struct hubbub_funcs hubbub4_01_funcs = {
.update_dchub = hubbub2_update_dchub,
.init_dchub_sys_ctx = hubbub3_init_dchub_sys_ctx,
@@ -1192,6 +1214,7 @@ static const struct hubbub_funcs hubbub4_01_funcs = {
.set_request_limit = hubbub32_set_request_limit,
.program_det_segments = dcn401_program_det_segments,
.program_compbuf_segments = dcn401_program_compbuf_segments,
+ .wait_for_det_update = dcn401_wait_for_det_update,
};
void hubbub401_construct(struct dcn20_hubbub *hubbub2,
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
index bf399819ca80..22ac2b7e49ae 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
@@ -749,7 +749,8 @@ bool hubp1_is_flip_pending(struct hubp *hubp)
if (flip_pending)
return true;
- if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
+ if (hubp &&
+ earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
return true;
return false;
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
index 6bba020ad6fb..0637e4c552d8 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
@@ -927,7 +927,8 @@ bool hubp2_is_flip_pending(struct hubp *hubp)
if (flip_pending)
return true;
- if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
+ if (hubp &&
+ earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
return true;
return false;
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c
index 771fcd0d3b99..d1f05b82b3dd 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c
@@ -188,7 +188,7 @@ void hubp35_program_surface_config(
hubp35_program_pixel_format(hubp, format);
}
-struct hubp_funcs dcn35_hubp_funcs = {
+static struct hubp_funcs dcn35_hubp_funcs = {
.hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
.hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled,
.hubp_program_surface_flip_and_addr = hubp3_program_surface_flip_and_addr,
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
index eb0da6c6b87c..b1ebf5053b4f 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
@@ -725,8 +725,8 @@ void hubp401_cursor_set_position(
CURSOR_ENABLE, cur_en);
REG_SET_2(CURSOR_POSITION, 0,
- CURSOR_X_POSITION, pos->x,
- CURSOR_Y_POSITION, pos->y);
+ CURSOR_X_POSITION, x_pos,
+ CURSOR_Y_POSITION, y_pos);
REG_SET_2(CURSOR_HOT_SPOT, 0,
CURSOR_HOT_SPOT_X, pos->x_hotspot,
@@ -990,7 +990,6 @@ static struct hubp_funcs dcn401_hubp_funcs = {
.hubp_soft_reset = hubp31_soft_reset,
.hubp_set_flip_int = hubp401_set_flip_int,
.hubp_in_blank = hubp401_in_blank,
- .hubp_update_force_pstate_disallow = hubp32_update_force_pstate_disallow,
.phantom_hubp_post_enable = hubp32_phantom_hubp_post_enable,
.hubp_update_mall_sel = hubp401_update_mall_sel,
.hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index 1f2eb2f727dc..d52ce58c6a98 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -949,7 +949,7 @@ void dce110_edp_backlight_control(
{
struct dc_context *ctx = link->ctx;
struct bp_transmitter_control cntl = { 0 };
- uint8_t pwrseq_instance;
+ uint8_t pwrseq_instance = 0;
unsigned int pre_T11_delay = OLED_PRE_T11_DELAY;
unsigned int post_T7_delay = OLED_POST_T7_DELAY;
@@ -1002,7 +1002,8 @@ void dce110_edp_backlight_control(
*/
/* dc_service_sleep_in_milliseconds(50); */
/*edp 1.2*/
- pwrseq_instance = link->panel_cntl->pwrseq_inst;
+ if (link->panel_cntl)
+ pwrseq_instance = link->panel_cntl->pwrseq_inst;
if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) {
if (!link->dc->config.edp_no_power_sequencing)
@@ -1231,20 +1232,21 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
* has changed or they enter protection state and hang.
*/
msleep(60);
- } else if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
- if (!link->dc->config.edp_no_power_sequencing) {
- /*
- * Sometimes, DP receiver chip power-controlled externally by an
- * Embedded Controller could be treated and used as eDP,
- * if it drives mobile display. In this case,
- * we shouldn't be doing power-sequencing, hence we can skip
- * waiting for T9-ready.
- */
- link->dc->link_srv->edp_receiver_ready_T9(link);
- }
}
}
+ if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
+ !link->dc->config.edp_no_power_sequencing) {
+ /*
+ * Sometimes, DP receiver chip power-controlled externally by an
+ * Embedded Controller could be treated and used as eDP,
+ * if it drives mobile display. In this case,
+ * we shouldn't be doing power-sequencing, hence we can skip
+ * waiting for T9-ready.
+ */
+ link->dc->link_srv->edp_receiver_ready_T9(link);
+ }
+
}
@@ -1549,6 +1551,7 @@ static enum dc_status dce110_enable_stream_timing(
0,
0,
0,
+ 0,
pipe_ctx->stream->signal,
true);
}
@@ -1597,6 +1600,11 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw(
&audio_output.crtc_info,
&pipe_ctx->stream->audio_info,
&audio_output.dp_link_info);
+
+ if (dc->config.disable_hbr_audio_dp2)
+ if (pipe_ctx->stream_res.audio->funcs->az_disable_hbr_audio &&
+ dc->link_srv->dp_is_128b_132b_signal(pipe_ctx))
+ pipe_ctx->stream_res.audio->funcs->az_disable_hbr_audio(pipe_ctx->stream_res.audio);
}
/* make sure no pipes syncd to the pipe being enabled */
@@ -1838,6 +1846,7 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
bool can_apply_edp_fast_boot = false;
bool can_apply_seamless_boot = false;
bool keep_edp_vdd_on = false;
+ struct dc_bios *dcb = dc->ctx->dc_bios;
DC_LOGGER_INIT();
@@ -1914,13 +1923,15 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
hws->funcs.edp_backlight_control(edp_link_with_sink, false);
}
/*resume from S3, no vbios posting, no need to power down again*/
- clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
+ if (dcb && dcb->funcs && !dcb->funcs->is_accelerated_mode(dcb))
+ clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
power_down_all_hw_blocks(dc);
disable_vga_and_power_gate_all_controllers(dc);
if (edp_link_with_sink && !keep_edp_vdd_on)
dc->hwss.edp_power_control(edp_link_with_sink, false);
- clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
+ if (dcb && dcb->funcs && !dcb->funcs->is_accelerated_mode(dcb))
+ clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
}
bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 1);
}
@@ -2340,19 +2351,6 @@ static void dce110_setup_audio_dto(
}
}
-static bool dce110_is_hpo_enabled(struct dc_state *context)
-{
- int i;
-
- for (i = 0; i < MAX_HPO_DP2_ENCODERS; i++) {
- if (context->res_ctx.is_hpo_dp_stream_enc_acquired[i]) {
- return true;
- }
- }
-
- return false;
-}
-
enum dc_status dce110_apply_ctx_to_hw(
struct dc *dc,
struct dc_state *context)
@@ -2361,8 +2359,8 @@ enum dc_status dce110_apply_ctx_to_hw(
struct dc_bios *dcb = dc->ctx->dc_bios;
enum dc_status status;
int i;
- bool was_hpo_enabled = dce110_is_hpo_enabled(dc->current_state);
- bool is_hpo_enabled = dce110_is_hpo_enabled(context);
+ bool was_hpo_acquired = resource_is_hpo_acquired(dc->current_state);
+ bool is_hpo_acquired = resource_is_hpo_acquired(context);
/* reset syncd pipes from disabled pipes */
if (dc->config.use_pipe_ctx_sync_logic)
@@ -2405,8 +2403,8 @@ enum dc_status dce110_apply_ctx_to_hw(
dce110_setup_audio_dto(dc, context);
- if (dc->hwseq->funcs.setup_hpo_hw_control && was_hpo_enabled != is_hpo_enabled) {
- dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, is_hpo_enabled);
+ if (dc->hwseq->funcs.setup_hpo_hw_control && was_hpo_acquired != is_hpo_acquired) {
+ dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, is_hpo_acquired);
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
@@ -2438,7 +2436,7 @@ enum dc_status dce110_apply_ctx_to_hw(
#ifdef CONFIG_DRM_AMD_DC_FP
if (hws->funcs.resync_fifo_dccg_dio)
- hws->funcs.resync_fifo_dccg_dio(hws, dc, context);
+ hws->funcs.resync_fifo_dccg_dio(hws, dc, context, i);
#endif
}
@@ -3312,7 +3310,6 @@ static const struct hw_sequencer_funcs dce110_funcs = {
static const struct hwseq_private_funcs dce110_private_funcs = {
.init_pipes = init_pipes,
- .update_plane_addr = update_plane_addr,
.set_input_transfer_func = dce110_set_input_transfer_func,
.set_output_transfer_func = dce110_set_output_transfer_func,
.power_down = dce110_power_down,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
index 1d2be574f668..a6a1db5ba8ba 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
@@ -1005,6 +1005,7 @@ enum dc_status dcn10_enable_stream_timing(
pipe_ctx->pipe_dlg_param.vstartup_start,
pipe_ctx->pipe_dlg_param.vupdate_offset,
pipe_ctx->pipe_dlg_param.vupdate_width,
+ pipe_ctx->pipe_dlg_param.pstate_keepout,
pipe_ctx->stream->signal,
true);
@@ -1554,7 +1555,7 @@ void dcn10_init_hw(struct dc *dc)
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
/* Align bw context with hw config when system resume. */
- if (dc->clk_mgr->clks.dispclk_khz != 0 && dc->clk_mgr->clks.dppclk_khz != 0) {
+ if (dc->clk_mgr && dc->clk_mgr->clks.dispclk_khz != 0 && dc->clk_mgr->clks.dppclk_khz != 0) {
dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz = dc->clk_mgr->clks.dispclk_khz;
dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz = dc->clk_mgr->clks.dppclk_khz;
}
@@ -1674,7 +1675,7 @@ void dcn10_init_hw(struct dc *dc)
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
}
- if (dc->clk_mgr->funcs->notify_wm_ranges)
+ if (dc->clk_mgr && dc->clk_mgr->funcs->notify_wm_ranges)
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
}
@@ -1697,10 +1698,10 @@ void dcn10_power_down_on_boot(struct dc *dc)
if (edp_link && edp_link->link_enc->funcs->is_dig_enabled &&
edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
dc->hwseq->funcs.edp_backlight_control &&
- dc->hwss.power_down &&
+ dc->hwseq->funcs.power_down &&
dc->hwss.edp_power_control) {
dc->hwseq->funcs.edp_backlight_control(edp_link, false);
- dc->hwss.power_down(dc);
+ dc->hwseq->funcs.power_down(dc);
dc->hwss.edp_power_control(edp_link, false);
} else {
for (i = 0; i < dc->link_count; i++) {
@@ -1708,8 +1709,8 @@ void dcn10_power_down_on_boot(struct dc *dc)
if (link->link_enc && link->link_enc->funcs->is_dig_enabled &&
link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
- dc->hwss.power_down) {
- dc->hwss.power_down(dc);
+ dc->hwseq->funcs.power_down) {
+ dc->hwseq->funcs.power_down(dc);
break;
}
@@ -2585,8 +2586,11 @@ static bool dcn10_is_rear_mpo_fix_required(struct pipe_ctx *pipe_ctx, enum dc_co
while (top->top_pipe)
top = top->top_pipe; // Traverse to top pipe_ctx
- if (top->plane_state && top->plane_state->layer_index == 0)
- return true; // Front MPO plane not hidden
+ if (top->plane_state && top->plane_state->layer_index == 0 && !top->plane_state->global_alpha)
+ // Global alpha used by top plane for PIP overlay
+ // Pre-multiplied/per-pixel alpha used by MPO
+ // Check top plane's global alpha to ensure layer_index > 0 not caused by PIP
+ return true; // MPO in use and front plane not hidden
}
}
return false;
@@ -2914,7 +2918,7 @@ static void dcn10_update_dchubp_dpp(
hubp->power_gated = false;
- hws->funcs.update_plane_addr(dc, pipe_ctx);
+ dc->hwss.update_plane_addr(dc, pipe_ctx);
if (is_pipe_tree_visible(pipe_ctx))
hubp->funcs->set_blank(hubp, false);
@@ -2997,7 +3001,8 @@ void dcn10_program_pipe(
calculate_vready_offset_for_group(pipe_ctx),
pipe_ctx->pipe_dlg_param.vstartup_start,
pipe_ctx->pipe_dlg_param.vupdate_offset,
- pipe_ctx->pipe_dlg_param.vupdate_width);
+ pipe_ctx->pipe_dlg_param.vupdate_width,
+ pipe_ctx->pipe_dlg_param.pstate_keepout);
pipe_ctx->stream_res.tg->funcs->set_vtg_params(
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, true);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_init.c
index a5bdac79a744..5e51e1761707 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_init.c
@@ -78,7 +78,6 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.get_clock = dcn10_get_clock,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
.calc_vupdate_position = dcn10_calc_vupdate_position,
- .power_down = dce110_power_down,
.set_backlight_level = dce110_set_backlight_level,
.set_abm_immediate_disable = dce110_set_abm_immediate_disable,
.set_pipe = dce110_set_pipe,
@@ -92,7 +91,6 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
static const struct hwseq_private_funcs dcn10_private_funcs = {
.init_pipes = dcn10_init_pipes,
- .update_plane_addr = dcn10_update_plane_addr,
.plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
.program_pipe = dcn10_program_pipe,
.update_mpcc = dcn10_update_mpcc,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
index 2532ad410cb5..a80c08582932 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
@@ -909,6 +909,7 @@ enum dc_status dcn20_enable_stream_timing(
pipe_ctx->pipe_dlg_param.vstartup_start,
pipe_ctx->pipe_dlg_param.vupdate_offset,
pipe_ctx->pipe_dlg_param.vupdate_width,
+ pipe_ctx->pipe_dlg_param.pstate_keepout,
pipe_ctx->stream->signal,
true);
@@ -1044,7 +1045,8 @@ bool dcn20_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
/*
* if above if is not executed then 'params' equal to 0 and set in bypass
*/
- mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+ if (mpc->funcs->set_output_gamma)
+ mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
return true;
}
@@ -1698,7 +1700,7 @@ static void dcn20_update_dchubp_dpp(
plane_state->update_flags.bits.input_csc_change ||
plane_state->update_flags.bits.color_space_change ||
plane_state->update_flags.bits.coeff_reduction_change) {
- struct dc_bias_and_scale bns_params = {0};
+ struct dc_bias_and_scale bns_params = plane_state->bias_and_scale;
// program the input csc
dpp->funcs->dpp_setup(dpp,
@@ -1715,7 +1717,6 @@ static void dcn20_update_dchubp_dpp(
}
if (dpp->funcs->dpp_program_bias_and_scale) {
//TODO :for CNVC set scale and bias registers if necessary
- build_prescale_params(&bns_params, plane_state);
dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params);
}
}
@@ -1825,7 +1826,7 @@ static void dcn20_update_dchubp_dpp(
params.subvp_save_surf_addr.subvp_index = pipe_ctx->subvp_index;
hwss_subvp_save_surf_addr(&params);
}
- hws->funcs.update_plane_addr(dc, pipe_ctx);
+ dc->hwss.update_plane_addr(dc, pipe_ctx);
}
if (pipe_ctx->update_flags.bits.enable)
@@ -1886,7 +1887,8 @@ static void dcn20_program_pipe(
calculate_vready_offset_for_group(pipe_ctx),
pipe_ctx->pipe_dlg_param.vstartup_start,
pipe_ctx->pipe_dlg_param.vupdate_offset,
- pipe_ctx->pipe_dlg_param.vupdate_width);
+ pipe_ctx->pipe_dlg_param.vupdate_width,
+ pipe_ctx->pipe_dlg_param.pstate_keepout);
if (dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM)
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
@@ -1921,22 +1923,28 @@ static void dcn20_program_pipe(
dc->res_pool->hubbub, pipe_ctx->plane_res.hubp->inst, pipe_ctx->hubp_regs.det_size);
}
- if (pipe_ctx->update_flags.raw || pipe_ctx->plane_state->update_flags.raw || pipe_ctx->stream->update_flags.raw)
+ if (pipe_ctx->update_flags.raw ||
+ (pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.raw) ||
+ pipe_ctx->stream->update_flags.raw)
dcn20_update_dchubp_dpp(dc, pipe_ctx, context);
- if (pipe_ctx->update_flags.bits.enable
- || pipe_ctx->plane_state->update_flags.bits.hdr_mult)
+ if (pipe_ctx->plane_state && (pipe_ctx->update_flags.bits.enable ||
+ pipe_ctx->plane_state->update_flags.bits.hdr_mult))
hws->funcs.set_hdr_multiplier(pipe_ctx);
if (hws->funcs.populate_mcm_luts) {
- hws->funcs.populate_mcm_luts(dc, pipe_ctx, pipe_ctx->plane_state->mcm_luts,
- pipe_ctx->plane_state->lut_bank_a);
- pipe_ctx->plane_state->lut_bank_a = !pipe_ctx->plane_state->lut_bank_a;
+ if (pipe_ctx->plane_state) {
+ hws->funcs.populate_mcm_luts(dc, pipe_ctx, pipe_ctx->plane_state->mcm_luts,
+ pipe_ctx->plane_state->lut_bank_a);
+ pipe_ctx->plane_state->lut_bank_a = !pipe_ctx->plane_state->lut_bank_a;
+ }
}
- if (pipe_ctx->update_flags.bits.enable ||
- pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
+
+ if (pipe_ctx->plane_state &&
+ (pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
pipe_ctx->plane_state->update_flags.bits.gamma_change ||
- pipe_ctx->plane_state->update_flags.bits.lut_3d)
+ pipe_ctx->plane_state->update_flags.bits.lut_3d ||
+ pipe_ctx->update_flags.bits.enable))
hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
/* dcn10_translate_regamma_to_hw_format takes 750us to finish
@@ -1946,7 +1954,8 @@ static void dcn20_program_pipe(
if (pipe_ctx->update_flags.bits.enable ||
pipe_ctx->update_flags.bits.plane_changed ||
pipe_ctx->stream->update_flags.bits.out_tf ||
- pipe_ctx->plane_state->update_flags.bits.output_tf_change)
+ (pipe_ctx->plane_state &&
+ pipe_ctx->plane_state->update_flags.bits.output_tf_change))
hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
/* If the pipe has been enabled or has a different opp, we
@@ -1970,7 +1979,7 @@ static void dcn20_program_pipe(
}
/* Set ABM pipe after other pipe configurations done */
- if (pipe_ctx->plane_state->visible) {
+ if ((pipe_ctx->plane_state && pipe_ctx->plane_state->visible)) {
if (pipe_ctx->stream_res.abm) {
dc->hwss.set_pipe(pipe_ctx);
pipe_ctx->stream_res.abm->funcs->set_abm_level(pipe_ctx->stream_res.abm,
@@ -2186,9 +2195,9 @@ static void post_unlock_reset_opp(struct dc *dc,
* yet power gated.
*/
dsc->funcs->dsc_wait_disconnect_pending_clear(dsc);
+ dsc->funcs->dsc_disable(dsc);
if (dccg->funcs->set_ref_dscclk)
dccg->funcs->set_ref_dscclk(dccg, dsc->inst);
- dsc->funcs->dsc_disable(dsc);
}
}
}
@@ -2283,6 +2292,9 @@ void dcn20_post_unlock_program_front_end(
}
}
+ if (!hwseq)
+ return;
+
/* P-State support transitions:
* Natural -> FPO: P-State disabled in prepare, force disallow anytime is safe
* FPO -> Natural: Unforce anytime after FW disable is safe (P-State will assert naturally)
@@ -2290,7 +2302,7 @@ void dcn20_post_unlock_program_front_end(
* FPO -> Unsupported: P-State disabled in prepare, unforce disallow anytime is safe
* FPO <-> SubVP: Force disallow is maintained on the FPO / SubVP pipes
*/
- if (hwseq && hwseq->funcs.update_force_pstate)
+ if (hwseq->funcs.update_force_pstate)
dc->hwseq->funcs.update_force_pstate(dc, context);
/* Only program the MALL registers after all the main and phantom pipes
@@ -2459,7 +2471,8 @@ bool dcn20_update_bandwidth(
calculate_vready_offset_for_group(pipe_ctx),
pipe_ctx->pipe_dlg_param.vstartup_start,
pipe_ctx->pipe_dlg_param.vupdate_offset,
- pipe_ctx->pipe_dlg_param.vupdate_width);
+ pipe_ctx->pipe_dlg_param.vupdate_width,
+ pipe_ctx->pipe_dlg_param.pstate_keepout);
pipe_ctx->stream_res.tg->funcs->set_vtg_params(
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, false);
@@ -2529,6 +2542,9 @@ bool dcn20_wait_for_blank_complete(
{
int counter;
+ if (!opp)
+ return false;
+
for (counter = 0; counter < 1000; counter++) {
if (!opp->funcs->dpg_is_pending(opp))
break;
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_init.c
index ef6488165b8f..32707b344f0b 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_init.c
@@ -105,7 +105,6 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
static const struct hwseq_private_funcs dcn20_private_funcs = {
.init_pipes = dcn10_init_pipes,
- .update_plane_addr = dcn20_update_plane_addr,
.plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
.update_mpcc = dcn20_update_mpcc,
.set_input_transfer_func = dcn20_set_input_transfer_func,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_init.c
index a13bf6c9386e..78351408e864 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_init.c
@@ -96,7 +96,6 @@ static const struct hw_sequencer_funcs dcn201_funcs = {
static const struct hwseq_private_funcs dcn201_private_funcs = {
.init_pipes = NULL,
- .update_plane_addr = dcn201_update_plane_addr,
.plane_atomic_disconnect = dcn201_plane_atomic_disconnect,
.program_pipe = dcn10_program_pipe,
.update_mpcc = dcn201_update_mpcc,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_init.c
index 3dfac372d165..e044e9e0a3a1 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_init.c
@@ -93,7 +93,6 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
.calc_vupdate_position = dcn10_calc_vupdate_position,
- .power_down = dce110_power_down,
.set_backlight_level = dcn21_set_backlight_level,
.set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
.set_pipe = dcn21_set_pipe,
@@ -109,7 +108,6 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
static const struct hwseq_private_funcs dcn21_private_funcs = {
.init_pipes = dcn10_init_pipes,
- .update_plane_addr = dcn20_update_plane_addr,
.plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
.update_mpcc = dcn20_update_mpcc,
.set_input_transfer_func = dcn20_set_input_transfer_func,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
index eaeeade31ed7..42c52284a868 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
@@ -398,7 +398,11 @@ bool dcn30_set_output_transfer_func(struct dc *dc,
}
}
- mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+ if (mpc->funcs->set_output_gamma)
+ mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+ else
+ DC_LOG_ERROR("%s: set_output_gamma function pointer is NULL.\n", __func__);
+
return ret;
}
@@ -625,7 +629,7 @@ void dcn30_init_hw(struct dc *dc)
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
uint32_t user_level = MAX_BACKLIGHT_LEVEL;
- if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks)
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
// Initialize the dccg
@@ -731,10 +735,10 @@ void dcn30_init_hw(struct dc *dc)
if (edp_link && edp_link->link_enc->funcs->is_dig_enabled &&
edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
dc->hwss.edp_backlight_control &&
- dc->hwss.power_down &&
+ hws->funcs.power_down &&
dc->hwss.edp_power_control) {
dc->hwss.edp_backlight_control(edp_link, false);
- dc->hwss.power_down(dc);
+ hws->funcs.power_down(dc);
dc->hwss.edp_power_control(edp_link, false);
} else {
for (i = 0; i < dc->link_count; i++) {
@@ -742,8 +746,8 @@ void dcn30_init_hw(struct dc *dc)
if (link->link_enc->funcs->is_dig_enabled &&
link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
- dc->hwss.power_down) {
- dc->hwss.power_down(dc);
+ hws->funcs.power_down) {
+ hws->funcs.power_down(dc);
break;
}
@@ -786,11 +790,12 @@ void dcn30_init_hw(struct dc *dc)
if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
- if (dc->clk_mgr->funcs->notify_wm_ranges)
+ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->notify_wm_ranges)
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
//if softmax is enabled then hardmax will be set by a different call
- if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->set_hard_max_memclk &&
+ !dc->clk_mgr->dc_mode_softmax_enabled)
dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c
index 4b32497c09d0..2a8dc40d2847 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c
@@ -113,7 +113,6 @@ static const struct hw_sequencer_funcs dcn30_funcs = {
static const struct hwseq_private_funcs dcn30_private_funcs = {
.init_pipes = dcn10_init_pipes,
- .update_plane_addr = dcn20_update_plane_addr,
.plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
.update_mpcc = dcn20_update_mpcc,
.set_input_transfer_func = dcn30_set_input_transfer_func,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_init.c
index 97e33eb7ac5a..93e49d87a67c 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_init.c
@@ -111,7 +111,6 @@ static const struct hw_sequencer_funcs dcn301_funcs = {
static const struct hwseq_private_funcs dcn301_private_funcs = {
.init_pipes = dcn10_init_pipes,
- .update_plane_addr = dcn20_update_plane_addr,
.plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
.update_mpcc = dcn20_update_mpcc,
.set_input_transfer_func = dcn30_set_input_transfer_func,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
index 746c522adf84..3d4b31bd9946 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
@@ -256,10 +256,10 @@ void dcn31_init_hw(struct dc *dc)
if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
- if (dc->clk_mgr->funcs->notify_wm_ranges)
+ if (dc->clk_mgr && dc->clk_mgr->funcs->notify_wm_ranges)
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
- if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+ if (dc->clk_mgr && dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c
index 9cb7afe0e731..56f3c70d4b55 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c
@@ -98,7 +98,6 @@ static const struct hw_sequencer_funcs dcn31_funcs = {
.set_flip_control_gsl = dcn20_set_flip_control_gsl,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
.calc_vupdate_position = dcn10_calc_vupdate_position,
- .power_down = dce110_power_down,
.set_backlight_level = dcn21_set_backlight_level,
.set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
.set_pipe = dcn21_set_pipe,
@@ -112,11 +111,11 @@ static const struct hw_sequencer_funcs dcn31_funcs = {
.optimize_pwr_state = dcn21_optimize_pwr_state,
.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
.update_visual_confirm_color = dcn10_update_visual_confirm_color,
+ .setup_hpo_hw_control = dcn31_setup_hpo_hw_control,
};
static const struct hwseq_private_funcs dcn31_private_funcs = {
.init_pipes = dcn10_init_pipes,
- .update_plane_addr = dcn20_update_plane_addr,
.plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
.update_mpcc = dcn20_update_mpcc,
.set_input_transfer_func = dcn30_set_input_transfer_func,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
index 388404cdeeaa..4e93eeedfc1b 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
@@ -355,14 +355,18 @@ void dcn314_calculate_pix_rate_divider(
}
}
-void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context)
+void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context, unsigned int current_pipe_idx)
{
unsigned int i;
struct pipe_ctx *pipe = NULL;
bool otg_disabled[MAX_PIPES] = {false};
for (i = 0; i < dc->res_pool->pipe_count; i++) {
- pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+ if (i <= current_pipe_idx) {
+ pipe = &context->res_ctx.pipe_ctx[i];
+ } else {
+ pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+ }
if (pipe->top_pipe || pipe->prev_odm_pipe)
continue;
@@ -377,7 +381,10 @@ void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc
hws->ctx->dc->res_pool->dccg->funcs->trigger_dio_fifo_resync(hws->ctx->dc->res_pool->dccg);
for (i = 0; i < dc->res_pool->pipe_count; i++) {
- pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+ if (i <= current_pipe_idx)
+ pipe = &context->res_ctx.pipe_ctx[i];
+ else
+ pipe = &dc->current_state->res_ctx.pipe_ctx[i];
if (otg_disabled[i]) {
int opp_inst[MAX_PIPES] = { pipe->stream_res.opp->inst };
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.h
index fb4f90f61b22..2305ad282f21 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.h
@@ -41,7 +41,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
void dcn314_calculate_pix_rate_divider(struct dc *dc, struct dc_state *context, const struct dc_stream_state *stream);
-void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context);
+void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context, unsigned int current_pipe_idx);
void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c
index 7a8db4b81471..68e6de6b5758 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c
@@ -100,7 +100,6 @@ static const struct hw_sequencer_funcs dcn314_funcs = {
.set_flip_control_gsl = dcn20_set_flip_control_gsl,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
.calc_vupdate_position = dcn10_calc_vupdate_position,
- .power_down = dce110_power_down,
.set_backlight_level = dcn21_set_backlight_level,
.set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
.set_pipe = dcn21_set_pipe,
@@ -115,11 +114,11 @@ static const struct hw_sequencer_funcs dcn314_funcs = {
.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
.update_visual_confirm_color = dcn10_update_visual_confirm_color,
.calculate_pix_rate_divider = dcn314_calculate_pix_rate_divider,
+ .setup_hpo_hw_control = dcn31_setup_hpo_hw_control,
};
static const struct hwseq_private_funcs dcn314_private_funcs = {
.init_pipes = dcn10_init_pipes,
- .update_plane_addr = dcn20_update_plane_addr,
.plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
.update_mpcc = dcn20_update_mpcc,
.set_input_transfer_func = dcn30_set_input_transfer_func,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
index 05d8f81daa06..a36e11606f90 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
@@ -582,7 +582,9 @@ bool dcn32_set_output_transfer_func(struct dc *dc,
}
}
- mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+ if (mpc->funcs->set_output_gamma)
+ mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+
return ret;
}
@@ -779,7 +781,7 @@ void dcn32_init_hw(struct dc *dc)
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
uint32_t user_level = MAX_BACKLIGHT_LEVEL;
- if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks)
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
// Initialize the dccg
@@ -901,10 +903,10 @@ void dcn32_init_hw(struct dc *dc)
if (edp_link->link_enc->funcs->is_dig_enabled &&
edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
dc->hwss.edp_backlight_control &&
- dc->hwss.power_down &&
+ hws->funcs.power_down &&
dc->hwss.edp_power_control) {
dc->hwss.edp_backlight_control(edp_link, false);
- dc->hwss.power_down(dc);
+ hws->funcs.power_down(dc);
dc->hwss.edp_power_control(edp_link, false);
}
}
@@ -914,8 +916,8 @@ void dcn32_init_hw(struct dc *dc)
if (link->link_enc->funcs->is_dig_enabled &&
link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
- dc->hwss.power_down) {
- dc->hwss.power_down(dc);
+ hws->funcs.power_down) {
+ hws->funcs.power_down(dc);
break;
}
@@ -958,10 +960,11 @@ void dcn32_init_hw(struct dc *dc)
if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
- if (dc->clk_mgr->funcs->notify_wm_ranges)
+ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->notify_wm_ranges)
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
- if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->set_hard_max_memclk &&
+ !dc->clk_mgr->dc_mode_softmax_enabled)
dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
@@ -982,8 +985,19 @@ void dcn32_init_hw(struct dc *dc)
dc->caps.dmub_caps.gecc_enable = dc->ctx->dmub_srv->dmub->feature_caps.gecc_enable;
dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver;
- if (dc->ctx->dmub_srv->dmub->fw_version <
+ /* for DCN401 testing only */
+ dc->caps.dmub_caps.fams_ver = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver;
+ if (dc->caps.dmub_caps.fams_ver == 2) {
+ /* FAMS2 is enabled */
+ dc->debug.fams2_config.bits.enable &= true;
+ } else if (dc->ctx->dmub_srv->dmub->fw_version <
DMUB_FW_VERSION(7, 0, 35)) {
+ /* FAMS2 is disabled */
+ dc->debug.fams2_config.bits.enable = false;
+ if (dc->debug.using_dml2 && dc->res_pool->funcs->update_bw_bounding_box) {
+ /* update bounding box if FAMS2 disabled */
+ dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params);
+ }
dc->debug.force_disable_subvp = true;
dc->debug.disable_fpo_optimizations = true;
}
@@ -1029,24 +1043,20 @@ void dcn32_update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
+ if (should_use_dto_dscclk)
+ dccg->funcs->set_dto_dscclk(dccg, dsc->inst);
dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
- if (should_use_dto_dscclk)
- dccg->funcs->set_dto_dscclk(dccg, dsc->inst, true);
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
ASSERT(odm_dsc);
+ if (should_use_dto_dscclk)
+ dccg->funcs->set_dto_dscclk(dccg, odm_dsc->inst);
odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
- if (should_use_dto_dscclk)
- dccg->funcs->set_dto_dscclk(dccg, odm_dsc->inst, true);
}
- dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
- dsc_cfg.pic_width *= opp_cnt;
-
optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
-
/* Enable DSC in OPTC */
DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
@@ -1060,13 +1070,9 @@ void dcn32_update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
OPTC_DSC_DISABLED, 0, 0);
/* only disconnect DSC block, DSC is disabled when OPP head pipe is reset */
- if (dccg->funcs->set_dto_dscclk)
- dccg->funcs->set_dto_dscclk(dccg, pipe_ctx->stream_res.dsc->inst, false);
- dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
+ dsc->funcs->dsc_disconnect(pipe_ctx->stream_res.dsc);
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
ASSERT(odm_pipe->stream_res.dsc);
- if (dccg->funcs->set_dto_dscclk)
- dccg->funcs->set_dto_dscclk(dccg, odm_pipe->stream_res.dsc->inst, false);
odm_pipe->stream_res.dsc->funcs->dsc_disconnect(odm_pipe->stream_res.dsc);
}
}
@@ -1137,10 +1143,7 @@ void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *
if (!pipe_ctx->next_odm_pipe && current_pipe_ctx->next_odm_pipe &&
current_pipe_ctx->next_odm_pipe->stream_res.dsc) {
struct display_stream_compressor *dsc = current_pipe_ctx->next_odm_pipe->stream_res.dsc;
- struct dccg *dccg = dc->res_pool->dccg;
- if (dccg->funcs->set_dto_dscclk)
- dccg->funcs->set_dto_dscclk(dccg, dsc->inst, false);
/* disconnect DSC block from stream */
dsc->funcs->dsc_disconnect(dsc);
}
@@ -1212,20 +1215,27 @@ void dcn32_calculate_pix_rate_divider(
}
}
-void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context)
+void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context, unsigned int current_pipe_idx)
{
unsigned int i;
struct pipe_ctx *pipe = NULL;
bool otg_disabled[MAX_PIPES] = {false};
+ struct dc_state *dc_state = NULL;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
- pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+ if (i <= current_pipe_idx) {
+ pipe = &context->res_ctx.pipe_ctx[i];
+ dc_state = context;
+ } else {
+ pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+ dc_state = dc->current_state;
+ }
if (!resource_is_pipe_type(pipe, OTG_MASTER))
continue;
if ((pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))
- && dc_state_get_pipe_subvp_type(dc->current_state, pipe) != SUBVP_PHANTOM) {
+ && dc_state_get_pipe_subvp_type(dc_state, pipe) != SUBVP_PHANTOM) {
pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
reset_sync_context_for_pipe(dc, context, i);
otg_disabled[i] = true;
@@ -1235,7 +1245,10 @@ void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_
hws->ctx->dc->res_pool->dccg->funcs->trigger_dio_fifo_resync(hws->ctx->dc->res_pool->dccg);
for (i = 0; i < dc->res_pool->pipe_count; i++) {
- pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+ if (i <= current_pipe_idx)
+ pipe = &context->res_ctx.pipe_ctx[i];
+ else
+ pipe = &dc->current_state->res_ctx.pipe_ctx[i];
if (otg_disabled[i]) {
int opp_inst[MAX_PIPES] = { pipe->stream_res.opp->inst };
@@ -1583,7 +1596,7 @@ void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context)
#ifdef CONFIG_DRM_AMD_DC_FP
if (hws->funcs.resync_fifo_dccg_dio)
- hws->funcs.resync_fifo_dccg_dio(hws, dc, context);
+ hws->funcs.resync_fifo_dccg_dio(hws, dc, context, i);
#endif
}
}
@@ -1717,6 +1730,28 @@ void dcn32_blank_phantom(struct dc *dc,
hws->funcs.wait_for_blank_complete(opp);
}
+/* phantom stream id's can change often, but can be identical between contexts.
+* This function checks for the condition the streams are identical to avoid
+* redundant pipe transitions.
+*/
+static bool is_subvp_phantom_topology_transition_seamless(
+ const struct dc_state *cur_ctx,
+ const struct dc_state *new_ctx,
+ const struct pipe_ctx *cur_pipe,
+ const struct pipe_ctx *new_pipe)
+{
+ enum mall_stream_type cur_pipe_type = dc_state_get_pipe_subvp_type(cur_ctx, cur_pipe);
+ enum mall_stream_type new_pipe_type = dc_state_get_pipe_subvp_type(new_ctx, new_pipe);
+
+ const struct dc_stream_state *cur_paired_stream = dc_state_get_paired_subvp_stream(cur_ctx, cur_pipe->stream);
+ const struct dc_stream_state *new_paired_stream = dc_state_get_paired_subvp_stream(new_ctx, new_pipe->stream);
+
+ return cur_pipe_type == SUBVP_PHANTOM &&
+ cur_pipe_type == new_pipe_type &&
+ cur_paired_stream && new_paired_stream &&
+ cur_paired_stream->stream_id == new_paired_stream->stream_id;
+}
+
bool dcn32_is_pipe_topology_transition_seamless(struct dc *dc,
const struct dc_state *cur_ctx,
const struct dc_state *new_ctx)
@@ -1735,7 +1770,8 @@ bool dcn32_is_pipe_topology_transition_seamless(struct dc *dc,
continue;
else if (resource_is_pipe_type(cur_pipe, OTG_MASTER)) {
if (resource_is_pipe_type(new_pipe, OTG_MASTER))
- if (cur_pipe->stream->stream_id == new_pipe->stream->stream_id)
+ if (cur_pipe->stream->stream_id == new_pipe->stream->stream_id ||
+ is_subvp_phantom_topology_transition_seamless(cur_ctx, new_ctx, cur_pipe, new_pipe))
/* OTG master with the same stream is seamless */
continue;
} else if (resource_is_pipe_type(cur_pipe, OPP_HEAD)) {
@@ -1821,3 +1857,13 @@ void dcn32_interdependent_update_lock(struct dc *dc,
dc->hwss.pipe_control_lock(dc, pipe, false);
}
}
+
+void dcn32_program_outstanding_updates(struct dc *dc,
+ struct dc_state *context)
+{
+ struct hubbub *hubbub = dc->res_pool->hubbub;
+
+ /* update compbuf if required */
+ if (hubbub->funcs->program_compbuf_size)
+ hubbub->funcs->program_compbuf_size(hubbub, context->bw_ctx.bw.dcn.compbuf_size_kb, true);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h
index db562e45d6ff..cac4a08b92a4 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h
@@ -75,7 +75,7 @@ void dcn32_update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div);
-void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context);
+void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context, unsigned int current_pipe_idx);
void dcn32_subvp_pipe_control_lock(struct dc *dc,
struct dc_state *context,
@@ -133,4 +133,8 @@ void dcn32_prepare_bandwidth(struct dc *dc,
void dcn32_interdependent_update_lock(struct dc *dc,
struct dc_state *context, bool lock);
+
+void dcn32_program_outstanding_updates(struct dc *dc,
+ struct dc_state *context);
+
#endif /* __DC_HWSS_DCN32_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c
index 5c50458b12cb..3422b564ae98 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c
@@ -120,11 +120,11 @@ static const struct hw_sequencer_funcs dcn32_funcs = {
.blank_phantom = dcn32_blank_phantom,
.is_pipe_topology_transition_seamless = dcn32_is_pipe_topology_transition_seamless,
.calculate_pix_rate_divider = dcn32_calculate_pix_rate_divider,
+ .program_outstanding_updates = dcn32_program_outstanding_updates,
};
static const struct hwseq_private_funcs dcn32_private_funcs = {
.init_pipes = dcn10_init_pipes,
- .update_plane_addr = dcn20_update_plane_addr,
.plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
.update_mpcc = dcn20_update_mpcc,
.set_input_transfer_func = dcn32_set_input_transfer_func,
@@ -163,7 +163,6 @@ static const struct hwseq_private_funcs dcn32_private_funcs = {
.is_dp_dig_pixel_rate_div_policy = dcn32_is_dp_dig_pixel_rate_div_policy,
.apply_single_controller_ctx_to_hw = dce110_apply_single_controller_ctx_to_hw,
.reset_back_end_for_pipe = dcn20_reset_back_end_for_pipe,
- .populate_mcm_luts = dcn401_populate_mcm_luts,
};
void dcn32_hw_sequencer_init_functions(struct dc *dc)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
index d5e9aec52a05..479fd3e89e5a 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
@@ -147,37 +147,6 @@ void dcn35_init_hw(struct dc *dc)
hws->funcs.bios_golden_init(dc);
}
- if (!dc->debug.disable_clock_gate) {
- REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
- REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
-
- /* Disable gating for PHYASYMCLK. This will be enabled in dccg if needed */
- REG_UPDATE_5(DCCG_GATE_DISABLE_CNTL2, PHYASYMCLK_ROOT_GATE_DISABLE, 1,
- PHYBSYMCLK_ROOT_GATE_DISABLE, 1,
- PHYCSYMCLK_ROOT_GATE_DISABLE, 1,
- PHYDSYMCLK_ROOT_GATE_DISABLE, 1,
- PHYESYMCLK_ROOT_GATE_DISABLE, 1);
-
- REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL4,
- DPIASYMCLK0_GATE_DISABLE, 0,
- DPIASYMCLK1_GATE_DISABLE, 0,
- DPIASYMCLK2_GATE_DISABLE, 0,
- DPIASYMCLK3_GATE_DISABLE, 0);
-
- REG_WRITE(DCCG_GATE_DISABLE_CNTL5, 0xFFFFFFFF);
- REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL5,
- DTBCLK_P0_GATE_DISABLE, 0,
- DTBCLK_P1_GATE_DISABLE, 0,
- DTBCLK_P2_GATE_DISABLE, 0,
- DTBCLK_P3_GATE_DISABLE, 0);
- REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL5,
- DPSTREAMCLK0_GATE_DISABLE, 0,
- DPSTREAMCLK1_GATE_DISABLE, 0,
- DPSTREAMCLK2_GATE_DISABLE, 0,
- DPSTREAMCLK3_GATE_DISABLE, 0);
-
- }
-
// Initialize the dccg
if (res_pool->dccg->funcs->dccg_init)
res_pool->dccg->funcs->dccg_init(res_pool->dccg);
@@ -235,7 +204,7 @@ void dcn35_init_hw(struct dc *dc)
if (hws->funcs.enable_power_gating_plane)
hws->funcs.enable_power_gating_plane(dc->hwseq, true);
*/
- if (res_pool->hubbub->funcs->dchubbub_init)
+ if (res_pool->hubbub && res_pool->hubbub->funcs->dchubbub_init)
res_pool->hubbub->funcs->dchubbub_init(dc->res_pool->hubbub);
/* If taking control over from VBIOS, we may want to optimize our first
* mode set, so we need to skip powering down pipes until we know which
@@ -271,6 +240,10 @@ void dcn35_init_hw(struct dc *dc)
dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
!dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
}
+ if (res_pool->dccg->funcs->dccg_root_gate_disable_control) {
+ for (i = 0; i < res_pool->pipe_count; i++)
+ res_pool->dccg->funcs->dccg_root_gate_disable_control(res_pool->dccg, i, 0);
+ }
for (i = 0; i < res_pool->audio_count; i++) {
struct audio *audio = res_pool->audios[i];
@@ -305,20 +278,6 @@ void dcn35_init_hw(struct dc *dc)
if (!dc->debug.disable_clock_gate) {
/* enable all DCN clock gating */
- REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
- REG_UPDATE_5(DCCG_GATE_DISABLE_CNTL2, SYMCLKA_FE_GATE_DISABLE, 0,
- SYMCLKB_FE_GATE_DISABLE, 0,
- SYMCLKC_FE_GATE_DISABLE, 0,
- SYMCLKD_FE_GATE_DISABLE, 0,
- SYMCLKE_FE_GATE_DISABLE, 0);
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, HDMICHARCLK0_GATE_DISABLE, 0);
- REG_UPDATE_5(DCCG_GATE_DISABLE_CNTL2, SYMCLKA_GATE_DISABLE, 0,
- SYMCLKB_GATE_DISABLE, 0,
- SYMCLKC_GATE_DISABLE, 0,
- SYMCLKD_GATE_DISABLE, 0,
- SYMCLKE_GATE_DISABLE, 0);
-
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
}
@@ -328,10 +287,10 @@ void dcn35_init_hw(struct dc *dc)
if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
- if (dc->clk_mgr->funcs->notify_wm_ranges)
+ if (dc->clk_mgr && dc->clk_mgr->funcs->notify_wm_ranges)
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
- if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+ if (dc->clk_mgr && dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
@@ -629,10 +588,10 @@ void dcn35_power_down_on_boot(struct dc *dc)
if (edp_link && edp_link->link_enc->funcs->is_dig_enabled &&
edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
dc->hwseq->funcs.edp_backlight_control &&
- dc->hwss.power_down &&
+ dc->hwseq->funcs.power_down &&
dc->hwss.edp_power_control) {
dc->hwseq->funcs.edp_backlight_control(edp_link, false);
- dc->hwss.power_down(dc);
+ dc->hwseq->funcs.power_down(dc);
dc->hwss.edp_power_control(edp_link, false);
} else {
for (i = 0; i < dc->link_count; i++) {
@@ -640,8 +599,8 @@ void dcn35_power_down_on_boot(struct dc *dc)
if (link->link_enc && link->link_enc->funcs->is_dig_enabled &&
link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
- dc->hwss.power_down) {
- dc->hwss.power_down(dc);
+ dc->hwseq->funcs.power_down) {
+ dc->hwseq->funcs.power_down(dc);
break;
}
@@ -1024,9 +983,6 @@ void dcn35_calc_blocks_to_gate(struct dc *dc, struct dc_state *context,
if (!hpo_frl_stream_enc_acquired && !hpo_dp_stream_enc_acquired)
update_state->pg_res_update[PG_HPO] = true;
- if (hpo_frl_stream_enc_acquired)
- update_state->pg_pipe_res_update[PG_HDMISTREAM][0] = true;
-
update_state->pg_res_update[PG_DWB] = true;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
@@ -1041,7 +997,7 @@ void dcn35_calc_blocks_to_gate(struct dc *dc, struct dc_state *context,
if (pipe_ctx->plane_res.hubp)
update_state->pg_pipe_res_update[PG_HUBP][pipe_ctx->plane_res.hubp->inst] = false;
- if (pipe_ctx->plane_res.dpp)
+ if (pipe_ctx->plane_res.dpp && pipe_ctx->plane_res.hubp)
update_state->pg_pipe_res_update[PG_DPP][pipe_ctx->plane_res.hubp->inst] = false;
if (pipe_ctx->plane_res.dpp || pipe_ctx->stream_res.opp)
@@ -1469,10 +1425,9 @@ void dcn35_set_drr(struct pipe_ctx **pipe_ctx,
struct timing_generator *tg = pipe_ctx[i]->stream_res.tg;
if ((tg != NULL) && tg->funcs) {
- struct dc_crtc_timing *timing = &pipe_ctx[i]->stream->timing;
- struct dc *dc = pipe_ctx[i]->stream->ctx->dc;
-
- if (dc->debug.static_screen_wait_frames) {
+ if (pipe_ctx[i]->stream && pipe_ctx[i]->stream->ctx->dc->debug.static_screen_wait_frames) {
+ struct dc_crtc_timing *timing = &pipe_ctx[i]->stream->timing;
+ struct dc *dc = pipe_ctx[i]->stream->ctx->dc;
unsigned int frame_rate = timing->pix_clk_100hz / (timing->h_total * timing->v_total);
if (frame_rate >= 120 && dc->caps.ips_support &&
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
index 428912f37129..2bbf1fef94fd 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
@@ -101,7 +101,6 @@ static const struct hw_sequencer_funcs dcn35_funcs = {
.set_flip_control_gsl = dcn20_set_flip_control_gsl,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
.calc_vupdate_position = dcn10_calc_vupdate_position,
- .power_down = dce110_power_down,
.set_backlight_level = dcn21_set_backlight_level,
.set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
.set_pipe = dcn21_set_pipe,
@@ -124,11 +123,11 @@ static const struct hw_sequencer_funcs dcn35_funcs = {
.root_clock_control = dcn35_root_clock_control,
.set_long_vtotal = dcn35_set_long_vblank,
.calculate_pix_rate_divider = dcn32_calculate_pix_rate_divider,
+ .program_outstanding_updates = dcn32_program_outstanding_updates,
};
static const struct hwseq_private_funcs dcn35_private_funcs = {
.init_pipes = dcn35_init_pipes,
- .update_plane_addr = dcn20_update_plane_addr,
.plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
.update_mpcc = dcn20_update_mpcc,
.set_input_transfer_func = dcn32_set_input_transfer_func,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c
index 55e791552bca..d00822e8daa5 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c
@@ -100,7 +100,6 @@ static const struct hw_sequencer_funcs dcn351_funcs = {
.set_flip_control_gsl = dcn20_set_flip_control_gsl,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
.calc_vupdate_position = dcn10_calc_vupdate_position,
- .power_down = dce110_power_down,
.set_backlight_level = dcn21_set_backlight_level,
.set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
.set_pipe = dcn21_set_pipe,
@@ -123,11 +122,12 @@ static const struct hw_sequencer_funcs dcn351_funcs = {
.root_clock_control = dcn35_root_clock_control,
.set_long_vtotal = dcn35_set_long_vblank,
.calculate_pix_rate_divider = dcn32_calculate_pix_rate_divider,
+ .program_outstanding_updates = dcn32_program_outstanding_updates,
+ .setup_hpo_hw_control = dcn35_setup_hpo_hw_control,
};
static const struct hwseq_private_funcs dcn351_private_funcs = {
.init_pipes = dcn35_init_pipes,
- .update_plane_addr = dcn20_update_plane_addr,
.plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
.update_mpcc = dcn20_update_mpcc,
.set_input_transfer_func = dcn32_set_input_transfer_func,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 2c50c0f745a0..0b743669f23b 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -221,8 +221,9 @@ void dcn401_init_hw(struct dc *dc)
int edp_num;
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
uint32_t user_level = MAX_BACKLIGHT_LEVEL;
+ int current_dchub_ref_freq = 0;
- if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) {
+ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks) {
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
// mark dcmode limits present if any clock has distinct AC and DC values from SMU
@@ -264,6 +265,8 @@ void dcn401_init_hw(struct dc *dc)
dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
&res_pool->ref_clocks.dccg_ref_clock_inKhz);
+ current_dchub_ref_freq = res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000;
+
(res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
res_pool->ref_clocks.dccg_ref_clock_inKhz,
&res_pool->ref_clocks.dchub_ref_clock_inKhz);
@@ -354,10 +357,10 @@ void dcn401_init_hw(struct dc *dc)
if (edp_link->link_enc->funcs->is_dig_enabled &&
edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
dc->hwss.edp_backlight_control &&
- dc->hwss.power_down &&
+ hws->funcs.power_down &&
dc->hwss.edp_power_control) {
dc->hwss.edp_backlight_control(edp_link, false);
- dc->hwss.power_down(dc);
+ hws->funcs.power_down(dc);
dc->hwss.edp_power_control(edp_link, false);
}
}
@@ -367,8 +370,8 @@ void dcn401_init_hw(struct dc *dc)
if (link->link_enc->funcs->is_dig_enabled &&
link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
- dc->hwss.power_down) {
- dc->hwss.power_down(dc);
+ hws->funcs.power_down) {
+ hws->funcs.power_down(dc);
break;
}
@@ -413,12 +416,9 @@ void dcn401_init_hw(struct dc *dc)
if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
- if (dc->clk_mgr->funcs->notify_wm_ranges)
+ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->notify_wm_ranges)
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
- if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
- dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
-
if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
dc->res_pool->hubbub->funcs->force_pstate_change_control(
dc->res_pool->hubbub, false, false);
@@ -436,9 +436,12 @@ void dcn401_init_hw(struct dc *dc)
dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver > 0;
dc->caps.dmub_caps.fams_ver = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver;
dc->debug.fams2_config.bits.enable &= dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver == 2;
- if (!dc->debug.fams2_config.bits.enable && dc->res_pool->funcs->update_bw_bounding_box) {
- /* update bounding box if FAMS2 disabled */
- dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params);
+ if ((!dc->debug.fams2_config.bits.enable && dc->res_pool->funcs->update_bw_bounding_box)
+ || res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000 != current_dchub_ref_freq) {
+ /* update bounding box if FAMS2 disabled, or if dchub clk has changed */
+ if (dc->clk_mgr)
+ dc->res_pool->funcs->update_bw_bounding_box(dc,
+ dc->clk_mgr->bw_params);
}
}
}
@@ -498,6 +501,7 @@ void dcn401_populate_mcm_luts(struct dc *dc,
enum MCM_LUT_XABLE lut3d_xable = MCM_LUT_DISABLE;
enum MCM_LUT_XABLE lut1d_xable = MCM_LUT_DISABLE;
bool is_17x17x17 = true;
+ bool rval;
dcn401_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable);
@@ -507,11 +511,10 @@ void dcn401_populate_mcm_luts(struct dc *dc,
if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL)
m_lut_params.pwl = &mcm_luts.lut1d_func->pwl;
else if (mcm_luts.lut1d_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
- cm_helper_translate_curve_to_hw_format(
- dc->ctx,
+ rval = cm3_helper_translate_curve_to_hw_format(
mcm_luts.lut1d_func,
&dpp_base->regamma_params, false);
- m_lut_params.pwl = &dpp_base->regamma_params;
+ m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
}
if (m_lut_params.pwl) {
if (mpc->funcs->populate_lut)
@@ -528,11 +531,10 @@ void dcn401_populate_mcm_luts(struct dc *dc,
m_lut_params.pwl = &mcm_luts.shaper->pwl;
else if (mcm_luts.shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
ASSERT(false);
- cm_helper_translate_curve_to_hw_format(
- dc->ctx,
+ rval = cm3_helper_translate_curve_to_hw_format(
mcm_luts.shaper,
&dpp_base->regamma_params, true);
- m_lut_params.pwl = &dpp_base->regamma_params;
+ m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
}
if (m_lut_params.pwl) {
if (mpc->funcs->populate_lut)
@@ -668,47 +670,40 @@ bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
int mpcc_id = pipe_ctx->plane_res.hubp->inst;
struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
- bool result = true;
+ bool result;
const struct pwl_params *lut_params = NULL;
+ bool rval;
mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
// 1D LUT
- if (plane_state->mcm_shaper_3dlut_setting == DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL) {
- if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
- lut_params = &plane_state->blend_tf.pwl;
- else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
- cm_helper_translate_curve_to_hw_format(plane_state->ctx,
- &plane_state->blend_tf,
- &dpp_base->regamma_params, false);
- lut_params = &dpp_base->regamma_params;
- }
- result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
- lut_params = NULL;
+ if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
+ lut_params = &plane_state->blend_tf.pwl;
+ else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
+ rval = cm3_helper_translate_curve_to_hw_format(&plane_state->blend_tf,
+ &dpp_base->regamma_params, false);
+ lut_params = rval ? &dpp_base->regamma_params : NULL;
}
+ result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
+ lut_params = NULL;
// Shaper
- if (plane_state->mcm_shaper_3dlut_setting == DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL) {
- if (plane_state->in_shaper_func.type == TF_TYPE_HWPWL)
- lut_params = &plane_state->in_shaper_func.pwl;
- else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
- // TODO: dpp_base replace
- ASSERT(false);
- cm_helper_translate_curve_to_hw_format(plane_state->ctx,
- &plane_state->in_shaper_func,
- &dpp_base->shaper_params, true);
- lut_params = &dpp_base->shaper_params;
- }
-
- result = mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
+ if (plane_state->in_shaper_func.type == TF_TYPE_HWPWL)
+ lut_params = &plane_state->in_shaper_func.pwl;
+ else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
+ // TODO: dpp_base replace
+ rval = cm3_helper_translate_curve_to_hw_format(&plane_state->in_shaper_func,
+ &dpp_base->shaper_params, true);
+ lut_params = rval ? &dpp_base->shaper_params : NULL;
}
+ result &= mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
// 3D
- if (plane_state->mcm_shaper_3dlut_setting == DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL) {
+ if (mpc->funcs->program_3dlut) {
if (plane_state->lut3d_func.state.bits.initialized == 1)
- result = mpc->funcs->program_3dlut(mpc, &plane_state->lut3d_func.lut_3d, mpcc_id);
+ result &= mpc->funcs->program_3dlut(mpc, &plane_state->lut3d_func.lut_3d, mpcc_id);
else
- result = mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
+ result &= mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
}
return result;
@@ -742,7 +737,9 @@ bool dcn401_set_output_transfer_func(struct dc *dc,
}
}
- mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+ if (mpc->funcs->set_output_gamma)
+ mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+
return ret;
}
@@ -871,6 +868,7 @@ enum dc_status dcn401_enable_stream_timing(
pipe_ctx->pipe_dlg_param.vstartup_start,
pipe_ctx->pipe_dlg_param.vupdate_offset,
pipe_ctx->pipe_dlg_param.vupdate_width,
+ pipe_ctx->pipe_dlg_param.pstate_keepout,
pipe_ctx->stream->signal,
true);
@@ -1115,10 +1113,10 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx)
.mirror = pipe_ctx->plane_state->horizontal_mirror,
.stream = pipe_ctx->stream
};
+ struct rect odm_slice_src = { 0 };
bool odm_combine_on = (pipe_ctx->next_odm_pipe != NULL) ||
(pipe_ctx->prev_odm_pipe != NULL);
int prev_odm_width = 0;
- int prev_odm_offset = 0;
struct pipe_ctx *prev_odm_pipe = NULL;
bool mpc_combine_on = false;
int bottom_pipe_x_pos = 0;
@@ -1183,12 +1181,12 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx)
prev_odm_pipe = pipe_ctx->prev_odm_pipe;
while (prev_odm_pipe != NULL) {
- prev_odm_width += prev_odm_pipe->plane_res.scl_data.recout.width;
- prev_odm_offset += prev_odm_pipe->plane_res.scl_data.recout.x;
+ odm_slice_src = resource_get_odm_slice_src_rect(prev_odm_pipe);
+ prev_odm_width += odm_slice_src.width;
prev_odm_pipe = prev_odm_pipe->prev_odm_pipe;
}
- x_pos -= (prev_odm_width + prev_odm_offset);
+ x_pos -= (prev_odm_width);
}
/* If the position is negative then we need to add to the hotspot
@@ -1311,8 +1309,10 @@ bool dcn401_apply_idle_power_optimizations(struct dc *dc, bool enable)
for (i = 0; i < dc->current_state->stream_count; i++) {
/* MALL SS messaging is not supported with PSR at this time */
if (dc->current_state->streams[i] != NULL &&
- dc->current_state->streams[i]->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED)
+ dc->current_state->streams[i]->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED) {
+ DC_LOG_MALL("MALL SS not supported with PSR at this time\n");
return false;
+ }
}
memset(&cmd, 0, sizeof(cmd));
@@ -1322,8 +1322,9 @@ bool dcn401_apply_idle_power_optimizations(struct dc *dc, bool enable)
if (enable) {
if (dcn401_check_no_memory_request_for_cab(dc)) {
/* 1. Check no memory request case for CAB.
- * If no memory request case, send CAB_ACTION NO_DF_REQ DMUB message
+ * If no memory request case, send CAB_ACTION NO_DCN_REQ DMUB message
*/
+ DC_LOG_MALL("sending CAB action NO_DCN_REQ\n");
cmd.cab.header.sub_type = DMUB_CMD__CAB_NO_DCN_REQ;
} else {
/* 2. Check if all surfaces can fit in CAB.
@@ -1351,13 +1352,16 @@ bool dcn401_apply_idle_power_optimizations(struct dc *dc, bool enable)
if (ways <= dc->caps.cache_num_ways && !mall_ss_unsupported) {
cmd.cab.header.sub_type = DMUB_CMD__CAB_DCN_SS_FIT_IN_CAB;
cmd.cab.cab_alloc_ways = ways;
+ DC_LOG_MALL("cab allocation: %d ways. CAB action: DCN_SS_FIT_IN_CAB\n", ways);
} else {
cmd.cab.header.sub_type = DMUB_CMD__CAB_DCN_SS_NOT_FIT_IN_CAB;
+ DC_LOG_MALL("frame does not fit in CAB: %d ways required. CAB action: DCN_SS_NOT_FIT_IN_CAB\n", ways);
}
}
} else {
/* Disable CAB */
cmd.cab.header.sub_type = DMUB_CMD__CAB_NO_IDLE_OPTIMIZATION;
+ DC_LOG_MALL("idle optimization disabled\n");
}
dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
@@ -1395,10 +1399,10 @@ void dcn401_prepare_bandwidth(struct dc *dc,
{
struct hubbub *hubbub = dc->res_pool->hubbub;
bool p_state_change_support = context->bw_ctx.bw.dcn.clk.p_state_change_support;
- unsigned int compbuf_size_kb = 0;
+ unsigned int compbuf_size = 0;
- /* Any transition into or out of a FAMS config should disable MCLK switching first to avoid hangs */
- if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) {
+ /* Any transition into P-State support should disable MCLK switching first to avoid hangs */
+ if (p_state_change_support) {
dc->optimized_required = true;
context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
}
@@ -1425,10 +1429,10 @@ void dcn401_prepare_bandwidth(struct dc *dc,
/* decrease compbuf size */
if (hubbub->funcs->program_compbuf_segments) {
- compbuf_size_kb = context->bw_ctx.bw.dcn.arb_regs.compbuf_size;
- dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.bw.dcn.arb_regs.compbuf_size);
+ compbuf_size = context->bw_ctx.bw.dcn.arb_regs.compbuf_size;
+ dc->wm_optimized_required |= (compbuf_size != dc->current_state->bw_ctx.bw.dcn.arb_regs.compbuf_size);
- hubbub->funcs->program_compbuf_segments(hubbub, compbuf_size_kb, false);
+ hubbub->funcs->program_compbuf_segments(hubbub, compbuf_size, false);
}
if (dc->debug.fams2_config.bits.enable) {
@@ -1437,7 +1441,7 @@ void dcn401_prepare_bandwidth(struct dc *dc,
dcn401_fams2_global_control_lock(dc, context, false);
}
- if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) {
+ if (p_state_change_support != context->bw_ctx.bw.dcn.clk.p_state_change_support) {
/* After disabling P-State, restore the original value to ensure we get the correct P-State
* on the next optimize. */
context->bw_ctx.bw.dcn.clk.p_state_change_support = p_state_change_support;
@@ -1530,7 +1534,7 @@ void dcn401_fams2_update_config(struct dc *dc, struct dc_state *context, bool en
if (!dc->ctx || !dc->ctx->dmub_srv || !dc->debug.fams2_config.bits.enable)
return;
- fams2_required = context->bw_ctx.bw.dcn.fams2_stream_count > 0;
+ fams2_required = context->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable;
dc_dmub_srv_fams2_update_config(dc, context, enable && fams2_required);
}
@@ -1542,7 +1546,6 @@ static void update_dsc_for_odm_change(struct dc *dc, struct dc_state *context,
struct pipe_ctx *old_pipe;
struct pipe_ctx *new_pipe;
struct pipe_ctx *old_opp_heads[MAX_PIPES];
- struct dccg *dccg = dc->res_pool->dccg;
struct pipe_ctx *old_otg_master;
int old_opp_head_count = 0;
@@ -1568,12 +1571,9 @@ static void update_dsc_for_odm_change(struct dc *dc, struct dc_state *context,
for (i = 0; i < old_opp_head_count; i++) {
old_pipe = old_opp_heads[i];
new_pipe = &context->res_ctx.pipe_ctx[old_pipe->pipe_idx];
- if (old_pipe->stream_res.dsc && !new_pipe->stream_res.dsc) {
- dccg->funcs->set_dto_dscclk(dccg,
- old_pipe->stream_res.dsc->inst, false);
+ if (old_pipe->stream_res.dsc && !new_pipe->stream_res.dsc)
old_pipe->stream_res.dsc->funcs->dsc_disconnect(
old_pipe->stream_res.dsc);
- }
}
}
}
@@ -1659,7 +1659,7 @@ void dcn401_hardware_release(struct dc *dc)
*/
if (dc->current_state) {
if ((!dc->clk_mgr->clks.p_state_change_support ||
- dc->current_state->bw_ctx.bw.dcn.fams2_stream_count > 0) &&
+ dc->current_state->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable) &&
dc->res_pool->hubbub->funcs->force_pstate_change_control)
dc->res_pool->hubbub->funcs->force_pstate_change_control(
dc->res_pool->hubbub, true, true);
@@ -1669,3 +1669,104 @@ void dcn401_hardware_release(struct dc *dc)
}
}
+void dcn401_wait_for_det_buffer_update(struct dc *dc, struct dc_state *context, struct pipe_ctx *otg_master)
+{
+ struct pipe_ctx *opp_heads[MAX_PIPES];
+ struct pipe_ctx *dpp_pipes[MAX_PIPES];
+ struct hubbub *hubbub = dc->res_pool->hubbub;
+ int dpp_count = 0;
+
+ if (!otg_master->stream)
+ return;
+
+ int slice_count = resource_get_opp_heads_for_otg_master(otg_master,
+ &context->res_ctx, opp_heads);
+
+ for (int slice_idx = 0; slice_idx < slice_count; slice_idx++) {
+ if (opp_heads[slice_idx]->plane_state) {
+ dpp_count = resource_get_dpp_pipes_for_opp_head(
+ opp_heads[slice_idx],
+ &context->res_ctx,
+ dpp_pipes);
+ for (int dpp_idx = 0; dpp_idx < dpp_count; dpp_idx++) {
+ struct pipe_ctx *dpp_pipe = dpp_pipes[dpp_idx];
+ if (dpp_pipe && hubbub &&
+ dpp_pipe->plane_res.hubp &&
+ hubbub->funcs->wait_for_det_update)
+ hubbub->funcs->wait_for_det_update(hubbub, dpp_pipe->plane_res.hubp->inst);
+ }
+ }
+ }
+}
+
+void dcn401_interdependent_update_lock(struct dc *dc,
+ struct dc_state *context, bool lock)
+{
+ unsigned int i = 0;
+ struct pipe_ctx *pipe = NULL;
+ struct timing_generator *tg = NULL;
+ bool pipe_unlocked[MAX_PIPES] = {0};
+
+ if (lock) {
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ pipe = &context->res_ctx.pipe_ctx[i];
+ tg = pipe->stream_res.tg;
+
+ if (!resource_is_pipe_type(pipe, OTG_MASTER) ||
+ !tg->funcs->is_tg_enabled(tg) ||
+ dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_PHANTOM)
+ continue;
+ dc->hwss.pipe_control_lock(dc, pipe, true);
+ }
+ } else {
+ /* Unlock pipes based on the change in DET allocation instead of pipe index
+ * Prevents over allocation of DET during unlock process
+ * e.g. 2 pipe config with different streams with a max of 20 DET segments
+ * Before: After:
+ * - Pipe0: 10 DET segments - Pipe0: 12 DET segments
+ * - Pipe1: 10 DET segments - Pipe1: 8 DET segments
+ * If Pipe0 gets updated first, 22 DET segments will be allocated
+ */
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ pipe = &context->res_ctx.pipe_ctx[i];
+ tg = pipe->stream_res.tg;
+ int current_pipe_idx = i;
+
+ if (!resource_is_pipe_type(pipe, OTG_MASTER) ||
+ !tg->funcs->is_tg_enabled(tg) ||
+ dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_PHANTOM) {
+ pipe_unlocked[i] = true;
+ continue;
+ }
+
+ // If the same stream exists in old context, ensure the OTG_MASTER pipes for the same stream get compared
+ struct pipe_ctx *old_otg_master = resource_get_otg_master_for_stream(&dc->current_state->res_ctx, pipe->stream);
+
+ if (old_otg_master)
+ current_pipe_idx = old_otg_master->pipe_idx;
+ if (resource_calculate_det_for_stream(context, pipe) <
+ resource_calculate_det_for_stream(dc->current_state, &dc->current_state->res_ctx.pipe_ctx[current_pipe_idx])) {
+ dc->hwss.pipe_control_lock(dc, pipe, false);
+ pipe_unlocked[i] = true;
+ dcn401_wait_for_det_buffer_update(dc, context, pipe);
+ }
+ }
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ if (pipe_unlocked[i])
+ continue;
+ pipe = &context->res_ctx.pipe_ctx[i];
+ dc->hwss.pipe_control_lock(dc, pipe, false);
+ }
+ }
+}
+
+void dcn401_program_outstanding_updates(struct dc *dc,
+ struct dc_state *context)
+{
+ struct hubbub *hubbub = dc->res_pool->hubbub;
+
+ /* update compbuf if required */
+ if (hubbub->funcs->program_compbuf_segments)
+ hubbub->funcs->program_compbuf_segments(hubbub, context->bw_ctx.bw.dcn.arb_regs.compbuf_size, true);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
index 8e9c1c17aa66..a27e62081685 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
@@ -81,4 +81,7 @@ void dcn401_hardware_release(struct dc *dc);
void dcn401_update_odm(struct dc *dc, struct dc_state *context,
struct pipe_ctx *otg_master);
void adjust_hotspot_between_slices_for_2x_magnify(uint32_t cursor_width, struct dc_cursor_position *pos_cpy);
+void dcn401_wait_for_det_buffer_update(struct dc *dc, struct dc_state *context, struct pipe_ctx *otg_master);
+void dcn401_interdependent_update_lock(struct dc *dc, struct dc_state *context, bool lock);
+void dcn401_program_outstanding_updates(struct dc *dc, struct dc_state *context);
#endif /* __DC_HWSS_DCN401_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
index 6a768702c7bd..a2ca07235c83 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
@@ -38,7 +38,7 @@ static const struct hw_sequencer_funcs dcn401_funcs = {
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn20_disable_plane,
.pipe_control_lock = dcn20_pipe_control_lock,
- .interdependent_update_lock = dcn32_interdependent_update_lock,
+ .interdependent_update_lock = dcn401_interdependent_update_lock,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn401_prepare_bandwidth,
.optimize_bandwidth = dcn401_optimize_bandwidth,
@@ -99,12 +99,11 @@ static const struct hw_sequencer_funcs dcn401_funcs = {
.fams2_global_control_lock = dcn401_fams2_global_control_lock,
.fams2_update_config = dcn401_fams2_update_config,
.fams2_global_control_lock_fast = dcn401_fams2_global_control_lock_fast,
- .power_down = dce110_power_down,
+ .program_outstanding_updates = dcn401_program_outstanding_updates,
};
static const struct hwseq_private_funcs dcn401_private_funcs = {
.init_pipes = dcn10_init_pipes,
- .update_plane_addr = dcn20_update_plane_addr,
.plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
.update_mpcc = dcn20_update_mpcc,
.set_input_transfer_func = dcn32_set_input_transfer_func,
@@ -115,8 +114,6 @@ static const struct hwseq_private_funcs dcn401_private_funcs = {
.reset_hw_ctx_wrap = dcn20_reset_hw_ctx_wrap,
.enable_stream_timing = dcn401_enable_stream_timing,
.edp_backlight_control = dce110_edp_backlight_control,
- .disable_stream_gating = dcn20_disable_stream_gating,
- .enable_stream_gating = dcn20_enable_stream_gating,
.setup_vupdate_interrupt = dcn20_setup_vupdate_interrupt,
.did_underflow_occur = dcn10_did_underflow_occur,
.init_blank = dcn32_init_blank,
@@ -136,12 +133,11 @@ static const struct hwseq_private_funcs dcn401_private_funcs = {
.dccg_init = dcn20_dccg_init,
.set_mcm_luts = dcn401_set_mcm_luts,
.program_mall_pipe_config = dcn32_program_mall_pipe_config,
- .update_force_pstate = dcn32_update_force_pstate,
.update_mall_sel = dcn32_update_mall_sel,
.calculate_dccg_k1_k2_values = NULL,
.apply_single_controller_ctx_to_hw = dce110_apply_single_controller_ctx_to_hw,
.reset_back_end_for_pipe = dcn20_reset_back_end_for_pipe,
- .populate_mcm_luts = dcn401_populate_mcm_luts,
+ .populate_mcm_luts = NULL,
};
void dcn401_hw_sequencer_init_functions(struct dc *dc)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
index d05be65a2256..ac9205625623 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
@@ -240,7 +240,6 @@ struct hw_sequencer_funcs {
void (*program_triplebuffer)(const struct dc *dc,
struct pipe_ctx *pipe_ctx, bool enableTripleBuffer);
void (*update_pending_status)(struct pipe_ctx *pipe_ctx);
- void (*power_down)(struct dc *dc);
void (*update_dsc_pg)(struct dc *dc, struct dc_state *context, bool safe_to_disable);
/* Pipe Lock Related */
@@ -460,6 +459,9 @@ struct hw_sequencer_funcs {
bool enable);
void (*fams2_global_control_lock_fast)(union block_sequence_params *params);
void (*set_long_vtotal)(struct pipe_ctx **pipe_ctx, int num_pipes, uint32_t v_total_min, uint32_t v_total_max);
+ void (*program_outstanding_updates)(struct dc *dc,
+ struct dc_state *context);
+ void (*setup_hpo_hw_control)(const struct dce_hwseq *hws, bool enable);
};
void color_space_to_black_color(
@@ -520,6 +522,21 @@ void hwss_build_fast_sequence(struct dc *dc,
struct dc_stream_status *stream_status,
struct dc_state *context);
+void hwss_wait_for_all_blank_complete(struct dc *dc,
+ struct dc_state *context);
+
+void hwss_wait_for_odm_update_pending_complete(struct dc *dc,
+ struct dc_state *context);
+
+void hwss_wait_for_no_pipes_pending(struct dc *dc,
+ struct dc_state *context);
+
+void hwss_wait_for_outstanding_hw_updates(struct dc *dc,
+ struct dc_state *dc_context);
+
+void hwss_process_outstanding_hw_updates(struct dc *dc,
+ struct dc_state *dc_context);
+
void hwss_send_dmcub_cmd(union block_sequence_params *params);
void hwss_program_manual_trigger(union block_sequence_params *params);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h
index 7ac3f2a09487..0ac675456979 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h
@@ -76,8 +76,6 @@ struct hwseq_private_funcs {
void (*enable_stream_gating)(struct dc *dc, struct pipe_ctx *pipe_ctx);
void (*init_pipes)(struct dc *dc, struct dc_state *context);
void (*reset_hw_ctx_wrap)(struct dc *dc, struct dc_state *context);
- void (*update_plane_addr)(const struct dc *dc,
- struct pipe_ctx *pipe_ctx);
void (*plane_atomic_disconnect)(struct dc *dc,
struct dc_state *state,
struct pipe_ctx *pipe_ctx);
@@ -170,7 +168,8 @@ struct hwseq_private_funcs {
unsigned int *k1_div,
unsigned int *k2_div);
void (*resync_fifo_dccg_dio)(struct dce_hwseq *hws, struct dc *dc,
- struct dc_state *context);
+ struct dc_state *context,
+ unsigned int current_pipe_idx);
enum dc_status (*apply_single_controller_ctx_to_hw)(
struct pipe_ctx *pipe_ctx,
struct dc_state *context,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index 4c8e6436c7e1..bfb8b8502d20 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -534,8 +534,8 @@ struct dcn_bw_output {
unsigned int legacy_svp_drr_stream_index;
bool legacy_svp_drr_stream_index_valid;
struct dml2_mcache_surface_allocation mcache_allocations[DML2_MAX_PLANES];
+ struct dmub_cmd_fams2_global_config fams2_global_config;
struct dmub_fams2_stream_static_state fams2_stream_params[DML2_MAX_PLANES];
- unsigned fams2_stream_count;
struct dml2_display_arb_regs arb_regs;
};
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h b/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h
index b6203253111c..8c18efc2aa70 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h
@@ -46,6 +46,8 @@ struct audio_funcs {
const struct audio_info *audio_info,
const struct audio_dp_link_info *dp_link_info);
+ void (*az_disable_hbr_audio)(struct audio *audio);
+
void (*wall_dto_setup)(struct audio *audio,
enum signal_type signal,
const struct audio_crtc_info *crtc_info,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
index d5fefce3e74b..2d06067ff36d 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
@@ -29,9 +29,6 @@
#include "dc.h"
#include "dm_pp_smu.h"
-#define DCN_MINIMUM_DISPCLK_Khz 100000
-#define DCN_MINIMUM_DPPCLK_Khz 100000
-
/* Constants */
#define DDR4_DRAM_WIDTH 64
#define WM_A 0
@@ -180,6 +177,7 @@ struct clk_state_registers_and_bypass {
uint32_t dispclk;
uint32_t dppclk;
uint32_t dtbclk;
+ uint32_t fclk;
uint32_t dppclk_bypass;
uint32_t dcfclk_bypass;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
index 12282f96dfe1..c2dd061892f4 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
@@ -191,7 +191,8 @@ enum dentist_divider_range {
CLK_SR_DCN401(CLK0_CLK1_DFS_CNTL, CLK01, 0), \
CLK_SR_DCN401(CLK0_CLK2_DFS_CNTL, CLK01, 0), \
CLK_SR_DCN401(CLK0_CLK3_DFS_CNTL, CLK01, 0), \
- CLK_SR_DCN401(CLK0_CLK4_DFS_CNTL, CLK01, 0)
+ CLK_SR_DCN401(CLK0_CLK4_DFS_CNTL, CLK01, 0), \
+ CLK_SR_DCN401(CLK2_CLK2_DFS_CNTL, CLK20, 0)
#define CLK_COMMON_MASK_SH_LIST_DCN401(mask_sh) \
CLK_COMMON_MASK_SH_LIST_DCN321(mask_sh)
@@ -235,6 +236,7 @@ struct clk_mgr_registers {
uint32_t CLK1_CLK2_DFS_CNTL;
uint32_t CLK1_CLK3_DFS_CNTL;
uint32_t CLK1_CLK4_DFS_CNTL;
+ uint32_t CLK2_CLK2_DFS_CNTL;
uint32_t CLK1_CLK0_CURRENT_CNT;
uint32_t CLK1_CLK1_CURRENT_CNT;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
index 4fb1aacee894..e94e9ba60f55 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
@@ -211,11 +211,9 @@ struct dccg_funcs {
struct dccg *dccg,
enum streamclk_source src,
uint32_t otg_inst);
- void (*set_dto_dscclk)(
- struct dccg *dccg,
- uint32_t dsc_inst,
- bool enable);
+ void (*set_dto_dscclk)(struct dccg *dccg, uint32_t dsc_inst);
void (*set_ref_dscclk)(struct dccg *dccg, uint32_t dsc_inst);
+ void (*dccg_root_gate_disable_control)(struct dccg *dccg, uint32_t pipe_idx, uint32_t disable_clock_gating);
};
#endif //__DAL_DCCG_H__
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
index dd2b2864876c..67c32401893e 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
@@ -227,6 +227,7 @@ struct hubbub_funcs {
void (*get_mall_en)(struct hubbub *hubbub, unsigned int *mall_in_use);
void (*program_det_segments)(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_seg);
void (*program_compbuf_segments)(struct hubbub *hubbub, unsigned compbuf_size_seg, bool safe_to_increase);
+ void (*wait_for_det_update)(struct hubbub *hubbub, int hubp_inst);
};
struct hubbub {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
index 27bba47186e9..41c76ba9ba56 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
@@ -217,12 +217,13 @@ enum optc_dsc_mode {
};
struct dc_bias_and_scale {
- uint16_t scale_red;
- uint16_t bias_red;
- uint16_t scale_green;
- uint16_t bias_green;
- uint16_t scale_blue;
- uint16_t bias_blue;
+ uint32_t scale_red;
+ uint32_t bias_red;
+ uint32_t scale_green;
+ uint32_t bias_green;
+ uint32_t scale_blue;
+ uint32_t bias_blue;
+ bool bias_and_scale_valid;
};
enum test_pattern_dyn_range {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
index 5f6c7daa14d9..a8b44f398ce6 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
@@ -63,7 +63,7 @@ union dcn_watermark_set {
struct dml2_dchub_watermark_regs b;
struct dml2_dchub_watermark_regs c;
struct dml2_dchub_watermark_regs d;
- } dcn4; //dcn4+
+ } dcn4x; //dcn4+
};
struct dce_watermarks {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/optc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/optc.h
index 287bf8a90ff6..03cbcbb36f1c 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/optc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/optc.h
@@ -65,6 +65,7 @@ struct optc {
int vupdate_offset;
int vupdate_width;
int vready_offset;
+ int pstate_keepout;
struct dc_crtc_timing orginal_patched_timing;
enum signal_type signal;
};
@@ -110,6 +111,7 @@ void optc1_program_timing(struct timing_generator *optc,
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+ int pstate_keepout,
const enum signal_type signal,
bool use_vbios);
@@ -127,7 +129,8 @@ void optc1_program_global_sync(struct timing_generator *optc,
int vready_offset,
int vstartup_start,
int vupdate_offset,
- int vupdate_width);
+ int vupdate_width,
+ int pstate_keepout);
bool optc1_disable_crtc(struct timing_generator *optc);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
index e5e11c84e9e2..fe7f3137f228 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
@@ -271,7 +271,9 @@ struct stream_encoder_funcs {
struct stream_encoder *enc, unsigned int pix_per_container);
void (*enable_fifo)(struct stream_encoder *enc);
void (*disable_fifo)(struct stream_encoder *enc);
+ bool (*is_fifo_enabled)(struct stream_encoder *enc);
void (*map_stream_to_link)(struct stream_encoder *enc, uint32_t stream_enc_inst, uint32_t link_enc_inst);
+ uint32_t (*get_pixels_per_cycle)(struct stream_encoder *enc);
};
struct hpo_dp_stream_encoder_state {
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 0f453452234c..3d4c8bd42b49 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
@@ -172,6 +172,7 @@ struct timing_generator_funcs {
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+ int pstate_keepout,
const enum signal_type signal,
bool use_vbios
);
@@ -256,7 +257,8 @@ struct timing_generator_funcs {
int vready_offset,
int vstartup_start,
int vupdate_offset,
- int vupdate_width);
+ int vupdate_width,
+ int pstate_keepout);
void (*enable_optc_clock)(struct timing_generator *tg, bool enable);
void (*program_stereo)(struct timing_generator *tg,
const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
index 28da1dddf0a0..45262cba675e 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
@@ -245,16 +245,6 @@ struct transform_funcs {
void (*set_cursor_attributes)(
struct transform *xfm_base,
const struct dc_cursor_attributes *attr);
-
- bool (*transform_program_blnd_lut)(
- struct transform *xfm,
- const struct pwl_params *params);
- bool (*transform_program_shaper_lut)(
- struct transform *xfm,
- const struct pwl_params *params);
- bool (*transform_program_3dlut)(
- struct transform *xfm,
- struct tetrahedral_params *params);
};
const uint16_t *get_filter_2tap_16p(void);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h
index 96d40d33a1f9..cd1157d225ab 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
@@ -639,4 +639,11 @@ struct dscl_prog_data *resource_get_dscl_prog_data(struct pipe_ctx *pipe_ctx);
* @dml2_options: struct to hold callbacks
*/
void resource_init_common_dml2_callbacks(struct dc *dc, struct dml2_configuration_options *dml2_options);
+
+/*
+ *Calculate total DET allocated for all pipes for a given OTG_MASTER pipe
+ */
+int resource_calculate_det_for_stream(struct dc_state *state, struct pipe_ctx *otg_master);
+
+bool resource_is_hpo_acquired(struct dc_state *context);
#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
index 555c1c484cfd..ff8fe1a94965 100644
--- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
+++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
@@ -67,6 +67,8 @@ static void dp_retrain_link_dp_test(struct dc_link *link,
{
struct pipe_ctx *pipes[MAX_PIPES];
struct dc_state *state = link->dc->current_state;
+ bool was_hpo_acquired = resource_is_hpo_acquired(link->dc->current_state);
+ bool is_hpo_acquired;
uint8_t count;
int i;
@@ -83,6 +85,12 @@ static void dp_retrain_link_dp_test(struct dc_link *link,
pipes[i]);
}
+ if (link->dc->hwss.setup_hpo_hw_control) {
+ is_hpo_acquired = resource_is_hpo_acquired(state);
+ if (was_hpo_acquired != is_hpo_acquired)
+ link->dc->hwss.setup_hpo_hw_control(link->dc->hwseq, is_hpo_acquired);
+ }
+
for (i = count-1; i >= 0; i--)
link_set_dpms_on(state, pipes[i]);
}
@@ -804,8 +812,11 @@ bool dp_set_test_pattern(
break;
}
+ if (!pipe_ctx->stream)
+ return false;
+
if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable) {
- if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
+ if (should_use_dmub_lock(pipe_ctx->stream->link)) {
union dmub_hw_lock_flags hw_locks = { 0 };
struct dmub_hw_lock_inst_flags inst_flags = { 0 };
diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
index b76737b7b9e4..3e47a6735912 100644
--- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
+++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
@@ -74,7 +74,10 @@ void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
- if (stream_enc && stream_enc->funcs->disable_fifo)
+ if (!stream_enc)
+ return;
+
+ if (stream_enc->funcs->disable_fifo)
stream_enc->funcs->disable_fifo(stream_enc);
if (stream_enc->funcs->set_input_mode)
stream_enc->funcs->set_input_mode(stream_enc, 0);
diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c
index e1257404357b..cec68c5dba13 100644
--- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c
@@ -28,6 +28,8 @@
#include "dccg.h"
#include "clk_mgr.h"
+#define DC_LOGGER link->ctx->logger
+
void set_hpo_dp_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
struct fixed31_32 throttled_vcp_size)
{
@@ -108,6 +110,11 @@ void enable_hpo_dp_link_output(struct dc_link *link,
enum clock_source_id clock_source,
const struct dc_link_settings *link_settings)
{
+ if (!link_res->hpo_dp_link_enc) {
+ DC_LOG_ERROR("%s: invalid hpo_dp_link_enc\n", __func__);
+ return;
+ }
+
if (link->dc->res_pool->dccg->funcs->set_symclk32_le_root_clock_gating)
link->dc->res_pool->dccg->funcs->set_symclk32_le_root_clock_gating(
link->dc->res_pool->dccg,
@@ -124,6 +131,11 @@ void disable_hpo_dp_link_output(struct dc_link *link,
const struct link_resource *link_res,
enum signal_type signal)
{
+ if (!link_res->hpo_dp_link_enc) {
+ DC_LOG_ERROR("%s: invalid hpo_dp_link_enc\n", __func__);
+ return;
+ }
+
link_res->hpo_dp_link_enc->funcs->link_disable(link_res->hpo_dp_link_enc);
link_res->hpo_dp_link_enc->funcs->disable_link_phy(
link_res->hpo_dp_link_enc, signal);
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
index bba644024780..d21ee9d12d26 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -863,7 +863,6 @@ static bool detect_link_and_local_sink(struct dc_link *link,
struct dc_sink *prev_sink = NULL;
struct dpcd_caps prev_dpcd_caps;
enum dc_connection_type new_connection_type = dc_connection_none;
- enum dc_connection_type pre_connection_type = link->type;
const uint32_t post_oui_delay = 30; // 30ms
DC_LOGGER_INIT(link->ctx->logger);
@@ -965,7 +964,6 @@ static bool detect_link_and_local_sink(struct dc_link *link,
}
if (!detect_dp(link, &sink_caps, reason)) {
- link->type = pre_connection_type;
if (prev_sink)
dc_sink_release(prev_sink);
@@ -1191,8 +1189,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
//sink only can use supported link rate table, we are foreced to enable it
if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)
link->panel_config.ilr.optimize_edp_link_rate = true;
- if (edp_is_ilr_optimization_enabled(link))
- link->reported_link_cap.link_rate = get_max_link_rate_from_ilr_table(link);
+ link->reported_link_cap.link_rate = get_max_edp_link_rate(link);
}
} else {
@@ -1299,8 +1296,7 @@ bool link_detect(struct dc_link *link, enum dc_detect_reason reason)
link->dpcd_caps.is_mst_capable)
is_delegated_to_mst_top_mgr = discover_dp_mst_topology(link, reason);
- if (is_local_sink_detect_success &&
- pre_link_type == dc_connection_mst_branch &&
+ if (pre_link_type == dc_connection_mst_branch &&
link->type != dc_connection_mst_branch)
is_delegated_to_mst_top_mgr = link_reset_cur_dp_mst_topology(link);
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
index 65607589495f..c4e03482ba9a 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
@@ -817,17 +817,17 @@ void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
+ if (should_use_dto_dscclk)
+ dccg->funcs->set_dto_dscclk(dccg, dsc->inst);
dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
- if (should_use_dto_dscclk)
- dccg->funcs->set_dto_dscclk(dccg, dsc->inst, true);
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
+ if (should_use_dto_dscclk)
+ dccg->funcs->set_dto_dscclk(dccg, odm_dsc->inst);
odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
- if (should_use_dto_dscclk)
- dccg->funcs->set_dto_dscclk(dccg, odm_dsc->inst, true);
}
dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
dsc_cfg.pic_width *= opp_cnt;
@@ -879,19 +879,32 @@ void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
}
/* disable DSC block */
- if (dccg->funcs->set_dto_dscclk)
- dccg->funcs->set_dto_dscclk(dccg, pipe_ctx->stream_res.dsc->inst, false);
- pipe_ctx->stream_res.dsc->funcs->dsc_disconnect(pipe_ctx->stream_res.dsc);
- if (dccg->funcs->set_ref_dscclk)
- dccg->funcs->set_ref_dscclk(dccg, pipe_ctx->stream_res.dsc->inst);
- pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
- for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
- if (dccg->funcs->set_dto_dscclk)
- dccg->funcs->set_dto_dscclk(dccg, odm_pipe->stream_res.dsc->inst, false);
+ for (odm_pipe = pipe_ctx; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
odm_pipe->stream_res.dsc->funcs->dsc_disconnect(odm_pipe->stream_res.dsc);
+ /*
+ * TODO - dsc_disconnect is a double buffered register.
+ * by the time we call dsc_disable, dsc may still remain
+ * connected to OPP. In this case OPTC will no longer
+ * get correct pixel data because DSCC is off. However
+ * we also can't wait for the disconnect pending
+ * complete, because this function can be called
+ * with/without OTG master lock acquired. When the lock
+ * is acquired we will never get pending complete until
+ * we release the lock later. So there is no easy way to
+ * solve this problem especially when the lock is
+ * acquired. DSC is a front end hw block it should be
+ * programmed as part of front end sequence, where the
+ * commit sequence without lock and update sequence
+ * with lock are completely separated. However because
+ * we are programming dsc as part of back end link
+ * programming sequence, we don't know if front end OPTC
+ * master lock is acquired. The back end should be
+ * agnostic to front end lock. DSC programming shouldn't
+ * belong to this sequence.
+ */
+ odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
if (dccg->funcs->set_ref_dscclk)
dccg->funcs->set_ref_dscclk(dccg, odm_pipe->stream_res.dsc->inst);
- odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
}
}
}
@@ -2345,7 +2358,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
deallocate_mst_payload(pipe_ctx);
- else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
+ else if (dc_is_dp_sst_signal(pipe_ctx->stream->signal) &&
dp_is_128b_132b_signal(pipe_ctx))
update_sst_payload(pipe_ctx, false);
@@ -2578,7 +2591,7 @@ void link_set_dpms_on(
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
allocate_mst_payload(pipe_ctx);
- else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
+ else if (dc_is_dp_sst_signal(pipe_ctx->stream->signal) &&
dp_is_128b_132b_signal(pipe_ctx))
update_sst_payload(pipe_ctx, true);
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
index 8246006857b3..5e1b5ab9fbc6 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
@@ -385,7 +385,7 @@ static void link_destruct(struct dc_link *link)
if (link->panel_cntl)
link->panel_cntl->funcs->destroy(&link->panel_cntl);
- if (link->link_enc) {
+ if (link->link_enc && !link->is_dig_mapping_flexible) {
/* Update link encoder resource tracking variables. These are used for
* the dynamic assignment of link encoders to streams. Virtual links
* are not assigned encoder resources on creation.
@@ -524,6 +524,7 @@ static bool construct_phy(struct dc_link *link,
link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
break;
case CONNECTOR_ID_DISPLAY_PORT:
+ case CONNECTOR_ID_MXM:
case CONNECTOR_ID_USBC:
link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
index 46bb7a855bc2..34a618a7278b 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
@@ -212,6 +212,13 @@ static enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in
case 10000000:
link_rate = LINK_RATE_UHBR10; // UHBR10 - 10.0 Gbps/Lane
break;
+ case 13500000:
+ link_rate = LINK_RATE_UHBR13_5; // UHBR13.5 - 13.5 Gbps/Lane
+ break;
+ case 20000000:
+ link_rate = LINK_RATE_UHBR20; // UHBR20 - 20.0 Gbps/Lane
+ break;
+
default:
link_rate = LINK_RATE_UNKNOWN;
break;
@@ -541,6 +548,23 @@ static enum dc_link_rate increase_link_rate(struct dc_link *link,
}
}
+static void increase_edp_link_rate(struct dc_link *link,
+ struct dc_link_settings *current_link_setting)
+{
+ if (current_link_setting->use_link_rate_set) {
+ if (current_link_setting->link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
+ current_link_setting->link_rate_set++;
+ current_link_setting->link_rate =
+ link->dpcd_caps.edp_supported_link_rates[current_link_setting->link_rate_set];
+ } else {
+ current_link_setting->use_link_rate_set = false;
+ current_link_setting->link_rate = LINK_RATE_UHBR10;
+ }
+ } else {
+ current_link_setting->link_rate = increase_link_rate(link, current_link_setting->link_rate);
+ }
+}
+
static bool decide_fallback_link_setting_max_bw_policy(
struct dc_link *link,
const struct dc_link_settings *max,
@@ -759,14 +783,7 @@ bool edp_decide_link_settings(struct dc_link *link,
increase_lane_count(
current_link_setting.lane_count);
} else {
- if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
- current_link_setting.link_rate_set++;
- current_link_setting.link_rate =
- link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
- current_link_setting.lane_count =
- initial_link_setting.lane_count;
- } else
- break;
+ increase_edp_link_rate(link, &current_link_setting);
}
}
return false;
@@ -818,9 +835,7 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
if (policy) {
/* minimize lane */
if (current_link_setting.link_rate < max_link_rate) {
- current_link_setting.link_rate =
- increase_link_rate(link,
- current_link_setting.link_rate);
+ increase_edp_link_rate(link, &current_link_setting);
} else {
if (current_link_setting.lane_count <
link->verified_link_cap.lane_count) {
@@ -839,9 +854,7 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
increase_lane_count(
current_link_setting.lane_count);
} else {
- current_link_setting.link_rate =
- increase_link_rate(link,
- current_link_setting.link_rate);
+ increase_edp_link_rate(link, &current_link_setting);
current_link_setting.lane_count =
initial_link_setting.lane_count;
}
@@ -874,18 +887,15 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
}
if (policy) {
/* minimize lane */
- if (current_link_setting.link_rate_set <
- link->dpcd_caps.edp_supported_link_rates_count
- && current_link_setting.link_rate < max_link_rate) {
- current_link_setting.link_rate_set++;
- current_link_setting.link_rate =
- link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
+ if (current_link_setting.link_rate < max_link_rate) {
+ increase_edp_link_rate(link, &current_link_setting);
} else {
if (current_link_setting.lane_count < link->verified_link_cap.lane_count) {
current_link_setting.lane_count =
increase_lane_count(
current_link_setting.lane_count);
current_link_setting.link_rate_set = initial_link_setting.link_rate_set;
+ current_link_setting.use_link_rate_set = initial_link_setting.use_link_rate_set;
current_link_setting.link_rate =
link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
} else
@@ -899,13 +909,8 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
increase_lane_count(
current_link_setting.lane_count);
} else {
- if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
- current_link_setting.link_rate_set++;
- current_link_setting.link_rate =
- link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
- current_link_setting.lane_count =
- initial_link_setting.lane_count;
- } else
+ increase_edp_link_rate(link, &current_link_setting);
+ if (current_link_setting.link_rate == LINK_RATE_UNKNOWN)
break;
}
}
@@ -1166,6 +1171,8 @@ static void get_active_converter_info(
link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps = intersect_frl_link_bw_support(
link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps,
hdmi_encoded_link_bw);
+ DC_LOG_DC("%s: pcon frl link bw = %u\n", __func__,
+ link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps);
}
if (link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps > 0)
@@ -1541,7 +1548,11 @@ enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link)
* Override count to 1 if we receive a known bad count (0 or an invalid value) */
if ((link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
(dp_parse_lttpr_repeater_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) == 0)) {
- ASSERT(0);
+ /* If you see this message consistently, either the host platform has FIXED_VS flag
+ * incorrectly configured or the sink device is returning an invalid count.
+ */
+ DC_LOG_ERROR("lttpr_caps phy_repeater_cnt is 0x%x, forcing it to 0x80.",
+ link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
link->dpcd_caps.lttpr_caps.phy_repeater_cnt = 0x80;
DC_LOG_DC("lttpr_caps forced phy_repeater_cnt = %d\n", link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
}
@@ -2254,7 +2265,7 @@ bool dp_verify_link_cap_with_retries(
memset(&link->verified_link_cap, 0,
sizeof(struct dc_link_settings));
- if (!link_detect_connection_type(link, &type) || type == dc_connection_none) {
+ if (link->link_enc && (!link_detect_connection_type(link, &type) || type == dc_connection_none)) {
link->verified_link_cap = fail_safe_link_settings;
break;
} else if (dp_verify_link_cap(link, known_limit_link_setting, &fail_count)) {
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
index bf820d2b4dc4..3aa05a2be6c0 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
@@ -305,16 +305,17 @@ bool edp_is_ilr_optimization_enabled(struct dc_link *link)
return true;
}
-enum dc_link_rate get_max_link_rate_from_ilr_table(struct dc_link *link)
+enum dc_link_rate get_max_edp_link_rate(struct dc_link *link)
{
- enum dc_link_rate link_rate = link->reported_link_cap.link_rate;
+ enum dc_link_rate max_ilr_rate = LINK_RATE_UNKNOWN;
+ enum dc_link_rate max_non_ilr_rate = dp_get_max_link_cap(link).link_rate;
for (int i = 0; i < link->dpcd_caps.edp_supported_link_rates_count; i++) {
- if (link_rate < link->dpcd_caps.edp_supported_link_rates[i])
- link_rate = link->dpcd_caps.edp_supported_link_rates[i];
+ if (max_ilr_rate < link->dpcd_caps.edp_supported_link_rates[i])
+ max_ilr_rate = link->dpcd_caps.edp_supported_link_rates[i];
}
- return link_rate;
+ return (max_ilr_rate > max_non_ilr_rate ? max_ilr_rate : max_non_ilr_rate);
}
bool edp_is_ilr_optimization_required(struct dc_link *link,
@@ -1167,6 +1168,9 @@ static void edp_set_assr_enable(const struct dc *pDC, struct dc_link *link,
link_enc_index = link->link_enc->transmitter - TRANSMITTER_UNIPHY_A;
if (link_res->hpo_dp_link_enc) {
+ if (link->wa_flags.disable_assr_for_uhbr)
+ return;
+
link_enc_index = link_res->hpo_dp_link_enc->inst;
use_hpo_dp_link_enc = true;
}
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h
index 8df8ac5bde5b..30dc8c24c008 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h
@@ -69,7 +69,7 @@ bool edp_wait_for_t12(struct dc_link *link);
bool edp_is_ilr_optimization_required(struct dc_link *link,
struct dc_crtc_timing *crtc_timing);
bool edp_is_ilr_optimization_enabled(struct dc_link *link);
-enum dc_link_rate get_max_link_rate_from_ilr_table(struct dc_link *link);
+enum dc_link_rate get_max_edp_link_rate(struct dc_link *link);
bool edp_backlight_enable_aux(struct dc_link *link, bool enable);
void edp_add_delay_for_T9(struct dc_link *link);
bool edp_receiver_ready_T9(struct dc_link *link);
diff --git a/drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile b/drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile
index 505bc0517e08..eab196c57c6c 100644
--- a/drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile
@@ -25,6 +25,15 @@
ifdef CONFIG_DRM_AMD_DC_FP
###############################################################################
+# DCN20
+###############################################################################
+MMHUBBUB_DCN20 = dcn20_mmhubbub.o
+
+AMD_DAL_MMHUBBUB_DCN20 = $(addprefix $(AMDDALPATH)/dc/mmhubbub/dcn20/,$(MMHUBBUB_DCN20))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_MMHUBBUB_DCN20)
+
+###############################################################################
# DCN32
###############################################################################
MMHUBBUB_DCN32 = dcn32_mmhubbub.o
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.c b/drivers/gpu/drm/amd/display/dc/mmhubbub/dcn20/dcn20_mmhubbub.c
index 259a98e4ee2c..259a98e4ee2c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/mmhubbub/dcn20/dcn20_mmhubbub.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.h b/drivers/gpu/drm/amd/display/dc/mmhubbub/dcn20/dcn20_mmhubbub.h
index 5ab32aa51e13..5ab32aa51e13 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/mmhubbub/dcn20/dcn20_mmhubbub.h
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/Makefile b/drivers/gpu/drm/amd/display/dc/mpc/Makefile
index 7f7458c07e2a..5402c3529f5e 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/mpc/Makefile
@@ -25,6 +25,33 @@
ifdef CONFIG_DRM_AMD_DC_FP
###############################################################################
+# DCN10
+###############################################################################
+MPC_DCN10 = dcn10_mpc.o
+
+AMD_DAL_MPC_DCN10 = $(addprefix $(AMDDALPATH)/dc/mpc/dcn10/,$(MPC_DCN10))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_MPC_DCN10)
+
+###############################################################################
+# DCN20
+###############################################################################
+MPC_DCN20 = dcn20_mpc.o
+
+AMD_DAL_MPC_DCN20 = $(addprefix $(AMDDALPATH)/dc/mpc/dcn20/,$(MPC_DCN20))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_MPC_DCN20)
+
+###############################################################################
+# DCN30
+###############################################################################
+MPC_DCN30 = dcn30_mpc.o
+
+AMD_DAL_MPC_DCN30 = $(addprefix $(AMDDALPATH)/dc/mpc/dcn30/,$(MPC_DCN30))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_MPC_DCN30)
+
+###############################################################################
# DCN32
###############################################################################
MPC_DCN32 = dcn32_mpc.o
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.c
index f2f55565e98a..f2f55565e98a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h b/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.h
index dbfffc6383dc..dbfffc6383dc 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.h
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c b/drivers/gpu/drm/amd/display/dc/mpc/dcn20/dcn20_mpc.c
index ea73473b970a..ea73473b970a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn20/dcn20_mpc.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h b/drivers/gpu/drm/amd/display/dc/mpc/dcn20/dcn20_mpc.h
index 496658f420db..496658f420db 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn20/dcn20_mpc.h
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c b/drivers/gpu/drm/amd/display/dc/mpc/dcn30/dcn30_mpc.c
index 3aeb85ec40b0..fe26fde12eeb 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn30/dcn30_mpc.c
@@ -25,7 +25,7 @@
#include "reg_helper.h"
#include "dcn30_mpc.h"
-#include "dcn30_cm_common.h"
+#include "dcn30/dcn30_cm_common.h"
#include "basics/conversion.h"
#include "dcn10/dcn10_cm_common.h"
#include "dc.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h b/drivers/gpu/drm/amd/display/dc/mpc/dcn30/dcn30_mpc.h
index ce93003dae01..ce93003dae01 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn30/dcn30_mpc.h
diff --git a/drivers/gpu/drm/amd/display/dc/opp/Makefile b/drivers/gpu/drm/amd/display/dc/opp/Makefile
index fbfb3c3ad819..1be76754db30 100644
--- a/drivers/gpu/drm/amd/display/dc/opp/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/opp/Makefile
@@ -25,6 +25,22 @@
ifdef CONFIG_DRM_AMD_DC_FP
###############################################################################
+# DCN10
+###############################################################################
+OPP_DCN10 = dcn10_opp.o
+
+AMD_DAL_OPP_DCN10 = $(addprefix $(AMDDALPATH)/dc/opp/dcn10/,$(OPP_DCN10))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_OPP_DCN10)
+###############################################################################
+# DCN20
+###############################################################################
+OPP_DCN20 = dcn20_opp.o
+
+AMD_DAL_OPP_DCN20 = $(addprefix $(AMDDALPATH)/dc/opp/dcn20/,$(OPP_DCN20))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_OPP_DCN20)
+###############################################################################
# DCN35
###############################################################################
OPP_DCN35 = dcn35_opp.o
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c b/drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.c
index 71e9288d60ed..71e9288d60ed 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
+++ b/drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h b/drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.h
index c87de68a509e..c87de68a509e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h
+++ b/drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.h
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c b/drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.c
index f5fe0cac7cb0..f5fe0cac7cb0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c
+++ b/drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.h b/drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.h
index 34936e6c49f3..34936e6c49f3 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.h
+++ b/drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.h
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.c
index 94427875bcdd..097d06023e64 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.c
@@ -65,7 +65,8 @@ void optc1_program_global_sync(
int vready_offset,
int vstartup_start,
int vupdate_offset,
- int vupdate_width)
+ int vupdate_width,
+ int pstate_keepout)
{
struct optc *optc1 = DCN10TG_FROM_TG(optc);
@@ -73,6 +74,7 @@ void optc1_program_global_sync(
optc1->vstartup_start = vstartup_start;
optc1->vupdate_offset = vupdate_offset;
optc1->vupdate_width = vupdate_width;
+ optc1->pstate_keepout = pstate_keepout;
if (optc1->vstartup_start == 0) {
BREAK_TO_DEBUGGER();
@@ -146,6 +148,7 @@ void optc1_setup_vertical_interrupt2(
* @vstartup_start: Vstartup period.
* @vupdate_offset: Vupdate starting position.
* @vupdate_width: Vupdate duration.
+ * @pstate_keepout: determines low power mode timing during refresh
* @signal: DC signal types.
* @use_vbios: to program timings from BIOS command table.
*
@@ -157,6 +160,7 @@ void optc1_program_timing(
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+ int pstate_keepout,
const enum signal_type signal,
bool use_vbios)
{
@@ -177,6 +181,7 @@ void optc1_program_timing(
optc1->vstartup_start = vstartup_start;
optc1->vupdate_offset = vupdate_offset;
optc1->vupdate_width = vupdate_width;
+ optc1->pstate_keepout = pstate_keepout;
patched_crtc_timing = *dc_crtc_timing;
apply_front_porch_workaround(&patched_crtc_timing);
optc1->orginal_patched_timing = patched_crtc_timing;
@@ -282,7 +287,8 @@ void optc1_program_timing(
vready_offset,
vstartup_start,
vupdate_offset,
- vupdate_width);
+ vupdate_width,
+ pstate_keepout);
optc->funcs->set_vtg_params(optc, dc_crtc_timing, true);
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
index 369a13244e5e..b7a57f98553d 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
@@ -201,6 +201,7 @@ struct dcn_optc_registers {
uint32_t OTG_CRC1_WINDOWB_Y_CONTROL_READBACK;
uint32_t OPTC_CLOCK_CONTROL;
uint32_t OPTC_WIDTH_CONTROL2;
+ uint32_t OTG_PSTATE_REGISTER;
};
#define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\
@@ -590,7 +591,11 @@ struct dcn_optc_registers {
type OTG_V_COUNT_STOP_TIMER;
#define TG_REG_FIELD_LIST_DCN401(type) \
- type OPTC_SEGMENT_WIDTH_LAST;
+ type OPTC_SEGMENT_WIDTH_LAST;\
+ type OTG_PSTATE_KEEPOUT_START;\
+ type OTG_PSTATE_EXTEND;\
+ type OTG_UNBLANK;\
+ type OTG_PSTATE_ALLOW_WIDTH_MIN;
struct dcn_optc_shift {
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.c
index 6bbbf313b2bb..4b6446ed4ce4 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.c
@@ -149,7 +149,9 @@ static bool optc31_disable_crtc(struct timing_generator *optc)
return true;
}
-
+/*
+ * Immediate_Disable_Crtc - this is to temp disable Timing generator without reset ODM.
+ */
bool optc31_immediate_disable_crtc(struct timing_generator *optc)
{
struct optc *optc1 = DCN10TG_FROM_TG(optc);
@@ -162,10 +164,12 @@ bool optc31_immediate_disable_crtc(struct timing_generator *optc)
VTG0_ENABLE, 0);
/* CRTC disabled, so disable clock. */
- REG_WAIT(OTG_CLOCK_CONTROL,
+ if (optc->ctx->dce_environment != DCE_ENV_DIAG)
+ REG_WAIT(OTG_CLOCK_CONTROL,
OTG_BUSY, 0,
1, 100000);
+
/* clear the false state */
optc1_clear_optc_underflow(optc);
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.c
index 9f5c2efa7560..a5d6a7dca554 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.c
@@ -396,13 +396,47 @@ void optc401_set_vtotal_min_max(struct timing_generator *optc, int vtotal_min, i
}
}
+static void optc401_program_global_sync(
+ struct timing_generator *optc,
+ int vready_offset,
+ int vstartup_start,
+ int vupdate_offset,
+ int vupdate_width,
+ int pstate_keepout)
+{
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
+
+ optc1->vready_offset = vready_offset;
+ optc1->vstartup_start = vstartup_start;
+ optc1->vupdate_offset = vupdate_offset;
+ optc1->vupdate_width = vupdate_width;
+ optc1->pstate_keepout = pstate_keepout;
+
+ if (optc1->vstartup_start == 0) {
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+
+ REG_SET(OTG_VSTARTUP_PARAM, 0,
+ VSTARTUP_START, optc1->vstartup_start);
+
+ REG_SET_2(OTG_VUPDATE_PARAM, 0,
+ VUPDATE_OFFSET, optc1->vupdate_offset,
+ VUPDATE_WIDTH, optc1->vupdate_width);
+
+ REG_SET(OTG_VREADY_PARAM, 0,
+ VREADY_OFFSET, optc1->vready_offset);
+
+ REG_UPDATE(OTG_PSTATE_REGISTER, OTG_PSTATE_KEEPOUT_START, pstate_keepout);
+}
+
static struct timing_generator_funcs dcn401_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,
+ .program_global_sync = optc401_program_global_sync,
.enable_crtc = optc401_enable_crtc,
.disable_crtc = optc401_disable_crtc,
.phantom_crtc_post_enable = optc401_phantom_crtc_post_enable,
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.h
index 3114ecef332a..bb13a645802d 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.h
@@ -155,7 +155,11 @@
SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE, mask_sh),\
SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE_MANUAL, mask_sh),\
SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_MODE, mask_sh),\
- SF(OTG0_OTG_DRR_CONTROL, OTG_V_TOTAL_LAST_USED_BY_DRR, mask_sh)
+ SF(OTG0_OTG_DRR_CONTROL, OTG_V_TOTAL_LAST_USED_BY_DRR, mask_sh),\
+ SF(OTG0_OTG_PSTATE_REGISTER, OTG_PSTATE_KEEPOUT_START, mask_sh),\
+ SF(OTG0_OTG_PSTATE_REGISTER, OTG_PSTATE_EXTEND, mask_sh),\
+ SF(OTG0_OTG_PSTATE_REGISTER, OTG_UNBLANK, mask_sh),\
+ SF(OTG0_OTG_PSTATE_REGISTER, OTG_PSTATE_ALLOW_WIDTH_MIN, mask_sh)
void dcn401_timing_generator_init(struct optc *optc1);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/Makefile b/drivers/gpu/drm/amd/display/dc/resource/Makefile
index 4860bb2531a1..09320344d8e9 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/resource/Makefile
@@ -198,8 +198,6 @@ AMD_DISPLAY_FILES += $(AMD_DAL_RESOURCE_DCN351)
###############################################################################
-###############################################################################
-
RESOURCE_DCN401 = dcn401_resource.o
AMD_DAL_RESOURCE_DCN401 = $(addprefix $(AMDDALPATH)/dc/resource/dcn401/,$(RESOURCE_DCN401))
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c
index fe518fd27b08..91da5cf85b69 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c
@@ -1163,6 +1163,7 @@ static struct pipe_ctx *dce110_acquire_underlay(
0,
0,
0,
+ 0,
pipe_ctx->stream->signal,
false);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c
index 88afb2a30eef..162856c523e4 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c
@@ -1067,7 +1067,10 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc)
struct dm_pp_clock_levels clks = {0};
int memory_type_multiplier = MEMORY_TYPE_MULTIPLIER_CZ;
- if (dc->bw_vbios && dc->bw_vbios->memory_type == bw_def_hbm)
+ if (!dc->bw_vbios)
+ return;
+
+ if (dc->bw_vbios->memory_type == bw_def_hbm)
memory_type_multiplier = MEMORY_TYPE_HBM;
/*do system clock TODO PPLIB: after PPLIB implement,
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
index 5e7cfa8e8ec9..eea2b3b307cd 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
@@ -2040,6 +2040,7 @@ bool dcn20_fast_validate_bw(
{
bool out = false;
int split[MAX_PIPES] = { 0 };
+ bool merge[MAX_PIPES] = { false };
int pipe_cnt, i, pipe_idx, vlevel;
ASSERT(pipes);
@@ -2064,7 +2065,7 @@ bool dcn20_fast_validate_bw(
if (vlevel > context->bw_ctx.dml.soc.num_states)
goto validate_fail;
- vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, NULL);
+ vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
/*initialize pipe_just_split_from to invalid idx*/
for (i = 0; i < MAX_PIPES; i++)
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
index 131d98025bd4..fc54483b9104 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
@@ -1007,8 +1007,10 @@ static struct pipe_ctx *dcn201_acquire_free_pipe_for_layer(
struct pipe_ctx *head_pipe = resource_get_otg_master_for_stream(res_ctx, opp_head_pipe->stream);
struct pipe_ctx *idle_pipe = resource_find_free_secondary_pipe_legacy(res_ctx, pool, head_pipe);
- if (!head_pipe)
+ if (!head_pipe) {
ASSERT(0);
+ return NULL;
+ }
if (!idle_pipe)
return NULL;
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
index 8663cbc3d1cf..347e6aaea582 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
@@ -774,6 +774,7 @@ bool dcn21_fast_validate_bw(struct dc *dc,
{
bool out = false;
int split[MAX_PIPES] = { 0 };
+ bool merge[MAX_PIPES] = { false };
int pipe_cnt, i, pipe_idx, vlevel;
ASSERT(pipes);
@@ -816,7 +817,7 @@ bool dcn21_fast_validate_bw(struct dc *dc,
goto validate_fail;
}
- vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, NULL);
+ vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
index 5d1801dce273..ac8cb20e2e3b 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
@@ -1948,6 +1948,7 @@ static bool dcn31_resource_construct(
/* Use pipe context based otg sync logic */
dc->config.use_pipe_ctx_sync_logic = true;
+ dc->config.disable_hbr_audio_dp2 = true;
/* read VBIOS LTTPR caps */
{
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
index 969658313fd6..a124ad9bd108 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
@@ -1651,6 +1651,9 @@ static void dcn32_enable_phantom_plane(struct dc *dc,
else
phantom_plane = dc_state_create_phantom_plane(dc, context, curr_pipe->plane_state);
+ if (!phantom_plane)
+ continue;
+
memcpy(&phantom_plane->address, &curr_pipe->plane_state->address, sizeof(phantom_plane->address));
memcpy(&phantom_plane->scaling_quality, &curr_pipe->plane_state->scaling_quality,
sizeof(phantom_plane->scaling_quality));
@@ -1717,6 +1720,9 @@ void dcn32_add_phantom_pipes(struct dc *dc, struct dc_state *context,
// be a valid candidate for SubVP (i.e. has a plane, stream, doesn't
// already have phantom pipe assigned, etc.) by previous checks.
phantom_stream = dcn32_enable_phantom_stream(dc, context, pipes, pipe_cnt, index);
+ if (!phantom_stream)
+ return;
+
dcn32_enable_phantom_plane(dc, context, phantom_stream, index);
for (i = 0; i < dc->res_pool->pipe_count; i++) {
@@ -2220,6 +2226,7 @@ static bool dcn32_resource_construct(
dc->config.dc_mode_clk_limit_support = true;
dc->config.enable_windowed_mpo_odm = true;
+ dc->config.disable_hbr_audio_dp2 = true;
/* read VBIOS LTTPR caps */
{
if (ctx->dc_bios->funcs->get_lttpr_caps) {
@@ -2671,8 +2678,10 @@ static struct pipe_ctx *dcn32_acquire_idle_pipe_for_head_pipe_in_layer(
struct resource_context *old_ctx = &stream->ctx->dc->current_state->res_ctx;
int head_index;
- if (!head_pipe)
+ if (!head_pipe) {
ASSERT(0);
+ return NULL;
+ }
/*
* Modified from dcn20_acquire_idle_pipe_for_layer
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
index fee67fbab8e2..7901792afb7b 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
@@ -505,6 +505,8 @@ unsigned int dcn32_calculate_mall_ways_from_bytes(const struct dc *dc, unsigned
SRI_ARR(CM_POST_CSC_B_C11_C12, CM, id), \
SRI_ARR(CM_POST_CSC_B_C33_C34, CM, id), \
SRI_ARR(CM_MEM_PWR_CTRL, CM, id), SRI_ARR(CM_CONTROL, CM, id), \
+ SRI_ARR(CM_TEST_DEBUG_INDEX, CM, id), \
+ SRI_ARR(CM_TEST_DEBUG_DATA, CM, id), \
SRI_ARR(FORMAT_CONTROL, CNVC_CFG, id), \
SRI_ARR(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
SRI_ARR(CURSOR0_CONTROL, CNVC_CUR, id), \
@@ -761,6 +763,7 @@ unsigned int dcn32_calculate_mall_ways_from_bytes(const struct dc *dc, unsigned
SRI_ARR(DSCC_RATE_CONTROL_BUFFER1_MAX_FULLNESS_LEVEL, DSCC, id), \
SRI_ARR(DSCC_RATE_CONTROL_BUFFER2_MAX_FULLNESS_LEVEL, DSCC, id), \
SRI_ARR(DSCC_RATE_CONTROL_BUFFER3_MAX_FULLNESS_LEVEL, DSCC, id), \
+ SRI_ARR(DSCC_TEST_DEBUG_BUS_ROTATE, DSCC, id), \
SRI_ARR(DSCCIF_CONFIG0, DSCCIF, id), \
SRI_ARR(DSCCIF_CONFIG1, DSCCIF, id), \
SRI_ARR(DSCRM_DSC_FORWARD_CONFIG, DSCRM, id)
@@ -1185,6 +1188,8 @@ unsigned int dcn32_calculate_mall_ways_from_bytes(const struct dc *dc, unsigned
SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL), \
SR(DCHUBBUB_ARB_DRAM_STATE_CNTL), SR(DCHUBBUB_ARB_SAT_LEVEL), \
SR(DCHUBBUB_ARB_DF_REQ_OUTSTAND), SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
+ SR(DCHUBBUB_TEST_DEBUG_INDEX), \
+ SR(DCHUBBUB_TEST_DEBUG_DATA), \
SR(DCHUBBUB_SOFT_RESET), SR(DCHUBBUB_CRC_CTRL), \
SR(DCN_VM_FB_LOCATION_BASE), SR(DCN_VM_FB_LOCATION_TOP), \
SR(DCN_VM_FB_OFFSET), SR(DCN_VM_AGP_BOT), SR(DCN_VM_AGP_TOP), \
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c
index d184105ce2b3..f5a4e97c40ce 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c
@@ -218,12 +218,12 @@ bool dcn32_is_center_timing(struct pipe_ctx *pipe)
pipe->stream->timing.v_addressable != pipe->stream->src.height) {
is_center_timing = true;
}
- }
- if (pipe->plane_state) {
- if (pipe->stream->timing.v_addressable != pipe->plane_state->dst_rect.height &&
- pipe->stream->timing.v_addressable != pipe->plane_state->src_rect.height) {
- is_center_timing = true;
+ if (pipe->plane_state) {
+ if (pipe->stream->timing.v_addressable != pipe->plane_state->dst_rect.height &&
+ pipe->stream->timing.v_addressable != pipe->plane_state->src_rect.height) {
+ is_center_timing = true;
+ }
}
}
@@ -663,7 +663,7 @@ bool dcn32_subvp_drr_admissable(struct dc *dc, struct dc_state *context)
subvp_disallow |= disallow_subvp_in_active_plus_blank(pipe);
refresh_rate = (pipe->stream->timing.pix_clk_100hz * (uint64_t)100 +
- pipe->stream->timing.v_total * pipe->stream->timing.h_total - (uint64_t)1);
+ pipe->stream->timing.v_total * (unsigned long long)pipe->stream->timing.h_total - (uint64_t)1);
refresh_rate = div_u64(refresh_rate, pipe->stream->timing.v_total);
refresh_rate = div_u64(refresh_rate, pipe->stream->timing.h_total);
}
@@ -724,7 +724,7 @@ bool dcn32_subvp_vblank_admissable(struct dc *dc, struct dc_state *context, int
subvp_disallow |= disallow_subvp_in_active_plus_blank(pipe);
refresh_rate = (pipe->stream->timing.pix_clk_100hz * (uint64_t)100 +
- pipe->stream->timing.v_total * pipe->stream->timing.h_total - (uint64_t)1);
+ pipe->stream->timing.v_total * (unsigned long long)pipe->stream->timing.h_total - (uint64_t)1);
refresh_rate = div_u64(refresh_rate, pipe->stream->timing.v_total);
refresh_rate = div_u64(refresh_rate, pipe->stream->timing.h_total);
}
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
index 8e0588b1cf30..827a94f84f10 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
@@ -1783,6 +1783,7 @@ static bool dcn321_resource_construct(
dc->config.dc_mode_clk_limit_support = true;
dc->config.enable_windowed_mpo_odm = true;
+ dc->config.disable_hbr_audio_dp2 = true;
/* read VBIOS LTTPR caps */
{
if (ctx->dc_bios->funcs->get_lttpr_caps) {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
index ddf251901fb3..46ad684fe192 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
@@ -786,6 +786,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.disable_dmub_reallow_idle = false,
.static_screen_wait_frames = 2,
.disable_timeout = true,
+ .min_disp_clk_khz = 50000,
};
static const struct dc_panel_config panel_config_defaults = {
@@ -1899,6 +1900,7 @@ static bool dcn35_resource_construct(
/* Use pipe context based otg sync logic */
dc->config.use_pipe_ctx_sync_logic = true;
+ dc->config.disable_hbr_audio_dp2 = true;
/* read VBIOS LTTPR caps */
{
if (ctx->dc_bios->funcs->get_lttpr_caps) {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
index 34b02147881d..9d56fbdcd06a 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
@@ -76,6 +76,9 @@
#include "dml2/dml2_wrapper.h"
+#include "spl/dc_spl_scl_easf_filters.h"
+#include "spl/dc_spl_isharp_filters.h"
+
#define DC_LOGGER_INIT(logger)
enum dcn401_clk_src_array_id {
@@ -1188,7 +1191,7 @@ static struct stream_encoder *dcn401_stream_encoder_create(
vpg = dcn401_vpg_create(ctx, vpg_inst);
afmt = dcn401_afmt_create(ctx, afmt_inst);
- if (!enc1 || !vpg || !afmt) {
+ if (!enc1 || !vpg || !afmt || eng_id >= ARRAY_SIZE(stream_enc_regs)) {
kfree(enc1);
kfree(vpg);
kfree(afmt);
@@ -1822,6 +1825,7 @@ static bool dcn401_resource_construct(
dc->caps.edp_dsc_support = true;
dc->caps.extended_aux_timeout_support = true;
dc->caps.dmcub_support = true;
+ dc->caps.max_v_total = (1 << 15) - 1;
if (ASICREV_IS_GC_12_0_1_A0(dc->ctx->asic_id.hw_internal_rev))
dc->caps.dcc_plane_width_limit = 7680;
@@ -2099,6 +2103,7 @@ static bool dcn401_resource_construct(
dc->dml2_options.use_native_soc_bb_construction = true;
dc->dml2_options.minimize_dispclk_using_odm = true;
dc->dml2_options.map_dc_pipes_with_callbacks = true;
+ dc->dml2_options.force_tdlut_enable = true;
resource_init_common_dml2_callbacks(dc, &dc->dml2_options);
dc->dml2_options.callbacks.can_support_mclk_switch_using_fw_based_vblank_stretch = &dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch;
@@ -2124,6 +2129,10 @@ static bool dcn401_resource_construct(
dc->dml2_options.max_segments_per_hubp = 20;
dc->dml2_options.det_segment_size = DCN4_01_CRB_SEGMENT_SIZE_KB;
+ /* SPL */
+ spl_init_easf_filter_coeffs();
+ spl_init_blur_scale_coeffs();
+
return true;
create_fail:
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h
index bb46f30d11d0..514d1ce20df9 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h
@@ -536,7 +536,8 @@ void dcn401_prepare_mcache_programming(struct dc *dc, struct dc_state *context);
SRI_ARR(OPTC_WIDTH_CONTROL, ODM, inst), \
SRI_ARR(OPTC_WIDTH_CONTROL2, ODM, inst), \
SRI_ARR(OPTC_MEMORY_CONFIG, ODM, inst), \
- SRI_ARR(OTG_DRR_CONTROL, OTG, inst)
+ SRI_ARR(OTG_DRR_CONTROL, OTG, inst), \
+ SRI_ARR(OTG_PSTATE_REGISTER, OTG, inst)
/* HUBBUB */
#define HUBBUB_REG_LIST_DCN4_01_RI(id) \
diff --git a/drivers/gpu/drm/amd/display/dc/spl/Makefile b/drivers/gpu/drm/amd/display/dc/spl/Makefile
index 89cad60b1a10..5edf3c6cf3e2 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/spl/Makefile
@@ -23,7 +23,7 @@
# Makefile for the 'spl' sub-component of DAL.
# It provides the scaling library interface.
-SPL = dc_spl.o dc_spl_scl_filters.o dc_spl_isharp_filters.o
+SPL = dc_spl.o dc_spl_scl_filters.o dc_spl_scl_easf_filters.o dc_spl_isharp_filters.o dc_spl_filters.o spl_fixpt31_32.o spl_custom_float.o
AMD_DAL_SPL = $(addprefix $(AMDDALPATH)/dc/spl/,$(SPL))
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
index e3e20cd86af6..15f7eda903e6 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
@@ -4,9 +4,11 @@
#include "dc_spl.h"
#include "dc_spl_scl_filters.h"
+#include "dc_spl_scl_easf_filters.h"
#include "dc_spl_isharp_filters.h"
+#include "spl_debug.h"
-#define IDENTITY_RATIO(ratio) (dc_fixpt_u2d19(ratio) == (1 << 19))
+#define IDENTITY_RATIO(ratio) (spl_fixpt_u2d19(ratio) == (1 << 19))
#define MIN_VIEWPORT_SIZE 12
static struct spl_rect intersect_rec(const struct spl_rect *r0, const struct spl_rect *r1)
@@ -107,26 +109,26 @@ static struct spl_rect calculate_plane_rec_in_timing_active(
const struct spl_rect *stream_src = &spl_in->basic_out.src_rect;
const struct spl_rect *stream_dst = &spl_in->basic_out.dst_rect;
struct spl_rect rec_out = {0};
- struct fixed31_32 temp;
+ struct spl_fixed31_32 temp;
- temp = dc_fixpt_from_fraction(rec_in->x * (long long)stream_dst->width,
+ temp = spl_fixpt_from_fraction(rec_in->x * (long long)stream_dst->width,
stream_src->width);
- rec_out.x = stream_dst->x + dc_fixpt_round(temp);
+ rec_out.x = stream_dst->x + spl_fixpt_round(temp);
- temp = dc_fixpt_from_fraction(
+ temp = spl_fixpt_from_fraction(
(rec_in->x + rec_in->width) * (long long)stream_dst->width,
stream_src->width);
- rec_out.width = stream_dst->x + dc_fixpt_round(temp) - rec_out.x;
+ rec_out.width = stream_dst->x + spl_fixpt_round(temp) - rec_out.x;
- temp = dc_fixpt_from_fraction(rec_in->y * (long long)stream_dst->height,
+ temp = spl_fixpt_from_fraction(rec_in->y * (long long)stream_dst->height,
stream_src->height);
- rec_out.y = stream_dst->y + dc_fixpt_round(temp);
+ rec_out.y = stream_dst->y + spl_fixpt_round(temp);
- temp = dc_fixpt_from_fraction(
+ temp = spl_fixpt_from_fraction(
(rec_in->y + rec_in->height) * (long long)stream_dst->height,
stream_src->height);
- rec_out.height = stream_dst->y + dc_fixpt_round(temp) - rec_out.y;
+ rec_out.height = stream_dst->y + spl_fixpt_round(temp) - rec_out.y;
return rec_out;
}
@@ -144,7 +146,7 @@ static struct spl_rect calculate_mpc_slice_in_timing_active(
mpc_rec.x = plane_clip_rec->x + mpc_rec.width * mpc_slice_idx;
mpc_rec.height = plane_clip_rec->height;
mpc_rec.y = plane_clip_rec->y;
- ASSERT(mpc_slice_count == 1 ||
+ SPL_ASSERT(mpc_slice_count == 1 ||
spl_in->basic_out.view_format != SPL_VIEW_3D_SIDE_BY_SIDE ||
mpc_rec.width % 2 == 0);
@@ -157,7 +159,7 @@ static struct spl_rect calculate_mpc_slice_in_timing_active(
}
if (spl_in->basic_out.view_format == SPL_VIEW_3D_TOP_AND_BOTTOM) {
- ASSERT(mpc_rec.height % 2 == 0);
+ SPL_ASSERT(mpc_rec.height % 2 == 0);
mpc_rec.height /= 2;
}
return mpc_rec;
@@ -197,7 +199,7 @@ static struct spl_rect calculate_odm_slice_in_timing_active(struct spl_in *spl_i
return spl_in->basic_out.odm_slice_rect;
}
-static void spl_calculate_recout(struct spl_in *spl_in, struct spl_out *spl_out)
+static void spl_calculate_recout(struct spl_in *spl_in, struct spl_scratch *spl_scratch, struct spl_out *spl_out)
{
/*
* A plane clip represents the desired plane size and position in Stream
@@ -340,20 +342,23 @@ static void spl_calculate_recout(struct spl_in *spl_in, struct spl_out *spl_out)
/* shift the overlapping area so it is with respect to current
* ODM slice's position
*/
- spl_out->scl_data.recout = shift_rec(
+ spl_scratch->scl_data.recout = shift_rec(
&overlapping_area,
-odm_slice.x, -odm_slice.y);
- spl_out->scl_data.recout.height -=
+ spl_scratch->scl_data.recout.height -=
spl_in->debug.visual_confirm_base_offset;
- spl_out->scl_data.recout.height -=
+ spl_scratch->scl_data.recout.height -=
spl_in->debug.visual_confirm_dpp_offset;
} else
/* if there is no overlap, zero recout */
- memset(&spl_out->scl_data.recout, 0,
+ memset(&spl_scratch->scl_data.recout, 0,
sizeof(struct spl_rect));
}
+
/* Calculate scaling ratios */
-static void spl_calculate_scaling_ratios(struct spl_in *spl_in, struct spl_out *spl_out)
+static void spl_calculate_scaling_ratios(struct spl_in *spl_in,
+ struct spl_scratch *spl_scratch,
+ struct spl_out *spl_out)
{
const int in_w = spl_in->basic_out.src_rect.width;
const int in_h = spl_in->basic_out.src_rect.height;
@@ -364,59 +369,75 @@ static void spl_calculate_scaling_ratios(struct spl_in *spl_in, struct spl_out *
/*Swap surf_src height and width since scaling ratios are in recout rotation*/
if (spl_in->basic_in.rotation == SPL_ROTATION_ANGLE_90 ||
spl_in->basic_in.rotation == SPL_ROTATION_ANGLE_270)
- swap(surf_src.height, surf_src.width);
+ spl_swap(surf_src.height, surf_src.width);
- spl_out->scl_data.ratios.horz = dc_fixpt_from_fraction(
+ spl_scratch->scl_data.ratios.horz = spl_fixpt_from_fraction(
surf_src.width,
spl_in->basic_in.dst_rect.width);
- spl_out->scl_data.ratios.vert = dc_fixpt_from_fraction(
+ spl_scratch->scl_data.ratios.vert = spl_fixpt_from_fraction(
surf_src.height,
spl_in->basic_in.dst_rect.height);
if (spl_in->basic_out.view_format == SPL_VIEW_3D_SIDE_BY_SIDE)
- spl_out->scl_data.ratios.horz.value *= 2;
+ spl_scratch->scl_data.ratios.horz.value *= 2;
else if (spl_in->basic_out.view_format == SPL_VIEW_3D_TOP_AND_BOTTOM)
- spl_out->scl_data.ratios.vert.value *= 2;
+ spl_scratch->scl_data.ratios.vert.value *= 2;
- spl_out->scl_data.ratios.vert.value = div64_s64(
- spl_out->scl_data.ratios.vert.value * in_h, out_h);
- spl_out->scl_data.ratios.horz.value = div64_s64(
- spl_out->scl_data.ratios.horz.value * in_w, out_w);
+ spl_scratch->scl_data.ratios.vert.value = spl_div64_s64(
+ spl_scratch->scl_data.ratios.vert.value * in_h, out_h);
+ spl_scratch->scl_data.ratios.horz.value = spl_div64_s64(
+ spl_scratch->scl_data.ratios.horz.value * in_w, out_w);
- spl_out->scl_data.ratios.horz_c = spl_out->scl_data.ratios.horz;
- spl_out->scl_data.ratios.vert_c = spl_out->scl_data.ratios.vert;
+ spl_scratch->scl_data.ratios.horz_c = spl_scratch->scl_data.ratios.horz;
+ spl_scratch->scl_data.ratios.vert_c = spl_scratch->scl_data.ratios.vert;
if (spl_in->basic_in.format == SPL_PIXEL_FORMAT_420BPP8
|| spl_in->basic_in.format == SPL_PIXEL_FORMAT_420BPP10) {
- spl_out->scl_data.ratios.horz_c.value /= 2;
- spl_out->scl_data.ratios.vert_c.value /= 2;
+ spl_scratch->scl_data.ratios.horz_c.value /= 2;
+ spl_scratch->scl_data.ratios.vert_c.value /= 2;
}
- spl_out->scl_data.ratios.horz = dc_fixpt_truncate(
- spl_out->scl_data.ratios.horz, 19);
- spl_out->scl_data.ratios.vert = dc_fixpt_truncate(
- spl_out->scl_data.ratios.vert, 19);
- spl_out->scl_data.ratios.horz_c = dc_fixpt_truncate(
- spl_out->scl_data.ratios.horz_c, 19);
- spl_out->scl_data.ratios.vert_c = dc_fixpt_truncate(
- spl_out->scl_data.ratios.vert_c, 19);
+ spl_scratch->scl_data.ratios.horz = spl_fixpt_truncate(
+ spl_scratch->scl_data.ratios.horz, 19);
+ spl_scratch->scl_data.ratios.vert = spl_fixpt_truncate(
+ spl_scratch->scl_data.ratios.vert, 19);
+ spl_scratch->scl_data.ratios.horz_c = spl_fixpt_truncate(
+ spl_scratch->scl_data.ratios.horz_c, 19);
+ spl_scratch->scl_data.ratios.vert_c = spl_fixpt_truncate(
+ spl_scratch->scl_data.ratios.vert_c, 19);
+
+ /*
+ * Coefficient table and some registers are different based on ratio
+ * that is output/input. Currently we calculate input/output
+ * Store 1/ratio in recip_ratio for those lookups
+ */
+ spl_scratch->scl_data.recip_ratios.horz = spl_fixpt_recip(
+ spl_scratch->scl_data.ratios.horz);
+ spl_scratch->scl_data.recip_ratios.vert = spl_fixpt_recip(
+ spl_scratch->scl_data.ratios.vert);
+ spl_scratch->scl_data.recip_ratios.horz_c = spl_fixpt_recip(
+ spl_scratch->scl_data.ratios.horz_c);
+ spl_scratch->scl_data.recip_ratios.vert_c = spl_fixpt_recip(
+ spl_scratch->scl_data.ratios.vert_c);
}
+
/* Calculate Viewport size */
-static void spl_calculate_viewport_size(struct spl_in *spl_in, struct spl_out *spl_out)
+static void spl_calculate_viewport_size(struct spl_in *spl_in, struct spl_scratch *spl_scratch)
{
- spl_out->scl_data.viewport.width = dc_fixpt_ceil(dc_fixpt_mul_int(spl_out->scl_data.ratios.horz,
- spl_out->scl_data.recout.width));
- spl_out->scl_data.viewport.height = dc_fixpt_ceil(dc_fixpt_mul_int(spl_out->scl_data.ratios.vert,
- spl_out->scl_data.recout.height));
- spl_out->scl_data.viewport_c.width = dc_fixpt_ceil(dc_fixpt_mul_int(spl_out->scl_data.ratios.horz_c,
- spl_out->scl_data.recout.width));
- spl_out->scl_data.viewport_c.height = dc_fixpt_ceil(dc_fixpt_mul_int(spl_out->scl_data.ratios.vert_c,
- spl_out->scl_data.recout.height));
+ spl_scratch->scl_data.viewport.width = spl_fixpt_ceil(spl_fixpt_mul_int(spl_scratch->scl_data.ratios.horz,
+ spl_scratch->scl_data.recout.width));
+ spl_scratch->scl_data.viewport.height = spl_fixpt_ceil(spl_fixpt_mul_int(spl_scratch->scl_data.ratios.vert,
+ spl_scratch->scl_data.recout.height));
+ spl_scratch->scl_data.viewport_c.width = spl_fixpt_ceil(spl_fixpt_mul_int(spl_scratch->scl_data.ratios.horz_c,
+ spl_scratch->scl_data.recout.width));
+ spl_scratch->scl_data.viewport_c.height = spl_fixpt_ceil(spl_fixpt_mul_int(spl_scratch->scl_data.ratios.vert_c,
+ spl_scratch->scl_data.recout.height));
if (spl_in->basic_in.rotation == SPL_ROTATION_ANGLE_90 ||
spl_in->basic_in.rotation == SPL_ROTATION_ANGLE_270) {
- swap(spl_out->scl_data.viewport.width, spl_out->scl_data.viewport.height);
- swap(spl_out->scl_data.viewport_c.width, spl_out->scl_data.viewport_c.height);
+ spl_swap(spl_scratch->scl_data.viewport.width, spl_scratch->scl_data.viewport.height);
+ spl_swap(spl_scratch->scl_data.viewport_c.width, spl_scratch->scl_data.viewport_c.height);
}
}
+
static void spl_get_vp_scan_direction(enum spl_rotation_angle rotation,
bool horizontal_mirror,
bool *orthogonal_rotation,
@@ -440,6 +461,7 @@ static void spl_get_vp_scan_direction(enum spl_rotation_angle rotation,
if (horizontal_mirror)
*flip_horz_scan_dir = !*flip_horz_scan_dir;
}
+
/*
* We completely calculate vp offset, size and inits here based entirely on scaling
* ratios and recout for pixel perfect pipe combine.
@@ -449,13 +471,13 @@ static void spl_calculate_init_and_vp(bool flip_scan_dir,
int recout_size,
int src_size,
int taps,
- struct fixed31_32 ratio,
- struct fixed31_32 init_adj,
- struct fixed31_32 *init,
+ struct spl_fixed31_32 ratio,
+ struct spl_fixed31_32 init_adj,
+ struct spl_fixed31_32 *init,
int *vp_offset,
int *vp_size)
{
- struct fixed31_32 temp;
+ struct spl_fixed31_32 temp;
int int_part;
/*
@@ -468,33 +490,33 @@ static void spl_calculate_init_and_vp(bool flip_scan_dir,
* init_bot = init + scaling_ratio
* to get pixel perfect combine add the fraction from calculating vp offset
*/
- temp = dc_fixpt_mul_int(ratio, recout_offset_within_recout_full);
- *vp_offset = dc_fixpt_floor(temp);
+ temp = spl_fixpt_mul_int(ratio, recout_offset_within_recout_full);
+ *vp_offset = spl_fixpt_floor(temp);
temp.value &= 0xffffffff;
- *init = dc_fixpt_add(dc_fixpt_div_int(dc_fixpt_add_int(ratio, taps + 1), 2), temp);
- *init = dc_fixpt_add(*init, init_adj);
- *init = dc_fixpt_truncate(*init, 19);
+ *init = spl_fixpt_add(spl_fixpt_div_int(spl_fixpt_add_int(ratio, taps + 1), 2), temp);
+ *init = spl_fixpt_add(*init, init_adj);
+ *init = spl_fixpt_truncate(*init, 19);
/*
* If viewport has non 0 offset and there are more taps than covered by init then
* we should decrease the offset and increase init so we are never sampling
* outside of viewport.
*/
- int_part = dc_fixpt_floor(*init);
+ int_part = spl_fixpt_floor(*init);
if (int_part < taps) {
int_part = taps - int_part;
if (int_part > *vp_offset)
int_part = *vp_offset;
*vp_offset -= int_part;
- *init = dc_fixpt_add_int(*init, int_part);
+ *init = spl_fixpt_add_int(*init, int_part);
}
/*
* If taps are sampling outside of viewport at end of recout and there are more pixels
* available in the surface we should increase the viewport size, regardless set vp to
* only what is used.
*/
- temp = dc_fixpt_add(*init, dc_fixpt_mul_int(ratio, recout_size - 1));
- *vp_size = dc_fixpt_floor(temp);
+ temp = spl_fixpt_add(*init, spl_fixpt_mul_int(ratio, recout_size - 1));
+ *vp_size = spl_fixpt_floor(temp);
if (*vp_size + *vp_offset > src_size)
*vp_size = src_size - *vp_offset;
@@ -509,15 +531,24 @@ static void spl_calculate_init_and_vp(bool flip_scan_dir,
static bool spl_is_yuv420(enum spl_pixel_format format)
{
- if ((format >= SPL_PIXEL_FORMAT_VIDEO_BEGIN) &&
- (format <= SPL_PIXEL_FORMAT_VIDEO_END))
+ if ((format >= SPL_PIXEL_FORMAT_420BPP8) &&
+ (format <= SPL_PIXEL_FORMAT_420BPP10))
+ return true;
+
+ return false;
+}
+
+static bool spl_is_rgb8(enum spl_pixel_format format)
+{
+ if (format == SPL_PIXEL_FORMAT_ARGB8888)
return true;
return false;
}
/*Calculate inits and viewport */
-static void spl_calculate_inits_and_viewports(struct spl_in *spl_in, struct spl_out *spl_out)
+static void spl_calculate_inits_and_viewports(struct spl_in *spl_in,
+ struct spl_scratch *spl_scratch)
{
struct spl_rect src = spl_in->basic_in.src_rect;
struct spl_rect recout_dst_in_active_timing;
@@ -528,11 +559,11 @@ static void spl_calculate_inits_and_viewports(struct spl_in *spl_in, struct spl_
int vpc_div = (spl_in->basic_in.format == SPL_PIXEL_FORMAT_420BPP8
|| spl_in->basic_in.format == SPL_PIXEL_FORMAT_420BPP10) ? 2 : 1;
bool orthogonal_rotation, flip_vert_scan_dir, flip_horz_scan_dir;
- struct fixed31_32 init_adj_h = dc_fixpt_zero;
- struct fixed31_32 init_adj_v = dc_fixpt_zero;
+ struct spl_fixed31_32 init_adj_h = spl_fixpt_zero;
+ struct spl_fixed31_32 init_adj_v = spl_fixpt_zero;
recout_clip_in_active_timing = shift_rec(
- &spl_out->scl_data.recout, odm_slice.x, odm_slice.y);
+ &spl_scratch->scl_data.recout, odm_slice.x, odm_slice.y);
recout_dst_in_active_timing = calculate_plane_rec_in_timing_active(
spl_in, &spl_in->basic_in.dst_rect);
overlap_in_active_timing = intersect_rec(&recout_clip_in_active_timing,
@@ -555,8 +586,8 @@ static void spl_calculate_inits_and_viewports(struct spl_in *spl_in, struct spl_
&flip_horz_scan_dir);
if (orthogonal_rotation) {
- swap(src.width, src.height);
- swap(flip_vert_scan_dir, flip_horz_scan_dir);
+ spl_swap(src.width, src.height);
+ spl_swap(flip_vert_scan_dir, flip_horz_scan_dir);
}
if (spl_is_yuv420(spl_in->basic_in.format)) {
@@ -568,17 +599,17 @@ static void spl_calculate_inits_and_viewports(struct spl_in *spl_in, struct spl_
switch (spl_in->basic_in.cositing) {
case CHROMA_COSITING_LEFT:
- init_adj_h = dc_fixpt_zero;
- init_adj_v = dc_fixpt_from_fraction(sign, 2);
+ init_adj_h = spl_fixpt_zero;
+ init_adj_v = spl_fixpt_from_fraction(sign, 4);
break;
case CHROMA_COSITING_NONE:
- init_adj_h = dc_fixpt_from_fraction(sign, 2);
- init_adj_v = dc_fixpt_from_fraction(sign, 2);
+ init_adj_h = spl_fixpt_from_fraction(sign, 4);
+ init_adj_v = spl_fixpt_from_fraction(sign, 4);
break;
case CHROMA_COSITING_TOPLEFT:
default:
- init_adj_h = dc_fixpt_zero;
- init_adj_v = dc_fixpt_zero;
+ init_adj_h = spl_fixpt_zero;
+ init_adj_v = spl_fixpt_zero;
break;
}
}
@@ -586,59 +617,60 @@ static void spl_calculate_inits_and_viewports(struct spl_in *spl_in, struct spl_
spl_calculate_init_and_vp(
flip_horz_scan_dir,
recout_clip_in_recout_dst.x,
- spl_out->scl_data.recout.width,
+ spl_scratch->scl_data.recout.width,
src.width,
- spl_out->scl_data.taps.h_taps,
- spl_out->scl_data.ratios.horz,
- dc_fixpt_zero,
- &spl_out->scl_data.inits.h,
- &spl_out->scl_data.viewport.x,
- &spl_out->scl_data.viewport.width);
+ spl_scratch->scl_data.taps.h_taps,
+ spl_scratch->scl_data.ratios.horz,
+ spl_fixpt_zero,
+ &spl_scratch->scl_data.inits.h,
+ &spl_scratch->scl_data.viewport.x,
+ &spl_scratch->scl_data.viewport.width);
spl_calculate_init_and_vp(
flip_horz_scan_dir,
recout_clip_in_recout_dst.x,
- spl_out->scl_data.recout.width,
+ spl_scratch->scl_data.recout.width,
src.width / vpc_div,
- spl_out->scl_data.taps.h_taps_c,
- spl_out->scl_data.ratios.horz_c,
+ spl_scratch->scl_data.taps.h_taps_c,
+ spl_scratch->scl_data.ratios.horz_c,
init_adj_h,
- &spl_out->scl_data.inits.h_c,
- &spl_out->scl_data.viewport_c.x,
- &spl_out->scl_data.viewport_c.width);
+ &spl_scratch->scl_data.inits.h_c,
+ &spl_scratch->scl_data.viewport_c.x,
+ &spl_scratch->scl_data.viewport_c.width);
spl_calculate_init_and_vp(
flip_vert_scan_dir,
recout_clip_in_recout_dst.y,
- spl_out->scl_data.recout.height,
+ spl_scratch->scl_data.recout.height,
src.height,
- spl_out->scl_data.taps.v_taps,
- spl_out->scl_data.ratios.vert,
- dc_fixpt_zero,
- &spl_out->scl_data.inits.v,
- &spl_out->scl_data.viewport.y,
- &spl_out->scl_data.viewport.height);
+ spl_scratch->scl_data.taps.v_taps,
+ spl_scratch->scl_data.ratios.vert,
+ spl_fixpt_zero,
+ &spl_scratch->scl_data.inits.v,
+ &spl_scratch->scl_data.viewport.y,
+ &spl_scratch->scl_data.viewport.height);
spl_calculate_init_and_vp(
flip_vert_scan_dir,
recout_clip_in_recout_dst.y,
- spl_out->scl_data.recout.height,
+ spl_scratch->scl_data.recout.height,
src.height / vpc_div,
- spl_out->scl_data.taps.v_taps_c,
- spl_out->scl_data.ratios.vert_c,
+ spl_scratch->scl_data.taps.v_taps_c,
+ spl_scratch->scl_data.ratios.vert_c,
init_adj_v,
- &spl_out->scl_data.inits.v_c,
- &spl_out->scl_data.viewport_c.y,
- &spl_out->scl_data.viewport_c.height);
+ &spl_scratch->scl_data.inits.v_c,
+ &spl_scratch->scl_data.viewport_c.y,
+ &spl_scratch->scl_data.viewport_c.height);
if (orthogonal_rotation) {
- swap(spl_out->scl_data.viewport.x, spl_out->scl_data.viewport.y);
- swap(spl_out->scl_data.viewport.width, spl_out->scl_data.viewport.height);
- swap(spl_out->scl_data.viewport_c.x, spl_out->scl_data.viewport_c.y);
- swap(spl_out->scl_data.viewport_c.width, spl_out->scl_data.viewport_c.height);
+ spl_swap(spl_scratch->scl_data.viewport.x, spl_scratch->scl_data.viewport.y);
+ spl_swap(spl_scratch->scl_data.viewport.width, spl_scratch->scl_data.viewport.height);
+ spl_swap(spl_scratch->scl_data.viewport_c.x, spl_scratch->scl_data.viewport_c.y);
+ spl_swap(spl_scratch->scl_data.viewport_c.width, spl_scratch->scl_data.viewport_c.height);
}
- spl_out->scl_data.viewport.x += src.x;
- spl_out->scl_data.viewport.y += src.y;
- ASSERT(src.x % vpc_div == 0 && src.y % vpc_div == 0);
- spl_out->scl_data.viewport_c.x += src.x / vpc_div;
- spl_out->scl_data.viewport_c.y += src.y / vpc_div;
+ spl_scratch->scl_data.viewport.x += src.x;
+ spl_scratch->scl_data.viewport.y += src.y;
+ SPL_ASSERT(src.x % vpc_div == 0 && src.y % vpc_div == 0);
+ spl_scratch->scl_data.viewport_c.x += src.x / vpc_div;
+ spl_scratch->scl_data.viewport_c.y += src.y / vpc_div;
}
+
static void spl_handle_3d_recout(struct spl_in *spl_in, struct spl_rect *recout)
{
/*
@@ -647,7 +679,7 @@ static void spl_handle_3d_recout(struct spl_in *spl_in, struct spl_rect *recout)
* This may break with rotation, good thing we aren't mixing hw rotation and 3d
*/
if (spl_in->basic_in.mpc_combine_v) {
- ASSERT(spl_in->basic_in.rotation == SPL_ROTATION_ANGLE_0 ||
+ SPL_ASSERT(spl_in->basic_in.rotation == SPL_ROTATION_ANGLE_0 ||
(spl_in->basic_out.view_format != SPL_VIEW_3D_TOP_AND_BOTTOM &&
spl_in->basic_out.view_format != SPL_VIEW_3D_SIDE_BY_SIDE));
if (spl_in->basic_out.view_format == SPL_VIEW_3D_TOP_AND_BOTTOM)
@@ -665,6 +697,7 @@ static void spl_clamp_viewport(struct spl_rect *viewport)
if (viewport->width < MIN_VIEWPORT_SIZE)
viewport->width = MIN_VIEWPORT_SIZE;
}
+
static bool spl_dscl_is_420_format(enum spl_pixel_format format)
{
if (format == SPL_PIXEL_FORMAT_420BPP8 ||
@@ -673,6 +706,7 @@ static bool spl_dscl_is_420_format(enum spl_pixel_format format)
else
return false;
}
+
static bool spl_dscl_is_video_format(enum spl_pixel_format format)
{
if (format >= SPL_PIXEL_FORMAT_VIDEO_BEGIN
@@ -681,17 +715,21 @@ static bool spl_dscl_is_video_format(enum spl_pixel_format format)
else
return false;
}
+
static enum scl_mode spl_get_dscl_mode(const struct spl_in *spl_in,
- const struct spl_scaler_data *data)
+ const struct spl_scaler_data *data,
+ bool enable_isharp, bool enable_easf)
{
- const long long one = dc_fixpt_one.value;
+ const long long one = spl_fixpt_one.value;
enum spl_pixel_format pixel_format = spl_in->basic_in.format;
+ /* Bypass if ratio is 1:1 with no ISHARP or force scale on */
if (data->ratios.horz.value == one
&& data->ratios.vert.value == one
&& data->ratios.horz_c.value == one
&& data->ratios.vert_c.value == one
- && !spl_in->basic_out.always_scale)
+ && !spl_in->basic_out.always_scale
+ && !enable_isharp)
return SCL_MODE_SCALING_444_BYPASS;
if (!spl_dscl_is_420_format(pixel_format)) {
@@ -700,69 +738,196 @@ static enum scl_mode spl_get_dscl_mode(const struct spl_in *spl_in,
else
return SCL_MODE_SCALING_444_RGB_ENABLE;
}
- if (data->ratios.horz.value == one && data->ratios.vert.value == one)
- return SCL_MODE_SCALING_420_LUMA_BYPASS;
- if (data->ratios.horz_c.value == one && data->ratios.vert_c.value == one)
- return SCL_MODE_SCALING_420_CHROMA_BYPASS;
+
+ /* Bypass YUV if at 1:1 with no ISHARP or if doing 2:1 YUV
+ * downscale without EASF
+ */
+ if ((!enable_isharp) && (!enable_easf)) {
+ if (data->ratios.horz.value == one && data->ratios.vert.value == one)
+ return SCL_MODE_SCALING_420_LUMA_BYPASS;
+ if (data->ratios.horz_c.value == one && data->ratios.vert_c.value == one)
+ return SCL_MODE_SCALING_420_CHROMA_BYPASS;
+ }
return SCL_MODE_SCALING_420_YCBCR_ENABLE;
}
+
+static bool spl_choose_lls_policy(enum spl_pixel_format format,
+ enum spl_transfer_func_type tf_type,
+ enum spl_transfer_func_predefined tf_predefined_type,
+ enum linear_light_scaling *lls_pref)
+{
+ if (spl_is_yuv420(format)) {
+ *lls_pref = LLS_PREF_NO;
+ if ((tf_type == SPL_TF_TYPE_PREDEFINED) ||
+ (tf_type == SPL_TF_TYPE_DISTRIBUTED_POINTS))
+ return true;
+ } else { /* RGB or YUV444 */
+ if ((tf_type == SPL_TF_TYPE_PREDEFINED) ||
+ (tf_type == SPL_TF_TYPE_BYPASS)) {
+ *lls_pref = LLS_PREF_YES;
+ return true;
+ }
+ }
+ *lls_pref = LLS_PREF_NO;
+ return false;
+}
+
+/* Enable EASF ?*/
+static bool enable_easf(struct spl_in *spl_in, struct spl_scratch *spl_scratch)
+{
+ int vratio = 0;
+ int hratio = 0;
+ bool skip_easf = false;
+ bool lls_enable_easf = true;
+
+ if (spl_in->disable_easf)
+ skip_easf = true;
+
+ vratio = spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert);
+ hratio = spl_fixpt_ceil(spl_scratch->scl_data.ratios.horz);
+
+ /*
+ * No EASF support for downscaling > 2:1
+ * EASF support for upscaling or downscaling up to 2:1
+ */
+ if ((vratio > 2) || (hratio > 2))
+ skip_easf = true;
+
+ /*
+ * If lls_pref is LLS_PREF_DONT_CARE, then use pixel format and transfer
+ * function to determine whether to use LINEAR or NONLINEAR scaling
+ */
+ if (spl_in->lls_pref == LLS_PREF_DONT_CARE)
+ lls_enable_easf = spl_choose_lls_policy(spl_in->basic_in.format,
+ spl_in->basic_in.tf_type, spl_in->basic_in.tf_predefined_type,
+ &spl_in->lls_pref);
+
+ if (!lls_enable_easf)
+ skip_easf = true;
+
+ /* Check for linear scaling or EASF preferred */
+ if (spl_in->lls_pref != LLS_PREF_YES && !spl_in->prefer_easf)
+ skip_easf = true;
+
+ return skip_easf;
+}
+
+static bool spl_get_isharp_en(struct spl_in *spl_in,
+ struct spl_scratch *spl_scratch)
+{
+ bool enable_isharp = false;
+ int vratio = 0;
+ int hratio = 0;
+ struct spl_taps taps = spl_scratch->scl_data.taps;
+
+ /* Return if adaptive sharpness is disabled */
+ if (spl_in->adaptive_sharpness.enable == false)
+ return enable_isharp;
+
+ vratio = spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert);
+ hratio = spl_fixpt_ceil(spl_scratch->scl_data.ratios.horz);
+
+ /* No iSHARP support for downscaling */
+ if (vratio > 1 || hratio > 1)
+ return enable_isharp;
+
+ // Scaling is up to 1:1 (no scaling) or upscaling
+
+ /*
+ * Apply sharpness to all RGB surfaces and to
+ * NV12/P010 surfaces
+ */
+
+ /*
+ * Apply sharpness if supports horizontal taps 4,6 AND
+ * vertical taps 3, 4, 6
+ */
+ if ((taps.h_taps == 4 || taps.h_taps == 6) &&
+ (taps.v_taps == 3 || taps.v_taps == 4 || taps.v_taps == 6))
+ enable_isharp = true;
+
+ return enable_isharp;
+}
+
/* Calculate optimal number of taps */
static bool spl_get_optimal_number_of_taps(
- int max_downscale_src_width, struct spl_in *spl_in, struct spl_out *spl_out,
- const struct spl_taps *in_taps)
+ int max_downscale_src_width, struct spl_in *spl_in, struct spl_scratch *spl_scratch,
+ const struct spl_taps *in_taps, bool *enable_easf_v, bool *enable_easf_h,
+ bool *enable_isharp)
{
int num_part_y, num_part_c;
int max_taps_y, max_taps_c;
int min_taps_y, min_taps_c;
enum lb_memory_config lb_config;
+ bool skip_easf = false;
- if (spl_out->scl_data.viewport.width > spl_out->scl_data.h_active &&
+ if (spl_scratch->scl_data.viewport.width > spl_scratch->scl_data.h_active &&
max_downscale_src_width != 0 &&
- spl_out->scl_data.viewport.width > max_downscale_src_width)
+ spl_scratch->scl_data.viewport.width > max_downscale_src_width)
return false;
+
+ /* Check if we are using EASF or not */
+ skip_easf = enable_easf(spl_in, spl_scratch);
+
/*
* Set default taps if none are provided
* From programming guide: taps = min{ ceil(2*H_RATIO,1), 8} for downscaling
* taps = 4 for upscaling
*/
- if (in_taps->h_taps == 0) {
- if (dc_fixpt_ceil(spl_out->scl_data.ratios.horz) > 1)
- spl_out->scl_data.taps.h_taps = min(2 * dc_fixpt_ceil(spl_out->scl_data.ratios.horz), 8);
- else
- spl_out->scl_data.taps.h_taps = 4;
- } else
- spl_out->scl_data.taps.h_taps = in_taps->h_taps;
- if (in_taps->v_taps == 0) {
- if (dc_fixpt_ceil(spl_out->scl_data.ratios.vert) > 1)
- spl_out->scl_data.taps.v_taps = min(dc_fixpt_ceil(dc_fixpt_mul_int(
- spl_out->scl_data.ratios.vert, 2)), 8);
- else
- spl_out->scl_data.taps.v_taps = 4;
- } else
- spl_out->scl_data.taps.v_taps = in_taps->v_taps;
- if (in_taps->v_taps_c == 0) {
- if (dc_fixpt_ceil(spl_out->scl_data.ratios.vert_c) > 1)
- spl_out->scl_data.taps.v_taps_c = min(dc_fixpt_ceil(dc_fixpt_mul_int(
- spl_out->scl_data.ratios.vert_c, 2)), 8);
- else
- spl_out->scl_data.taps.v_taps_c = 4;
- } else
- spl_out->scl_data.taps.v_taps_c = in_taps->v_taps_c;
- if (in_taps->h_taps_c == 0) {
- if (dc_fixpt_ceil(spl_out->scl_data.ratios.horz_c) > 1)
- spl_out->scl_data.taps.h_taps_c = min(2 * dc_fixpt_ceil(spl_out->scl_data.ratios.horz_c), 8);
+ if (skip_easf) {
+ if (in_taps->h_taps == 0) {
+ if (spl_fixpt_ceil(spl_scratch->scl_data.ratios.horz) > 1)
+ spl_scratch->scl_data.taps.h_taps = spl_min(2 * spl_fixpt_ceil(
+ spl_scratch->scl_data.ratios.horz), 8);
+ else
+ spl_scratch->scl_data.taps.h_taps = 4;
+ } else
+ spl_scratch->scl_data.taps.h_taps = in_taps->h_taps;
+ if (in_taps->v_taps == 0) {
+ if (spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert) > 1)
+ spl_scratch->scl_data.taps.v_taps = spl_min(spl_fixpt_ceil(spl_fixpt_mul_int(
+ spl_scratch->scl_data.ratios.vert, 2)), 8);
+ else
+ spl_scratch->scl_data.taps.v_taps = 4;
+ } else
+ spl_scratch->scl_data.taps.v_taps = in_taps->v_taps;
+ if (in_taps->v_taps_c == 0) {
+ if (spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert_c) > 1)
+ spl_scratch->scl_data.taps.v_taps_c = spl_min(spl_fixpt_ceil(spl_fixpt_mul_int(
+ spl_scratch->scl_data.ratios.vert_c, 2)), 8);
+ else
+ spl_scratch->scl_data.taps.v_taps_c = 4;
+ } else
+ spl_scratch->scl_data.taps.v_taps_c = in_taps->v_taps_c;
+ if (in_taps->h_taps_c == 0) {
+ if (spl_fixpt_ceil(spl_scratch->scl_data.ratios.horz_c) > 1)
+ spl_scratch->scl_data.taps.h_taps_c = spl_min(2 * spl_fixpt_ceil(
+ spl_scratch->scl_data.ratios.horz_c), 8);
+ else
+ spl_scratch->scl_data.taps.h_taps_c = 4;
+ } else if ((in_taps->h_taps_c % 2) != 0 && in_taps->h_taps_c != 1)
+ /* Only 1 and even h_taps_c are supported by hw */
+ spl_scratch->scl_data.taps.h_taps_c = in_taps->h_taps_c - 1;
else
- spl_out->scl_data.taps.h_taps_c = 4;
- } else if ((in_taps->h_taps_c % 2) != 0 && in_taps->h_taps_c != 1)
- /* Only 1 and even h_taps_c are supported by hw */
- spl_out->scl_data.taps.h_taps_c = in_taps->h_taps_c - 1;
- else
- spl_out->scl_data.taps.h_taps_c = in_taps->h_taps_c;
+ spl_scratch->scl_data.taps.h_taps_c = in_taps->h_taps_c;
+ } else {
+ if (spl_is_yuv420(spl_in->basic_in.format)) {
+ spl_scratch->scl_data.taps.h_taps = 6;
+ spl_scratch->scl_data.taps.v_taps = 6;
+ spl_scratch->scl_data.taps.h_taps_c = 4;
+ spl_scratch->scl_data.taps.v_taps_c = 4;
+ } else { /* RGB */
+ spl_scratch->scl_data.taps.h_taps = 6;
+ spl_scratch->scl_data.taps.v_taps = 6;
+ spl_scratch->scl_data.taps.h_taps_c = 6;
+ spl_scratch->scl_data.taps.v_taps_c = 6;
+ }
+ }
/*Ensure we can support the requested number of vtaps*/
- min_taps_y = dc_fixpt_ceil(spl_out->scl_data.ratios.vert);
- min_taps_c = dc_fixpt_ceil(spl_out->scl_data.ratios.vert_c);
+ min_taps_y = spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert);
+ min_taps_c = spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert_c);
/* Use LB_MEMORY_CONFIG_3 for 4:2:0 */
if ((spl_in->basic_in.format == SPL_PIXEL_FORMAT_420BPP8)
@@ -771,16 +936,16 @@ static bool spl_get_optimal_number_of_taps(
else
lb_config = LB_MEMORY_CONFIG_0;
// Determine max vtap support by calculating how much line buffer can fit
- spl_in->funcs->spl_calc_lb_num_partitions(spl_in->basic_out.alpha_en, &spl_out->scl_data,
+ spl_in->funcs->spl_calc_lb_num_partitions(spl_in->basic_out.alpha_en, &spl_scratch->scl_data,
lb_config, &num_part_y, &num_part_c);
/* MAX_V_TAPS = MIN (NUM_LINES - MAX(CEILING(V_RATIO,1)-2, 0), 8) */
- if (dc_fixpt_ceil(spl_out->scl_data.ratios.vert) > 2)
- max_taps_y = num_part_y - (dc_fixpt_ceil(spl_out->scl_data.ratios.vert) - 2);
+ if (spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert) > 2)
+ max_taps_y = num_part_y - (spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert) - 2);
else
max_taps_y = num_part_y;
- if (dc_fixpt_ceil(spl_out->scl_data.ratios.vert_c) > 2)
- max_taps_c = num_part_c - (dc_fixpt_ceil(spl_out->scl_data.ratios.vert_c) - 2);
+ if (spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert_c) > 2)
+ max_taps_c = num_part_c - (spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert_c) - 2);
else
max_taps_c = num_part_c;
@@ -789,48 +954,108 @@ static bool spl_get_optimal_number_of_taps(
else if (max_taps_c < min_taps_c)
return false;
- if (spl_out->scl_data.taps.v_taps > max_taps_y)
- spl_out->scl_data.taps.v_taps = max_taps_y;
-
- if (spl_out->scl_data.taps.v_taps_c > max_taps_c)
- spl_out->scl_data.taps.v_taps_c = max_taps_c;
- if (spl_in->prefer_easf) {
- // EASF can be enabled only for taps 3,4,6
- // If optimal no of taps is 5, then set it to 4
- // If optimal no of taps is 7 or 8, then set it to 6
- if (spl_out->scl_data.taps.v_taps == 5)
- spl_out->scl_data.taps.v_taps = 4;
- if (spl_out->scl_data.taps.v_taps == 7 || spl_out->scl_data.taps.v_taps == 8)
- spl_out->scl_data.taps.v_taps = 6;
-
- if (spl_out->scl_data.taps.v_taps_c == 5)
- spl_out->scl_data.taps.v_taps_c = 4;
- if (spl_out->scl_data.taps.v_taps_c == 7 || spl_out->scl_data.taps.v_taps_c == 8)
- spl_out->scl_data.taps.v_taps_c = 6;
-
- if (spl_out->scl_data.taps.h_taps == 5)
- spl_out->scl_data.taps.h_taps = 4;
- if (spl_out->scl_data.taps.h_taps == 7 || spl_out->scl_data.taps.h_taps == 8)
- spl_out->scl_data.taps.h_taps = 6;
-
- if (spl_out->scl_data.taps.h_taps_c == 5)
- spl_out->scl_data.taps.h_taps_c = 4;
- if (spl_out->scl_data.taps.h_taps_c == 7 || spl_out->scl_data.taps.h_taps_c == 8)
- spl_out->scl_data.taps.h_taps_c = 6;
+ if (spl_scratch->scl_data.taps.v_taps > max_taps_y)
+ spl_scratch->scl_data.taps.v_taps = max_taps_y;
+ if (spl_scratch->scl_data.taps.v_taps_c > max_taps_c)
+ spl_scratch->scl_data.taps.v_taps_c = max_taps_c;
+
+ if (!skip_easf) {
+ /*
+ * RGB ( L + NL ) and Linear HDR support 6x6, 6x4, 6x3, 4x4, 4x3
+ * NL YUV420 only supports 6x6, 6x4 for Y and 4x4 for UV
+ *
+ * If LB does not support 3, 4, or 6 taps, then disable EASF_V
+ * and only enable EASF_H. So for RGB, support 6x2, 4x2
+ * and for NL YUV420, support 6x2 for Y and 4x2 for UV
+ *
+ * All other cases, have to disable EASF_V and EASF_H
+ *
+ * If optimal no of taps is 5, then set it to 4
+ * If optimal no of taps is 7 or 8, then fine since max tap is 6
+ *
+ */
+ if (spl_scratch->scl_data.taps.v_taps == 5)
+ spl_scratch->scl_data.taps.v_taps = 4;
+
+ if (spl_scratch->scl_data.taps.v_taps_c == 5)
+ spl_scratch->scl_data.taps.v_taps_c = 4;
+
+ if (spl_scratch->scl_data.taps.h_taps == 5)
+ spl_scratch->scl_data.taps.h_taps = 4;
+
+ if (spl_scratch->scl_data.taps.h_taps_c == 5)
+ spl_scratch->scl_data.taps.h_taps_c = 4;
+
+ if (spl_is_yuv420(spl_in->basic_in.format)) {
+ if ((spl_scratch->scl_data.taps.h_taps <= 4) ||
+ (spl_scratch->scl_data.taps.h_taps_c <= 3)) {
+ *enable_easf_v = false;
+ *enable_easf_h = false;
+ } else if ((spl_scratch->scl_data.taps.v_taps <= 3) ||
+ (spl_scratch->scl_data.taps.v_taps_c <= 3)) {
+ *enable_easf_v = false;
+ *enable_easf_h = true;
+ } else {
+ *enable_easf_v = true;
+ *enable_easf_h = true;
+ }
+ SPL_ASSERT((spl_scratch->scl_data.taps.v_taps > 1) &&
+ (spl_scratch->scl_data.taps.v_taps_c > 1));
+ } else { /* RGB */
+ if (spl_scratch->scl_data.taps.h_taps <= 3) {
+ *enable_easf_v = false;
+ *enable_easf_h = false;
+ } else if (spl_scratch->scl_data.taps.v_taps < 3) {
+ *enable_easf_v = false;
+ *enable_easf_h = true;
+ } else {
+ *enable_easf_v = true;
+ *enable_easf_h = true;
+ }
+ SPL_ASSERT(spl_scratch->scl_data.taps.v_taps > 1);
+ }
+ } else {
+ *enable_easf_v = false;
+ *enable_easf_h = false;
} // end of if prefer_easf
- if (!spl_in->basic_out.always_scale) {
- if (IDENTITY_RATIO(spl_out->scl_data.ratios.horz))
- spl_out->scl_data.taps.h_taps = 1;
- if (IDENTITY_RATIO(spl_out->scl_data.ratios.vert))
- spl_out->scl_data.taps.v_taps = 1;
- if (IDENTITY_RATIO(spl_out->scl_data.ratios.horz_c))
- spl_out->scl_data.taps.h_taps_c = 1;
- if (IDENTITY_RATIO(spl_out->scl_data.ratios.vert_c))
- spl_out->scl_data.taps.v_taps_c = 1;
+
+ /* Sharpener requires scaler to be enabled, including for 1:1
+ * Check if ISHARP can be enabled
+ * If ISHARP is not enabled, for 1:1, set taps to 1 and disable
+ * EASF
+ * For case of 2:1 YUV where chroma is 1:1, set taps to 1 if
+ * EASF is not enabled
+ */
+
+ *enable_isharp = spl_get_isharp_en(spl_in, spl_scratch);
+ if (!*enable_isharp && !spl_in->basic_out.always_scale) {
+ if ((IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz)) &&
+ (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert))) {
+ spl_scratch->scl_data.taps.h_taps = 1;
+ spl_scratch->scl_data.taps.v_taps = 1;
+
+ if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz_c))
+ spl_scratch->scl_data.taps.h_taps_c = 1;
+
+ if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert_c))
+ spl_scratch->scl_data.taps.v_taps_c = 1;
+
+ *enable_easf_v = false;
+ *enable_easf_h = false;
+ } else {
+ if ((!*enable_easf_h) &&
+ (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz_c)))
+ spl_scratch->scl_data.taps.h_taps_c = 1;
+
+ if ((!*enable_easf_v) &&
+ (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert_c)))
+ spl_scratch->scl_data.taps.v_taps_c = 1;
+ }
}
return true;
}
+
static void spl_set_black_color_data(enum spl_pixel_format format,
struct scl_black_color *scl_black_color)
{
@@ -848,38 +1073,38 @@ static void spl_set_black_color_data(enum spl_pixel_format format,
static void spl_set_manual_ratio_init_data(struct dscl_prog_data *dscl_prog_data,
const struct spl_scaler_data *scl_data)
{
- struct fixed31_32 bot;
+ struct spl_fixed31_32 bot;
- dscl_prog_data->ratios.h_scale_ratio = dc_fixpt_u3d19(scl_data->ratios.horz) << 5;
- dscl_prog_data->ratios.v_scale_ratio = dc_fixpt_u3d19(scl_data->ratios.vert) << 5;
- dscl_prog_data->ratios.h_scale_ratio_c = dc_fixpt_u3d19(scl_data->ratios.horz_c) << 5;
- dscl_prog_data->ratios.v_scale_ratio_c = dc_fixpt_u3d19(scl_data->ratios.vert_c) << 5;
+ dscl_prog_data->ratios.h_scale_ratio = spl_fixpt_u3d19(scl_data->ratios.horz) << 5;
+ dscl_prog_data->ratios.v_scale_ratio = spl_fixpt_u3d19(scl_data->ratios.vert) << 5;
+ dscl_prog_data->ratios.h_scale_ratio_c = spl_fixpt_u3d19(scl_data->ratios.horz_c) << 5;
+ dscl_prog_data->ratios.v_scale_ratio_c = spl_fixpt_u3d19(scl_data->ratios.vert_c) << 5;
/*
* 0.24 format for fraction, first five bits zeroed
*/
dscl_prog_data->init.h_filter_init_frac =
- dc_fixpt_u0d19(scl_data->inits.h) << 5;
+ spl_fixpt_u0d19(scl_data->inits.h) << 5;
dscl_prog_data->init.h_filter_init_int =
- dc_fixpt_floor(scl_data->inits.h);
+ spl_fixpt_floor(scl_data->inits.h);
dscl_prog_data->init.h_filter_init_frac_c =
- dc_fixpt_u0d19(scl_data->inits.h_c) << 5;
+ spl_fixpt_u0d19(scl_data->inits.h_c) << 5;
dscl_prog_data->init.h_filter_init_int_c =
- dc_fixpt_floor(scl_data->inits.h_c);
+ spl_fixpt_floor(scl_data->inits.h_c);
dscl_prog_data->init.v_filter_init_frac =
- dc_fixpt_u0d19(scl_data->inits.v) << 5;
+ spl_fixpt_u0d19(scl_data->inits.v) << 5;
dscl_prog_data->init.v_filter_init_int =
- dc_fixpt_floor(scl_data->inits.v);
+ spl_fixpt_floor(scl_data->inits.v);
dscl_prog_data->init.v_filter_init_frac_c =
- dc_fixpt_u0d19(scl_data->inits.v_c) << 5;
+ spl_fixpt_u0d19(scl_data->inits.v_c) << 5;
dscl_prog_data->init.v_filter_init_int_c =
- dc_fixpt_floor(scl_data->inits.v_c);
-
- bot = dc_fixpt_add(scl_data->inits.v, scl_data->ratios.vert);
- dscl_prog_data->init.v_filter_init_bot_frac = dc_fixpt_u0d19(bot) << 5;
- dscl_prog_data->init.v_filter_init_bot_int = dc_fixpt_floor(bot);
- bot = dc_fixpt_add(scl_data->inits.v_c, scl_data->ratios.vert_c);
- dscl_prog_data->init.v_filter_init_bot_frac_c = dc_fixpt_u0d19(bot) << 5;
- dscl_prog_data->init.v_filter_init_bot_int_c = dc_fixpt_floor(bot);
+ spl_fixpt_floor(scl_data->inits.v_c);
+
+ bot = spl_fixpt_add(scl_data->inits.v, scl_data->ratios.vert);
+ dscl_prog_data->init.v_filter_init_bot_frac = spl_fixpt_u0d19(bot) << 5;
+ dscl_prog_data->init.v_filter_init_bot_int = spl_fixpt_floor(bot);
+ bot = spl_fixpt_add(scl_data->inits.v_c, scl_data->ratios.vert_c);
+ dscl_prog_data->init.v_filter_init_bot_frac_c = spl_fixpt_u0d19(bot) << 5;
+ dscl_prog_data->init.v_filter_init_bot_int_c = spl_fixpt_floor(bot);
}
static void spl_set_taps_data(struct dscl_prog_data *dscl_prog_data,
@@ -890,77 +1115,28 @@ static void spl_set_taps_data(struct dscl_prog_data *dscl_prog_data,
dscl_prog_data->taps.v_taps_c = scl_data->taps.v_taps_c - 1;
dscl_prog_data->taps.h_taps_c = scl_data->taps.h_taps_c - 1;
}
-static const uint16_t *spl_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
-{
- if (taps == 8)
- return spl_get_filter_8tap_64p(ratio);
- else if (taps == 7)
- return spl_get_filter_7tap_64p(ratio);
- else if (taps == 6)
- return spl_get_filter_6tap_64p(ratio);
- else if (taps == 5)
- return spl_get_filter_5tap_64p(ratio);
- else if (taps == 4)
- return spl_get_filter_4tap_64p(ratio);
- else if (taps == 3)
- return spl_get_filter_3tap_64p(ratio);
- else if (taps == 2)
- return spl_get_filter_2tap_64p();
- else if (taps == 1)
- return NULL;
- else {
- /* should never happen, bug */
- return NULL;
- }
-}
-static void spl_set_filters_data(struct dscl_prog_data *dscl_prog_data,
- const struct spl_scaler_data *data)
-{
- dscl_prog_data->filter_h = spl_dscl_get_filter_coeffs_64p(
- data->taps.h_taps, data->ratios.horz);
- dscl_prog_data->filter_v = spl_dscl_get_filter_coeffs_64p(
- data->taps.v_taps, data->ratios.vert);
- dscl_prog_data->filter_h_c = spl_dscl_get_filter_coeffs_64p(
- data->taps.h_taps_c, data->ratios.horz_c);
- dscl_prog_data->filter_v_c = spl_dscl_get_filter_coeffs_64p(
- data->taps.v_taps_c, data->ratios.vert_c);
-}
-
-static const uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps)
-{
- if ((taps == 3) || (taps == 4) || (taps == 6))
- return spl_get_filter_isharp_bs_4tap_64p();
- else {
- /* should never happen, bug */
- return NULL;
- }
-}
-static void spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data,
- const struct spl_scaler_data *data)
-{
- dscl_prog_data->filter_blur_scale_h = spl_dscl_get_blur_scale_coeffs_64p(
- data->taps.h_taps);
- dscl_prog_data->filter_blur_scale_v = spl_dscl_get_blur_scale_coeffs_64p(
- data->taps.v_taps);
-}
/* Populate dscl prog data structure from scaler data calculated by SPL */
-static void spl_set_dscl_prog_data(struct spl_in *spl_in, struct spl_out *spl_out)
+static void spl_set_dscl_prog_data(struct spl_in *spl_in, struct spl_scratch *spl_scratch,
+ struct spl_out *spl_out, bool enable_easf_v, bool enable_easf_h, bool enable_isharp)
{
struct dscl_prog_data *dscl_prog_data = spl_out->dscl_prog_data;
- const struct spl_scaler_data *data = &spl_out->scl_data;
+ const struct spl_scaler_data *data = &spl_scratch->scl_data;
struct scl_black_color *scl_black_color = &dscl_prog_data->scl_black_color;
+ bool enable_easf = enable_easf_v || enable_easf_h;
+
// Set values for recout
- dscl_prog_data->recout = spl_out->scl_data.recout;
+ dscl_prog_data->recout = spl_scratch->scl_data.recout;
// Set values for MPC Size
- dscl_prog_data->mpc_size.width = spl_out->scl_data.h_active;
- dscl_prog_data->mpc_size.height = spl_out->scl_data.v_active;
+ dscl_prog_data->mpc_size.width = spl_scratch->scl_data.h_active;
+ dscl_prog_data->mpc_size.height = spl_scratch->scl_data.v_active;
// SCL_MODE - Set SCL_MODE data
- dscl_prog_data->dscl_mode = spl_get_dscl_mode(spl_in, data);
+ dscl_prog_data->dscl_mode = spl_get_dscl_mode(spl_in, data, enable_isharp,
+ enable_easf);
// SCL_BLACK_COLOR
spl_set_black_color_data(spl_in->basic_in.format, scl_black_color);
@@ -971,103 +1147,135 @@ static void spl_set_dscl_prog_data(struct spl_in *spl_in, struct spl_out *spl_ou
// Set HTaps/VTaps
spl_set_taps_data(dscl_prog_data, data);
// Set viewport
- dscl_prog_data->viewport = spl_out->scl_data.viewport;
+ dscl_prog_data->viewport = spl_scratch->scl_data.viewport;
// Set viewport_c
- dscl_prog_data->viewport_c = spl_out->scl_data.viewport_c;
+ dscl_prog_data->viewport_c = spl_scratch->scl_data.viewport_c;
// Set filters data
- spl_set_filters_data(dscl_prog_data, data);
+ spl_set_filters_data(dscl_prog_data, data, enable_easf_v, enable_easf_h);
}
-/* Enable EASF ?*/
-static bool enable_easf(int scale_ratio, int taps,
- enum linear_light_scaling lls_pref, bool prefer_easf)
+
+/* Calculate C0-C3 coefficients based on HDR_mult */
+static void spl_calculate_c0_c3_hdr(struct dscl_prog_data *dscl_prog_data, uint32_t hdr_multx100)
{
- // Is downscaling > 6:1 ?
- if (scale_ratio > 6) {
- // END - No EASF support for downscaling > 6:1
- return false;
- }
- // Is upscaling or downscaling up to 2:1?
- if (scale_ratio <= 2) {
- // Is linear scaling or EASF preferred?
- if (lls_pref == LLS_PREF_YES || prefer_easf) {
- // LB support taps 3, 4, 6
- if (taps == 3 || taps == 4 || taps == 6) {
- // END - EASF supported
- return true;
- }
- }
- }
- // END - EASF not supported
- return false;
+ struct spl_fixed31_32 hdr_mult, c0_mult, c1_mult, c2_mult;
+ struct spl_fixed31_32 c0_calc, c1_calc, c2_calc;
+ struct spl_custom_float_format fmt;
+
+ SPL_ASSERT(hdr_multx100);
+ hdr_mult = spl_fixpt_from_fraction((long long)hdr_multx100, 100LL);
+ c0_mult = spl_fixpt_from_fraction(2126LL, 10000LL);
+ c1_mult = spl_fixpt_from_fraction(7152LL, 10000LL);
+ c2_mult = spl_fixpt_from_fraction(722LL, 10000LL);
+
+ c0_calc = spl_fixpt_mul(hdr_mult, spl_fixpt_mul(c0_mult, spl_fixpt_from_fraction(
+ 16384LL, 125LL)));
+ c1_calc = spl_fixpt_mul(hdr_mult, spl_fixpt_mul(c1_mult, spl_fixpt_from_fraction(
+ 16384LL, 125LL)));
+ c2_calc = spl_fixpt_mul(hdr_mult, spl_fixpt_mul(c2_mult, spl_fixpt_from_fraction(
+ 16384LL, 125LL)));
+
+ fmt.exponenta_bits = 5;
+ fmt.mantissa_bits = 10;
+ fmt.sign = true;
+
+ // fp1.5.10, C0 coefficient (LN_rec709: HDR_MULT * 0.212600 * 2^14/125)
+ spl_convert_to_custom_float_format(c0_calc, &fmt, &dscl_prog_data->easf_matrix_c0);
+ // fp1.5.10, C1 coefficient (LN_rec709: HDR_MULT * 0.715200 * 2^14/125)
+ spl_convert_to_custom_float_format(c1_calc, &fmt, &dscl_prog_data->easf_matrix_c1);
+ // fp1.5.10, C2 coefficient (LN_rec709: HDR_MULT * 0.072200 * 2^14/125)
+ spl_convert_to_custom_float_format(c2_calc, &fmt, &dscl_prog_data->easf_matrix_c2);
+ dscl_prog_data->easf_matrix_c3 = 0x0; // fp1.5.10, C3 coefficient
}
+
/* Set EASF data */
-static void spl_set_easf_data(struct dscl_prog_data *dscl_prog_data,
- bool enable_easf_v, bool enable_easf_h, enum linear_light_scaling lls_pref,
- enum spl_pixel_format format)
+static void spl_set_easf_data(struct spl_scratch *spl_scratch, struct spl_out *spl_out, bool enable_easf_v,
+ bool enable_easf_h, enum linear_light_scaling lls_pref,
+ enum spl_pixel_format format, enum system_setup setup,
+ uint32_t hdr_multx100)
{
- if (spl_is_yuv420(format)) /* TODO: 0 = RGB, 1 = YUV */
- dscl_prog_data->easf_matrix_mode = 1;
- else
- dscl_prog_data->easf_matrix_mode = 0;
-
+ struct dscl_prog_data *dscl_prog_data = spl_out->dscl_prog_data;
if (enable_easf_v) {
dscl_prog_data->easf_v_en = true;
dscl_prog_data->easf_v_ring = 0;
- dscl_prog_data->easf_v_sharp_factor = 1;
+ dscl_prog_data->easf_v_sharp_factor = 0;
dscl_prog_data->easf_v_bf1_en = 1; // 1-bit, BF1 calculation enable, 0=disable, 1=enable
dscl_prog_data->easf_v_bf2_mode = 0xF; // 4-bit, BF2 calculation mode
- dscl_prog_data->easf_v_bf3_mode = 2; // 2-bit, BF3 chroma mode correction calculation mode
- dscl_prog_data->easf_v_bf2_flat1_gain = 4; // U1.3, BF2 Flat1 Gain control
- dscl_prog_data->easf_v_bf2_flat2_gain = 8; // U4.0, BF2 Flat2 Gain control
- dscl_prog_data->easf_v_bf2_roc_gain = 4; // U2.2, Rate Of Change control
+ /* 2-bit, BF3 chroma mode correction calculation mode */
+ dscl_prog_data->easf_v_bf3_mode = spl_get_v_bf3_mode(
+ spl_scratch->scl_data.recip_ratios.vert);
+ /* FP1.5.10 [ minCoef ]*/
dscl_prog_data->easf_v_ringest_3tap_dntilt_uptilt =
- 0x9F00;// FP1.5.10 [minCoef] (-0.036109167214271)
+ spl_get_3tap_dntilt_uptilt_offset(spl_scratch->scl_data.taps.v_taps,
+ spl_scratch->scl_data.recip_ratios.vert);
+ /* FP1.5.10 [ upTiltMaxVal ]*/
dscl_prog_data->easf_v_ringest_3tap_uptilt_max =
- 0x24FE; // FP1.5.10 [upTiltMaxVal] ( 0.904556445553545)
+ spl_get_3tap_uptilt_maxval(spl_scratch->scl_data.taps.v_taps,
+ spl_scratch->scl_data.recip_ratios.vert);
+ /* FP1.5.10 [ dnTiltSlope ]*/
dscl_prog_data->easf_v_ringest_3tap_dntilt_slope =
- 0x3940; // FP1.5.10 [dnTiltSlope] ( 0.910488988173371)
+ spl_get_3tap_dntilt_slope(spl_scratch->scl_data.taps.v_taps,
+ spl_scratch->scl_data.recip_ratios.vert);
+ /* FP1.5.10 [ upTilt1Slope ]*/
dscl_prog_data->easf_v_ringest_3tap_uptilt1_slope =
- 0x359C; // FP1.5.10 [upTilt1Slope] ( 0.125620179040899)
+ spl_get_3tap_uptilt1_slope(spl_scratch->scl_data.taps.v_taps,
+ spl_scratch->scl_data.recip_ratios.vert);
+ /* FP1.5.10 [ upTilt2Slope ]*/
dscl_prog_data->easf_v_ringest_3tap_uptilt2_slope =
- 0x359C; // FP1.5.10 [upTilt2Slope] ( 0.006786817723568)
+ spl_get_3tap_uptilt2_slope(spl_scratch->scl_data.taps.v_taps,
+ spl_scratch->scl_data.recip_ratios.vert);
+ /* FP1.5.10 [ upTilt2Offset ]*/
dscl_prog_data->easf_v_ringest_3tap_uptilt2_offset =
- 0x9F00; // FP1.5.10 [upTilt2Offset] (-0.006139059716651)
+ spl_get_3tap_uptilt2_offset(spl_scratch->scl_data.taps.v_taps,
+ spl_scratch->scl_data.recip_ratios.vert);
+ /* FP1.5.10; (2.0) Ring reducer gain for 4 or 6-tap mode [H_REDUCER_GAIN4] */
dscl_prog_data->easf_v_ringest_eventap_reduceg1 =
- 0x4000; // FP1.5.10; (2.0) Ring reducer gain for 4 or 6-tap mode [H_REDUCER_GAIN4]
+ spl_get_reducer_gain4(spl_scratch->scl_data.taps.v_taps,
+ spl_scratch->scl_data.recip_ratios.vert);
+ /* FP1.5.10; (2.5) Ring reducer gain for 6-tap mode [V_REDUCER_GAIN6] */
dscl_prog_data->easf_v_ringest_eventap_reduceg2 =
- 0x4100; // FP1.5.10; (2.5) Ring reducer gain for 6-tap mode [V_REDUCER_GAIN6]
+ spl_get_reducer_gain6(spl_scratch->scl_data.taps.v_taps,
+ spl_scratch->scl_data.recip_ratios.vert);
+ /* FP1.5.10; (-0.135742) Ring gain for 6-tap set to -139/1024 */
dscl_prog_data->easf_v_ringest_eventap_gain1 =
- 0xB058; // FP1.5.10; (-0.135742) Ring gain for 6-tap set to -139/1024
+ spl_get_gainRing4(spl_scratch->scl_data.taps.v_taps,
+ spl_scratch->scl_data.recip_ratios.vert);
+ /* FP1.5.10; (-0.024414) Ring gain for 6-tap set to -25/1024 */
dscl_prog_data->easf_v_ringest_eventap_gain2 =
- 0xA640; // FP1.5.10; (-0.024414) Ring gain for 6-tap set to -25/1024
+ spl_get_gainRing6(spl_scratch->scl_data.taps.v_taps,
+ spl_scratch->scl_data.recip_ratios.vert);
dscl_prog_data->easf_v_bf_maxa = 63; //Vertical Max BF value A in U0.6 format.Selected if V_FCNTL == 0
dscl_prog_data->easf_v_bf_maxb = 63; //Vertical Max BF value A in U0.6 format.Selected if V_FCNTL == 1
dscl_prog_data->easf_v_bf_mina = 0; //Vertical Min BF value A in U0.6 format.Selected if V_FCNTL == 0
dscl_prog_data->easf_v_bf_minb = 0; //Vertical Min BF value A in U0.6 format.Selected if V_FCNTL == 1
- dscl_prog_data->easf_v_bf1_pwl_in_seg0 = -512; // S0.10, BF1 PWL Segment 0
- dscl_prog_data->easf_v_bf1_pwl_base_seg0 = 0; // U0.6, BF1 Base PWL Segment 0
- dscl_prog_data->easf_v_bf1_pwl_slope_seg0 = 3; // S7.3, BF1 Slope PWL Segment 0
- dscl_prog_data->easf_v_bf1_pwl_in_seg1 = -20; // S0.10, BF1 PWL Segment 1
- dscl_prog_data->easf_v_bf1_pwl_base_seg1 = 12; // U0.6, BF1 Base PWL Segment 1
- dscl_prog_data->easf_v_bf1_pwl_slope_seg1 = 326; // S7.3, BF1 Slope PWL Segment 1
- dscl_prog_data->easf_v_bf1_pwl_in_seg2 = 0; // S0.10, BF1 PWL Segment 2
- dscl_prog_data->easf_v_bf1_pwl_base_seg2 = 63; // U0.6, BF1 Base PWL Segment 2
- dscl_prog_data->easf_v_bf1_pwl_slope_seg2 = 0; // S7.3, BF1 Slope PWL Segment 2
- dscl_prog_data->easf_v_bf1_pwl_in_seg3 = 16; // S0.10, BF1 PWL Segment 3
- dscl_prog_data->easf_v_bf1_pwl_base_seg3 = 63; // U0.6, BF1 Base PWL Segment 3
- dscl_prog_data->easf_v_bf1_pwl_slope_seg3 = -56; // S7.3, BF1 Slope PWL Segment 3
- dscl_prog_data->easf_v_bf1_pwl_in_seg4 = 32; // S0.10, BF1 PWL Segment 4
- dscl_prog_data->easf_v_bf1_pwl_base_seg4 = 56; // U0.6, BF1 Base PWL Segment 4
- dscl_prog_data->easf_v_bf1_pwl_slope_seg4 = -48; // S7.3, BF1 Slope PWL Segment 4
- dscl_prog_data->easf_v_bf1_pwl_in_seg5 = 48; // S0.10, BF1 PWL Segment 5
- dscl_prog_data->easf_v_bf1_pwl_base_seg5 = 50; // U0.6, BF1 Base PWL Segment 5
- dscl_prog_data->easf_v_bf1_pwl_slope_seg5 = -240; // S7.3, BF1 Slope PWL Segment 5
- dscl_prog_data->easf_v_bf1_pwl_in_seg6 = 64; // S0.10, BF1 PWL Segment 6
- dscl_prog_data->easf_v_bf1_pwl_base_seg6 = 20; // U0.6, BF1 Base PWL Segment 6
- dscl_prog_data->easf_v_bf1_pwl_slope_seg6 = -160; // S7.3, BF1 Slope PWL Segment 6
- dscl_prog_data->easf_v_bf1_pwl_in_seg7 = 80; // S0.10, BF1 PWL Segment 7
- dscl_prog_data->easf_v_bf1_pwl_base_seg7 = 0; // U0.6, BF1 Base PWL Segment 7
if (lls_pref == LLS_PREF_YES) {
+ dscl_prog_data->easf_v_bf2_flat1_gain = 4; // U1.3, BF2 Flat1 Gain control
+ dscl_prog_data->easf_v_bf2_flat2_gain = 8; // U4.0, BF2 Flat2 Gain control
+ dscl_prog_data->easf_v_bf2_roc_gain = 4; // U2.2, Rate Of Change control
+
+ dscl_prog_data->easf_v_bf1_pwl_in_seg0 = 0x600; // S0.10, BF1 PWL Segment 0 = -512
+ dscl_prog_data->easf_v_bf1_pwl_base_seg0 = 0; // U0.6, BF1 Base PWL Segment 0
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg0 = 3; // S7.3, BF1 Slope PWL Segment 0
+ dscl_prog_data->easf_v_bf1_pwl_in_seg1 = 0x7EC; // S0.10, BF1 PWL Segment 1 = -20
+ dscl_prog_data->easf_v_bf1_pwl_base_seg1 = 12; // U0.6, BF1 Base PWL Segment 1
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg1 = 326; // S7.3, BF1 Slope PWL Segment 1
+ dscl_prog_data->easf_v_bf1_pwl_in_seg2 = 0; // S0.10, BF1 PWL Segment 2
+ dscl_prog_data->easf_v_bf1_pwl_base_seg2 = 63; // U0.6, BF1 Base PWL Segment 2
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg2 = 0; // S7.3, BF1 Slope PWL Segment 2
+ dscl_prog_data->easf_v_bf1_pwl_in_seg3 = 16; // S0.10, BF1 PWL Segment 3
+ dscl_prog_data->easf_v_bf1_pwl_base_seg3 = 63; // U0.6, BF1 Base PWL Segment 3
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg3 = 0x7C8; // S7.3, BF1 Slope PWL Segment 3 = -56
+ dscl_prog_data->easf_v_bf1_pwl_in_seg4 = 32; // S0.10, BF1 PWL Segment 4
+ dscl_prog_data->easf_v_bf1_pwl_base_seg4 = 56; // U0.6, BF1 Base PWL Segment 4
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg4 = 0x7D0; // S7.3, BF1 Slope PWL Segment 4 = -48
+ dscl_prog_data->easf_v_bf1_pwl_in_seg5 = 48; // S0.10, BF1 PWL Segment 5
+ dscl_prog_data->easf_v_bf1_pwl_base_seg5 = 50; // U0.6, BF1 Base PWL Segment 5
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg5 = 0x710; // S7.3, BF1 Slope PWL Segment 5 = -240
+ dscl_prog_data->easf_v_bf1_pwl_in_seg6 = 64; // S0.10, BF1 PWL Segment 6
+ dscl_prog_data->easf_v_bf1_pwl_base_seg6 = 20; // U0.6, BF1 Base PWL Segment 6
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg6 = 0x760; // S7.3, BF1 Slope PWL Segment 6 = -160
+ dscl_prog_data->easf_v_bf1_pwl_in_seg7 = 80; // S0.10, BF1 PWL Segment 7
+ dscl_prog_data->easf_v_bf1_pwl_base_seg7 = 0; // U0.6, BF1 Base PWL Segment 7
+
dscl_prog_data->easf_v_bf3_pwl_in_set0 = 0x000; // FP0.6.6, BF3 Input value PWL Segment 0
dscl_prog_data->easf_v_bf3_pwl_base_set0 = 63; // S0.6, BF3 Base PWL Segment 0
dscl_prog_data->easf_v_bf3_pwl_slope_set0 = 0x12C5; // FP1.6.6, BF3 Slope PWL Segment 0
@@ -1088,13 +1296,41 @@ static void spl_set_easf_data(struct dscl_prog_data *dscl_prog_data,
0x136B; // FP1.6.6, BF3 Slope PWL Segment 3
dscl_prog_data->easf_v_bf3_pwl_in_set4 =
0x0C37; // FP0.6.6, BF3 Input value PWL Segment 4 (0.125 * 125^3)
- dscl_prog_data->easf_v_bf3_pwl_base_set4 = -50; // S0.6, BF3 Base PWL Segment 4
+ dscl_prog_data->easf_v_bf3_pwl_base_set4 = 0x4E; // S0.6, BF3 Base PWL Segment 4 = -50
dscl_prog_data->easf_v_bf3_pwl_slope_set4 =
0x1200; // FP1.6.6, BF3 Slope PWL Segment 4
dscl_prog_data->easf_v_bf3_pwl_in_set5 =
0x0CF7; // FP0.6.6, BF3 Input value PWL Segment 5 (1.0 * 125^3)
- dscl_prog_data->easf_v_bf3_pwl_base_set5 = -63; // S0.6, BF3 Base PWL Segment 5
+ dscl_prog_data->easf_v_bf3_pwl_base_set5 = 0x41; // S0.6, BF3 Base PWL Segment 5 = -63
} else {
+ dscl_prog_data->easf_v_bf2_flat1_gain = 13; // U1.3, BF2 Flat1 Gain control
+ dscl_prog_data->easf_v_bf2_flat2_gain = 15; // U4.0, BF2 Flat2 Gain control
+ dscl_prog_data->easf_v_bf2_roc_gain = 14; // U2.2, Rate Of Change control
+
+ dscl_prog_data->easf_v_bf1_pwl_in_seg0 = 0x440; // S0.10, BF1 PWL Segment 0 = -960
+ dscl_prog_data->easf_v_bf1_pwl_base_seg0 = 0; // U0.6, BF1 Base PWL Segment 0
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg0 = 2; // S7.3, BF1 Slope PWL Segment 0
+ dscl_prog_data->easf_v_bf1_pwl_in_seg1 = 0x7C4; // S0.10, BF1 PWL Segment 1 = -60
+ dscl_prog_data->easf_v_bf1_pwl_base_seg1 = 12; // U0.6, BF1 Base PWL Segment 1
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg1 = 109; // S7.3, BF1 Slope PWL Segment 1
+ dscl_prog_data->easf_v_bf1_pwl_in_seg2 = 0; // S0.10, BF1 PWL Segment 2
+ dscl_prog_data->easf_v_bf1_pwl_base_seg2 = 63; // U0.6, BF1 Base PWL Segment 2
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg2 = 0; // S7.3, BF1 Slope PWL Segment 2
+ dscl_prog_data->easf_v_bf1_pwl_in_seg3 = 48; // S0.10, BF1 PWL Segment 3
+ dscl_prog_data->easf_v_bf1_pwl_base_seg3 = 63; // U0.6, BF1 Base PWL Segment 3
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg3 = 0x7ED; // S7.3, BF1 Slope PWL Segment 3 = -19
+ dscl_prog_data->easf_v_bf1_pwl_in_seg4 = 96; // S0.10, BF1 PWL Segment 4
+ dscl_prog_data->easf_v_bf1_pwl_base_seg4 = 56; // U0.6, BF1 Base PWL Segment 4
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg4 = 0x7F0; // S7.3, BF1 Slope PWL Segment 4 = -16
+ dscl_prog_data->easf_v_bf1_pwl_in_seg5 = 144; // S0.10, BF1 PWL Segment 5
+ dscl_prog_data->easf_v_bf1_pwl_base_seg5 = 50; // U0.6, BF1 Base PWL Segment 5
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg5 = 0x7B0; // S7.3, BF1 Slope PWL Segment 5 = -80
+ dscl_prog_data->easf_v_bf1_pwl_in_seg6 = 192; // S0.10, BF1 PWL Segment 6
+ dscl_prog_data->easf_v_bf1_pwl_base_seg6 = 20; // U0.6, BF1 Base PWL Segment 6
+ dscl_prog_data->easf_v_bf1_pwl_slope_seg6 = 0x7CB; // S7.3, BF1 Slope PWL Segment 6 = -53
+ dscl_prog_data->easf_v_bf1_pwl_in_seg7 = 240; // S0.10, BF1 PWL Segment 7
+ dscl_prog_data->easf_v_bf1_pwl_base_seg7 = 0; // U0.6, BF1 Base PWL Segment 7
+
dscl_prog_data->easf_v_bf3_pwl_in_set0 = 0x000; // FP0.6.6, BF3 Input value PWL Segment 0
dscl_prog_data->easf_v_bf3_pwl_base_set0 = 63; // S0.6, BF3 Base PWL Segment 0
dscl_prog_data->easf_v_bf3_pwl_slope_set0 = 0x0000; // FP1.6.6, BF3 Slope PWL Segment 0
@@ -1113,11 +1349,11 @@ static void spl_set_easf_data(struct dscl_prog_data *dscl_prog_data,
0x1878; // FP1.6.6, BF3 Slope PWL Segment 3
dscl_prog_data->easf_v_bf3_pwl_in_set4 =
0x0761; // FP0.6.6, BF3 Input value PWL Segment 4 (0.375)
- dscl_prog_data->easf_v_bf3_pwl_base_set4 = -60; // S0.6, BF3 Base PWL Segment 4
+ dscl_prog_data->easf_v_bf3_pwl_base_set4 = 0x44; // S0.6, BF3 Base PWL Segment 4 = -60
dscl_prog_data->easf_v_bf3_pwl_slope_set4 = 0x1760; // FP1.6.6, BF3 Slope PWL Segment 4
dscl_prog_data->easf_v_bf3_pwl_in_set5 =
0x0780; // FP0.6.6, BF3 Input value PWL Segment 5 (0.5)
- dscl_prog_data->easf_v_bf3_pwl_base_set5 = -63; // S0.6, BF3 Base PWL Segment 5
+ dscl_prog_data->easf_v_bf3_pwl_base_set5 = 0x41; // S0.6, BF3 Base PWL Segment 5 = -63
}
} else
dscl_prog_data->easf_v_en = false;
@@ -1125,52 +1361,63 @@ static void spl_set_easf_data(struct dscl_prog_data *dscl_prog_data,
if (enable_easf_h) {
dscl_prog_data->easf_h_en = true;
dscl_prog_data->easf_h_ring = 0;
- dscl_prog_data->easf_h_sharp_factor = 1;
+ dscl_prog_data->easf_h_sharp_factor = 0;
dscl_prog_data->easf_h_bf1_en =
1; // 1-bit, BF1 calculation enable, 0=disable, 1=enable
dscl_prog_data->easf_h_bf2_mode =
0xF; // 4-bit, BF2 calculation mode
- dscl_prog_data->easf_h_bf3_mode =
- 2; // 2-bit, BF3 chroma mode correction calculation mode
- dscl_prog_data->easf_h_bf2_flat1_gain = 4; // U1.3, BF2 Flat1 Gain control
- dscl_prog_data->easf_h_bf2_flat2_gain = 8; // U4.0, BF2 Flat2 Gain control
- dscl_prog_data->easf_h_bf2_roc_gain = 4; // U2.2, Rate Of Change control
+ /* 2-bit, BF3 chroma mode correction calculation mode */
+ dscl_prog_data->easf_h_bf3_mode = spl_get_h_bf3_mode(
+ spl_scratch->scl_data.recip_ratios.horz);
+ /* FP1.5.10; (2.0) Ring reducer gain for 4 or 6-tap mode [H_REDUCER_GAIN4] */
dscl_prog_data->easf_h_ringest_eventap_reduceg1 =
- 0x4000; // FP1.5.10; (2.0) Ring reducer gain for 4 or 6-tap mode [H_REDUCER_GAIN4]
+ spl_get_reducer_gain4(spl_scratch->scl_data.taps.h_taps,
+ spl_scratch->scl_data.recip_ratios.horz);
+ /* FP1.5.10; (2.5) Ring reducer gain for 6-tap mode [V_REDUCER_GAIN6] */
dscl_prog_data->easf_h_ringest_eventap_reduceg2 =
- 0x4100; // FP1.5.10; (2.5) Ring reducer gain for 6-tap mode [V_REDUCER_GAIN6]
+ spl_get_reducer_gain6(spl_scratch->scl_data.taps.h_taps,
+ spl_scratch->scl_data.recip_ratios.horz);
+ /* FP1.5.10; (-0.135742) Ring gain for 6-tap set to -139/1024 */
dscl_prog_data->easf_h_ringest_eventap_gain1 =
- 0xB058; // FP1.5.10; (-0.135742) Ring gain for 6-tap set to -139/1024
+ spl_get_gainRing4(spl_scratch->scl_data.taps.h_taps,
+ spl_scratch->scl_data.recip_ratios.horz);
+ /* FP1.5.10; (-0.024414) Ring gain for 6-tap set to -25/1024 */
dscl_prog_data->easf_h_ringest_eventap_gain2 =
- 0xA640; // FP1.5.10; (-0.024414) Ring gain for 6-tap set to -25/1024
+ spl_get_gainRing6(spl_scratch->scl_data.taps.h_taps,
+ spl_scratch->scl_data.recip_ratios.horz);
dscl_prog_data->easf_h_bf_maxa = 63; //Horz Max BF value A in U0.6 format.Selected if H_FCNTL==0
dscl_prog_data->easf_h_bf_maxb = 63; //Horz Max BF value B in U0.6 format.Selected if H_FCNTL==1
dscl_prog_data->easf_h_bf_mina = 0; //Horz Min BF value B in U0.6 format.Selected if H_FCNTL==0
dscl_prog_data->easf_h_bf_minb = 0; //Horz Min BF value B in U0.6 format.Selected if H_FCNTL==1
- dscl_prog_data->easf_h_bf1_pwl_in_seg0 = -512; // S0.10, BF1 PWL Segment 0
- dscl_prog_data->easf_h_bf1_pwl_base_seg0 = 0; // U0.6, BF1 Base PWL Segment 0
- dscl_prog_data->easf_h_bf1_pwl_slope_seg0 = 3; // S7.3, BF1 Slope PWL Segment 0
- dscl_prog_data->easf_h_bf1_pwl_in_seg1 = -20; // S0.10, BF1 PWL Segment 1
- dscl_prog_data->easf_h_bf1_pwl_base_seg1 = 12; // U0.6, BF1 Base PWL Segment 1
- dscl_prog_data->easf_h_bf1_pwl_slope_seg1 = 326; // S7.3, BF1 Slope PWL Segment 1
- dscl_prog_data->easf_h_bf1_pwl_in_seg2 = 0; // S0.10, BF1 PWL Segment 2
- dscl_prog_data->easf_h_bf1_pwl_base_seg2 = 63; // U0.6, BF1 Base PWL Segment 2
- dscl_prog_data->easf_h_bf1_pwl_slope_seg2 = 0; // S7.3, BF1 Slope PWL Segment 2
- dscl_prog_data->easf_h_bf1_pwl_in_seg3 = 16; // S0.10, BF1 PWL Segment 3
- dscl_prog_data->easf_h_bf1_pwl_base_seg3 = 63; // U0.6, BF1 Base PWL Segment 3
- dscl_prog_data->easf_h_bf1_pwl_slope_seg3 = -56; // S7.3, BF1 Slope PWL Segment 3
- dscl_prog_data->easf_h_bf1_pwl_in_seg4 = 32; // S0.10, BF1 PWL Segment 4
- dscl_prog_data->easf_h_bf1_pwl_base_seg4 = 56; // U0.6, BF1 Base PWL Segment 4
- dscl_prog_data->easf_h_bf1_pwl_slope_seg4 = -48; // S7.3, BF1 Slope PWL Segment 4
- dscl_prog_data->easf_h_bf1_pwl_in_seg5 = 48; // S0.10, BF1 PWL Segment 5
- dscl_prog_data->easf_h_bf1_pwl_base_seg5 = 50; // U0.6, BF1 Base PWL Segment 5
- dscl_prog_data->easf_h_bf1_pwl_slope_seg5 = -240; // S7.3, BF1 Slope PWL Segment 5
- dscl_prog_data->easf_h_bf1_pwl_in_seg6 = 64; // S0.10, BF1 PWL Segment 6
- dscl_prog_data->easf_h_bf1_pwl_base_seg6 = 20; // U0.6, BF1 Base PWL Segment 6
- dscl_prog_data->easf_h_bf1_pwl_slope_seg6 = -160; // S7.3, BF1 Slope PWL Segment 6
- dscl_prog_data->easf_h_bf1_pwl_in_seg7 = 80; // S0.10, BF1 PWL Segment 7
- dscl_prog_data->easf_h_bf1_pwl_base_seg7 = 0; // U0.6, BF1 Base PWL Segment 7
if (lls_pref == LLS_PREF_YES) {
+ dscl_prog_data->easf_h_bf2_flat1_gain = 4; // U1.3, BF2 Flat1 Gain control
+ dscl_prog_data->easf_h_bf2_flat2_gain = 8; // U4.0, BF2 Flat2 Gain control
+ dscl_prog_data->easf_h_bf2_roc_gain = 4; // U2.2, Rate Of Change control
+
+ dscl_prog_data->easf_h_bf1_pwl_in_seg0 = 0x600; // S0.10, BF1 PWL Segment 0 = -512
+ dscl_prog_data->easf_h_bf1_pwl_base_seg0 = 0; // U0.6, BF1 Base PWL Segment 0
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg0 = 3; // S7.3, BF1 Slope PWL Segment 0
+ dscl_prog_data->easf_h_bf1_pwl_in_seg1 = 0x7EC; // S0.10, BF1 PWL Segment 1 = -20
+ dscl_prog_data->easf_h_bf1_pwl_base_seg1 = 12; // U0.6, BF1 Base PWL Segment 1
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg1 = 326; // S7.3, BF1 Slope PWL Segment 1
+ dscl_prog_data->easf_h_bf1_pwl_in_seg2 = 0; // S0.10, BF1 PWL Segment 2
+ dscl_prog_data->easf_h_bf1_pwl_base_seg2 = 63; // U0.6, BF1 Base PWL Segment 2
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg2 = 0; // S7.3, BF1 Slope PWL Segment 2
+ dscl_prog_data->easf_h_bf1_pwl_in_seg3 = 16; // S0.10, BF1 PWL Segment 3
+ dscl_prog_data->easf_h_bf1_pwl_base_seg3 = 63; // U0.6, BF1 Base PWL Segment 3
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg3 = 0x7C8; // S7.3, BF1 Slope PWL Segment 3 = -56
+ dscl_prog_data->easf_h_bf1_pwl_in_seg4 = 32; // S0.10, BF1 PWL Segment 4
+ dscl_prog_data->easf_h_bf1_pwl_base_seg4 = 56; // U0.6, BF1 Base PWL Segment 4
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg4 = 0x7D0; // S7.3, BF1 Slope PWL Segment 4 = -48
+ dscl_prog_data->easf_h_bf1_pwl_in_seg5 = 48; // S0.10, BF1 PWL Segment 5
+ dscl_prog_data->easf_h_bf1_pwl_base_seg5 = 50; // U0.6, BF1 Base PWL Segment 5
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg5 = 0x710; // S7.3, BF1 Slope PWL Segment 5 = -240
+ dscl_prog_data->easf_h_bf1_pwl_in_seg6 = 64; // S0.10, BF1 PWL Segment 6
+ dscl_prog_data->easf_h_bf1_pwl_base_seg6 = 20; // U0.6, BF1 Base PWL Segment 6
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg6 = 0x760; // S7.3, BF1 Slope PWL Segment 6 = -160
+ dscl_prog_data->easf_h_bf1_pwl_in_seg7 = 80; // S0.10, BF1 PWL Segment 7
+ dscl_prog_data->easf_h_bf1_pwl_base_seg7 = 0; // U0.6, BF1 Base PWL Segment 7
+
dscl_prog_data->easf_h_bf3_pwl_in_set0 = 0x000; // FP0.6.6, BF3 Input value PWL Segment 0
dscl_prog_data->easf_h_bf3_pwl_base_set0 = 63; // S0.6, BF3 Base PWL Segment 0
dscl_prog_data->easf_h_bf3_pwl_slope_set0 = 0x12C5; // FP1.6.6, BF3 Slope PWL Segment 0
@@ -1188,12 +1435,40 @@ static void spl_set_easf_data(struct dscl_prog_data *dscl_prog_data,
dscl_prog_data->easf_h_bf3_pwl_slope_set3 = 0x136B; // FP1.6.6, BF3 Slope PWL Segment 3
dscl_prog_data->easf_h_bf3_pwl_in_set4 =
0x0C37; // FP0.6.6, BF3 Input value PWL Segment 4 (0.125 * 125^3)
- dscl_prog_data->easf_h_bf3_pwl_base_set4 = -50; // S0.6, BF3 Base PWL Segment 4
+ dscl_prog_data->easf_h_bf3_pwl_base_set4 = 0x4E; // S0.6, BF3 Base PWL Segment 4 = -50
dscl_prog_data->easf_h_bf3_pwl_slope_set4 = 0x1200; // FP1.6.6, BF3 Slope PWL Segment 4
dscl_prog_data->easf_h_bf3_pwl_in_set5 =
0x0CF7; // FP0.6.6, BF3 Input value PWL Segment 5 (1.0 * 125^3)
- dscl_prog_data->easf_h_bf3_pwl_base_set5 = -63; // S0.6, BF3 Base PWL Segment 5
+ dscl_prog_data->easf_h_bf3_pwl_base_set5 = 0x41; // S0.6, BF3 Base PWL Segment 5 = -63
} else {
+ dscl_prog_data->easf_h_bf2_flat1_gain = 13; // U1.3, BF2 Flat1 Gain control
+ dscl_prog_data->easf_h_bf2_flat2_gain = 15; // U4.0, BF2 Flat2 Gain control
+ dscl_prog_data->easf_h_bf2_roc_gain = 14; // U2.2, Rate Of Change control
+
+ dscl_prog_data->easf_h_bf1_pwl_in_seg0 = 0x440; // S0.10, BF1 PWL Segment 0 = -960
+ dscl_prog_data->easf_h_bf1_pwl_base_seg0 = 0; // U0.6, BF1 Base PWL Segment 0
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg0 = 2; // S7.3, BF1 Slope PWL Segment 0
+ dscl_prog_data->easf_h_bf1_pwl_in_seg1 = 0x7C4; // S0.10, BF1 PWL Segment 1 = -60
+ dscl_prog_data->easf_h_bf1_pwl_base_seg1 = 12; // U0.6, BF1 Base PWL Segment 1
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg1 = 109; // S7.3, BF1 Slope PWL Segment 1
+ dscl_prog_data->easf_h_bf1_pwl_in_seg2 = 0; // S0.10, BF1 PWL Segment 2
+ dscl_prog_data->easf_h_bf1_pwl_base_seg2 = 63; // U0.6, BF1 Base PWL Segment 2
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg2 = 0; // S7.3, BF1 Slope PWL Segment 2
+ dscl_prog_data->easf_h_bf1_pwl_in_seg3 = 48; // S0.10, BF1 PWL Segment 3
+ dscl_prog_data->easf_h_bf1_pwl_base_seg3 = 63; // U0.6, BF1 Base PWL Segment 3
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg3 = 0x7ED; // S7.3, BF1 Slope PWL Segment 3 = -19
+ dscl_prog_data->easf_h_bf1_pwl_in_seg4 = 96; // S0.10, BF1 PWL Segment 4
+ dscl_prog_data->easf_h_bf1_pwl_base_seg4 = 56; // U0.6, BF1 Base PWL Segment 4
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg4 = 0x7F0; // S7.3, BF1 Slope PWL Segment 4 = -16
+ dscl_prog_data->easf_h_bf1_pwl_in_seg5 = 144; // S0.10, BF1 PWL Segment 5
+ dscl_prog_data->easf_h_bf1_pwl_base_seg5 = 50; // U0.6, BF1 Base PWL Segment 5
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg5 = 0x7B0; // S7.3, BF1 Slope PWL Segment 5 = -80
+ dscl_prog_data->easf_h_bf1_pwl_in_seg6 = 192; // S0.10, BF1 PWL Segment 6
+ dscl_prog_data->easf_h_bf1_pwl_base_seg6 = 20; // U0.6, BF1 Base PWL Segment 6
+ dscl_prog_data->easf_h_bf1_pwl_slope_seg6 = 0x7CB; // S7.3, BF1 Slope PWL Segment 6 = -53
+ dscl_prog_data->easf_h_bf1_pwl_in_seg7 = 240; // S0.10, BF1 PWL Segment 7
+ dscl_prog_data->easf_h_bf1_pwl_base_seg7 = 0; // U0.6, BF1 Base PWL Segment 7
+
dscl_prog_data->easf_h_bf3_pwl_in_set0 = 0x000; // FP0.6.6, BF3 Input value PWL Segment 0
dscl_prog_data->easf_h_bf3_pwl_base_set0 = 63; // S0.6, BF3 Base PWL Segment 0
dscl_prog_data->easf_h_bf3_pwl_slope_set0 = 0x0000; // FP1.6.6, BF3 Slope PWL Segment 0
@@ -1211,25 +1486,30 @@ static void spl_set_easf_data(struct dscl_prog_data *dscl_prog_data,
dscl_prog_data->easf_h_bf3_pwl_slope_set3 = 0x1878; // FP1.6.6, BF3 Slope PWL Segment 3
dscl_prog_data->easf_h_bf3_pwl_in_set4 =
0x0761; // FP0.6.6, BF3 Input value PWL Segment 4 (0.375)
- dscl_prog_data->easf_h_bf3_pwl_base_set4 = -60; // S0.6, BF3 Base PWL Segment 4
+ dscl_prog_data->easf_h_bf3_pwl_base_set4 = 0x44; // S0.6, BF3 Base PWL Segment 4 = -60
dscl_prog_data->easf_h_bf3_pwl_slope_set4 = 0x1760; // FP1.6.6, BF3 Slope PWL Segment 4
dscl_prog_data->easf_h_bf3_pwl_in_set5 =
0x0780; // FP0.6.6, BF3 Input value PWL Segment 5 (0.5)
- dscl_prog_data->easf_h_bf3_pwl_base_set5 = -63; // S0.6, BF3 Base PWL Segment 5
+ dscl_prog_data->easf_h_bf3_pwl_base_set5 = 0x41; // S0.6, BF3 Base PWL Segment 5 = -63
} // if (lls_pref == LLS_PREF_YES)
} else
dscl_prog_data->easf_h_en = false;
if (lls_pref == LLS_PREF_YES) {
dscl_prog_data->easf_ltonl_en = 1; // Linear input
- dscl_prog_data->easf_matrix_c0 =
- 0x504E; // fp1.5.10, C0 coefficient (LN_BT2020: 0.2627 * (2^14)/125 = 34.43750000)
- dscl_prog_data->easf_matrix_c1 =
- 0x558E; // fp1.5.10, C1 coefficient (LN_BT2020: 0.6780 * (2^14)/125 = 88.87500000)
- dscl_prog_data->easf_matrix_c2 =
- 0x47C6; // fp1.5.10, C2 coefficient (LN_BT2020: 0.0593 * (2^14)/125 = 7.77343750)
- dscl_prog_data->easf_matrix_c3 =
- 0x0; // fp1.5.10, C3 coefficient
+ if ((setup == HDR_L) && (spl_is_rgb8(format))) {
+ /* Calculate C0-C3 coefficients based on HDR multiplier */
+ spl_calculate_c0_c3_hdr(dscl_prog_data, hdr_multx100);
+ } else { // HDR_L ( DWM ) and SDR_L
+ dscl_prog_data->easf_matrix_c0 =
+ 0x4EF7; // fp1.5.10, C0 coefficient (LN_rec709: 0.2126 * (2^14)/125 = 27.86590720)
+ dscl_prog_data->easf_matrix_c1 =
+ 0x55DC; // fp1.5.10, C1 coefficient (LN_rec709: 0.7152 * (2^14)/125 = 93.74269440)
+ dscl_prog_data->easf_matrix_c2 =
+ 0x48BB; // fp1.5.10, C2 coefficient (LN_rec709: 0.0722 * (2^14)/125 = 9.46339840)
+ dscl_prog_data->easf_matrix_c3 =
+ 0x0; // fp1.5.10, C3 coefficient
+ }
} else {
dscl_prog_data->easf_ltonl_en = 0; // Non-Linear input
dscl_prog_data->easf_matrix_c0 =
@@ -1241,27 +1521,43 @@ static void spl_set_easf_data(struct dscl_prog_data *dscl_prog_data,
dscl_prog_data->easf_matrix_c3 =
0x0; // fp1.5.10, C3 coefficient
}
+
+ if (spl_is_yuv420(format)) { /* TODO: 0 = RGB, 1 = YUV */
+ dscl_prog_data->easf_matrix_mode = 1;
+ /*
+ * 2-bit, BF3 chroma mode correction calculation mode
+ * Needs to be disabled for YUV420 mode
+ * Override lookup value
+ */
+ dscl_prog_data->easf_v_bf3_mode = 0;
+ dscl_prog_data->easf_h_bf3_mode = 0;
+ } else
+ dscl_prog_data->easf_matrix_mode = 0;
+
}
+
/*Set isharp noise detection */
-static void spl_set_isharp_noise_det_mode(struct dscl_prog_data *dscl_prog_data)
+static void spl_set_isharp_noise_det_mode(struct dscl_prog_data *dscl_prog_data,
+ const struct spl_scaler_data *data)
{
// ISHARP_NOISEDET_MODE
// 0: 3x5 as VxH
// 1: 4x5 as VxH
// 2:
// 3: 5x5 as VxH
- if (dscl_prog_data->taps.v_taps == 6)
- dscl_prog_data->isharp_noise_det.mode = 3; // ISHARP_NOISEDET_MODE
- else if (dscl_prog_data->taps.h_taps == 4)
- dscl_prog_data->isharp_noise_det.mode = 1; // ISHARP_NOISEDET_MODE
- else if (dscl_prog_data->taps.h_taps == 3)
- dscl_prog_data->isharp_noise_det.mode = 0; // ISHARP_NOISEDET_MODE
+ if (data->taps.v_taps == 6)
+ dscl_prog_data->isharp_noise_det.mode = 3;
+ else if (data->taps.v_taps == 4)
+ dscl_prog_data->isharp_noise_det.mode = 1;
+ else if (data->taps.v_taps == 3)
+ dscl_prog_data->isharp_noise_det.mode = 0;
};
/* Set Sharpener data */
static void spl_set_isharp_data(struct dscl_prog_data *dscl_prog_data,
struct adaptive_sharpness adp_sharpness, bool enable_isharp,
enum linear_light_scaling lls_pref, enum spl_pixel_format format,
- const struct spl_scaler_data *data)
+ const struct spl_scaler_data *data, struct spl_fixed31_32 ratio,
+ enum system_setup setup)
{
/* Turn off sharpener if not required */
if (!enable_isharp) {
@@ -1270,10 +1566,12 @@ static void spl_set_isharp_data(struct dscl_prog_data *dscl_prog_data,
}
dscl_prog_data->isharp_en = 1; // ISHARP_EN
- dscl_prog_data->isharp_noise_det.enable = 1; // ISHARP_NOISEDET_EN
// Set ISHARP_NOISEDET_MODE if htaps = 6-tap
- if (dscl_prog_data->taps.h_taps == 6)
- spl_set_isharp_noise_det_mode(dscl_prog_data); // ISHARP_NOISEDET_MODE
+ if (data->taps.h_taps == 6) {
+ dscl_prog_data->isharp_noise_det.enable = 1; /* ISHARP_NOISEDET_EN */
+ spl_set_isharp_noise_det_mode(dscl_prog_data, data); /* ISHARP_NOISEDET_MODE */
+ } else
+ dscl_prog_data->isharp_noise_det.enable = 0; // ISHARP_NOISEDET_EN
// Program noise detection threshold
dscl_prog_data->isharp_noise_det.uthreshold = 24; // ISHARP_NOISEDET_UTHRE
dscl_prog_data->isharp_noise_det.dthreshold = 4; // ISHARP_NOISEDET_DTHRE
@@ -1282,50 +1580,93 @@ static void spl_set_isharp_data(struct dscl_prog_data *dscl_prog_data,
dscl_prog_data->isharp_noise_det.pwl_end_in = 13; // ISHARP_NOISEDET_PWL_END_IN
dscl_prog_data->isharp_noise_det.pwl_slope = 1623; // ISHARP_NOISEDET_PWL_SLOPE
- if ((lls_pref == LLS_PREF_NO) && !spl_is_yuv420(format)) /* ISHARP_FMT_MODE */
+ if (lls_pref == LLS_PREF_NO) /* ISHARP_FMT_MODE */
dscl_prog_data->isharp_fmt.mode = 1;
else
dscl_prog_data->isharp_fmt.mode = 0;
dscl_prog_data->isharp_fmt.norm = 0x3C00; // ISHARP_FMT_NORM
dscl_prog_data->isharp_lba.mode = 0; // ISHARP_LBA_MODE
- // ISHARP_LBA_PWL_SEG0: ISHARP Local Brightness Adjustment PWL Segment 0
- dscl_prog_data->isharp_lba.in_seg[0] = 0; // ISHARP LBA PWL for Seg 0. INPUT value in U0.10 format
- dscl_prog_data->isharp_lba.base_seg[0] = 0; // ISHARP LBA PWL for Seg 0. BASE value in U0.6 format
- dscl_prog_data->isharp_lba.slope_seg[0] = 32; // ISHARP LBA for Seg 0. SLOPE value in S5.3 format
- // ISHARP_LBA_PWL_SEG1: ISHARP LBA PWL Segment 1
- dscl_prog_data->isharp_lba.in_seg[1] = 256; // ISHARP LBA PWL for Seg 1. INPUT value in U0.10 format
- dscl_prog_data->isharp_lba.base_seg[1] = 63; // ISHARP LBA PWL for Seg 1. BASE value in U0.6 format
- dscl_prog_data->isharp_lba.slope_seg[1] = 0; // ISHARP LBA for Seg 1. SLOPE value in S5.3 format
- // ISHARP_LBA_PWL_SEG2: ISHARP LBA PWL Segment 2
- dscl_prog_data->isharp_lba.in_seg[2] = 614; // ISHARP LBA PWL for Seg 2. INPUT value in U0.10 format
- dscl_prog_data->isharp_lba.base_seg[2] = 63; // ISHARP LBA PWL for Seg 2. BASE value in U0.6 format
- dscl_prog_data->isharp_lba.slope_seg[2] = -20; // ISHARP LBA for Seg 2. SLOPE value in S5.3 format
- // ISHARP_LBA_PWL_SEG3: ISHARP LBA PWL Segment 3
- dscl_prog_data->isharp_lba.in_seg[3] = 1023; // ISHARP LBA PWL for Seg 3.INPUT value in U0.10 format
- dscl_prog_data->isharp_lba.base_seg[3] = 0; // ISHARP LBA PWL for Seg 3. BASE value in U0.6 format
- dscl_prog_data->isharp_lba.slope_seg[3] = 0; // ISHARP LBA for Seg 3. SLOPE value in S5.3 format
- // ISHARP_LBA_PWL_SEG4: ISHARP LBA PWL Segment 4
- dscl_prog_data->isharp_lba.in_seg[4] = 1023; // ISHARP LBA PWL for Seg 4.INPUT value in U0.10 format
- dscl_prog_data->isharp_lba.base_seg[4] = 0; // ISHARP LBA PWL for Seg 4. BASE value in U0.6 format
- dscl_prog_data->isharp_lba.slope_seg[4] = 0; // ISHARP LBA for Seg 4. SLOPE value in S5.3 format
- // ISHARP_LBA_PWL_SEG5: ISHARP LBA PWL Segment 5
- dscl_prog_data->isharp_lba.in_seg[5] = 1023; // ISHARP LBA PWL for Seg 5.INPUT value in U0.10 format
- dscl_prog_data->isharp_lba.base_seg[5] = 0; // ISHARP LBA PWL for Seg 5. BASE value in U0.6 format
- switch (adp_sharpness.sharpness) {
- case SHARPNESS_LOW:
- dscl_prog_data->isharp_delta = spl_get_filter_isharp_1D_lut_0p5x();
- break;
- case SHARPNESS_MID:
- dscl_prog_data->isharp_delta = spl_get_filter_isharp_1D_lut_1p0x();
- break;
- case SHARPNESS_HIGH:
- dscl_prog_data->isharp_delta = spl_get_filter_isharp_1D_lut_2p0x();
- break;
- default:
- BREAK_TO_DEBUGGER();
+
+ if (setup == SDR_L) {
+ // ISHARP_LBA_PWL_SEG0: ISHARP Local Brightness Adjustment PWL Segment 0
+ dscl_prog_data->isharp_lba.in_seg[0] = 0; // ISHARP LBA PWL for Seg 0. INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[0] = 0; // ISHARP LBA PWL for Seg 0. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[0] = 62; // ISHARP LBA for Seg 0. SLOPE value in S5.3 format
+ // ISHARP_LBA_PWL_SEG1: ISHARP LBA PWL Segment 1
+ dscl_prog_data->isharp_lba.in_seg[1] = 130; // ISHARP LBA PWL for Seg 1. INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[1] = 63; // ISHARP LBA PWL for Seg 1. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[1] = 0; // ISHARP LBA for Seg 1. SLOPE value in S5.3 format
+ // ISHARP_LBA_PWL_SEG2: ISHARP LBA PWL Segment 2
+ dscl_prog_data->isharp_lba.in_seg[2] = 450; // ISHARP LBA PWL for Seg 2. INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[2] = 63; // ISHARP LBA PWL for Seg 2. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[2] = 0x18D; // ISHARP LBA for Seg 2. SLOPE value in S5.3 format = -115
+ // ISHARP_LBA_PWL_SEG3: ISHARP LBA PWL Segment 3
+ dscl_prog_data->isharp_lba.in_seg[3] = 520; // ISHARP LBA PWL for Seg 3.INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[3] = 0; // ISHARP LBA PWL for Seg 3. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[3] = 0; // ISHARP LBA for Seg 3. SLOPE value in S5.3 format
+ // ISHARP_LBA_PWL_SEG4: ISHARP LBA PWL Segment 4
+ dscl_prog_data->isharp_lba.in_seg[4] = 520; // ISHARP LBA PWL for Seg 4.INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[4] = 0; // ISHARP LBA PWL for Seg 4. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[4] = 0; // ISHARP LBA for Seg 4. SLOPE value in S5.3 format
+ // ISHARP_LBA_PWL_SEG5: ISHARP LBA PWL Segment 5
+ dscl_prog_data->isharp_lba.in_seg[5] = 520; // ISHARP LBA PWL for Seg 5.INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[5] = 0; // ISHARP LBA PWL for Seg 5. BASE value in U0.6 format
+ } else if (setup == HDR_L) {
+ // ISHARP_LBA_PWL_SEG0: ISHARP Local Brightness Adjustment PWL Segment 0
+ dscl_prog_data->isharp_lba.in_seg[0] = 0; // ISHARP LBA PWL for Seg 0. INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[0] = 0; // ISHARP LBA PWL for Seg 0. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[0] = 32; // ISHARP LBA for Seg 0. SLOPE value in S5.3 format
+ // ISHARP_LBA_PWL_SEG1: ISHARP LBA PWL Segment 1
+ dscl_prog_data->isharp_lba.in_seg[1] = 254; // ISHARP LBA PWL for Seg 1. INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[1] = 63; // ISHARP LBA PWL for Seg 1. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[1] = 0; // ISHARP LBA for Seg 1. SLOPE value in S5.3 format
+ // ISHARP_LBA_PWL_SEG2: ISHARP LBA PWL Segment 2
+ dscl_prog_data->isharp_lba.in_seg[2] = 559; // ISHARP LBA PWL for Seg 2. INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[2] = 63; // ISHARP LBA PWL for Seg 2. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[2] = 0x10C; // ISHARP LBA for Seg 2. SLOPE value in S5.3 format = -244
+ // ISHARP_LBA_PWL_SEG3: ISHARP LBA PWL Segment 3
+ dscl_prog_data->isharp_lba.in_seg[3] = 592; // ISHARP LBA PWL for Seg 3.INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[3] = 0; // ISHARP LBA PWL for Seg 3. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[3] = 0; // ISHARP LBA for Seg 3. SLOPE value in S5.3 format
+ // ISHARP_LBA_PWL_SEG4: ISHARP LBA PWL Segment 4
+ dscl_prog_data->isharp_lba.in_seg[4] = 1023; // ISHARP LBA PWL for Seg 4.INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[4] = 0; // ISHARP LBA PWL for Seg 4. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[4] = 0; // ISHARP LBA for Seg 4. SLOPE value in S5.3 format
+ // ISHARP_LBA_PWL_SEG5: ISHARP LBA PWL Segment 5
+ dscl_prog_data->isharp_lba.in_seg[5] = 1023; // ISHARP LBA PWL for Seg 5.INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[5] = 0; // ISHARP LBA PWL for Seg 5. BASE value in U0.6 format
+ } else {
+ // ISHARP_LBA_PWL_SEG0: ISHARP Local Brightness Adjustment PWL Segment 0
+ dscl_prog_data->isharp_lba.in_seg[0] = 0; // ISHARP LBA PWL for Seg 0. INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[0] = 0; // ISHARP LBA PWL for Seg 0. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[0] = 40; // ISHARP LBA for Seg 0. SLOPE value in S5.3 format
+ // ISHARP_LBA_PWL_SEG1: ISHARP LBA PWL Segment 1
+ dscl_prog_data->isharp_lba.in_seg[1] = 204; // ISHARP LBA PWL for Seg 1. INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[1] = 63; // ISHARP LBA PWL for Seg 1. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[1] = 0; // ISHARP LBA for Seg 1. SLOPE value in S5.3 format
+ // ISHARP_LBA_PWL_SEG2: ISHARP LBA PWL Segment 2
+ dscl_prog_data->isharp_lba.in_seg[2] = 818; // ISHARP LBA PWL for Seg 2. INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[2] = 63; // ISHARP LBA PWL for Seg 2. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[2] = 0x1D9; // ISHARP LBA for Seg 2. SLOPE value in S5.3 format = -39
+ // ISHARP_LBA_PWL_SEG3: ISHARP LBA PWL Segment 3
+ dscl_prog_data->isharp_lba.in_seg[3] = 1023; // ISHARP LBA PWL for Seg 3.INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[3] = 0; // ISHARP LBA PWL for Seg 3. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[3] = 0; // ISHARP LBA for Seg 3. SLOPE value in S5.3 format
+ // ISHARP_LBA_PWL_SEG4: ISHARP LBA PWL Segment 4
+ dscl_prog_data->isharp_lba.in_seg[4] = 1023; // ISHARP LBA PWL for Seg 4.INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[4] = 0; // ISHARP LBA PWL for Seg 4. BASE value in U0.6 format
+ dscl_prog_data->isharp_lba.slope_seg[4] = 0; // ISHARP LBA for Seg 4. SLOPE value in S5.3 format
+ // ISHARP_LBA_PWL_SEG5: ISHARP LBA PWL Segment 5
+ dscl_prog_data->isharp_lba.in_seg[5] = 1023; // ISHARP LBA PWL for Seg 5.INPUT value in U0.10 format
+ dscl_prog_data->isharp_lba.base_seg[5] = 0; // ISHARP LBA PWL for Seg 5. BASE value in U0.6 format
}
+
+ spl_build_isharp_1dlut_from_reference_curve(ratio, setup, adp_sharpness);
+ dscl_prog_data->isharp_delta = spl_get_pregen_filter_isharp_1D_lut(setup);
+ dscl_prog_data->sharpness_level = adp_sharpness.sharpness_level;
+
// Program the nldelta soft clip values
if (lls_pref == LLS_PREF_YES) {
dscl_prog_data->isharp_nldelta_sclip.enable_p = 0; /* ISHARP_NLDELTA_SCLIP_EN_P */
@@ -1346,59 +1687,6 @@ static void spl_set_isharp_data(struct dscl_prog_data *dscl_prog_data,
// Set the values as per lookup table
spl_set_blur_scale_data(dscl_prog_data, data);
}
-static bool spl_get_isharp_en(struct adaptive_sharpness adp_sharpness,
- int vscale_ratio, int hscale_ratio, struct spl_taps taps,
- enum spl_pixel_format format)
-{
- bool enable_isharp = false;
-
- if (adp_sharpness.enable == false)
- return enable_isharp; // Return if adaptive sharpness is disabled
- // Is downscaling ?
- if (vscale_ratio > 1 || hscale_ratio > 1) {
- // END - No iSHARP support for downscaling
- return enable_isharp;
- }
- // Scaling is up to 1:1 (no scaling) or upscaling
-
- /* Only apply sharpness to NV12 and not P010 */
- if (format != SPL_PIXEL_FORMAT_420BPP8)
- return enable_isharp;
-
- // LB support horizontal taps 4,6 or vertical taps 3, 4, 6
- if (taps.h_taps == 4 || taps.h_taps == 6 ||
- taps.v_taps == 3 || taps.v_taps == 4 || taps.v_taps == 6) {
- // END - iSHARP supported
- enable_isharp = true;
- }
- return enable_isharp;
-}
-
-static bool spl_choose_lls_policy(enum spl_pixel_format format,
- enum spl_transfer_func_type tf_type,
- enum spl_transfer_func_predefined tf_predefined_type,
- enum linear_light_scaling *lls_pref)
-{
- if (spl_is_yuv420(format)) {
- *lls_pref = LLS_PREF_NO;
- if ((tf_type == SPL_TF_TYPE_PREDEFINED) || (tf_type == SPL_TF_TYPE_DISTRIBUTED_POINTS))
- return true;
- } else { /* RGB or YUV444 */
- if (tf_type == SPL_TF_TYPE_PREDEFINED) {
- if ((tf_predefined_type == SPL_TRANSFER_FUNCTION_HLG) ||
- (tf_predefined_type == SPL_TRANSFER_FUNCTION_HLG12))
- *lls_pref = LLS_PREF_NO;
- else
- *lls_pref = LLS_PREF_YES;
- return true;
- } else if (tf_type == SPL_TF_TYPE_BYPASS) {
- *lls_pref = LLS_PREF_YES;
- return true;
- }
- }
- *lls_pref = LLS_PREF_NO;
- return false;
-}
/* Calculate scaler parameters */
bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out)
@@ -1406,65 +1694,74 @@ bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out)
bool res = false;
bool enable_easf_v = false;
bool enable_easf_h = false;
- bool lls_enable_easf = true;
- const struct spl_scaler_data *data = &spl_out->scl_data;
+ int vratio = 0;
+ int hratio = 0;
+ struct spl_scratch spl_scratch;
+ struct spl_fixed31_32 isharp_scale_ratio;
+ enum system_setup setup;
+ bool enable_isharp = false;
+ const struct spl_scaler_data *data = &spl_scratch.scl_data;
+
+ memset(&spl_scratch, 0, sizeof(struct spl_scratch));
+ spl_scratch.scl_data.h_active = spl_in->h_active;
+ spl_scratch.scl_data.v_active = spl_in->v_active;
+
// All SPL calls
/* recout calculation */
/* depends on h_active */
- spl_calculate_recout(spl_in, spl_out);
+ spl_calculate_recout(spl_in, &spl_scratch, spl_out);
/* depends on pixel format */
- spl_calculate_scaling_ratios(spl_in, spl_out);
+ spl_calculate_scaling_ratios(spl_in, &spl_scratch, spl_out);
/* depends on scaling ratios and recout, does not calculate offset yet */
- spl_calculate_viewport_size(spl_in, spl_out);
+ spl_calculate_viewport_size(spl_in, &spl_scratch);
res = spl_get_optimal_number_of_taps(
spl_in->basic_out.max_downscale_src_width, spl_in,
- spl_out, &spl_in->scaling_quality);
+ &spl_scratch, &spl_in->scaling_quality, &enable_easf_v,
+ &enable_easf_h, &enable_isharp);
/*
* Depends on recout, scaling ratios, h_active and taps
* May need to re-check lb size after this in some obscure scenario
*/
if (res)
- spl_calculate_inits_and_viewports(spl_in, spl_out);
+ spl_calculate_inits_and_viewports(spl_in, &spl_scratch);
// Handle 3d recout
- spl_handle_3d_recout(spl_in, &spl_out->scl_data.recout);
+ spl_handle_3d_recout(spl_in, &spl_scratch.scl_data.recout);
// Clamp
- spl_clamp_viewport(&spl_out->scl_data.viewport);
+ spl_clamp_viewport(&spl_scratch.scl_data.viewport);
if (!res)
return res;
- /*
- * If lls_pref is LLS_PREF_DONT_CARE, then use pixel format and transfer
- * function to determine whether to use LINEAR or NONLINEAR scaling
- */
- if (spl_in->lls_pref == LLS_PREF_DONT_CARE)
- lls_enable_easf = spl_choose_lls_policy(spl_in->basic_in.format,
- spl_in->basic_in.tf_type, spl_in->basic_in.tf_predefined_type,
- &spl_in->lls_pref);
-
// Save all calculated parameters in dscl_prog_data structure to program hw registers
- spl_set_dscl_prog_data(spl_in, spl_out);
+ spl_set_dscl_prog_data(spl_in, &spl_scratch, spl_out, enable_easf_v, enable_easf_h, enable_isharp);
- int vratio = dc_fixpt_ceil(spl_out->scl_data.ratios.vert);
- int hratio = dc_fixpt_ceil(spl_out->scl_data.ratios.horz);
- if (!lls_enable_easf || spl_in->disable_easf) {
- enable_easf_v = false;
- enable_easf_h = false;
+ if (spl_in->lls_pref == LLS_PREF_YES) {
+ if (spl_in->is_hdr_on)
+ setup = HDR_L;
+ else
+ setup = SDR_L;
} else {
- /* Enable EASF on vertical? */
- enable_easf_v = enable_easf(vratio, spl_out->scl_data.taps.v_taps, spl_in->lls_pref, spl_in->prefer_easf);
- /* Enable EASF on horizontal? */
- enable_easf_h = enable_easf(hratio, spl_out->scl_data.taps.h_taps, spl_in->lls_pref, spl_in->prefer_easf);
+ if (spl_in->is_hdr_on)
+ setup = HDR_NL;
+ else
+ setup = SDR_NL;
}
+
// Set EASF
- spl_set_easf_data(spl_out->dscl_prog_data, enable_easf_v, enable_easf_h, spl_in->lls_pref,
- spl_in->basic_in.format);
+ spl_set_easf_data(&spl_scratch, spl_out, enable_easf_v, enable_easf_h, spl_in->lls_pref,
+ spl_in->basic_in.format, setup, spl_in->hdr_multx100);
+
// Set iSHARP
- bool enable_isharp = spl_get_isharp_en(spl_in->adaptive_sharpness, vratio, hratio,
- spl_out->scl_data.taps, spl_in->basic_in.format);
+ vratio = spl_fixpt_ceil(spl_scratch.scl_data.ratios.vert);
+ hratio = spl_fixpt_ceil(spl_scratch.scl_data.ratios.horz);
+ if (vratio <= hratio)
+ isharp_scale_ratio = spl_scratch.scl_data.recip_ratios.vert;
+ else
+ isharp_scale_ratio = spl_scratch.scl_data.recip_ratios.horz;
+
spl_set_isharp_data(spl_out->dscl_prog_data, spl_in->adaptive_sharpness, enable_isharp,
- spl_in->lls_pref, spl_in->basic_in.format, data);
+ spl_in->lls_pref, spl_in->basic_in.format, data, isharp_scale_ratio, setup);
return res;
}
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.h b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.h
index f1fd3eb92f8a..205e59a2a8ee 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.h
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.h
@@ -9,16 +9,8 @@
#define BLACK_OFFSET_RGB_Y 0x0
#define BLACK_OFFSET_CBCR 0x8000
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* SPL interfaces */
bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __DC_SPL_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.c b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.c
new file mode 100644
index 000000000000..99238644e0a1
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: MIT
+//
+// Copyright 2024 Advanced Micro Devices, Inc.
+
+#include "dc_spl_filters.h"
+
+void convert_filter_s1_10_to_s1_12(const uint16_t *s1_10_filter,
+ uint16_t *s1_12_filter, int num_taps)
+{
+ int num_entries = NUM_PHASES_COEFF * num_taps;
+ int i;
+
+ for (i = 0; i < num_entries; i++)
+ *(s1_12_filter + i) = *(s1_10_filter + i) * 4;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.h b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.h
new file mode 100644
index 000000000000..20439cdbdb10
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: MIT */
+
+/* Copyright 2024 Advanced Micro Devices, Inc. */
+
+#ifndef __DC_SPL_FILTERS_H__
+#define __DC_SPL_FILTERS_H__
+
+#include "dc_spl_types.h"
+
+#define NUM_PHASES_COEFF 33
+
+void convert_filter_s1_10_to_s1_12(const uint16_t *s1_10_filter,
+ uint16_t *s1_12_filter, int num_taps);
+
+#endif /* __DC_SPL_FILTERS_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.c b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.c
index 8bc838c7c3c5..33712f50d303 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.c
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.c
@@ -2,7 +2,8 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-#include "dc_spl_types.h"
+#include "spl_debug.h"
+#include "dc_spl_filters.h"
#include "dc_spl_isharp_filters.h"
//========================================
@@ -16,7 +17,7 @@
// C_start = 40.000000
// C_end = 64.000000
//========================================
-static const uint32_t filter_isharp_1D_lut_0[32] = {
+static const uint32_t filter_isharp_1D_lut_0[ISHARP_LUT_TABLE_SIZE] = {
0x02010000,
0x0A070503,
0x1614100D,
@@ -62,7 +63,7 @@ static const uint32_t filter_isharp_1D_lut_0[32] = {
// C_end = 127.000000
//========================================
-static const uint32_t filter_isharp_1D_lut_0p5x[32] = {
+static const uint32_t filter_isharp_1D_lut_0p5x[ISHARP_LUT_TABLE_SIZE] = {
0x00000000,
0x02020101,
0x06050403,
@@ -107,7 +108,7 @@ static const uint32_t filter_isharp_1D_lut_0p5x[32] = {
// C_start = 96.000000
// C_end = 127.000000
//========================================
-static const uint32_t filter_isharp_1D_lut_1p0x[32] = {
+static const uint32_t filter_isharp_1D_lut_1p0x[ISHARP_LUT_TABLE_SIZE] = {
0x01000000,
0x05040302,
0x0B0A0806,
@@ -152,7 +153,7 @@ static const uint32_t filter_isharp_1D_lut_1p0x[32] = {
// C_start = 96.000000
// C_end = 127.000000
//========================================
-static const uint32_t filter_isharp_1D_lut_1p5x[32] = {
+static const uint32_t filter_isharp_1D_lut_1p5x[ISHARP_LUT_TABLE_SIZE] = {
0x01010000,
0x07050402,
0x110F0C0A,
@@ -197,7 +198,7 @@ static const uint32_t filter_isharp_1D_lut_1p5x[32] = {
// C_start = 40.000000
// C_end = 127.000000
//========================================
-static const uint32_t filter_isharp_1D_lut_2p0x[32] = {
+static const uint32_t filter_isharp_1D_lut_2p0x[ISHARP_LUT_TABLE_SIZE] = {
0x02010000,
0x0A070503,
0x1614100D,
@@ -231,6 +232,53 @@ static const uint32_t filter_isharp_1D_lut_2p0x[32] = {
0x080B0D0E,
0x00020406,
};
+//========================================
+// Delta Gain 1DLUT
+// LUT content is packed as 4-bytes into one DWORD/entry
+// A_start = 0.000000
+// A_end = 10.000000
+// A_gain = 3.000000
+// B_start = 11.000000
+// B_end = 127.000000
+// C_start = 40.000000
+// C_end = 127.000000
+//========================================
+static const uint32_t filter_isharp_1D_lut_3p0x[ISHARP_LUT_TABLE_SIZE] = {
+0x03010000,
+0x0F0B0805,
+0x211E1813,
+0x2B292624,
+0x3533302E,
+0x3E3C3A37,
+0x46444240,
+0x4D4B4A48,
+0x5352504F,
+0x59575655,
+0x5D5C5B5A,
+0x61605F5E,
+0x64646362,
+0x66666565,
+0x68686767,
+0x68686868,
+0x68686868,
+0x67676868,
+0x65656666,
+0x62636464,
+0x5E5F6061,
+0x5A5B5C5D,
+0x55565759,
+0x4F505253,
+0x484A4B4D,
+0x40424446,
+0x373A3C3E,
+0x2E303335,
+0x2426292B,
+0x191B1E21,
+0x0D101316,
+0x0003060A,
+};
+
+//========================================
// Wide scaler coefficients
//========================================================
// <using> gen_scaler_coeffs.m
@@ -285,7 +333,7 @@ static const uint16_t filter_isharp_wide_6tap_64p[198] = {
// <CoefType> Blur & Scale LPF
// <CoefQuant> S1.10
//========================================================
-static const uint16_t filter_isharp_bs_4tap_64p[198] = {
+static const uint16_t filter_isharp_bs_4tap_in_6_64p[198] = {
0x0000, 0x00E5, 0x0237, 0x00E4, 0x0000, 0x0000,
0x0000, 0x00DE, 0x0237, 0x00EB, 0x0000, 0x0000,
0x0000, 0x00D7, 0x0236, 0x00F2, 0x0001, 0x0000,
@@ -320,6 +368,138 @@ static const uint16_t filter_isharp_bs_4tap_64p[198] = {
0x0000, 0x003B, 0x01CF, 0x01C2, 0x0034, 0x0000,
0x0000, 0x0037, 0x01C9, 0x01C9, 0x0037, 0x0000
};
+//========================================================
+// <using> gen_BlurScale_coeffs.m
+// <date> 25-Apr-2022
+// <num_taps> 4
+// <num_phases> 64
+// <CoefType> Blur & Scale LPF
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t filter_isharp_bs_4tap_64p[132] = {
+0x00E5, 0x0237, 0x00E4, 0x0000,
+0x00DE, 0x0237, 0x00EB, 0x0000,
+0x00D7, 0x0236, 0x00F2, 0x0001,
+0x00D0, 0x0235, 0x00FA, 0x0001,
+0x00C9, 0x0234, 0x0101, 0x0002,
+0x00C2, 0x0233, 0x0108, 0x0003,
+0x00BB, 0x0232, 0x0110, 0x0003,
+0x00B5, 0x0230, 0x0117, 0x0004,
+0x00AE, 0x022E, 0x011F, 0x0005,
+0x00A8, 0x022C, 0x0126, 0x0006,
+0x00A2, 0x022A, 0x012D, 0x0007,
+0x009C, 0x0228, 0x0134, 0x0008,
+0x0096, 0x0225, 0x013C, 0x0009,
+0x0090, 0x0222, 0x0143, 0x000B,
+0x008A, 0x021F, 0x014B, 0x000C,
+0x0085, 0x021C, 0x0151, 0x000E,
+0x007F, 0x0218, 0x015A, 0x000F,
+0x007A, 0x0215, 0x0160, 0x0011,
+0x0074, 0x0211, 0x0168, 0x0013,
+0x006F, 0x020D, 0x016F, 0x0015,
+0x006A, 0x0209, 0x0176, 0x0017,
+0x0065, 0x0204, 0x017E, 0x0019,
+0x0060, 0x0200, 0x0185, 0x001B,
+0x005C, 0x01FB, 0x018C, 0x001D,
+0x0057, 0x01F6, 0x0193, 0x0020,
+0x0053, 0x01F1, 0x019A, 0x0022,
+0x004E, 0x01EC, 0x01A1, 0x0025,
+0x004A, 0x01E6, 0x01A8, 0x0028,
+0x0046, 0x01E1, 0x01AF, 0x002A,
+0x0042, 0x01DB, 0x01B6, 0x002D,
+0x003F, 0x01D5, 0x01BB, 0x0031,
+0x003B, 0x01CF, 0x01C2, 0x0034,
+0x0037, 0x01C9, 0x01C9, 0x0037,
+};
+//========================================================
+// <using> gen_BlurScale_coeffs.m
+// <date> 09-Jun-2022
+// <num_taps> 3
+// <num_phases> 64
+// <CoefType> Blur & Scale LPF
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t filter_isharp_bs_3tap_64p[99] = {
+0x0200, 0x0200, 0x0000,
+0x01F6, 0x0206, 0x0004,
+0x01EC, 0x020B, 0x0009,
+0x01E2, 0x0211, 0x000D,
+0x01D8, 0x0216, 0x0012,
+0x01CE, 0x021C, 0x0016,
+0x01C4, 0x0221, 0x001B,
+0x01BA, 0x0226, 0x0020,
+0x01B0, 0x022A, 0x0026,
+0x01A6, 0x022F, 0x002B,
+0x019C, 0x0233, 0x0031,
+0x0192, 0x0238, 0x0036,
+0x0188, 0x023C, 0x003C,
+0x017E, 0x0240, 0x0042,
+0x0174, 0x0244, 0x0048,
+0x016A, 0x0248, 0x004E,
+0x0161, 0x024A, 0x0055,
+0x0157, 0x024E, 0x005B,
+0x014D, 0x0251, 0x0062,
+0x0144, 0x0253, 0x0069,
+0x013A, 0x0256, 0x0070,
+0x0131, 0x0258, 0x0077,
+0x0127, 0x025B, 0x007E,
+0x011E, 0x025C, 0x0086,
+0x0115, 0x025E, 0x008D,
+0x010B, 0x0260, 0x0095,
+0x0102, 0x0262, 0x009C,
+0x00F9, 0x0263, 0x00A4,
+0x00F0, 0x0264, 0x00AC,
+0x00E7, 0x0265, 0x00B4,
+0x00DF, 0x0264, 0x00BD,
+0x00D6, 0x0265, 0x00C5,
+0x00CD, 0x0266, 0x00CD,
+};
+
+/* Converted Blur & Scale coeff tables from S1.10 to S1.12 */
+static uint16_t filter_isharp_bs_4tap_in_6_64p_s1_12[198];
+static uint16_t filter_isharp_bs_4tap_64p_s1_12[132];
+static uint16_t filter_isharp_bs_3tap_64p_s1_12[99];
+
+/* Pre-generated 1DLUT for given setup and sharpness level */
+struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] = {
+ {
+ 0, 0,
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ }
+ },
+ {
+ 0, 0,
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ }
+ },
+ {
+ 0, 0,
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ }
+ },
+ {
+ 0, 0,
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ }
+ },
+};
+
const uint32_t *spl_get_filter_isharp_1D_lut_0(void)
{
return filter_isharp_1D_lut_0;
@@ -340,11 +520,165 @@ const uint32_t *spl_get_filter_isharp_1D_lut_2p0x(void)
{
return filter_isharp_1D_lut_2p0x;
}
+const uint32_t *spl_get_filter_isharp_1D_lut_3p0x(void)
+{
+ return filter_isharp_1D_lut_3p0x;
+}
const uint16_t *spl_get_filter_isharp_wide_6tap_64p(void)
{
return filter_isharp_wide_6tap_64p;
}
-const uint16_t *spl_get_filter_isharp_bs_4tap_64p(void)
+uint16_t *spl_get_filter_isharp_bs_4tap_in_6_64p(void)
{
- return filter_isharp_bs_4tap_64p;
+ return filter_isharp_bs_4tap_in_6_64p_s1_12;
}
+uint16_t *spl_get_filter_isharp_bs_4tap_64p(void)
+{
+ return filter_isharp_bs_4tap_64p_s1_12;
+}
+uint16_t *spl_get_filter_isharp_bs_3tap_64p(void)
+{
+ return filter_isharp_bs_3tap_64p_s1_12;
+}
+
+static unsigned int spl_calculate_sharpness_level(int discrete_sharpness_level, enum system_setup setup,
+ struct spl_sharpness_range sharpness_range)
+{
+ unsigned int sharpness_level = 0;
+
+ int min_sharpness, max_sharpness, mid_sharpness;
+
+ switch (setup) {
+
+ case HDR_L:
+ min_sharpness = sharpness_range.hdr_rgb_min;
+ max_sharpness = sharpness_range.hdr_rgb_max;
+ mid_sharpness = sharpness_range.hdr_rgb_mid;
+ break;
+ case HDR_NL:
+ /* currently no use case, use Non-linear SDR values for now */
+ case SDR_NL:
+ min_sharpness = sharpness_range.sdr_yuv_min;
+ max_sharpness = sharpness_range.sdr_yuv_max;
+ mid_sharpness = sharpness_range.sdr_yuv_mid;
+ break;
+ case SDR_L:
+ default:
+ min_sharpness = sharpness_range.sdr_rgb_min;
+ max_sharpness = sharpness_range.sdr_rgb_max;
+ mid_sharpness = sharpness_range.sdr_rgb_mid;
+ break;
+ }
+
+ int lower_half_step_size = (mid_sharpness - min_sharpness) / 5;
+ int upper_half_step_size = (max_sharpness - mid_sharpness) / 5;
+
+ // lower half linear approximation
+ if (discrete_sharpness_level < 5)
+ sharpness_level = min_sharpness + (lower_half_step_size * discrete_sharpness_level);
+ // upper half linear approximation
+ else
+ sharpness_level = mid_sharpness + (upper_half_step_size * (discrete_sharpness_level - 5));
+
+ return sharpness_level;
+}
+
+void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup,
+ struct adaptive_sharpness sharpness)
+{
+ uint8_t *byte_ptr_1dlut_src, *byte_ptr_1dlut_dst;
+ struct spl_fixed31_32 sharp_base, sharp_calc, sharp_level;
+ int j;
+ int size_1dlut;
+ int sharp_calc_int;
+ uint32_t filter_pregen_store[ISHARP_LUT_TABLE_SIZE];
+
+ /* Custom sharpnessX1000 value */
+ unsigned int sharpnessX1000 = spl_calculate_sharpness_level(sharpness.sharpness_level,
+ setup, sharpness.sharpness_range);
+ sharp_level = spl_fixpt_from_fraction(sharpnessX1000, 1000);
+
+ /*
+ * Check if pregen 1dlut table is already precalculated
+ * If numer/denom is different, then recalculate
+ */
+ if ((filter_isharp_1D_lut_pregen[setup].sharpness_numer == sharpnessX1000) &&
+ (filter_isharp_1D_lut_pregen[setup].sharpness_denom == 1000))
+ return;
+
+
+ /*
+ * Calculate LUT_128_gained with this equation:
+ *
+ * LUT_128_gained[i] = (uint8)(0.5 + min(255,(double)(LUT_128[i])*sharpLevel/iGain))
+ * where LUT_128[i] is contents of 3p0x isharp 1dlut
+ * where sharpLevel is desired sharpness level
+ * where iGain is base sharpness level 3.0
+ * where LUT_128_gained[i] is adjusted 1dlut value based on desired sharpness level
+ */
+ byte_ptr_1dlut_src = (uint8_t *)filter_isharp_1D_lut_3p0x;
+ byte_ptr_1dlut_dst = (uint8_t *)filter_pregen_store;
+ size_1dlut = sizeof(filter_isharp_1D_lut_3p0x);
+ memset(byte_ptr_1dlut_dst, 0, size_1dlut);
+ for (j = 0; j < size_1dlut; j++) {
+ sharp_base = spl_fixpt_from_int((int)*byte_ptr_1dlut_src);
+ sharp_calc = spl_fixpt_mul(sharp_base, sharp_level);
+ sharp_calc = spl_fixpt_div(sharp_calc, spl_fixpt_from_int(3));
+ sharp_calc = spl_fixpt_min(spl_fixpt_from_int(255), sharp_calc);
+ sharp_calc = spl_fixpt_add(sharp_calc, spl_fixpt_from_fraction(1, 2));
+ sharp_calc_int = spl_fixpt_floor(sharp_calc);
+ /* Clamp it at 0x7F so it doesn't wrap */
+ if (sharp_calc_int > 127)
+ sharp_calc_int = 127;
+ *byte_ptr_1dlut_dst = (uint8_t)sharp_calc_int;
+
+ byte_ptr_1dlut_src++;
+ byte_ptr_1dlut_dst++;
+ }
+
+ /* Update 1dlut table and sharpness level */
+ memcpy((void *)filter_isharp_1D_lut_pregen[setup].value, (void *)filter_pregen_store, size_1dlut);
+ filter_isharp_1D_lut_pregen[setup].sharpness_numer = sharpnessX1000;
+ filter_isharp_1D_lut_pregen[setup].sharpness_denom = 1000;
+}
+
+uint32_t *spl_get_pregen_filter_isharp_1D_lut(enum system_setup setup)
+{
+ return filter_isharp_1D_lut_pregen[setup].value;
+}
+
+void spl_init_blur_scale_coeffs(void)
+{
+ convert_filter_s1_10_to_s1_12(filter_isharp_bs_3tap_64p,
+ filter_isharp_bs_3tap_64p_s1_12, 3);
+ convert_filter_s1_10_to_s1_12(filter_isharp_bs_4tap_64p,
+ filter_isharp_bs_4tap_64p_s1_12, 4);
+ convert_filter_s1_10_to_s1_12(filter_isharp_bs_4tap_in_6_64p,
+ filter_isharp_bs_4tap_in_6_64p_s1_12, 6);
+}
+
+uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps)
+{
+ if (taps == 3)
+ return spl_get_filter_isharp_bs_3tap_64p();
+ else if (taps == 4)
+ return spl_get_filter_isharp_bs_4tap_64p();
+ else if (taps == 6)
+ return spl_get_filter_isharp_bs_4tap_in_6_64p();
+ else {
+ /* should never happen, bug */
+ SPL_BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+}
+
+void spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data,
+ const struct spl_scaler_data *data)
+{
+ dscl_prog_data->filter_blur_scale_h =
+ spl_dscl_get_blur_scale_coeffs_64p(data->taps.h_taps);
+
+ dscl_prog_data->filter_blur_scale_v =
+ spl_dscl_get_blur_scale_coeffs_64p(data->taps.v_taps);
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.h b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.h
index 1aaf4c50c1bc..fe0b12571f2c 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.h
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.h
@@ -7,11 +7,44 @@
#include "dc_spl_types.h"
+#define ISHARP_LUT_TABLE_SIZE 32
const uint32_t *spl_get_filter_isharp_1D_lut_0(void);
const uint32_t *spl_get_filter_isharp_1D_lut_0p5x(void);
const uint32_t *spl_get_filter_isharp_1D_lut_1p0x(void);
const uint32_t *spl_get_filter_isharp_1D_lut_1p5x(void);
const uint32_t *spl_get_filter_isharp_1D_lut_2p0x(void);
-const uint16_t *spl_get_filter_isharp_bs_4tap_64p(void);
+const uint32_t *spl_get_filter_isharp_1D_lut_3p0x(void);
+uint16_t *spl_get_filter_isharp_bs_4tap_in_6_64p(void);
+uint16_t *spl_get_filter_isharp_bs_4tap_64p(void);
+uint16_t *spl_get_filter_isharp_bs_3tap_64p(void);
const uint16_t *spl_get_filter_isharp_wide_6tap_64p(void);
+uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps);
+
+struct scale_ratio_to_sharpness_level_lookup {
+ unsigned int ratio_numer;
+ unsigned int ratio_denom;
+ unsigned int sharpness_numer;
+ unsigned int sharpness_denom;
+};
+
+struct isharp_1D_lut_pregen {
+ unsigned int sharpness_numer;
+ unsigned int sharpness_denom;
+ uint32_t value[ISHARP_LUT_TABLE_SIZE];
+};
+
+enum system_setup {
+ SDR_NL = 0,
+ SDR_L,
+ HDR_NL,
+ HDR_L,
+ NUM_SHARPNESS_SETUPS
+};
+
+void spl_init_blur_scale_coeffs(void);
+void spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data,
+ const struct spl_scaler_data *data);
+
+void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup, struct adaptive_sharpness sharpness);
+uint32_t *spl_get_pregen_filter_isharp_1D_lut(enum system_setup setup);
#endif /* __DC_SPL_ISHARP_FILTERS_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.c b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.c
new file mode 100644
index 000000000000..09bf82f7d468
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.c
@@ -0,0 +1,1726 @@
+// SPDX-License-Identifier: MIT
+//
+// Copyright 2024 Advanced Micro Devices, Inc.
+
+#include "spl_debug.h"
+#include "dc_spl_filters.h"
+#include "dc_spl_scl_filters.h"
+#include "dc_spl_scl_easf_filters.h"
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 3t_64p_LanczosEd_p_0.3_p_10qb_
+// <num_taps> 3
+// <num_phases> 64
+// <scale_ratio> input/output = 0.300000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_3tap_64p_ratio_0_30[99] = {
+ 0x0200, 0x0200, 0x0000,
+ 0x01F6, 0x0206, 0x0004,
+ 0x01EC, 0x020B, 0x0009,
+ 0x01E2, 0x0211, 0x000D,
+ 0x01D8, 0x0216, 0x0012,
+ 0x01CE, 0x021C, 0x0016,
+ 0x01C4, 0x0221, 0x001B,
+ 0x01BA, 0x0226, 0x0020,
+ 0x01B0, 0x022A, 0x0026,
+ 0x01A6, 0x022F, 0x002B,
+ 0x019C, 0x0233, 0x0031,
+ 0x0192, 0x0238, 0x0036,
+ 0x0188, 0x023C, 0x003C,
+ 0x017E, 0x0240, 0x0042,
+ 0x0174, 0x0244, 0x0048,
+ 0x016A, 0x0248, 0x004E,
+ 0x0161, 0x024A, 0x0055,
+ 0x0157, 0x024E, 0x005B,
+ 0x014D, 0x0251, 0x0062,
+ 0x0144, 0x0253, 0x0069,
+ 0x013A, 0x0256, 0x0070,
+ 0x0131, 0x0258, 0x0077,
+ 0x0127, 0x025B, 0x007E,
+ 0x011E, 0x025C, 0x0086,
+ 0x0115, 0x025E, 0x008D,
+ 0x010B, 0x0260, 0x0095,
+ 0x0102, 0x0262, 0x009C,
+ 0x00F9, 0x0263, 0x00A4,
+ 0x00F0, 0x0264, 0x00AC,
+ 0x00E7, 0x0265, 0x00B4,
+ 0x00DF, 0x0264, 0x00BD,
+ 0x00D6, 0x0265, 0x00C5,
+ 0x00CD, 0x0266, 0x00CD,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 3t_64p_LanczosEd_p_0.4_p_10qb_
+// <num_taps> 3
+// <num_phases> 64
+// <scale_ratio> input/output = 0.400000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_3tap_64p_ratio_0_40[99] = {
+ 0x0200, 0x0200, 0x0000,
+ 0x01F6, 0x0206, 0x0004,
+ 0x01EB, 0x020E, 0x0007,
+ 0x01E1, 0x0214, 0x000B,
+ 0x01D7, 0x021A, 0x000F,
+ 0x01CD, 0x0220, 0x0013,
+ 0x01C2, 0x0226, 0x0018,
+ 0x01B8, 0x022C, 0x001C,
+ 0x01AE, 0x0231, 0x0021,
+ 0x01A3, 0x0237, 0x0026,
+ 0x0199, 0x023C, 0x002B,
+ 0x018F, 0x0240, 0x0031,
+ 0x0185, 0x0245, 0x0036,
+ 0x017A, 0x024A, 0x003C,
+ 0x0170, 0x024F, 0x0041,
+ 0x0166, 0x0253, 0x0047,
+ 0x015C, 0x0257, 0x004D,
+ 0x0152, 0x025A, 0x0054,
+ 0x0148, 0x025E, 0x005A,
+ 0x013E, 0x0261, 0x0061,
+ 0x0134, 0x0264, 0x0068,
+ 0x012B, 0x0266, 0x006F,
+ 0x0121, 0x0269, 0x0076,
+ 0x0117, 0x026C, 0x007D,
+ 0x010E, 0x026E, 0x0084,
+ 0x0104, 0x0270, 0x008C,
+ 0x00FB, 0x0271, 0x0094,
+ 0x00F2, 0x0272, 0x009C,
+ 0x00E9, 0x0273, 0x00A4,
+ 0x00E0, 0x0274, 0x00AC,
+ 0x00D7, 0x0275, 0x00B4,
+ 0x00CE, 0x0275, 0x00BD,
+ 0x00C5, 0x0276, 0x00C5,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 3t_64p_LanczosEd_p_0.5_p_10qb_
+// <num_taps> 3
+// <num_phases> 64
+// <scale_ratio> input/output = 0.500000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_3tap_64p_ratio_0_50[99] = {
+ 0x0200, 0x0200, 0x0000,
+ 0x01F5, 0x0209, 0x0002,
+ 0x01EA, 0x0211, 0x0005,
+ 0x01DF, 0x021A, 0x0007,
+ 0x01D4, 0x0222, 0x000A,
+ 0x01C9, 0x022A, 0x000D,
+ 0x01BE, 0x0232, 0x0010,
+ 0x01B3, 0x0239, 0x0014,
+ 0x01A8, 0x0241, 0x0017,
+ 0x019D, 0x0248, 0x001B,
+ 0x0192, 0x024F, 0x001F,
+ 0x0187, 0x0255, 0x0024,
+ 0x017C, 0x025C, 0x0028,
+ 0x0171, 0x0262, 0x002D,
+ 0x0166, 0x0268, 0x0032,
+ 0x015B, 0x026E, 0x0037,
+ 0x0150, 0x0273, 0x003D,
+ 0x0146, 0x0278, 0x0042,
+ 0x013B, 0x027D, 0x0048,
+ 0x0130, 0x0282, 0x004E,
+ 0x0126, 0x0286, 0x0054,
+ 0x011B, 0x028A, 0x005B,
+ 0x0111, 0x028D, 0x0062,
+ 0x0107, 0x0290, 0x0069,
+ 0x00FD, 0x0293, 0x0070,
+ 0x00F3, 0x0296, 0x0077,
+ 0x00E9, 0x0298, 0x007F,
+ 0x00DF, 0x029A, 0x0087,
+ 0x00D5, 0x029C, 0x008F,
+ 0x00CC, 0x029D, 0x0097,
+ 0x00C3, 0x029E, 0x009F,
+ 0x00BA, 0x029E, 0x00A8,
+ 0x00B1, 0x029E, 0x00B1,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 3t_64p_LanczosEd_p_0.6_p_10qb_
+// <num_taps> 3
+// <num_phases> 64
+// <scale_ratio> input/output = 0.600000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_3tap_64p_ratio_0_60[99] = {
+ 0x0200, 0x0200, 0x0000,
+ 0x01F4, 0x020B, 0x0001,
+ 0x01E8, 0x0216, 0x0002,
+ 0x01DC, 0x0221, 0x0003,
+ 0x01D0, 0x022B, 0x0005,
+ 0x01C4, 0x0235, 0x0007,
+ 0x01B8, 0x0240, 0x0008,
+ 0x01AC, 0x0249, 0x000B,
+ 0x01A0, 0x0253, 0x000D,
+ 0x0194, 0x025C, 0x0010,
+ 0x0188, 0x0265, 0x0013,
+ 0x017C, 0x026E, 0x0016,
+ 0x0170, 0x0277, 0x0019,
+ 0x0164, 0x027F, 0x001D,
+ 0x0158, 0x0287, 0x0021,
+ 0x014C, 0x028F, 0x0025,
+ 0x0140, 0x0297, 0x0029,
+ 0x0135, 0x029D, 0x002E,
+ 0x0129, 0x02A4, 0x0033,
+ 0x011D, 0x02AB, 0x0038,
+ 0x0112, 0x02B0, 0x003E,
+ 0x0107, 0x02B5, 0x0044,
+ 0x00FC, 0x02BA, 0x004A,
+ 0x00F1, 0x02BF, 0x0050,
+ 0x00E6, 0x02C3, 0x0057,
+ 0x00DB, 0x02C7, 0x005E,
+ 0x00D1, 0x02CA, 0x0065,
+ 0x00C7, 0x02CC, 0x006D,
+ 0x00BD, 0x02CE, 0x0075,
+ 0x00B3, 0x02D0, 0x007D,
+ 0x00A9, 0x02D2, 0x0085,
+ 0x00A0, 0x02D2, 0x008E,
+ 0x0097, 0x02D2, 0x0097,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 3t_64p_LanczosEd_p_0.7_p_10qb_
+// <num_taps> 3
+// <num_phases> 64
+// <scale_ratio> input/output = 0.700000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_3tap_64p_ratio_0_70[99] = {
+ 0x0200, 0x0200, 0x0000,
+ 0x01F3, 0x020D, 0x0000,
+ 0x01E5, 0x021B, 0x0000,
+ 0x01D8, 0x0228, 0x0000,
+ 0x01CB, 0x0235, 0x0000,
+ 0x01BD, 0x0243, 0x0000,
+ 0x01B0, 0x024F, 0x0001,
+ 0x01A2, 0x025C, 0x0002,
+ 0x0195, 0x0268, 0x0003,
+ 0x0187, 0x0275, 0x0004,
+ 0x017A, 0x0280, 0x0006,
+ 0x016D, 0x028C, 0x0007,
+ 0x015F, 0x0298, 0x0009,
+ 0x0152, 0x02A2, 0x000C,
+ 0x0145, 0x02AD, 0x000E,
+ 0x0138, 0x02B7, 0x0011,
+ 0x012B, 0x02C0, 0x0015,
+ 0x011E, 0x02CA, 0x0018,
+ 0x0111, 0x02D3, 0x001C,
+ 0x0105, 0x02DB, 0x0020,
+ 0x00F8, 0x02E3, 0x0025,
+ 0x00EC, 0x02EA, 0x002A,
+ 0x00E0, 0x02F1, 0x002F,
+ 0x00D5, 0x02F6, 0x0035,
+ 0x00C9, 0x02FC, 0x003B,
+ 0x00BE, 0x0301, 0x0041,
+ 0x00B3, 0x0305, 0x0048,
+ 0x00A8, 0x0309, 0x004F,
+ 0x009E, 0x030C, 0x0056,
+ 0x0094, 0x030E, 0x005E,
+ 0x008A, 0x0310, 0x0066,
+ 0x0081, 0x0310, 0x006F,
+ 0x0077, 0x0312, 0x0077,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 3t_64p_LanczosEd_p_0.8_p_10qb_
+// <num_taps> 3
+// <num_phases> 64
+// <scale_ratio> input/output = 0.800000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_3tap_64p_ratio_0_80[99] = {
+ 0x0200, 0x0200, 0x0000,
+ 0x01F1, 0x0210, 0x0FFF,
+ 0x01E2, 0x0220, 0x0FFE,
+ 0x01D2, 0x0232, 0x0FFC,
+ 0x01C3, 0x0241, 0x0FFC,
+ 0x01B4, 0x0251, 0x0FFB,
+ 0x01A4, 0x0262, 0x0FFA,
+ 0x0195, 0x0271, 0x0FFA,
+ 0x0186, 0x0281, 0x0FF9,
+ 0x0176, 0x0291, 0x0FF9,
+ 0x0167, 0x02A0, 0x0FF9,
+ 0x0158, 0x02AE, 0x0FFA,
+ 0x0149, 0x02BD, 0x0FFA,
+ 0x013A, 0x02CB, 0x0FFB,
+ 0x012C, 0x02D7, 0x0FFD,
+ 0x011D, 0x02E5, 0x0FFE,
+ 0x010F, 0x02F1, 0x0000,
+ 0x0101, 0x02FD, 0x0002,
+ 0x00F3, 0x0308, 0x0005,
+ 0x00E5, 0x0313, 0x0008,
+ 0x00D8, 0x031D, 0x000B,
+ 0x00CB, 0x0326, 0x000F,
+ 0x00BE, 0x032F, 0x0013,
+ 0x00B2, 0x0337, 0x0017,
+ 0x00A6, 0x033E, 0x001C,
+ 0x009A, 0x0345, 0x0021,
+ 0x008F, 0x034A, 0x0027,
+ 0x0084, 0x034F, 0x002D,
+ 0x0079, 0x0353, 0x0034,
+ 0x006F, 0x0356, 0x003B,
+ 0x0065, 0x0358, 0x0043,
+ 0x005C, 0x0359, 0x004B,
+ 0x0053, 0x035A, 0x0053,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 3t_64p_LanczosEd_p_0.9_p_10qb_
+// <num_taps> 3
+// <num_phases> 64
+// <scale_ratio> input/output = 0.900000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_3tap_64p_ratio_0_90[99] = {
+ 0x0200, 0x0200, 0x0000,
+ 0x01EE, 0x0214, 0x0FFE,
+ 0x01DC, 0x0228, 0x0FFC,
+ 0x01CA, 0x023C, 0x0FFA,
+ 0x01B9, 0x024F, 0x0FF8,
+ 0x01A7, 0x0262, 0x0FF7,
+ 0x0195, 0x0276, 0x0FF5,
+ 0x0183, 0x028A, 0x0FF3,
+ 0x0172, 0x029C, 0x0FF2,
+ 0x0160, 0x02AF, 0x0FF1,
+ 0x014F, 0x02C2, 0x0FEF,
+ 0x013E, 0x02D4, 0x0FEE,
+ 0x012D, 0x02E5, 0x0FEE,
+ 0x011C, 0x02F7, 0x0FED,
+ 0x010C, 0x0307, 0x0FED,
+ 0x00FB, 0x0318, 0x0FED,
+ 0x00EC, 0x0327, 0x0FED,
+ 0x00DC, 0x0336, 0x0FEE,
+ 0x00CD, 0x0344, 0x0FEF,
+ 0x00BE, 0x0352, 0x0FF0,
+ 0x00B0, 0x035E, 0x0FF2,
+ 0x00A2, 0x036A, 0x0FF4,
+ 0x0095, 0x0375, 0x0FF6,
+ 0x0088, 0x037F, 0x0FF9,
+ 0x007B, 0x0388, 0x0FFD,
+ 0x006F, 0x0391, 0x0000,
+ 0x0064, 0x0397, 0x0005,
+ 0x0059, 0x039D, 0x000A,
+ 0x004E, 0x03A3, 0x000F,
+ 0x0045, 0x03A6, 0x0015,
+ 0x003B, 0x03A9, 0x001C,
+ 0x0033, 0x03AA, 0x0023,
+ 0x002A, 0x03AC, 0x002A,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 3t_64p_LanczosEd_p_1_p_10qb_
+// <num_taps> 3
+// <num_phases> 64
+// <scale_ratio> input/output = 1.000000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_3tap_64p_ratio_1_00[99] = {
+ 0x0200, 0x0200, 0x0000,
+ 0x01EB, 0x0217, 0x0FFE,
+ 0x01D5, 0x022F, 0x0FFC,
+ 0x01C0, 0x0247, 0x0FF9,
+ 0x01AB, 0x025E, 0x0FF7,
+ 0x0196, 0x0276, 0x0FF4,
+ 0x0181, 0x028D, 0x0FF2,
+ 0x016C, 0x02A5, 0x0FEF,
+ 0x0158, 0x02BB, 0x0FED,
+ 0x0144, 0x02D1, 0x0FEB,
+ 0x0130, 0x02E8, 0x0FE8,
+ 0x011C, 0x02FE, 0x0FE6,
+ 0x0109, 0x0313, 0x0FE4,
+ 0x00F6, 0x0328, 0x0FE2,
+ 0x00E4, 0x033C, 0x0FE0,
+ 0x00D2, 0x034F, 0x0FDF,
+ 0x00C0, 0x0363, 0x0FDD,
+ 0x00B0, 0x0374, 0x0FDC,
+ 0x009F, 0x0385, 0x0FDC,
+ 0x0090, 0x0395, 0x0FDB,
+ 0x0081, 0x03A4, 0x0FDB,
+ 0x0072, 0x03B3, 0x0FDB,
+ 0x0064, 0x03C0, 0x0FDC,
+ 0x0057, 0x03CC, 0x0FDD,
+ 0x004B, 0x03D6, 0x0FDF,
+ 0x003F, 0x03E0, 0x0FE1,
+ 0x0034, 0x03E8, 0x0FE4,
+ 0x002A, 0x03EF, 0x0FE7,
+ 0x0020, 0x03F5, 0x0FEB,
+ 0x0017, 0x03FA, 0x0FEF,
+ 0x000F, 0x03FD, 0x0FF4,
+ 0x0007, 0x03FF, 0x0FFA,
+ 0x0000, 0x0400, 0x0000,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 4t_64p_LanczosEd_p_0.3_p_10qb_
+// <num_taps> 4
+// <num_phases> 64
+// <scale_ratio> input/output = 0.300000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_4tap_64p_ratio_0_30[132] = {
+ 0x0104, 0x01F8, 0x0104, 0x0000,
+ 0x00FE, 0x01F7, 0x010A, 0x0001,
+ 0x00F8, 0x01F6, 0x010F, 0x0003,
+ 0x00F2, 0x01F5, 0x0114, 0x0005,
+ 0x00EB, 0x01F4, 0x011B, 0x0006,
+ 0x00E5, 0x01F3, 0x0120, 0x0008,
+ 0x00DF, 0x01F2, 0x0125, 0x000A,
+ 0x00DA, 0x01F0, 0x012A, 0x000C,
+ 0x00D4, 0x01EE, 0x0130, 0x000E,
+ 0x00CE, 0x01ED, 0x0135, 0x0010,
+ 0x00C8, 0x01EB, 0x013A, 0x0013,
+ 0x00C2, 0x01E9, 0x0140, 0x0015,
+ 0x00BD, 0x01E7, 0x0145, 0x0017,
+ 0x00B7, 0x01E5, 0x014A, 0x001A,
+ 0x00B1, 0x01E2, 0x0151, 0x001C,
+ 0x00AC, 0x01E0, 0x0155, 0x001F,
+ 0x00A7, 0x01DD, 0x015A, 0x0022,
+ 0x00A1, 0x01DB, 0x015F, 0x0025,
+ 0x009C, 0x01D8, 0x0165, 0x0027,
+ 0x0097, 0x01D5, 0x016A, 0x002A,
+ 0x0092, 0x01D2, 0x016E, 0x002E,
+ 0x008C, 0x01CF, 0x0174, 0x0031,
+ 0x0087, 0x01CC, 0x0179, 0x0034,
+ 0x0083, 0x01C9, 0x017D, 0x0037,
+ 0x007E, 0x01C5, 0x0182, 0x003B,
+ 0x0079, 0x01C2, 0x0187, 0x003E,
+ 0x0074, 0x01BE, 0x018C, 0x0042,
+ 0x0070, 0x01BA, 0x0190, 0x0046,
+ 0x006B, 0x01B7, 0x0195, 0x0049,
+ 0x0066, 0x01B3, 0x019A, 0x004D,
+ 0x0062, 0x01AF, 0x019E, 0x0051,
+ 0x005E, 0x01AB, 0x01A2, 0x0055,
+ 0x005A, 0x01A6, 0x01A6, 0x005A,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 4t_64p_LanczosEd_p_0.4_p_10qb_
+// <num_taps> 4
+// <num_phases> 64
+// <scale_ratio> input/output = 0.400000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_4tap_64p_ratio_0_40[132] = {
+ 0x00FB, 0x0209, 0x00FC, 0x0000,
+ 0x00F5, 0x0209, 0x0101, 0x0001,
+ 0x00EE, 0x0208, 0x0108, 0x0002,
+ 0x00E8, 0x0207, 0x010E, 0x0003,
+ 0x00E2, 0x0206, 0x0114, 0x0004,
+ 0x00DB, 0x0205, 0x011A, 0x0006,
+ 0x00D5, 0x0204, 0x0120, 0x0007,
+ 0x00CF, 0x0203, 0x0125, 0x0009,
+ 0x00C9, 0x0201, 0x012C, 0x000A,
+ 0x00C3, 0x01FF, 0x0132, 0x000C,
+ 0x00BD, 0x01FD, 0x0138, 0x000E,
+ 0x00B7, 0x01FB, 0x013E, 0x0010,
+ 0x00B1, 0x01F9, 0x0144, 0x0012,
+ 0x00AC, 0x01F7, 0x0149, 0x0014,
+ 0x00A6, 0x01F4, 0x0150, 0x0016,
+ 0x00A0, 0x01F2, 0x0156, 0x0018,
+ 0x009B, 0x01EF, 0x015C, 0x001A,
+ 0x0095, 0x01EC, 0x0162, 0x001D,
+ 0x0090, 0x01E9, 0x0168, 0x001F,
+ 0x008B, 0x01E6, 0x016D, 0x0022,
+ 0x0085, 0x01E3, 0x0173, 0x0025,
+ 0x0080, 0x01DF, 0x0179, 0x0028,
+ 0x007B, 0x01DC, 0x017E, 0x002B,
+ 0x0076, 0x01D8, 0x0184, 0x002E,
+ 0x0071, 0x01D4, 0x018A, 0x0031,
+ 0x006D, 0x01D1, 0x018E, 0x0034,
+ 0x0068, 0x01CD, 0x0193, 0x0038,
+ 0x0063, 0x01C8, 0x019A, 0x003B,
+ 0x005F, 0x01C4, 0x019E, 0x003F,
+ 0x005B, 0x01C0, 0x01A3, 0x0042,
+ 0x0056, 0x01BB, 0x01A9, 0x0046,
+ 0x0052, 0x01B7, 0x01AD, 0x004A,
+ 0x004E, 0x01B2, 0x01B2, 0x004E,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 4t_64p_LanczosEd_p_0.5_p_10qb_
+// <num_taps> 4
+// <num_phases> 64
+// <scale_ratio> input/output = 0.500000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_4tap_64p_ratio_0_50[132] = {
+ 0x00E5, 0x0236, 0x00E5, 0x0000,
+ 0x00DE, 0x0235, 0x00ED, 0x0000,
+ 0x00D7, 0x0235, 0x00F4, 0x0000,
+ 0x00D0, 0x0235, 0x00FB, 0x0000,
+ 0x00C9, 0x0234, 0x0102, 0x0001,
+ 0x00C2, 0x0233, 0x010A, 0x0001,
+ 0x00BC, 0x0232, 0x0111, 0x0001,
+ 0x00B5, 0x0230, 0x0119, 0x0002,
+ 0x00AE, 0x022F, 0x0121, 0x0002,
+ 0x00A8, 0x022D, 0x0128, 0x0003,
+ 0x00A2, 0x022B, 0x012F, 0x0004,
+ 0x009B, 0x0229, 0x0137, 0x0005,
+ 0x0095, 0x0226, 0x013F, 0x0006,
+ 0x008F, 0x0224, 0x0146, 0x0007,
+ 0x0089, 0x0221, 0x014E, 0x0008,
+ 0x0083, 0x021E, 0x0155, 0x000A,
+ 0x007E, 0x021B, 0x015C, 0x000B,
+ 0x0078, 0x0217, 0x0164, 0x000D,
+ 0x0072, 0x0213, 0x016D, 0x000E,
+ 0x006D, 0x0210, 0x0173, 0x0010,
+ 0x0068, 0x020C, 0x017A, 0x0012,
+ 0x0063, 0x0207, 0x0182, 0x0014,
+ 0x005E, 0x0203, 0x0189, 0x0016,
+ 0x0059, 0x01FE, 0x0191, 0x0018,
+ 0x0054, 0x01F9, 0x0198, 0x001B,
+ 0x0050, 0x01F4, 0x019F, 0x001D,
+ 0x004B, 0x01EF, 0x01A6, 0x0020,
+ 0x0047, 0x01EA, 0x01AC, 0x0023,
+ 0x0043, 0x01E4, 0x01B3, 0x0026,
+ 0x003F, 0x01DF, 0x01B9, 0x0029,
+ 0x003B, 0x01D9, 0x01C0, 0x002C,
+ 0x0037, 0x01D3, 0x01C6, 0x0030,
+ 0x0033, 0x01CD, 0x01CD, 0x0033,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 4t_64p_LanczosEd_p_0.6_p_10qb_
+// <num_taps> 4
+// <num_phases> 64
+// <scale_ratio> input/output = 0.600000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_4tap_64p_ratio_0_60[132] = {
+ 0x00C8, 0x026F, 0x00C9, 0x0000,
+ 0x00C0, 0x0270, 0x00D1, 0x0FFF,
+ 0x00B8, 0x0270, 0x00D9, 0x0FFF,
+ 0x00B1, 0x0270, 0x00E1, 0x0FFE,
+ 0x00A9, 0x026F, 0x00EB, 0x0FFD,
+ 0x00A2, 0x026E, 0x00F3, 0x0FFD,
+ 0x009A, 0x026D, 0x00FD, 0x0FFC,
+ 0x0093, 0x026C, 0x0105, 0x0FFC,
+ 0x008C, 0x026A, 0x010F, 0x0FFB,
+ 0x0085, 0x0268, 0x0118, 0x0FFB,
+ 0x007E, 0x0265, 0x0122, 0x0FFB,
+ 0x0078, 0x0263, 0x012A, 0x0FFB,
+ 0x0071, 0x0260, 0x0134, 0x0FFB,
+ 0x006B, 0x025C, 0x013E, 0x0FFB,
+ 0x0065, 0x0259, 0x0147, 0x0FFB,
+ 0x005F, 0x0255, 0x0151, 0x0FFB,
+ 0x0059, 0x0251, 0x015A, 0x0FFC,
+ 0x0054, 0x024D, 0x0163, 0x0FFC,
+ 0x004E, 0x0248, 0x016D, 0x0FFD,
+ 0x0049, 0x0243, 0x0176, 0x0FFE,
+ 0x0044, 0x023E, 0x017F, 0x0FFF,
+ 0x003F, 0x0238, 0x0189, 0x0000,
+ 0x003A, 0x0232, 0x0193, 0x0001,
+ 0x0036, 0x022C, 0x019C, 0x0002,
+ 0x0031, 0x0226, 0x01A5, 0x0004,
+ 0x002D, 0x021F, 0x01AF, 0x0005,
+ 0x0029, 0x0218, 0x01B8, 0x0007,
+ 0x0025, 0x0211, 0x01C1, 0x0009,
+ 0x0022, 0x020A, 0x01C9, 0x000B,
+ 0x001E, 0x0203, 0x01D2, 0x000D,
+ 0x001B, 0x01FB, 0x01DA, 0x0010,
+ 0x0018, 0x01F3, 0x01E3, 0x0012,
+ 0x0015, 0x01EB, 0x01EB, 0x0015,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 4t_64p_LanczosEd_p_0.7_p_10qb_
+// <num_taps> 4
+// <num_phases> 64
+// <scale_ratio> input/output = 0.700000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_4tap_64p_ratio_0_70[132] = {
+ 0x00A3, 0x02B9, 0x00A4, 0x0000,
+ 0x009A, 0x02BA, 0x00AD, 0x0FFF,
+ 0x0092, 0x02BA, 0x00B6, 0x0FFE,
+ 0x0089, 0x02BA, 0x00C1, 0x0FFC,
+ 0x0081, 0x02B9, 0x00CB, 0x0FFB,
+ 0x0079, 0x02B8, 0x00D5, 0x0FFA,
+ 0x0071, 0x02B7, 0x00DF, 0x0FF9,
+ 0x0069, 0x02B5, 0x00EA, 0x0FF8,
+ 0x0062, 0x02B3, 0x00F4, 0x0FF7,
+ 0x005B, 0x02B0, 0x00FF, 0x0FF6,
+ 0x0054, 0x02AD, 0x010B, 0x0FF4,
+ 0x004D, 0x02A9, 0x0117, 0x0FF3,
+ 0x0046, 0x02A5, 0x0123, 0x0FF2,
+ 0x0040, 0x02A1, 0x012D, 0x0FF2,
+ 0x003A, 0x029C, 0x0139, 0x0FF1,
+ 0x0034, 0x0297, 0x0145, 0x0FF0,
+ 0x002F, 0x0292, 0x0150, 0x0FEF,
+ 0x0029, 0x028C, 0x015C, 0x0FEF,
+ 0x0024, 0x0285, 0x0169, 0x0FEE,
+ 0x001F, 0x027F, 0x0174, 0x0FEE,
+ 0x001B, 0x0278, 0x017F, 0x0FEE,
+ 0x0016, 0x0270, 0x018D, 0x0FED,
+ 0x0012, 0x0268, 0x0199, 0x0FED,
+ 0x000E, 0x0260, 0x01A4, 0x0FEE,
+ 0x000B, 0x0258, 0x01AF, 0x0FEE,
+ 0x0007, 0x024F, 0x01BC, 0x0FEE,
+ 0x0004, 0x0246, 0x01C7, 0x0FEF,
+ 0x0001, 0x023D, 0x01D3, 0x0FEF,
+ 0x0FFE, 0x0233, 0x01DF, 0x0FF0,
+ 0x0FFC, 0x0229, 0x01EA, 0x0FF1,
+ 0x0FFA, 0x021F, 0x01F4, 0x0FF3,
+ 0x0FF8, 0x0215, 0x01FF, 0x0FF4,
+ 0x0FF6, 0x020A, 0x020A, 0x0FF6,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 4t_64p_LanczosEd_p_0.8_p_10qb_
+// <num_taps> 4
+// <num_phases> 64
+// <scale_ratio> input/output = 0.800000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_4tap_64p_ratio_0_80[132] = {
+ 0x0075, 0x0315, 0x0076, 0x0000,
+ 0x006C, 0x0316, 0x007F, 0x0FFF,
+ 0x0062, 0x0316, 0x008A, 0x0FFE,
+ 0x0059, 0x0315, 0x0096, 0x0FFC,
+ 0x0050, 0x0314, 0x00A1, 0x0FFB,
+ 0x0048, 0x0312, 0x00AD, 0x0FF9,
+ 0x0040, 0x0310, 0x00B8, 0x0FF8,
+ 0x0038, 0x030D, 0x00C5, 0x0FF6,
+ 0x0030, 0x030A, 0x00D1, 0x0FF5,
+ 0x0029, 0x0306, 0x00DE, 0x0FF3,
+ 0x0022, 0x0301, 0x00EB, 0x0FF2,
+ 0x001C, 0x02FC, 0x00F8, 0x0FF0,
+ 0x0015, 0x02F7, 0x0106, 0x0FEE,
+ 0x0010, 0x02F1, 0x0112, 0x0FED,
+ 0x000A, 0x02EA, 0x0121, 0x0FEB,
+ 0x0005, 0x02E3, 0x012F, 0x0FE9,
+ 0x0000, 0x02DB, 0x013D, 0x0FE8,
+ 0x0FFB, 0x02D3, 0x014C, 0x0FE6,
+ 0x0FF7, 0x02CA, 0x015A, 0x0FE5,
+ 0x0FF3, 0x02C1, 0x0169, 0x0FE3,
+ 0x0FF0, 0x02B7, 0x0177, 0x0FE2,
+ 0x0FEC, 0x02AD, 0x0186, 0x0FE1,
+ 0x0FE9, 0x02A2, 0x0196, 0x0FDF,
+ 0x0FE7, 0x0297, 0x01A4, 0x0FDE,
+ 0x0FE4, 0x028C, 0x01B3, 0x0FDD,
+ 0x0FE2, 0x0280, 0x01C2, 0x0FDC,
+ 0x0FE0, 0x0274, 0x01D0, 0x0FDC,
+ 0x0FDF, 0x0268, 0x01DE, 0x0FDB,
+ 0x0FDD, 0x025B, 0x01EE, 0x0FDA,
+ 0x0FDC, 0x024E, 0x01FC, 0x0FDA,
+ 0x0FDB, 0x0241, 0x020A, 0x0FDA,
+ 0x0FDB, 0x0233, 0x0218, 0x0FDA,
+ 0x0FDA, 0x0226, 0x0226, 0x0FDA,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 4t_64p_LanczosEd_p_0.9_p_10qb_
+// <num_taps> 4
+// <num_phases> 64
+// <scale_ratio> input/output = 0.900000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_4tap_64p_ratio_0_90[132] = {
+ 0x003F, 0x0383, 0x003E, 0x0000,
+ 0x0034, 0x0383, 0x004A, 0x0FFF,
+ 0x002B, 0x0383, 0x0054, 0x0FFE,
+ 0x0021, 0x0381, 0x0061, 0x0FFD,
+ 0x0019, 0x037F, 0x006C, 0x0FFC,
+ 0x0010, 0x037C, 0x0079, 0x0FFB,
+ 0x0008, 0x0378, 0x0086, 0x0FFA,
+ 0x0001, 0x0374, 0x0093, 0x0FF8,
+ 0x0FFA, 0x036E, 0x00A1, 0x0FF7,
+ 0x0FF3, 0x0368, 0x00B0, 0x0FF5,
+ 0x0FED, 0x0361, 0x00BF, 0x0FF3,
+ 0x0FE8, 0x035A, 0x00CD, 0x0FF1,
+ 0x0FE2, 0x0352, 0x00DC, 0x0FF0,
+ 0x0FDE, 0x0349, 0x00EB, 0x0FEE,
+ 0x0FD9, 0x033F, 0x00FC, 0x0FEC,
+ 0x0FD5, 0x0335, 0x010D, 0x0FE9,
+ 0x0FD2, 0x032A, 0x011D, 0x0FE7,
+ 0x0FCF, 0x031E, 0x012E, 0x0FE5,
+ 0x0FCC, 0x0312, 0x013F, 0x0FE3,
+ 0x0FCA, 0x0305, 0x0150, 0x0FE1,
+ 0x0FC8, 0x02F8, 0x0162, 0x0FDE,
+ 0x0FC6, 0x02EA, 0x0174, 0x0FDC,
+ 0x0FC5, 0x02DC, 0x0185, 0x0FDA,
+ 0x0FC4, 0x02CD, 0x0197, 0x0FD8,
+ 0x0FC3, 0x02BE, 0x01AA, 0x0FD5,
+ 0x0FC3, 0x02AF, 0x01BB, 0x0FD3,
+ 0x0FC3, 0x029F, 0x01CD, 0x0FD1,
+ 0x0FC3, 0x028E, 0x01E0, 0x0FCF,
+ 0x0FC3, 0x027E, 0x01F2, 0x0FCD,
+ 0x0FC4, 0x026D, 0x0203, 0x0FCC,
+ 0x0FC5, 0x025C, 0x0215, 0x0FCA,
+ 0x0FC6, 0x024B, 0x0227, 0x0FC8,
+ 0x0FC7, 0x0239, 0x0239, 0x0FC7,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 03-Apr-2024
+// <coeffDescrip> 4t_64p_LanczosEd_p_1_p_10qb_
+// <num_taps> 4
+// <num_phases> 64
+// <scale_ratio> input/output = 1.000000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_4tap_64p_ratio_1_00[132] = {
+ 0x0000, 0x0400, 0x0000, 0x0000,
+ 0x0FF6, 0x03FF, 0x000B, 0x0000,
+ 0x0FED, 0x03FE, 0x0015, 0x0000,
+ 0x0FE4, 0x03FB, 0x0022, 0x0FFF,
+ 0x0FDC, 0x03F7, 0x002E, 0x0FFF,
+ 0x0FD5, 0x03F2, 0x003B, 0x0FFE,
+ 0x0FCE, 0x03EC, 0x0048, 0x0FFE,
+ 0x0FC8, 0x03E5, 0x0056, 0x0FFD,
+ 0x0FC3, 0x03DC, 0x0065, 0x0FFC,
+ 0x0FBE, 0x03D3, 0x0075, 0x0FFA,
+ 0x0FB9, 0x03C9, 0x0085, 0x0FF9,
+ 0x0FB6, 0x03BE, 0x0094, 0x0FF8,
+ 0x0FB2, 0x03B2, 0x00A6, 0x0FF6,
+ 0x0FB0, 0x03A5, 0x00B7, 0x0FF4,
+ 0x0FAD, 0x0397, 0x00CA, 0x0FF2,
+ 0x0FAB, 0x0389, 0x00DC, 0x0FF0,
+ 0x0FAA, 0x0379, 0x00EF, 0x0FEE,
+ 0x0FA9, 0x0369, 0x0102, 0x0FEC,
+ 0x0FA9, 0x0359, 0x0115, 0x0FE9,
+ 0x0FA9, 0x0348, 0x0129, 0x0FE6,
+ 0x0FA9, 0x0336, 0x013D, 0x0FE4,
+ 0x0FA9, 0x0323, 0x0153, 0x0FE1,
+ 0x0FAA, 0x0310, 0x0168, 0x0FDE,
+ 0x0FAC, 0x02FD, 0x017C, 0x0FDB,
+ 0x0FAD, 0x02E9, 0x0192, 0x0FD8,
+ 0x0FAF, 0x02D5, 0x01A7, 0x0FD5,
+ 0x0FB1, 0x02C0, 0x01BD, 0x0FD2,
+ 0x0FB3, 0x02AC, 0x01D2, 0x0FCF,
+ 0x0FB5, 0x0296, 0x01E9, 0x0FCC,
+ 0x0FB8, 0x0281, 0x01FE, 0x0FC9,
+ 0x0FBA, 0x026C, 0x0214, 0x0FC6,
+ 0x0FBD, 0x0256, 0x022A, 0x0FC3,
+ 0x0FC0, 0x0240, 0x0240, 0x0FC0,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 02-Apr-2024
+// <coeffDescrip> 6t_64p_LanczosEd_p_0.3_p_10qb_
+// <num_taps> 6
+// <num_phases> 64
+// <scale_ratio> input/output = 0.300000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_6tap_64p_ratio_0_30[198] = {
+ 0x004B, 0x0100, 0x0169, 0x0101, 0x004B, 0x0000,
+ 0x0049, 0x00FD, 0x0169, 0x0103, 0x004E, 0x0000,
+ 0x0047, 0x00FA, 0x0169, 0x0106, 0x0050, 0x0000,
+ 0x0045, 0x00F7, 0x0168, 0x0109, 0x0052, 0x0001,
+ 0x0043, 0x00F5, 0x0168, 0x010B, 0x0054, 0x0001,
+ 0x0040, 0x00F2, 0x0168, 0x010E, 0x0057, 0x0001,
+ 0x003E, 0x00EF, 0x0168, 0x0110, 0x0059, 0x0002,
+ 0x003C, 0x00EC, 0x0167, 0x0113, 0x005C, 0x0002,
+ 0x003A, 0x00E9, 0x0167, 0x0116, 0x005E, 0x0002,
+ 0x0038, 0x00E6, 0x0166, 0x0118, 0x0061, 0x0003,
+ 0x0036, 0x00E3, 0x0165, 0x011C, 0x0063, 0x0003,
+ 0x0034, 0x00E0, 0x0165, 0x011D, 0x0066, 0x0004,
+ 0x0033, 0x00DD, 0x0164, 0x0120, 0x0068, 0x0004,
+ 0x0031, 0x00DA, 0x0163, 0x0122, 0x006B, 0x0005,
+ 0x002F, 0x00D7, 0x0163, 0x0125, 0x006D, 0x0005,
+ 0x002D, 0x00D3, 0x0162, 0x0128, 0x0070, 0x0006,
+ 0x002B, 0x00D0, 0x0161, 0x012A, 0x0073, 0x0007,
+ 0x002A, 0x00CD, 0x0160, 0x012D, 0x0075, 0x0007,
+ 0x0028, 0x00CA, 0x015F, 0x012F, 0x0078, 0x0008,
+ 0x0026, 0x00C7, 0x015E, 0x0131, 0x007B, 0x0009,
+ 0x0025, 0x00C4, 0x015D, 0x0133, 0x007E, 0x0009,
+ 0x0023, 0x00C1, 0x015C, 0x0136, 0x0080, 0x000A,
+ 0x0022, 0x00BE, 0x015A, 0x0138, 0x0083, 0x000B,
+ 0x0020, 0x00BB, 0x0159, 0x013A, 0x0086, 0x000C,
+ 0x001F, 0x00B8, 0x0158, 0x013B, 0x0089, 0x000D,
+ 0x001E, 0x00B5, 0x0156, 0x013E, 0x008C, 0x000D,
+ 0x001C, 0x00B2, 0x0155, 0x0140, 0x008F, 0x000E,
+ 0x001B, 0x00AF, 0x0153, 0x0143, 0x0091, 0x000F,
+ 0x0019, 0x00AC, 0x0152, 0x0145, 0x0094, 0x0010,
+ 0x0018, 0x00A9, 0x0150, 0x0147, 0x0097, 0x0011,
+ 0x0017, 0x00A6, 0x014F, 0x0148, 0x009A, 0x0012,
+ 0x0016, 0x00A3, 0x014D, 0x0149, 0x009D, 0x0014,
+ 0x0015, 0x00A0, 0x014B, 0x014B, 0x00A0, 0x0015,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 02-Apr-2024
+// <coeffDescrip> 6t_64p_LanczosEd_p_0.4_p_10qb_
+// <num_taps> 6
+// <num_phases> 64
+// <scale_ratio> input/output = 0.400000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_6tap_64p_ratio_0_40[198] = {
+ 0x0028, 0x0106, 0x01A3, 0x0107, 0x0028, 0x0000,
+ 0x0026, 0x0102, 0x01A3, 0x010A, 0x002B, 0x0000,
+ 0x0024, 0x00FE, 0x01A3, 0x010F, 0x002D, 0x0FFF,
+ 0x0022, 0x00FA, 0x01A3, 0x0113, 0x002F, 0x0FFF,
+ 0x0021, 0x00F6, 0x01A3, 0x0116, 0x0031, 0x0FFF,
+ 0x001F, 0x00F2, 0x01A2, 0x011B, 0x0034, 0x0FFE,
+ 0x001D, 0x00EE, 0x01A2, 0x011F, 0x0036, 0x0FFE,
+ 0x001B, 0x00EA, 0x01A1, 0x0123, 0x0039, 0x0FFE,
+ 0x0019, 0x00E6, 0x01A1, 0x0127, 0x003B, 0x0FFE,
+ 0x0018, 0x00E2, 0x01A0, 0x012A, 0x003E, 0x0FFE,
+ 0x0016, 0x00DE, 0x01A0, 0x012E, 0x0041, 0x0FFD,
+ 0x0015, 0x00DA, 0x019F, 0x0132, 0x0043, 0x0FFD,
+ 0x0013, 0x00D6, 0x019E, 0x0136, 0x0046, 0x0FFD,
+ 0x0012, 0x00D2, 0x019D, 0x0139, 0x0049, 0x0FFD,
+ 0x0010, 0x00CE, 0x019C, 0x013D, 0x004C, 0x0FFD,
+ 0x000F, 0x00CA, 0x019A, 0x0141, 0x004F, 0x0FFD,
+ 0x000E, 0x00C6, 0x0199, 0x0144, 0x0052, 0x0FFD,
+ 0x000D, 0x00C2, 0x0197, 0x0148, 0x0055, 0x0FFD,
+ 0x000B, 0x00BE, 0x0196, 0x014C, 0x0058, 0x0FFD,
+ 0x000A, 0x00BA, 0x0195, 0x014F, 0x005B, 0x0FFD,
+ 0x0009, 0x00B6, 0x0193, 0x0153, 0x005E, 0x0FFD,
+ 0x0008, 0x00B2, 0x0191, 0x0157, 0x0061, 0x0FFD,
+ 0x0007, 0x00AE, 0x0190, 0x015A, 0x0064, 0x0FFD,
+ 0x0006, 0x00AA, 0x018E, 0x015D, 0x0068, 0x0FFD,
+ 0x0005, 0x00A6, 0x018C, 0x0161, 0x006B, 0x0FFD,
+ 0x0005, 0x00A2, 0x0189, 0x0164, 0x006F, 0x0FFD,
+ 0x0004, 0x009E, 0x0187, 0x0167, 0x0072, 0x0FFE,
+ 0x0003, 0x009A, 0x0185, 0x016B, 0x0075, 0x0FFE,
+ 0x0002, 0x0096, 0x0183, 0x016E, 0x0079, 0x0FFE,
+ 0x0002, 0x0093, 0x0180, 0x016F, 0x007D, 0x0FFF,
+ 0x0001, 0x008F, 0x017E, 0x0173, 0x0080, 0x0FFF,
+ 0x0001, 0x008B, 0x017B, 0x0175, 0x0084, 0x0000,
+ 0x0000, 0x0087, 0x0179, 0x0179, 0x0087, 0x0000,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 02-Apr-2024
+// <coeffDescrip> 6t_64p_LanczosEd_p_0.5_p_10qb_
+// <num_taps> 6
+// <num_phases> 64
+// <scale_ratio> input/output = 0.500000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_6tap_64p_ratio_0_50[198] = {
+ 0x0000, 0x0107, 0x01F3, 0x0106, 0x0000, 0x0000,
+ 0x0FFE, 0x0101, 0x01F3, 0x010D, 0x0002, 0x0FFF,
+ 0x0FFD, 0x00FB, 0x01F3, 0x0113, 0x0003, 0x0FFF,
+ 0x0FFC, 0x00F6, 0x01F3, 0x0118, 0x0005, 0x0FFE,
+ 0x0FFA, 0x00F0, 0x01F3, 0x011E, 0x0007, 0x0FFE,
+ 0x0FF9, 0x00EB, 0x01F2, 0x0124, 0x0009, 0x0FFD,
+ 0x0FF8, 0x00E5, 0x01F2, 0x0129, 0x000B, 0x0FFD,
+ 0x0FF7, 0x00E0, 0x01F1, 0x012F, 0x000D, 0x0FFC,
+ 0x0FF6, 0x00DA, 0x01F0, 0x0135, 0x0010, 0x0FFB,
+ 0x0FF5, 0x00D4, 0x01EF, 0x013B, 0x0012, 0x0FFB,
+ 0x0FF4, 0x00CF, 0x01EE, 0x0141, 0x0014, 0x0FFA,
+ 0x0FF3, 0x00C9, 0x01ED, 0x0147, 0x0017, 0x0FF9,
+ 0x0FF2, 0x00C4, 0x01EB, 0x014C, 0x001A, 0x0FF9,
+ 0x0FF1, 0x00BF, 0x01EA, 0x0152, 0x001C, 0x0FF8,
+ 0x0FF1, 0x00B9, 0x01E8, 0x0157, 0x001F, 0x0FF8,
+ 0x0FF0, 0x00B4, 0x01E6, 0x015D, 0x0022, 0x0FF7,
+ 0x0FF0, 0x00AE, 0x01E4, 0x0163, 0x0025, 0x0FF6,
+ 0x0FEF, 0x00A9, 0x01E2, 0x0168, 0x0028, 0x0FF6,
+ 0x0FEF, 0x00A4, 0x01DF, 0x016E, 0x002B, 0x0FF5,
+ 0x0FEF, 0x009F, 0x01DD, 0x0172, 0x002E, 0x0FF5,
+ 0x0FEE, 0x009A, 0x01DA, 0x0178, 0x0032, 0x0FF4,
+ 0x0FEE, 0x0094, 0x01D8, 0x017E, 0x0035, 0x0FF3,
+ 0x0FEE, 0x008F, 0x01D5, 0x0182, 0x0039, 0x0FF3,
+ 0x0FEE, 0x008A, 0x01D2, 0x0188, 0x003C, 0x0FF2,
+ 0x0FEE, 0x0085, 0x01CF, 0x018C, 0x0040, 0x0FF2,
+ 0x0FEE, 0x0081, 0x01CB, 0x0191, 0x0044, 0x0FF1,
+ 0x0FEE, 0x007C, 0x01C8, 0x0196, 0x0047, 0x0FF1,
+ 0x0FEE, 0x0077, 0x01C4, 0x019C, 0x004B, 0x0FF0,
+ 0x0FEE, 0x0072, 0x01C1, 0x01A0, 0x004F, 0x0FF0,
+ 0x0FEE, 0x006E, 0x01BD, 0x01A4, 0x0053, 0x0FF0,
+ 0x0FEE, 0x0069, 0x01B9, 0x01A9, 0x0058, 0x0FEF,
+ 0x0FEE, 0x0065, 0x01B5, 0x01AD, 0x005C, 0x0FEF,
+ 0x0FEF, 0x0060, 0x01B1, 0x01B1, 0x0060, 0x0FEF,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 02-Apr-2024
+// <coeffDescrip> 6t_64p_LanczosEd_p_0.6_p_10qb_
+// <num_taps> 6
+// <num_phases> 64
+// <scale_ratio> input/output = 0.600000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_6tap_64p_ratio_0_60[198] = {
+ 0x0FD9, 0x00FB, 0x0258, 0x00FB, 0x0FD9, 0x0000,
+ 0x0FD9, 0x00F3, 0x0258, 0x0102, 0x0FDA, 0x0000,
+ 0x0FD8, 0x00EB, 0x0258, 0x010B, 0x0FDB, 0x0FFF,
+ 0x0FD8, 0x00E3, 0x0258, 0x0112, 0x0FDC, 0x0FFF,
+ 0x0FD8, 0x00DC, 0x0257, 0x011B, 0x0FDC, 0x0FFE,
+ 0x0FD7, 0x00D4, 0x0256, 0x0123, 0x0FDE, 0x0FFE,
+ 0x0FD7, 0x00CD, 0x0255, 0x012B, 0x0FDF, 0x0FFD,
+ 0x0FD7, 0x00C5, 0x0254, 0x0133, 0x0FE0, 0x0FFD,
+ 0x0FD7, 0x00BE, 0x0252, 0x013C, 0x0FE1, 0x0FFC,
+ 0x0FD7, 0x00B6, 0x0251, 0x0143, 0x0FE3, 0x0FFC,
+ 0x0FD8, 0x00AF, 0x024F, 0x014B, 0x0FE4, 0x0FFB,
+ 0x0FD8, 0x00A8, 0x024C, 0x0154, 0x0FE6, 0x0FFA,
+ 0x0FD8, 0x00A1, 0x024A, 0x015B, 0x0FE8, 0x0FFA,
+ 0x0FD9, 0x009A, 0x0247, 0x0163, 0x0FEA, 0x0FF9,
+ 0x0FD9, 0x0093, 0x0244, 0x016C, 0x0FEC, 0x0FF8,
+ 0x0FD9, 0x008C, 0x0241, 0x0174, 0x0FEF, 0x0FF7,
+ 0x0FDA, 0x0085, 0x023E, 0x017B, 0x0FF1, 0x0FF7,
+ 0x0FDB, 0x007F, 0x023A, 0x0183, 0x0FF3, 0x0FF6,
+ 0x0FDB, 0x0078, 0x0237, 0x018B, 0x0FF6, 0x0FF5,
+ 0x0FDC, 0x0072, 0x0233, 0x0192, 0x0FF9, 0x0FF4,
+ 0x0FDD, 0x006C, 0x022F, 0x0199, 0x0FFC, 0x0FF3,
+ 0x0FDD, 0x0065, 0x022A, 0x01A3, 0x0FFF, 0x0FF2,
+ 0x0FDE, 0x005F, 0x0226, 0x01AA, 0x0002, 0x0FF1,
+ 0x0FDF, 0x005A, 0x0221, 0x01B0, 0x0006, 0x0FF0,
+ 0x0FE0, 0x0054, 0x021C, 0x01B7, 0x0009, 0x0FF0,
+ 0x0FE1, 0x004E, 0x0217, 0x01BE, 0x000D, 0x0FEF,
+ 0x0FE2, 0x0048, 0x0212, 0x01C6, 0x0010, 0x0FEE,
+ 0x0FE3, 0x0043, 0x020C, 0x01CD, 0x0014, 0x0FED,
+ 0x0FE4, 0x003E, 0x0207, 0x01D3, 0x0018, 0x0FEC,
+ 0x0FE5, 0x0039, 0x0200, 0x01DA, 0x001D, 0x0FEB,
+ 0x0FE6, 0x0034, 0x01FA, 0x01E1, 0x0021, 0x0FEA,
+ 0x0FE7, 0x002F, 0x01F5, 0x01E7, 0x0025, 0x0FE9,
+ 0x0FE8, 0x002A, 0x01EE, 0x01EE, 0x002A, 0x0FE8,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 02-Apr-2024
+// <coeffDescrip> 6t_64p_LanczosEd_p_0.7_p_10qb_
+// <num_taps> 6
+// <num_phases> 64
+// <scale_ratio> input/output = 0.700000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_6tap_64p_ratio_0_70[198] = {
+ 0x0FC0, 0x00DA, 0x02CC, 0x00DA, 0x0FC0, 0x0000,
+ 0x0FC1, 0x00D0, 0x02CC, 0x00E4, 0x0FBF, 0x0000,
+ 0x0FC2, 0x00C6, 0x02CB, 0x00EF, 0x0FBE, 0x0000,
+ 0x0FC3, 0x00BC, 0x02CA, 0x00F9, 0x0FBE, 0x0000,
+ 0x0FC4, 0x00B2, 0x02C9, 0x0104, 0x0FBD, 0x0000,
+ 0x0FC5, 0x00A8, 0x02C7, 0x010F, 0x0FBD, 0x0000,
+ 0x0FC7, 0x009F, 0x02C5, 0x0119, 0x0FBC, 0x0000,
+ 0x0FC8, 0x0095, 0x02C3, 0x0124, 0x0FBC, 0x0000,
+ 0x0FC9, 0x008C, 0x02C0, 0x012F, 0x0FBC, 0x0000,
+ 0x0FCB, 0x0083, 0x02BD, 0x0139, 0x0FBC, 0x0000,
+ 0x0FCC, 0x007A, 0x02BA, 0x0144, 0x0FBC, 0x0000,
+ 0x0FCE, 0x0072, 0x02B6, 0x014D, 0x0FBD, 0x0000,
+ 0x0FD0, 0x0069, 0x02B2, 0x0159, 0x0FBD, 0x0FFF,
+ 0x0FD1, 0x0061, 0x02AD, 0x0164, 0x0FBE, 0x0FFF,
+ 0x0FD3, 0x0059, 0x02A9, 0x016E, 0x0FBF, 0x0FFE,
+ 0x0FD4, 0x0051, 0x02A4, 0x017A, 0x0FBF, 0x0FFE,
+ 0x0FD6, 0x0049, 0x029E, 0x0184, 0x0FC1, 0x0FFE,
+ 0x0FD8, 0x0042, 0x0299, 0x018E, 0x0FC2, 0x0FFD,
+ 0x0FD9, 0x003A, 0x0293, 0x019B, 0x0FC3, 0x0FFC,
+ 0x0FDB, 0x0033, 0x028D, 0x01A4, 0x0FC5, 0x0FFC,
+ 0x0FDC, 0x002D, 0x0286, 0x01AF, 0x0FC7, 0x0FFB,
+ 0x0FDE, 0x0026, 0x0280, 0x01BA, 0x0FC8, 0x0FFA,
+ 0x0FE0, 0x001F, 0x0279, 0x01C4, 0x0FCB, 0x0FF9,
+ 0x0FE1, 0x0019, 0x0272, 0x01CE, 0x0FCD, 0x0FF9,
+ 0x0FE3, 0x0013, 0x026A, 0x01D9, 0x0FCF, 0x0FF8,
+ 0x0FE4, 0x000D, 0x0263, 0x01E3, 0x0FD2, 0x0FF7,
+ 0x0FE6, 0x0008, 0x025B, 0x01EC, 0x0FD5, 0x0FF6,
+ 0x0FE7, 0x0002, 0x0253, 0x01F7, 0x0FD8, 0x0FF5,
+ 0x0FE9, 0x0FFD, 0x024A, 0x0202, 0x0FDB, 0x0FF3,
+ 0x0FEA, 0x0FF8, 0x0242, 0x020B, 0x0FDF, 0x0FF2,
+ 0x0FEC, 0x0FF3, 0x0239, 0x0215, 0x0FE2, 0x0FF1,
+ 0x0FED, 0x0FEF, 0x0230, 0x021E, 0x0FE6, 0x0FF0,
+ 0x0FEF, 0x0FEB, 0x0226, 0x0226, 0x0FEB, 0x0FEF,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 02-Apr-2024
+// <coeffDescrip> 6t_64p_LanczosEd_p_0.8_p_10qb_
+// <num_taps> 6
+// <num_phases> 64
+// <scale_ratio> input/output = 0.800000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_6tap_64p_ratio_0_80[198] = {
+ 0x0FBF, 0x00A1, 0x0340, 0x00A1, 0x0FBF, 0x0000,
+ 0x0FC1, 0x0095, 0x0340, 0x00AD, 0x0FBC, 0x0001,
+ 0x0FC4, 0x0089, 0x033E, 0x00BA, 0x0FBA, 0x0001,
+ 0x0FC6, 0x007D, 0x033D, 0x00C6, 0x0FB8, 0x0002,
+ 0x0FC9, 0x0072, 0x033A, 0x00D3, 0x0FB6, 0x0002,
+ 0x0FCC, 0x0067, 0x0338, 0x00DF, 0x0FB3, 0x0003,
+ 0x0FCE, 0x005C, 0x0334, 0x00EE, 0x0FB1, 0x0003,
+ 0x0FD1, 0x0051, 0x0331, 0x00FA, 0x0FAF, 0x0004,
+ 0x0FD3, 0x0047, 0x032D, 0x0108, 0x0FAD, 0x0004,
+ 0x0FD6, 0x003D, 0x0328, 0x0116, 0x0FAB, 0x0004,
+ 0x0FD8, 0x0033, 0x0323, 0x0123, 0x0FAA, 0x0005,
+ 0x0FDB, 0x002A, 0x031D, 0x0131, 0x0FA8, 0x0005,
+ 0x0FDD, 0x0021, 0x0317, 0x013F, 0x0FA7, 0x0005,
+ 0x0FDF, 0x0018, 0x0311, 0x014D, 0x0FA5, 0x0006,
+ 0x0FE2, 0x0010, 0x030A, 0x015A, 0x0FA4, 0x0006,
+ 0x0FE4, 0x0008, 0x0302, 0x0169, 0x0FA3, 0x0006,
+ 0x0FE6, 0x0000, 0x02FB, 0x0177, 0x0FA2, 0x0006,
+ 0x0FE8, 0x0FF9, 0x02F3, 0x0185, 0x0FA1, 0x0006,
+ 0x0FEB, 0x0FF1, 0x02EA, 0x0193, 0x0FA1, 0x0006,
+ 0x0FED, 0x0FEB, 0x02E1, 0x01A1, 0x0FA0, 0x0006,
+ 0x0FEE, 0x0FE4, 0x02D8, 0x01B0, 0x0FA0, 0x0006,
+ 0x0FF0, 0x0FDE, 0x02CE, 0x01BE, 0x0FA0, 0x0006,
+ 0x0FF2, 0x0FD8, 0x02C5, 0x01CB, 0x0FA0, 0x0006,
+ 0x0FF4, 0x0FD3, 0x02BA, 0x01D8, 0x0FA1, 0x0006,
+ 0x0FF6, 0x0FCD, 0x02B0, 0x01E7, 0x0FA1, 0x0005,
+ 0x0FF7, 0x0FC8, 0x02A5, 0x01F5, 0x0FA2, 0x0005,
+ 0x0FF9, 0x0FC4, 0x029A, 0x0202, 0x0FA3, 0x0004,
+ 0x0FFA, 0x0FC0, 0x028E, 0x0210, 0x0FA4, 0x0004,
+ 0x0FFB, 0x0FBC, 0x0283, 0x021D, 0x0FA6, 0x0003,
+ 0x0FFD, 0x0FB8, 0x0276, 0x022A, 0x0FA8, 0x0003,
+ 0x0FFE, 0x0FB4, 0x026B, 0x0237, 0x0FAA, 0x0002,
+ 0x0FFF, 0x0FB1, 0x025E, 0x0245, 0x0FAC, 0x0001,
+ 0x0000, 0x0FAE, 0x0252, 0x0252, 0x0FAE, 0x0000,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 02-Apr-2024
+// <coeffDescrip> 6t_64p_LanczosEd_p_0.9_p_10qb_
+// <num_taps> 6
+// <num_phases> 64
+// <scale_ratio> input/output = 0.900000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_6tap_64p_ratio_0_90[198] = {
+ 0x0FD8, 0x0055, 0x03A7, 0x0054, 0x0FD8, 0x0000,
+ 0x0FDB, 0x0047, 0x03A7, 0x0063, 0x0FD4, 0x0000,
+ 0x0FDF, 0x003B, 0x03A5, 0x006F, 0x0FD1, 0x0001,
+ 0x0FE2, 0x002E, 0x03A3, 0x007E, 0x0FCD, 0x0002,
+ 0x0FE5, 0x0022, 0x03A0, 0x008D, 0x0FCA, 0x0002,
+ 0x0FE8, 0x0017, 0x039D, 0x009B, 0x0FC6, 0x0003,
+ 0x0FEB, 0x000C, 0x0398, 0x00AC, 0x0FC2, 0x0003,
+ 0x0FEE, 0x0001, 0x0394, 0x00BA, 0x0FBF, 0x0004,
+ 0x0FF1, 0x0FF7, 0x038E, 0x00CA, 0x0FBB, 0x0005,
+ 0x0FF4, 0x0FED, 0x0388, 0x00DA, 0x0FB8, 0x0005,
+ 0x0FF6, 0x0FE4, 0x0381, 0x00EB, 0x0FB4, 0x0006,
+ 0x0FF9, 0x0FDB, 0x037A, 0x00FA, 0x0FB1, 0x0007,
+ 0x0FFB, 0x0FD3, 0x0372, 0x010B, 0x0FAD, 0x0008,
+ 0x0FFD, 0x0FCB, 0x0369, 0x011D, 0x0FAA, 0x0008,
+ 0x0000, 0x0FC3, 0x0360, 0x012E, 0x0FA6, 0x0009,
+ 0x0002, 0x0FBC, 0x0356, 0x013F, 0x0FA3, 0x000A,
+ 0x0003, 0x0FB6, 0x034C, 0x0150, 0x0FA0, 0x000B,
+ 0x0005, 0x0FB0, 0x0341, 0x0162, 0x0F9D, 0x000B,
+ 0x0007, 0x0FAA, 0x0336, 0x0173, 0x0F9A, 0x000C,
+ 0x0008, 0x0FA5, 0x032A, 0x0185, 0x0F97, 0x000D,
+ 0x000A, 0x0FA0, 0x031E, 0x0197, 0x0F94, 0x000D,
+ 0x000B, 0x0F9B, 0x0311, 0x01A9, 0x0F92, 0x000E,
+ 0x000C, 0x0F97, 0x0303, 0x01BC, 0x0F8F, 0x000F,
+ 0x000D, 0x0F94, 0x02F6, 0x01CD, 0x0F8D, 0x000F,
+ 0x000E, 0x0F91, 0x02E8, 0x01DE, 0x0F8B, 0x0010,
+ 0x000F, 0x0F8E, 0x02D9, 0x01F1, 0x0F89, 0x0010,
+ 0x0010, 0x0F8B, 0x02CA, 0x0202, 0x0F88, 0x0011,
+ 0x0010, 0x0F89, 0x02BB, 0x0214, 0x0F87, 0x0011,
+ 0x0011, 0x0F87, 0x02AB, 0x0226, 0x0F86, 0x0011,
+ 0x0011, 0x0F86, 0x029C, 0x0236, 0x0F85, 0x0012,
+ 0x0011, 0x0F85, 0x028B, 0x0249, 0x0F84, 0x0012,
+ 0x0012, 0x0F84, 0x027B, 0x0259, 0x0F84, 0x0012,
+ 0x0012, 0x0F84, 0x026A, 0x026A, 0x0F84, 0x0012,
+};
+
+//========================================================
+// <using> gen_scaler_coeffs_cnf_file.m
+// <using> make_test_script.m
+// <date> 02-Apr-2024
+// <coeffDescrip> 6t_64p_LanczosEd_p_1_p_10qb_
+// <num_taps> 6
+// <num_phases> 64
+// <scale_ratio> input/output = 1.000000000000
+// <CoefType> LanczosEd
+// <CoefQuant> S1.10
+//========================================================
+static const uint16_t easf_filter_6tap_64p_ratio_1_00[198] = {
+ 0x0000, 0x0000, 0x0400, 0x0000, 0x0000, 0x0000,
+ 0x0003, 0x0FF3, 0x0400, 0x000D, 0x0FFD, 0x0000,
+ 0x0006, 0x0FE7, 0x03FE, 0x001C, 0x0FF9, 0x0000,
+ 0x0009, 0x0FDB, 0x03FC, 0x002B, 0x0FF5, 0x0000,
+ 0x000C, 0x0FD0, 0x03F9, 0x003A, 0x0FF1, 0x0000,
+ 0x000E, 0x0FC5, 0x03F5, 0x004A, 0x0FED, 0x0001,
+ 0x0011, 0x0FBB, 0x03F0, 0x005A, 0x0FE9, 0x0001,
+ 0x0013, 0x0FB2, 0x03EB, 0x006A, 0x0FE5, 0x0001,
+ 0x0015, 0x0FA9, 0x03E4, 0x007B, 0x0FE1, 0x0002,
+ 0x0017, 0x0FA1, 0x03DD, 0x008D, 0x0FDC, 0x0002,
+ 0x0018, 0x0F99, 0x03D4, 0x00A0, 0x0FD8, 0x0003,
+ 0x001A, 0x0F92, 0x03CB, 0x00B2, 0x0FD3, 0x0004,
+ 0x001B, 0x0F8C, 0x03C1, 0x00C6, 0x0FCE, 0x0004,
+ 0x001C, 0x0F86, 0x03B7, 0x00D9, 0x0FC9, 0x0005,
+ 0x001D, 0x0F80, 0x03AB, 0x00EE, 0x0FC4, 0x0006,
+ 0x001E, 0x0F7C, 0x039F, 0x0101, 0x0FBF, 0x0007,
+ 0x001F, 0x0F78, 0x0392, 0x0115, 0x0FBA, 0x0008,
+ 0x001F, 0x0F74, 0x0385, 0x012B, 0x0FB5, 0x0008,
+ 0x0020, 0x0F71, 0x0376, 0x0140, 0x0FB0, 0x0009,
+ 0x0020, 0x0F6E, 0x0367, 0x0155, 0x0FAB, 0x000B,
+ 0x0020, 0x0F6C, 0x0357, 0x016B, 0x0FA6, 0x000C,
+ 0x0020, 0x0F6A, 0x0347, 0x0180, 0x0FA2, 0x000D,
+ 0x0020, 0x0F69, 0x0336, 0x0196, 0x0F9D, 0x000E,
+ 0x0020, 0x0F69, 0x0325, 0x01AB, 0x0F98, 0x000F,
+ 0x001F, 0x0F68, 0x0313, 0x01C3, 0x0F93, 0x0010,
+ 0x001F, 0x0F69, 0x0300, 0x01D8, 0x0F8F, 0x0011,
+ 0x001E, 0x0F69, 0x02ED, 0x01EF, 0x0F8B, 0x0012,
+ 0x001D, 0x0F6A, 0x02D9, 0x0205, 0x0F87, 0x0014,
+ 0x001D, 0x0F6C, 0x02C5, 0x021A, 0x0F83, 0x0015,
+ 0x001C, 0x0F6E, 0x02B1, 0x0230, 0x0F7F, 0x0016,
+ 0x001B, 0x0F70, 0x029C, 0x0247, 0x0F7B, 0x0017,
+ 0x001A, 0x0F72, 0x0287, 0x025D, 0x0F78, 0x0018,
+ 0x0019, 0x0F75, 0x0272, 0x0272, 0x0F75, 0x0019,
+};
+
+/* Converted scaler coeff tables from S1.10 to S1.12 */
+static uint16_t easf_filter_3tap_64p_ratio_0_30_s1_12[99];
+static uint16_t easf_filter_3tap_64p_ratio_0_40_s1_12[99];
+static uint16_t easf_filter_3tap_64p_ratio_0_50_s1_12[99];
+static uint16_t easf_filter_3tap_64p_ratio_0_60_s1_12[99];
+static uint16_t easf_filter_3tap_64p_ratio_0_70_s1_12[99];
+static uint16_t easf_filter_3tap_64p_ratio_0_80_s1_12[99];
+static uint16_t easf_filter_3tap_64p_ratio_0_90_s1_12[99];
+static uint16_t easf_filter_3tap_64p_ratio_1_00_s1_12[99];
+static uint16_t easf_filter_4tap_64p_ratio_0_30_s1_12[132];
+static uint16_t easf_filter_4tap_64p_ratio_0_40_s1_12[132];
+static uint16_t easf_filter_4tap_64p_ratio_0_50_s1_12[132];
+static uint16_t easf_filter_4tap_64p_ratio_0_60_s1_12[132];
+static uint16_t easf_filter_4tap_64p_ratio_0_70_s1_12[132];
+static uint16_t easf_filter_4tap_64p_ratio_0_80_s1_12[132];
+static uint16_t easf_filter_4tap_64p_ratio_0_90_s1_12[132];
+static uint16_t easf_filter_4tap_64p_ratio_1_00_s1_12[132];
+static uint16_t easf_filter_6tap_64p_ratio_0_30_s1_12[198];
+static uint16_t easf_filter_6tap_64p_ratio_0_40_s1_12[198];
+static uint16_t easf_filter_6tap_64p_ratio_0_50_s1_12[198];
+static uint16_t easf_filter_6tap_64p_ratio_0_60_s1_12[198];
+static uint16_t easf_filter_6tap_64p_ratio_0_70_s1_12[198];
+static uint16_t easf_filter_6tap_64p_ratio_0_80_s1_12[198];
+static uint16_t easf_filter_6tap_64p_ratio_0_90_s1_12[198];
+static uint16_t easf_filter_6tap_64p_ratio_1_00_s1_12[198];
+
+struct scale_ratio_to_reg_value_lookup easf_v_bf3_mode_lookup[] = {
+ {3, 10, 0x0000},
+ {4, 10, 0x0000},
+ {5, 10, 0x0000},
+ {6, 10, 0x0000},
+ {7, 10, 0x0000},
+ {8, 10, 0x0000},
+ {9, 10, 0x0000},
+ {1, 1, 0x0000},
+ {-1, -1, 0x0002},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_h_bf3_mode_lookup[] = {
+ {3, 10, 0x0000},
+ {4, 10, 0x0000},
+ {5, 10, 0x0000},
+ {6, 10, 0x0000},
+ {7, 10, 0x0000},
+ {8, 10, 0x0000},
+ {9, 10, 0x0000},
+ {1, 1, 0x0000},
+ {-1, -1, 0x0002},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_reducer_gain6_6tap_lookup[] = {
+ {3, 10, 0x4100},
+ {4, 10, 0x4100},
+ {5, 10, 0x4100},
+ {6, 10, 0x4100},
+ {7, 10, 0x4100},
+ {8, 10, 0x4100},
+ {9, 10, 0x4100},
+ {1, 1, 0x4100},
+ {-1, -1, 0x4100},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_reducer_gain4_6tap_lookup[] = {
+ {3, 10, 0x4000},
+ {4, 10, 0x4000},
+ {5, 10, 0x4000},
+ {6, 10, 0x4000},
+ {7, 10, 0x4000},
+ {8, 10, 0x4000},
+ {9, 10, 0x4000},
+ {1, 1, 0x4000},
+ {-1, -1, 0x4000},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_gain_ring6_6tap_lookup[] = {
+ {3, 10, 0x0000},
+ {4, 10, 0x251F},
+ {5, 10, 0x291F},
+ {6, 10, 0xA51F},
+ {7, 10, 0xA51F},
+ {8, 10, 0xAA66},
+ {9, 10, 0xA51F},
+ {1, 1, 0xA640},
+ {-1, -1, 0xA640},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_gain_ring4_6tap_lookup[] = {
+ {3, 10, 0x0000},
+ {4, 10, 0x9600},
+ {5, 10, 0xA460},
+ {6, 10, 0xA8E0},
+ {7, 10, 0xAC00},
+ {8, 10, 0xAD20},
+ {9, 10, 0xAFC0},
+ {1, 1, 0xB058},
+ {-1, -1, 0xB058},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_reducer_gain6_4tap_lookup[] = {
+ {3, 10, 0x4100},
+ {4, 10, 0x4100},
+ {5, 10, 0x4100},
+ {6, 10, 0x4100},
+ {7, 10, 0x4100},
+ {8, 10, 0x4100},
+ {9, 10, 0x4100},
+ {1, 1, 0x4100},
+ {-1, -1, 0x4100},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_reducer_gain4_4tap_lookup[] = {
+ {3, 10, 0x4000},
+ {4, 10, 0x4000},
+ {5, 10, 0x4000},
+ {6, 10, 0x4000},
+ {7, 10, 0x4000},
+ {8, 10, 0x4000},
+ {9, 10, 0x4000},
+ {1, 1, 0x4000},
+ {-1, -1, 0x4000},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_gain_ring6_4tap_lookup[] = {
+ {3, 10, 0x0000},
+ {4, 10, 0x0000},
+ {5, 10, 0x0000},
+ {6, 10, 0x0000},
+ {7, 10, 0x0000},
+ {8, 10, 0x0000},
+ {9, 10, 0x0000},
+ {1, 1, 0x0000},
+ {-1, -1, 0x0000},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_gain_ring4_4tap_lookup[] = {
+ {3, 10, 0x0000},
+ {4, 10, 0x0000},
+ {5, 10, 0x0000},
+ {6, 10, 0x9900},
+ {7, 10, 0xA100},
+ {8, 10, 0xA8C0},
+ {9, 10, 0xAB20},
+ {1, 1, 0xAC00},
+ {-1, -1, 0xAC00},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_3tap_dntilt_uptilt_offset_lookup[] = {
+ {3, 10, 0x0000},
+ {4, 10, 0x0000},
+ {5, 10, 0x0000},
+ {6, 10, 0x0000},
+ {7, 10, 0x0000},
+ {8, 10, 0x4100},
+ {9, 10, 0x9F00},
+ {1, 1, 0xA4C0},
+ {-1, -1, 0xA8D8},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt_maxval_lookup[] = {
+ {3, 10, 0x0000},
+ {4, 10, 0x0000},
+ {5, 10, 0x0000},
+ {6, 10, 0x0000},
+ {7, 10, 0x0000},
+ {8, 10, 0x4000},
+ {9, 10, 0x24FE},
+ {1, 1, 0x2D64},
+ {-1, -1, 0x3ADB},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_3tap_dntilt_slope_lookup[] = {
+ {3, 10, 0x3800},
+ {4, 10, 0x3800},
+ {5, 10, 0x3800},
+ {6, 10, 0x3800},
+ {7, 10, 0x3800},
+ {8, 10, 0x3886},
+ {9, 10, 0x3940},
+ {1, 1, 0x3A4E},
+ {-1, -1, 0x3B66},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt1_slope_lookup[] = {
+ {3, 10, 0x3800},
+ {4, 10, 0x3800},
+ {5, 10, 0x3800},
+ {6, 10, 0x3800},
+ {7, 10, 0x3800},
+ {8, 10, 0x36F4},
+ {9, 10, 0x359C},
+ {1, 1, 0x3360},
+ {-1, -1, 0x2F20},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt2_slope_lookup[] = {
+ {3, 10, 0x0000},
+ {4, 10, 0x0000},
+ {5, 10, 0x0000},
+ {6, 10, 0x0000},
+ {7, 10, 0x0000},
+ {8, 10, 0x0000},
+ {9, 10, 0x359C},
+ {1, 1, 0x31F0},
+ {-1, -1, 0x1F00},
+};
+
+struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt2_offset_lookup[] = {
+ {3, 10, 0x0000},
+ {4, 10, 0x0000},
+ {5, 10, 0x0000},
+ {6, 10, 0x0000},
+ {7, 10, 0x0000},
+ {8, 10, 0x0000},
+ {9, 10, 0x9F00},
+ {1, 1, 0xA400},
+ {-1, -1, 0x9E00},
+};
+
+void spl_init_easf_filter_coeffs(void)
+{
+ convert_filter_s1_10_to_s1_12(easf_filter_3tap_64p_ratio_0_30,
+ easf_filter_3tap_64p_ratio_0_30_s1_12, 3);
+ convert_filter_s1_10_to_s1_12(easf_filter_3tap_64p_ratio_0_40,
+ easf_filter_3tap_64p_ratio_0_40_s1_12, 3);
+ convert_filter_s1_10_to_s1_12(easf_filter_3tap_64p_ratio_0_50,
+ easf_filter_3tap_64p_ratio_0_50_s1_12, 3);
+ convert_filter_s1_10_to_s1_12(easf_filter_3tap_64p_ratio_0_60,
+ easf_filter_3tap_64p_ratio_0_60_s1_12, 3);
+ convert_filter_s1_10_to_s1_12(easf_filter_3tap_64p_ratio_0_70,
+ easf_filter_3tap_64p_ratio_0_70_s1_12, 3);
+ convert_filter_s1_10_to_s1_12(easf_filter_3tap_64p_ratio_0_80,
+ easf_filter_3tap_64p_ratio_0_80_s1_12, 3);
+ convert_filter_s1_10_to_s1_12(easf_filter_3tap_64p_ratio_0_90,
+ easf_filter_3tap_64p_ratio_0_90_s1_12, 3);
+ convert_filter_s1_10_to_s1_12(easf_filter_3tap_64p_ratio_1_00,
+ easf_filter_3tap_64p_ratio_1_00_s1_12, 3);
+
+ convert_filter_s1_10_to_s1_12(easf_filter_4tap_64p_ratio_0_30,
+ easf_filter_4tap_64p_ratio_0_30_s1_12, 4);
+ convert_filter_s1_10_to_s1_12(easf_filter_4tap_64p_ratio_0_40,
+ easf_filter_4tap_64p_ratio_0_40_s1_12, 4);
+ convert_filter_s1_10_to_s1_12(easf_filter_4tap_64p_ratio_0_50,
+ easf_filter_4tap_64p_ratio_0_50_s1_12, 4);
+ convert_filter_s1_10_to_s1_12(easf_filter_4tap_64p_ratio_0_60,
+ easf_filter_4tap_64p_ratio_0_60_s1_12, 4);
+ convert_filter_s1_10_to_s1_12(easf_filter_4tap_64p_ratio_0_70,
+ easf_filter_4tap_64p_ratio_0_70_s1_12, 4);
+ convert_filter_s1_10_to_s1_12(easf_filter_4tap_64p_ratio_0_80,
+ easf_filter_4tap_64p_ratio_0_80_s1_12, 4);
+ convert_filter_s1_10_to_s1_12(easf_filter_4tap_64p_ratio_0_90,
+ easf_filter_4tap_64p_ratio_0_90_s1_12, 4);
+ convert_filter_s1_10_to_s1_12(easf_filter_4tap_64p_ratio_1_00,
+ easf_filter_4tap_64p_ratio_1_00_s1_12, 4);
+
+ convert_filter_s1_10_to_s1_12(easf_filter_6tap_64p_ratio_0_30,
+ easf_filter_6tap_64p_ratio_0_30_s1_12, 6);
+ convert_filter_s1_10_to_s1_12(easf_filter_6tap_64p_ratio_0_40,
+ easf_filter_6tap_64p_ratio_0_40_s1_12, 6);
+ convert_filter_s1_10_to_s1_12(easf_filter_6tap_64p_ratio_0_50,
+ easf_filter_6tap_64p_ratio_0_50_s1_12, 6);
+ convert_filter_s1_10_to_s1_12(easf_filter_6tap_64p_ratio_0_60,
+ easf_filter_6tap_64p_ratio_0_60_s1_12, 6);
+ convert_filter_s1_10_to_s1_12(easf_filter_6tap_64p_ratio_0_70,
+ easf_filter_6tap_64p_ratio_0_70_s1_12, 6);
+ convert_filter_s1_10_to_s1_12(easf_filter_6tap_64p_ratio_0_80,
+ easf_filter_6tap_64p_ratio_0_80_s1_12, 6);
+ convert_filter_s1_10_to_s1_12(easf_filter_6tap_64p_ratio_0_90,
+ easf_filter_6tap_64p_ratio_0_90_s1_12, 6);
+ convert_filter_s1_10_to_s1_12(easf_filter_6tap_64p_ratio_1_00,
+ easf_filter_6tap_64p_ratio_1_00_s1_12, 6);
+}
+
+uint16_t *spl_get_easf_filter_3tap_64p(struct spl_fixed31_32 ratio)
+{
+ if (ratio.value < spl_fixpt_from_fraction(3, 10).value)
+ return easf_filter_3tap_64p_ratio_0_30_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(4, 10).value)
+ return easf_filter_3tap_64p_ratio_0_40_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(5, 10).value)
+ return easf_filter_3tap_64p_ratio_0_50_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(6, 10).value)
+ return easf_filter_3tap_64p_ratio_0_60_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(7, 10).value)
+ return easf_filter_3tap_64p_ratio_0_70_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(8, 10).value)
+ return easf_filter_3tap_64p_ratio_0_80_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(9, 10).value)
+ return easf_filter_3tap_64p_ratio_0_90_s1_12;
+ else
+ return easf_filter_3tap_64p_ratio_1_00_s1_12;
+}
+
+uint16_t *spl_get_easf_filter_4tap_64p(struct spl_fixed31_32 ratio)
+{
+ if (ratio.value < spl_fixpt_from_fraction(3, 10).value)
+ return easf_filter_4tap_64p_ratio_0_30_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(4, 10).value)
+ return easf_filter_4tap_64p_ratio_0_40_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(5, 10).value)
+ return easf_filter_4tap_64p_ratio_0_50_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(6, 10).value)
+ return easf_filter_4tap_64p_ratio_0_60_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(7, 10).value)
+ return easf_filter_4tap_64p_ratio_0_70_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(8, 10).value)
+ return easf_filter_4tap_64p_ratio_0_80_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(9, 10).value)
+ return easf_filter_4tap_64p_ratio_0_90_s1_12;
+ else
+ return easf_filter_4tap_64p_ratio_1_00_s1_12;
+}
+
+uint16_t *spl_get_easf_filter_6tap_64p(struct spl_fixed31_32 ratio)
+{
+ if (ratio.value < spl_fixpt_from_fraction(3, 10).value)
+ return easf_filter_6tap_64p_ratio_0_30_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(4, 10).value)
+ return easf_filter_6tap_64p_ratio_0_40_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(5, 10).value)
+ return easf_filter_6tap_64p_ratio_0_50_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(6, 10).value)
+ return easf_filter_6tap_64p_ratio_0_60_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(7, 10).value)
+ return easf_filter_6tap_64p_ratio_0_70_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(8, 10).value)
+ return easf_filter_6tap_64p_ratio_0_80_s1_12;
+ else if (ratio.value < spl_fixpt_from_fraction(9, 10).value)
+ return easf_filter_6tap_64p_ratio_0_90_s1_12;
+ else
+ return easf_filter_6tap_64p_ratio_1_00_s1_12;
+}
+
+uint16_t *spl_dscl_get_easf_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio)
+{
+ if (taps == 6)
+ return spl_get_easf_filter_6tap_64p(ratio);
+ else if (taps == 4)
+ return spl_get_easf_filter_4tap_64p(ratio);
+ else if (taps == 3)
+ return spl_get_easf_filter_3tap_64p(ratio);
+ else {
+ /* should never happen, bug */
+ SPL_BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+}
+
+void spl_set_filters_data(struct dscl_prog_data *dscl_prog_data,
+ const struct spl_scaler_data *data, bool enable_easf_v,
+ bool enable_easf_h)
+{
+ /*
+ * Old coefficients calculated scaling ratio = input / output
+ * New coefficients are calculated based on = output / input
+ */
+ if (enable_easf_h) {
+ dscl_prog_data->filter_h = spl_dscl_get_easf_filter_coeffs_64p(
+ data->taps.h_taps, data->recip_ratios.horz);
+
+ dscl_prog_data->filter_h_c = spl_dscl_get_easf_filter_coeffs_64p(
+ data->taps.h_taps_c, data->recip_ratios.horz_c);
+ } else {
+ dscl_prog_data->filter_h = spl_dscl_get_filter_coeffs_64p(
+ data->taps.h_taps, data->ratios.horz);
+
+ dscl_prog_data->filter_h_c = spl_dscl_get_filter_coeffs_64p(
+ data->taps.h_taps_c, data->ratios.horz_c);
+ }
+ if (enable_easf_v) {
+ dscl_prog_data->filter_v = spl_dscl_get_easf_filter_coeffs_64p(
+ data->taps.v_taps, data->recip_ratios.vert);
+
+ dscl_prog_data->filter_v_c = spl_dscl_get_easf_filter_coeffs_64p(
+ data->taps.v_taps_c, data->recip_ratios.vert_c);
+ } else {
+ dscl_prog_data->filter_v = spl_dscl_get_filter_coeffs_64p(
+ data->taps.v_taps, data->ratios.vert);
+
+ dscl_prog_data->filter_v_c = spl_dscl_get_filter_coeffs_64p(
+ data->taps.v_taps_c, data->ratios.vert_c);
+ }
+}
+
+static uint32_t spl_easf_get_scale_ratio_to_reg_value(struct spl_fixed31_32 ratio,
+ struct scale_ratio_to_reg_value_lookup *lookup_table_base_ptr,
+ unsigned int num_entries)
+{
+ unsigned int count = 0;
+ uint32_t value = 0;
+ struct scale_ratio_to_reg_value_lookup *lookup_table_index_ptr;
+
+ lookup_table_index_ptr = (lookup_table_base_ptr + num_entries - 1);
+ value = lookup_table_index_ptr->reg_value;
+
+ while (count < num_entries) {
+
+ lookup_table_index_ptr = (lookup_table_base_ptr + count);
+ if (lookup_table_index_ptr->numer < 0)
+ break;
+
+ if (ratio.value < spl_fixpt_from_fraction(
+ lookup_table_index_ptr->numer,
+ lookup_table_index_ptr->denom).value) {
+ value = lookup_table_index_ptr->reg_value;
+ break;
+ }
+
+ count++;
+ }
+ return value;
+}
+uint32_t spl_get_v_bf3_mode(struct spl_fixed31_32 ratio)
+{
+ uint32_t value;
+ unsigned int num_entries = sizeof(easf_v_bf3_mode_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_v_bf3_mode_lookup, num_entries);
+ return value;
+}
+uint32_t spl_get_h_bf3_mode(struct spl_fixed31_32 ratio)
+{
+ uint32_t value;
+ unsigned int num_entries = sizeof(easf_h_bf3_mode_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_h_bf3_mode_lookup, num_entries);
+ return value;
+}
+uint32_t spl_get_reducer_gain6(int taps, struct spl_fixed31_32 ratio)
+{
+ uint32_t value;
+ unsigned int num_entries;
+
+ if (taps == 4) {
+ num_entries = sizeof(easf_reducer_gain6_4tap_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_reducer_gain6_4tap_lookup, num_entries);
+ } else if (taps == 6) {
+ num_entries = sizeof(easf_reducer_gain6_6tap_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_reducer_gain6_6tap_lookup, num_entries);
+ } else
+ value = 0;
+ return value;
+}
+uint32_t spl_get_reducer_gain4(int taps, struct spl_fixed31_32 ratio)
+{
+ uint32_t value;
+ unsigned int num_entries;
+
+ if (taps == 4) {
+ num_entries = sizeof(easf_reducer_gain4_4tap_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_reducer_gain4_4tap_lookup, num_entries);
+ } else if (taps == 6) {
+ num_entries = sizeof(easf_reducer_gain4_6tap_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_reducer_gain4_6tap_lookup, num_entries);
+ } else
+ value = 0;
+ return value;
+}
+uint32_t spl_get_gainRing6(int taps, struct spl_fixed31_32 ratio)
+{
+ uint32_t value;
+ unsigned int num_entries;
+
+ if (taps == 4) {
+ num_entries = sizeof(easf_gain_ring6_4tap_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_gain_ring6_4tap_lookup, num_entries);
+ } else if (taps == 6) {
+ num_entries = sizeof(easf_gain_ring6_6tap_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_gain_ring6_6tap_lookup, num_entries);
+ } else
+ value = 0;
+ return value;
+}
+uint32_t spl_get_gainRing4(int taps, struct spl_fixed31_32 ratio)
+{
+ uint32_t value;
+ unsigned int num_entries;
+
+ if (taps == 4) {
+ num_entries = sizeof(easf_gain_ring4_4tap_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_gain_ring4_4tap_lookup, num_entries);
+ } else if (taps == 6) {
+ num_entries = sizeof(easf_gain_ring4_6tap_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_gain_ring4_6tap_lookup, num_entries);
+ } else
+ value = 0;
+ return value;
+}
+uint32_t spl_get_3tap_dntilt_uptilt_offset(int taps, struct spl_fixed31_32 ratio)
+{
+ uint32_t value;
+ unsigned int num_entries;
+
+ if (taps == 3) {
+ num_entries = sizeof(easf_3tap_dntilt_uptilt_offset_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_3tap_dntilt_uptilt_offset_lookup, num_entries);
+ } else
+ value = 0;
+ return value;
+}
+uint32_t spl_get_3tap_uptilt_maxval(int taps, struct spl_fixed31_32 ratio)
+{
+ uint32_t value;
+ unsigned int num_entries;
+
+ if (taps == 3) {
+ num_entries = sizeof(easf_3tap_uptilt_maxval_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_3tap_uptilt_maxval_lookup, num_entries);
+ } else
+ value = 0;
+ return value;
+}
+uint32_t spl_get_3tap_dntilt_slope(int taps, struct spl_fixed31_32 ratio)
+{
+ uint32_t value;
+ unsigned int num_entries;
+
+ if (taps == 3) {
+ num_entries = sizeof(easf_3tap_dntilt_slope_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_3tap_dntilt_slope_lookup, num_entries);
+ } else
+ value = 0;
+ return value;
+}
+uint32_t spl_get_3tap_uptilt1_slope(int taps, struct spl_fixed31_32 ratio)
+{
+ uint32_t value;
+ unsigned int num_entries;
+
+ if (taps == 3) {
+ num_entries = sizeof(easf_3tap_uptilt1_slope_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_3tap_uptilt1_slope_lookup, num_entries);
+ } else
+ value = 0;
+ return value;
+}
+uint32_t spl_get_3tap_uptilt2_slope(int taps, struct spl_fixed31_32 ratio)
+{
+ uint32_t value;
+ unsigned int num_entries;
+
+ if (taps == 3) {
+ num_entries = sizeof(easf_3tap_uptilt2_slope_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_3tap_uptilt2_slope_lookup, num_entries);
+ } else
+ value = 0;
+ return value;
+}
+uint32_t spl_get_3tap_uptilt2_offset(int taps, struct spl_fixed31_32 ratio)
+{
+ uint32_t value;
+ unsigned int num_entries;
+
+ if (taps == 3) {
+ num_entries = sizeof(easf_3tap_uptilt2_offset_lookup) /
+ sizeof(struct scale_ratio_to_reg_value_lookup);
+ value = spl_easf_get_scale_ratio_to_reg_value(ratio,
+ easf_3tap_uptilt2_offset_lookup, num_entries);
+ } else
+ value = 0;
+ return value;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.h b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.h
new file mode 100644
index 000000000000..8bb2b8108e38
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: MIT */
+
+/* Copyright 2024 Advanced Micro Devices, Inc. */
+
+#ifndef __DC_SPL_SCL_EASF_FILTERS_H__
+#define __DC_SPL_SCL_EASF_FILTERS_H__
+
+#include "dc_spl_types.h"
+
+struct scale_ratio_to_reg_value_lookup {
+ int numer;
+ int denom;
+ const uint32_t reg_value;
+};
+
+void spl_init_easf_filter_coeffs(void);
+uint16_t *spl_get_easf_filter_3tap_64p(struct spl_fixed31_32 ratio);
+uint16_t *spl_get_easf_filter_4tap_64p(struct spl_fixed31_32 ratio);
+uint16_t *spl_get_easf_filter_6tap_64p(struct spl_fixed31_32 ratio);
+uint16_t *spl_dscl_get_easf_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio);
+void spl_set_filters_data(struct dscl_prog_data *dscl_prog_data,
+ const struct spl_scaler_data *data, bool enable_easf_v,
+ bool enable_easf_h);
+
+uint32_t spl_get_v_bf3_mode(struct spl_fixed31_32 ratio);
+uint32_t spl_get_h_bf3_mode(struct spl_fixed31_32 ratio);
+uint32_t spl_get_reducer_gain6(int taps, struct spl_fixed31_32 ratio);
+uint32_t spl_get_reducer_gain4(int taps, struct spl_fixed31_32 ratio);
+uint32_t spl_get_gainRing6(int taps, struct spl_fixed31_32 ratio);
+uint32_t spl_get_gainRing4(int taps, struct spl_fixed31_32 ratio);
+uint32_t spl_get_3tap_dntilt_uptilt_offset(int taps, struct spl_fixed31_32 ratio);
+uint32_t spl_get_3tap_uptilt_maxval(int taps, struct spl_fixed31_32 ratio);
+uint32_t spl_get_3tap_dntilt_slope(int taps, struct spl_fixed31_32 ratio);
+uint32_t spl_get_3tap_uptilt1_slope(int taps, struct spl_fixed31_32 ratio);
+uint32_t spl_get_3tap_uptilt2_slope(int taps, struct spl_fixed31_32 ratio);
+uint32_t spl_get_3tap_uptilt2_offset(int taps, struct spl_fixed31_32 ratio);
+
+#endif /* __DC_SPL_SCL_EASF_FILTERS_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.c b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.c
index c174b2e8a150..b02c7b0b262b 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.c
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.c
@@ -2,7 +2,7 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-#include "dc_spl_types.h"
+#include "spl_debug.h"
#include "dc_spl_scl_filters.h"
//=========================================
// <num_taps> = 2
@@ -1318,97 +1318,97 @@ static const uint16_t filter_8tap_64p_183[264] = {
0x3FD4, 0x3F84, 0x0214, 0x0694, 0x0694, 0x0214, 0x3F84, 0x3FD4
};
-const uint16_t *spl_get_filter_3tap_16p(struct fixed31_32 ratio)
+const uint16_t *spl_get_filter_3tap_16p(struct spl_fixed31_32 ratio)
{
- if (ratio.value < dc_fixpt_one.value)
+ if (ratio.value < spl_fixpt_one.value)
return filter_3tap_16p_upscale;
- else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
return filter_3tap_16p_116;
- else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
return filter_3tap_16p_149;
else
return filter_3tap_16p_183;
}
-const uint16_t *spl_get_filter_3tap_64p(struct fixed31_32 ratio)
+const uint16_t *spl_get_filter_3tap_64p(struct spl_fixed31_32 ratio)
{
- if (ratio.value < dc_fixpt_one.value)
+ if (ratio.value < spl_fixpt_one.value)
return filter_3tap_64p_upscale;
- else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
return filter_3tap_64p_116;
- else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
return filter_3tap_64p_149;
else
return filter_3tap_64p_183;
}
-const uint16_t *spl_get_filter_4tap_16p(struct fixed31_32 ratio)
+const uint16_t *spl_get_filter_4tap_16p(struct spl_fixed31_32 ratio)
{
- if (ratio.value < dc_fixpt_one.value)
+ if (ratio.value < spl_fixpt_one.value)
return filter_4tap_16p_upscale;
- else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
return filter_4tap_16p_116;
- else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
return filter_4tap_16p_149;
else
return filter_4tap_16p_183;
}
-const uint16_t *spl_get_filter_4tap_64p(struct fixed31_32 ratio)
+const uint16_t *spl_get_filter_4tap_64p(struct spl_fixed31_32 ratio)
{
- if (ratio.value < dc_fixpt_one.value)
+ if (ratio.value < spl_fixpt_one.value)
return filter_4tap_64p_upscale;
- else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
return filter_4tap_64p_116;
- else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
return filter_4tap_64p_149;
else
return filter_4tap_64p_183;
}
-const uint16_t *spl_get_filter_5tap_64p(struct fixed31_32 ratio)
+const uint16_t *spl_get_filter_5tap_64p(struct spl_fixed31_32 ratio)
{
- if (ratio.value < dc_fixpt_one.value)
+ if (ratio.value < spl_fixpt_one.value)
return filter_5tap_64p_upscale;
- else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
return filter_5tap_64p_116;
- else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
return filter_5tap_64p_149;
else
return filter_5tap_64p_183;
}
-const uint16_t *spl_get_filter_6tap_64p(struct fixed31_32 ratio)
+const uint16_t *spl_get_filter_6tap_64p(struct spl_fixed31_32 ratio)
{
- if (ratio.value < dc_fixpt_one.value)
+ if (ratio.value < spl_fixpt_one.value)
return filter_6tap_64p_upscale;
- else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
return filter_6tap_64p_116;
- else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
return filter_6tap_64p_149;
else
return filter_6tap_64p_183;
}
-const uint16_t *spl_get_filter_7tap_64p(struct fixed31_32 ratio)
+const uint16_t *spl_get_filter_7tap_64p(struct spl_fixed31_32 ratio)
{
- if (ratio.value < dc_fixpt_one.value)
+ if (ratio.value < spl_fixpt_one.value)
return filter_7tap_64p_upscale;
- else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
return filter_7tap_64p_116;
- else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
return filter_7tap_64p_149;
else
return filter_7tap_64p_183;
}
-const uint16_t *spl_get_filter_8tap_64p(struct fixed31_32 ratio)
+const uint16_t *spl_get_filter_8tap_64p(struct spl_fixed31_32 ratio)
{
- if (ratio.value < dc_fixpt_one.value)
+ if (ratio.value < spl_fixpt_one.value)
return filter_8tap_64p_upscale;
- else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
return filter_8tap_64p_116;
- else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
+ else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
return filter_8tap_64p_149;
else
return filter_8tap_64p_183;
@@ -1423,3 +1423,29 @@ const uint16_t *spl_get_filter_2tap_64p(void)
{
return filter_2tap_64p;
}
+
+const uint16_t *spl_dscl_get_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio)
+{
+ if (taps == 8)
+ return spl_get_filter_8tap_64p(ratio);
+ else if (taps == 7)
+ return spl_get_filter_7tap_64p(ratio);
+ else if (taps == 6)
+ return spl_get_filter_6tap_64p(ratio);
+ else if (taps == 5)
+ return spl_get_filter_5tap_64p(ratio);
+ else if (taps == 4)
+ return spl_get_filter_4tap_64p(ratio);
+ else if (taps == 3)
+ return spl_get_filter_3tap_64p(ratio);
+ else if (taps == 2)
+ return spl_get_filter_2tap_64p();
+ else if (taps == 1)
+ return NULL;
+ else {
+ /* should never happen, bug */
+ SPL_BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.h b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.h
index 6d96aca53b24..48202bc4f81e 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.h
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.h
@@ -7,53 +7,16 @@
#include "dc_spl_types.h"
-const uint16_t *spl_get_filter_3tap_16p(struct fixed31_32 ratio);
-const uint16_t *spl_get_filter_3tap_64p(struct fixed31_32 ratio);
-const uint16_t *spl_get_filter_4tap_16p(struct fixed31_32 ratio);
-const uint16_t *spl_get_filter_4tap_64p(struct fixed31_32 ratio);
-const uint16_t *spl_get_filter_5tap_64p(struct fixed31_32 ratio);
-const uint16_t *spl_get_filter_6tap_64p(struct fixed31_32 ratio);
-const uint16_t *spl_get_filter_7tap_64p(struct fixed31_32 ratio);
-const uint16_t *spl_get_filter_8tap_64p(struct fixed31_32 ratio);
+const uint16_t *spl_get_filter_3tap_16p(struct spl_fixed31_32 ratio);
+const uint16_t *spl_get_filter_3tap_64p(struct spl_fixed31_32 ratio);
+const uint16_t *spl_get_filter_4tap_16p(struct spl_fixed31_32 ratio);
+const uint16_t *spl_get_filter_4tap_64p(struct spl_fixed31_32 ratio);
+const uint16_t *spl_get_filter_5tap_64p(struct spl_fixed31_32 ratio);
+const uint16_t *spl_get_filter_6tap_64p(struct spl_fixed31_32 ratio);
+const uint16_t *spl_get_filter_7tap_64p(struct spl_fixed31_32 ratio);
+const uint16_t *spl_get_filter_8tap_64p(struct spl_fixed31_32 ratio);
const uint16_t *spl_get_filter_2tap_16p(void);
const uint16_t *spl_get_filter_2tap_64p(void);
-const uint16_t *spl_get_filter_3tap_16p_upscale(void);
-const uint16_t *spl_get_filter_3tap_16p_116(void);
-const uint16_t *spl_get_filter_3tap_16p_149(void);
-const uint16_t *spl_get_filter_3tap_16p_183(void);
+const uint16_t *spl_dscl_get_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio);
-const uint16_t *spl_get_filter_4tap_16p_upscale(void);
-const uint16_t *spl_get_filter_4tap_16p_116(void);
-const uint16_t *spl_get_filter_4tap_16p_149(void);
-const uint16_t *spl_get_filter_4tap_16p_183(void);
-
-const uint16_t *spl_get_filter_3tap_64p_upscale(void);
-const uint16_t *spl_get_filter_3tap_64p_116(void);
-const uint16_t *spl_get_filter_3tap_64p_149(void);
-const uint16_t *spl_get_filter_3tap_64p_183(void);
-
-const uint16_t *spl_get_filter_4tap_64p_upscale(void);
-const uint16_t *spl_get_filter_4tap_64p_116(void);
-const uint16_t *spl_get_filter_4tap_64p_149(void);
-const uint16_t *spl_get_filter_4tap_64p_183(void);
-
-const uint16_t *spl_get_filter_5tap_64p_upscale(void);
-const uint16_t *spl_get_filter_5tap_64p_116(void);
-const uint16_t *spl_get_filter_5tap_64p_149(void);
-const uint16_t *spl_get_filter_5tap_64p_183(void);
-
-const uint16_t *spl_get_filter_6tap_64p_upscale(void);
-const uint16_t *spl_get_filter_6tap_64p_116(void);
-const uint16_t *spl_get_filter_6tap_64p_149(void);
-const uint16_t *spl_get_filter_6tap_64p_183(void);
-
-const uint16_t *spl_get_filter_7tap_64p_upscale(void);
-const uint16_t *spl_get_filter_7tap_64p_116(void);
-const uint16_t *spl_get_filter_7tap_64p_149(void);
-const uint16_t *spl_get_filter_7tap_64p_183(void);
-
-const uint16_t *spl_get_filter_8tap_64p_upscale(void);
-const uint16_t *spl_get_filter_8tap_64p_116(void);
-const uint16_t *spl_get_filter_8tap_64p_149(void);
-const uint16_t *spl_get_filter_8tap_64p_183(void);
#endif /* __DC_SPL_SCL_FILTERS_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h
index 201201d3f55b..85b19ebe2c57 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h
@@ -2,30 +2,15 @@
//
// Copyright 2024 Advanced Micro Devices, Inc.
-#include "os_types.h"
-#include "dc_hw_types.h"
-#ifndef ASSERT
-#define ASSERT(_bool) (void *)0
-#endif
-#include "include/fixed31_32.h" // fixed31_32 and related functions
#ifndef __DC_SPL_TYPES_H__
#define __DC_SPL_TYPES_H__
-enum lb_memory_config {
- /* Enable all 3 pieces of memory */
- LB_MEMORY_CONFIG_0 = 0,
-
- /* Enable only the first piece of memory */
- LB_MEMORY_CONFIG_1 = 1,
-
- /* Enable only the second piece of memory */
- LB_MEMORY_CONFIG_2 = 2,
-
- /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the
- * last piece of chroma memory used for the luma storage
- */
- LB_MEMORY_CONFIG_3 = 3
-};
+#include "spl_os_types.h" // swap
+#ifndef SPL_ASSERT
+#define SPL_ASSERT(_bool) ((void *)0)
+#endif
+#include "spl_fixpt31_32.h" // fixed31_32 and related functions
+#include "spl_custom_float.h" // custom float and related functions
struct spl_size {
uint32_t width;
@@ -39,16 +24,16 @@ struct spl_rect {
};
struct spl_ratios {
- struct fixed31_32 horz;
- struct fixed31_32 vert;
- struct fixed31_32 horz_c;
- struct fixed31_32 vert_c;
+ struct spl_fixed31_32 horz;
+ struct spl_fixed31_32 vert;
+ struct spl_fixed31_32 horz_c;
+ struct spl_fixed31_32 vert_c;
};
struct spl_inits {
- struct fixed31_32 h;
- struct fixed31_32 h_c;
- struct fixed31_32 v;
- struct fixed31_32 v_c;
+ struct spl_fixed31_32 h;
+ struct spl_fixed31_32 h_c;
+ struct spl_fixed31_32 v;
+ struct spl_fixed31_32 v_c;
};
struct spl_taps {
@@ -81,6 +66,8 @@ enum spl_pixel_format {
SPL_PIXEL_FORMAT_420BPP10,
/*end of pixel format definition*/
SPL_PIXEL_FORMAT_INVALID,
+ SPL_PIXEL_FORMAT_422BPP8,
+ SPL_PIXEL_FORMAT_422BPP10,
SPL_PIXEL_FORMAT_GRPH_BEGIN = SPL_PIXEL_FORMAT_INDEX8,
SPL_PIXEL_FORMAT_GRPH_END = SPL_PIXEL_FORMAT_FP16,
SPL_PIXEL_FORMAT_VIDEO_BEGIN = SPL_PIXEL_FORMAT_420BPP8,
@@ -88,6 +75,22 @@ enum spl_pixel_format {
SPL_PIXEL_FORMAT_UNKNOWN
};
+enum lb_memory_config {
+ /* Enable all 3 pieces of memory */
+ LB_MEMORY_CONFIG_0 = 0,
+
+ /* Enable only the first piece of memory */
+ LB_MEMORY_CONFIG_1 = 1,
+
+ /* Enable only the second piece of memory */
+ LB_MEMORY_CONFIG_2 = 2,
+
+ /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the
+ * last piece of chroma memory used for the luma storage
+ */
+ LB_MEMORY_CONFIG_3 = 3
+};
+
/* Rotation angle */
enum spl_rotation_angle {
SPL_ROTATION_ANGLE_0 = 0,
@@ -120,6 +123,13 @@ enum spl_color_space {
SPL_COLOR_SPACE_YCBCR709_BLACK,
};
+enum chroma_cositing {
+ CHROMA_COSITING_NONE,
+ CHROMA_COSITING_LEFT,
+ CHROMA_COSITING_TOPLEFT,
+ CHROMA_COSITING_COUNT
+};
+
// Scratch space for calculating scaler params
struct spl_scaler_data {
int h_active;
@@ -129,6 +139,7 @@ struct spl_scaler_data {
struct spl_rect viewport_c;
struct spl_rect recout;
struct spl_ratios ratios;
+ struct spl_ratios recip_ratios;
struct spl_inits inits;
};
@@ -396,13 +407,19 @@ struct dscl_prog_data {
/* blur and scale filter */
const uint16_t *filter_blur_scale_v;
const uint16_t *filter_blur_scale_h;
+ int sharpness_level; /* Track sharpness level */
};
/* SPL input and output definitions */
-// SPL outputs struct
-struct spl_out {
+// SPL scratch struct
+struct spl_scratch {
// Pack all SPL outputs in scl_data
struct spl_scaler_data scl_data;
+};
+
+/* SPL input and output definitions */
+// SPL outputs struct
+struct spl_out {
// Pack all output need to program hw registers
struct dscl_prog_data *dscl_prog_data;
};
@@ -444,14 +461,26 @@ struct basic_out {
bool alpha_en;
bool use_two_pixels_per_container;
};
-enum explicit_sharpness {
- SHARPNESS_LOW = 0,
- SHARPNESS_MID,
- SHARPNESS_HIGH
-};
-struct adaptive_sharpness {
+enum sharpness_setting {
+ SHARPNESS_HW_OFF = 0,
+ SHARPNESS_ZERO,
+ SHARPNESS_CUSTOM
+};
+struct spl_sharpness_range {
+ int sdr_rgb_min;
+ int sdr_rgb_max;
+ int sdr_rgb_mid;
+ int sdr_yuv_min;
+ int sdr_yuv_max;
+ int sdr_yuv_mid;
+ int hdr_rgb_min;
+ int hdr_rgb_max;
+ int hdr_rgb_mid;
+};
+struct adaptive_sharpness {
bool enable;
- enum explicit_sharpness sharpness;
+ int sharpness_level;
+ struct spl_sharpness_range sharpness_range;
};
enum linear_light_scaling { // convert it in translation logic
LLS_PREF_DONT_CARE = 0,
@@ -485,6 +514,11 @@ struct spl_in {
bool prefer_easf;
bool disable_easf;
struct spl_debug debug;
+ bool is_fullscreen;
+ bool is_hdr_on;
+ int h_active;
+ int v_active;
+ int hdr_multx100;
};
// end of SPL inputs
diff --git a/drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.c b/drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.c
new file mode 100644
index 000000000000..be2f34d034c5
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: MIT
+//
+// Copyright 2024 Advanced Micro Devices, Inc.
+
+#include "spl_debug.h"
+#include "spl_custom_float.h"
+
+static bool spl_build_custom_float(struct spl_fixed31_32 value,
+ const struct spl_custom_float_format *format,
+ bool *negative,
+ uint32_t *mantissa,
+ uint32_t *exponenta)
+{
+ uint32_t exp_offset = (1 << (format->exponenta_bits - 1)) - 1;
+
+ const struct spl_fixed31_32 mantissa_constant_plus_max_fraction =
+ spl_fixpt_from_fraction((1LL << (format->mantissa_bits + 1)) - 1,
+ 1LL << format->mantissa_bits);
+
+ struct spl_fixed31_32 mantiss;
+
+ if (spl_fixpt_eq(value, spl_fixpt_zero)) {
+ *negative = false;
+ *mantissa = 0;
+ *exponenta = 0;
+ return true;
+ }
+
+ if (spl_fixpt_lt(value, spl_fixpt_zero)) {
+ *negative = format->sign;
+ value = spl_fixpt_neg(value);
+ } else {
+ *negative = false;
+ }
+
+ if (spl_fixpt_lt(value, spl_fixpt_one)) {
+ uint32_t i = 1;
+
+ do {
+ value = spl_fixpt_shl(value, 1);
+ ++i;
+ } while (spl_fixpt_lt(value, spl_fixpt_one));
+
+ --i;
+
+ if (exp_offset <= i) {
+ *mantissa = 0;
+ *exponenta = 0;
+ return true;
+ }
+
+ *exponenta = exp_offset - i;
+ } else if (spl_fixpt_le(mantissa_constant_plus_max_fraction, value)) {
+ uint32_t i = 1;
+
+ do {
+ value = spl_fixpt_shr(value, 1);
+ ++i;
+ } while (spl_fixpt_lt(mantissa_constant_plus_max_fraction, value));
+
+ *exponenta = exp_offset + i - 1;
+ } else {
+ *exponenta = exp_offset;
+ }
+
+ mantiss = spl_fixpt_sub(value, spl_fixpt_one);
+
+ if (spl_fixpt_lt(mantiss, spl_fixpt_zero) ||
+ spl_fixpt_lt(spl_fixpt_one, mantiss))
+ mantiss = spl_fixpt_zero;
+ else
+ mantiss = spl_fixpt_shl(mantiss, format->mantissa_bits);
+
+ *mantissa = spl_fixpt_floor(mantiss);
+
+ return true;
+}
+
+static bool spl_setup_custom_float(const struct spl_custom_float_format *format,
+ bool negative,
+ uint32_t mantissa,
+ uint32_t exponenta,
+ uint32_t *result)
+{
+ uint32_t i = 0;
+ uint32_t j = 0;
+ uint32_t value = 0;
+
+ /* verification code:
+ * once calculation is ok we can remove it
+ */
+
+ const uint32_t mantissa_mask =
+ (1 << (format->mantissa_bits + 1)) - 1;
+
+ const uint32_t exponenta_mask =
+ (1 << (format->exponenta_bits + 1)) - 1;
+
+ if (mantissa & ~mantissa_mask) {
+ SPL_BREAK_TO_DEBUGGER();
+ mantissa = mantissa_mask;
+ }
+
+ if (exponenta & ~exponenta_mask) {
+ SPL_BREAK_TO_DEBUGGER();
+ exponenta = exponenta_mask;
+ }
+
+ /* end of verification code */
+
+ while (i < format->mantissa_bits) {
+ uint32_t mask = 1 << i;
+
+ if (mantissa & mask)
+ value |= mask;
+
+ ++i;
+ }
+
+ while (j < format->exponenta_bits) {
+ uint32_t mask = 1 << j;
+
+ if (exponenta & mask)
+ value |= mask << i;
+
+ ++j;
+ }
+
+ if (negative && format->sign)
+ value |= 1 << (i + j);
+
+ *result = value;
+
+ return true;
+}
+
+bool spl_convert_to_custom_float_format(struct spl_fixed31_32 value,
+ const struct spl_custom_float_format *format,
+ uint32_t *result)
+{
+ uint32_t mantissa;
+ uint32_t exponenta;
+ bool negative;
+
+ return spl_build_custom_float(value, format, &negative, &mantissa, &exponenta) &&
+ spl_setup_custom_float(format,
+ negative,
+ mantissa,
+ exponenta,
+ result);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.h b/drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.h
new file mode 100644
index 000000000000..cdc4e107b9de
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: MIT */
+
+/* Copyright 2024 Advanced Micro Devices, Inc. */
+
+#ifndef SPL_CUSTOM_FLOAT_H_
+#define SPL_CUSTOM_FLOAT_H_
+
+#include "spl_os_types.h"
+#include "spl_fixpt31_32.h"
+
+struct spl_custom_float_format {
+ uint32_t mantissa_bits;
+ uint32_t exponenta_bits;
+ bool sign;
+};
+
+struct spl_custom_float_value {
+ uint32_t mantissa;
+ uint32_t exponenta;
+ uint32_t value;
+ bool negative;
+};
+
+bool spl_convert_to_custom_float_format(
+ struct spl_fixed31_32 value,
+ const struct spl_custom_float_format *format,
+ uint32_t *result);
+
+#endif //SPL_CUSTOM_FLOAT_H_
diff --git a/drivers/gpu/drm/amd/display/dc/spl/spl_debug.h b/drivers/gpu/drm/amd/display/dc/spl/spl_debug.h
new file mode 100644
index 000000000000..5696dafd0894
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/spl/spl_debug.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: MIT */
+
+/* Copyright 2024 Advanced Micro Devices, Inc. */
+
+#ifndef SPL_DEBUG_H
+#define SPL_DEBUG_H
+
+#ifdef SPL_ASSERT
+#undef SPL_ASSERT
+#endif
+#define SPL_ASSERT(b)
+
+#define SPL_ASSERT_CRITICAL(expr) do {if (expr)/* Do nothing */; } while (0)
+
+#ifdef SPL_DALMSG
+#undef SPL_DALMSG
+#endif
+#define SPL_DALMSG(b)
+
+#ifdef SPL_DAL_ASSERT_MSG
+#undef SPL_DAL_ASSERT_MSG
+#endif
+#define SPL_DAL_ASSERT_MSG(b, m)
+
+#endif // SPL_DEBUG_H
diff --git a/drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.c
new file mode 100644
index 000000000000..a95565df5487
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.c
@@ -0,0 +1,497 @@
+// SPDX-License-Identifier: MIT
+//
+// Copyright 2024 Advanced Micro Devices, Inc.
+
+#include "spl_fixpt31_32.h"
+
+static const struct spl_fixed31_32 spl_fixpt_two_pi = { 26986075409LL };
+static const struct spl_fixed31_32 spl_fixpt_ln2 = { 2977044471LL };
+static const struct spl_fixed31_32 spl_fixpt_ln2_div_2 = { 1488522236LL };
+
+static inline unsigned long long abs_i64(
+ long long arg)
+{
+ if (arg > 0)
+ return (unsigned long long)arg;
+ else
+ return (unsigned long long)(-arg);
+}
+
+/*
+ * @brief
+ * result = dividend / divisor
+ * *remainder = dividend % divisor
+ */
+static inline unsigned long long complete_integer_division_u64(
+ unsigned long long dividend,
+ unsigned long long divisor,
+ unsigned long long *remainder)
+{
+ unsigned long long result;
+
+ ASSERT(divisor);
+
+ result = spl_div64_u64_rem(dividend, divisor, remainder);
+
+ return result;
+}
+
+
+#define FRACTIONAL_PART_MASK \
+ ((1ULL << FIXED31_32_BITS_PER_FRACTIONAL_PART) - 1)
+
+#define GET_INTEGER_PART(x) \
+ ((x) >> FIXED31_32_BITS_PER_FRACTIONAL_PART)
+
+#define GET_FRACTIONAL_PART(x) \
+ (FRACTIONAL_PART_MASK & (x))
+
+struct spl_fixed31_32 spl_fixpt_from_fraction(long long numerator, long long denominator)
+{
+ struct spl_fixed31_32 res;
+
+ bool arg1_negative = numerator < 0;
+ bool arg2_negative = denominator < 0;
+
+ unsigned long long arg1_value = arg1_negative ? -numerator : numerator;
+ unsigned long long arg2_value = arg2_negative ? -denominator : denominator;
+
+ unsigned long long remainder;
+
+ /* determine integer part */
+
+ unsigned long long res_value = complete_integer_division_u64(
+ arg1_value, arg2_value, &remainder);
+
+ ASSERT(res_value <= LONG_MAX);
+
+ /* determine fractional part */
+ {
+ unsigned int i = FIXED31_32_BITS_PER_FRACTIONAL_PART;
+
+ do {
+ remainder <<= 1;
+
+ res_value <<= 1;
+
+ if (remainder >= arg2_value) {
+ res_value |= 1;
+ remainder -= arg2_value;
+ }
+ } while (--i != 0);
+ }
+
+ /* round up LSB */
+ {
+ unsigned long long summand = (remainder << 1) >= arg2_value;
+
+ ASSERT(res_value <= LLONG_MAX - summand);
+
+ res_value += summand;
+ }
+
+ res.value = (long long)res_value;
+
+ if (arg1_negative ^ arg2_negative)
+ res.value = -res.value;
+
+ return res;
+}
+
+struct spl_fixed31_32 spl_fixpt_mul(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
+{
+ struct spl_fixed31_32 res;
+
+ bool arg1_negative = arg1.value < 0;
+ bool arg2_negative = arg2.value < 0;
+
+ unsigned long long arg1_value = arg1_negative ? -arg1.value : arg1.value;
+ unsigned long long arg2_value = arg2_negative ? -arg2.value : arg2.value;
+
+ unsigned long long arg1_int = GET_INTEGER_PART(arg1_value);
+ unsigned long long arg2_int = GET_INTEGER_PART(arg2_value);
+
+ unsigned long long arg1_fra = GET_FRACTIONAL_PART(arg1_value);
+ unsigned long long arg2_fra = GET_FRACTIONAL_PART(arg2_value);
+
+ unsigned long long tmp;
+
+ res.value = arg1_int * arg2_int;
+
+ ASSERT(res.value <= (long long)LONG_MAX);
+
+ res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART;
+
+ tmp = arg1_int * arg2_fra;
+
+ ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
+
+ res.value += tmp;
+
+ tmp = arg2_int * arg1_fra;
+
+ ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
+
+ res.value += tmp;
+
+ tmp = arg1_fra * arg2_fra;
+
+ tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) +
+ (tmp >= (unsigned long long)spl_fixpt_half.value);
+
+ ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
+
+ res.value += tmp;
+
+ if (arg1_negative ^ arg2_negative)
+ res.value = -res.value;
+
+ return res;
+}
+
+struct spl_fixed31_32 spl_fixpt_sqr(struct spl_fixed31_32 arg)
+{
+ struct spl_fixed31_32 res;
+
+ unsigned long long arg_value = abs_i64(arg.value);
+
+ unsigned long long arg_int = GET_INTEGER_PART(arg_value);
+
+ unsigned long long arg_fra = GET_FRACTIONAL_PART(arg_value);
+
+ unsigned long long tmp;
+
+ res.value = arg_int * arg_int;
+
+ ASSERT(res.value <= (long long)LONG_MAX);
+
+ res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART;
+
+ tmp = arg_int * arg_fra;
+
+ ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
+
+ res.value += tmp;
+
+ ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
+
+ res.value += tmp;
+
+ tmp = arg_fra * arg_fra;
+
+ tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) +
+ (tmp >= (unsigned long long)spl_fixpt_half.value);
+
+ ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
+
+ res.value += tmp;
+
+ return res;
+}
+
+struct spl_fixed31_32 spl_fixpt_recip(struct spl_fixed31_32 arg)
+{
+ /*
+ * @note
+ * Good idea to use Newton's method
+ */
+
+ ASSERT(arg.value);
+
+ return spl_fixpt_from_fraction(
+ spl_fixpt_one.value,
+ arg.value);
+}
+
+struct spl_fixed31_32 spl_fixpt_sinc(struct spl_fixed31_32 arg)
+{
+ struct spl_fixed31_32 square;
+
+ struct spl_fixed31_32 res = spl_fixpt_one;
+
+ int n = 27;
+
+ struct spl_fixed31_32 arg_norm = arg;
+
+ if (spl_fixpt_le(
+ spl_fixpt_two_pi,
+ spl_fixpt_abs(arg))) {
+ arg_norm = spl_fixpt_sub(
+ arg_norm,
+ spl_fixpt_mul_int(
+ spl_fixpt_two_pi,
+ (int)spl_div64_s64(
+ arg_norm.value,
+ spl_fixpt_two_pi.value)));
+ }
+
+ square = spl_fixpt_sqr(arg_norm);
+
+ do {
+ res = spl_fixpt_sub(
+ spl_fixpt_one,
+ spl_fixpt_div_int(
+ spl_fixpt_mul(
+ square,
+ res),
+ n * (n - 1)));
+
+ n -= 2;
+ } while (n > 2);
+
+ if (arg.value != arg_norm.value)
+ res = spl_fixpt_div(
+ spl_fixpt_mul(res, arg_norm),
+ arg);
+
+ return res;
+}
+
+struct spl_fixed31_32 spl_fixpt_sin(struct spl_fixed31_32 arg)
+{
+ return spl_fixpt_mul(
+ arg,
+ spl_fixpt_sinc(arg));
+}
+
+struct spl_fixed31_32 spl_fixpt_cos(struct spl_fixed31_32 arg)
+{
+ /* TODO implement argument normalization */
+
+ const struct spl_fixed31_32 square = spl_fixpt_sqr(arg);
+
+ struct spl_fixed31_32 res = spl_fixpt_one;
+
+ int n = 26;
+
+ do {
+ res = spl_fixpt_sub(
+ spl_fixpt_one,
+ spl_fixpt_div_int(
+ spl_fixpt_mul(
+ square,
+ res),
+ n * (n - 1)));
+
+ n -= 2;
+ } while (n != 0);
+
+ return res;
+}
+
+/*
+ * @brief
+ * result = exp(arg),
+ * where abs(arg) < 1
+ *
+ * Calculated as Taylor series.
+ */
+static struct spl_fixed31_32 fixed31_32_exp_from_taylor_series(struct spl_fixed31_32 arg)
+{
+ unsigned int n = 9;
+
+ struct spl_fixed31_32 res = spl_fixpt_from_fraction(
+ n + 2,
+ n + 1);
+ /* TODO find correct res */
+
+ ASSERT(spl_fixpt_lt(arg, spl_fixpt_one));
+
+ do
+ res = spl_fixpt_add(
+ spl_fixpt_one,
+ spl_fixpt_div_int(
+ spl_fixpt_mul(
+ arg,
+ res),
+ n));
+ while (--n != 1);
+
+ return spl_fixpt_add(
+ spl_fixpt_one,
+ spl_fixpt_mul(
+ arg,
+ res));
+}
+
+struct spl_fixed31_32 spl_fixpt_exp(struct spl_fixed31_32 arg)
+{
+ /*
+ * @brief
+ * Main equation is:
+ * exp(x) = exp(r + m * ln(2)) = (1 << m) * exp(r),
+ * where m = round(x / ln(2)), r = x - m * ln(2)
+ */
+
+ if (spl_fixpt_le(
+ spl_fixpt_ln2_div_2,
+ spl_fixpt_abs(arg))) {
+ int m = spl_fixpt_round(
+ spl_fixpt_div(
+ arg,
+ spl_fixpt_ln2));
+
+ struct spl_fixed31_32 r = spl_fixpt_sub(
+ arg,
+ spl_fixpt_mul_int(
+ spl_fixpt_ln2,
+ m));
+
+ ASSERT(m != 0);
+
+ ASSERT(spl_fixpt_lt(
+ spl_fixpt_abs(r),
+ spl_fixpt_one));
+
+ if (m > 0)
+ return spl_fixpt_shl(
+ fixed31_32_exp_from_taylor_series(r),
+ (unsigned char)m);
+ else
+ return spl_fixpt_div_int(
+ fixed31_32_exp_from_taylor_series(r),
+ 1LL << -m);
+ } else if (arg.value != 0)
+ return fixed31_32_exp_from_taylor_series(arg);
+ else
+ return spl_fixpt_one;
+}
+
+struct spl_fixed31_32 spl_fixpt_log(struct spl_fixed31_32 arg)
+{
+ struct spl_fixed31_32 res = spl_fixpt_neg(spl_fixpt_one);
+ /* TODO improve 1st estimation */
+
+ struct spl_fixed31_32 error;
+
+ ASSERT(arg.value > 0);
+ /* TODO if arg is negative, return NaN */
+ /* TODO if arg is zero, return -INF */
+
+ do {
+ struct spl_fixed31_32 res1 = spl_fixpt_add(
+ spl_fixpt_sub(
+ res,
+ spl_fixpt_one),
+ spl_fixpt_div(
+ arg,
+ spl_fixpt_exp(res)));
+
+ error = spl_fixpt_sub(
+ res,
+ res1);
+
+ res = res1;
+ /* TODO determine max_allowed_error based on quality of exp() */
+ } while (abs_i64(error.value) > 100ULL);
+
+ return res;
+}
+
+
+/* this function is a generic helper to translate fixed point value to
+ * specified integer format that will consist of integer_bits integer part and
+ * fractional_bits fractional part. For example it is used in
+ * spl_fixpt_u2d19 to receive 2 bits integer part and 19 bits fractional
+ * part in 32 bits. It is used in hw programming (scaler)
+ */
+
+static inline unsigned int ux_dy(
+ long long value,
+ unsigned int integer_bits,
+ unsigned int fractional_bits)
+{
+ /* 1. create mask of integer part */
+ unsigned int result = (1 << integer_bits) - 1;
+ /* 2. mask out fractional part */
+ unsigned int fractional_part = FRACTIONAL_PART_MASK & value;
+ /* 3. shrink fixed point integer part to be of integer_bits width*/
+ result &= GET_INTEGER_PART(value);
+ /* 4. make space for fractional part to be filled in after integer */
+ result <<= fractional_bits;
+ /* 5. shrink fixed point fractional part to of fractional_bits width*/
+ fractional_part >>= FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits;
+ /* 6. merge the result */
+ return result | fractional_part;
+}
+
+static inline unsigned int clamp_ux_dy(
+ long long value,
+ unsigned int integer_bits,
+ unsigned int fractional_bits,
+ unsigned int min_clamp)
+{
+ unsigned int truncated_val = ux_dy(value, integer_bits, fractional_bits);
+
+ if (value >= (1LL << (integer_bits + FIXED31_32_BITS_PER_FRACTIONAL_PART)))
+ return (1 << (integer_bits + fractional_bits)) - 1;
+ else if (truncated_val > min_clamp)
+ return truncated_val;
+ else
+ return min_clamp;
+}
+
+unsigned int spl_fixpt_u4d19(struct spl_fixed31_32 arg)
+{
+ return ux_dy(arg.value, 4, 19);
+}
+
+unsigned int spl_fixpt_u3d19(struct spl_fixed31_32 arg)
+{
+ return ux_dy(arg.value, 3, 19);
+}
+
+unsigned int spl_fixpt_u2d19(struct spl_fixed31_32 arg)
+{
+ return ux_dy(arg.value, 2, 19);
+}
+
+unsigned int spl_fixpt_u0d19(struct spl_fixed31_32 arg)
+{
+ return ux_dy(arg.value, 0, 19);
+}
+
+unsigned int spl_fixpt_clamp_u0d14(struct spl_fixed31_32 arg)
+{
+ return clamp_ux_dy(arg.value, 0, 14, 1);
+}
+
+unsigned int spl_fixpt_clamp_u0d10(struct spl_fixed31_32 arg)
+{
+ return clamp_ux_dy(arg.value, 0, 10, 1);
+}
+
+int spl_fixpt_s4d19(struct spl_fixed31_32 arg)
+{
+ if (arg.value < 0)
+ return -(int)ux_dy(spl_fixpt_abs(arg).value, 4, 19);
+ else
+ return ux_dy(arg.value, 4, 19);
+}
+
+struct spl_fixed31_32 spl_fixpt_from_ux_dy(unsigned int value,
+ unsigned int integer_bits,
+ unsigned int fractional_bits)
+{
+ struct spl_fixed31_32 fixpt_value = spl_fixpt_zero;
+ struct spl_fixed31_32 fixpt_int_value = spl_fixpt_zero;
+ long long frac_mask = ((long long)1 << (long long)integer_bits) - 1;
+
+ fixpt_value.value = (long long)value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
+ frac_mask = frac_mask << fractional_bits;
+ fixpt_int_value.value = value & frac_mask;
+ fixpt_int_value.value <<= (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
+ fixpt_value.value |= fixpt_int_value.value;
+ return fixpt_value;
+}
+
+struct spl_fixed31_32 spl_fixpt_from_int_dy(unsigned int int_value,
+ unsigned int frac_value,
+ unsigned int integer_bits,
+ unsigned int fractional_bits)
+{
+ struct spl_fixed31_32 fixpt_value = spl_fixpt_from_int(int_value);
+
+ fixpt_value.value |= (long long)frac_value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
+ return fixpt_value;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.h b/drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.h
new file mode 100644
index 000000000000..8a045e2f8699
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.h
@@ -0,0 +1,525 @@
+/* SPDX-License-Identifier: MIT */
+
+/* Copyright 2024 Advanced Micro Devices, Inc. */
+
+#ifndef __SPL_FIXED31_32_H__
+#define __SPL_FIXED31_32_H__
+
+#include "os_types.h"
+#include "spl_os_types.h" // swap
+#ifndef ASSERT
+#define ASSERT(_bool) ((void *)0)
+#endif
+
+#ifndef LLONG_MAX
+#define LLONG_MAX 9223372036854775807ll
+#endif
+#ifndef LLONG_MIN
+#define LLONG_MIN (-LLONG_MAX - 1ll)
+#endif
+
+#define FIXED31_32_BITS_PER_FRACTIONAL_PART 32
+#ifndef LLONG_MIN
+#define LLONG_MIN (1LL<<63)
+#endif
+#ifndef LLONG_MAX
+#define LLONG_MAX (-1LL>>1)
+#endif
+
+/*
+ * @brief
+ * Arithmetic operations on real numbers
+ * represented as fixed-point numbers.
+ * There are: 1 bit for sign,
+ * 31 bit for integer part,
+ * 32 bits for fractional part.
+ *
+ * @note
+ * Currently, overflows and underflows are asserted;
+ * no special result returned.
+ */
+
+struct spl_fixed31_32 {
+ long long value;
+};
+
+
+/*
+ * @brief
+ * Useful constants
+ */
+
+static const struct spl_fixed31_32 spl_fixpt_zero = { 0 };
+static const struct spl_fixed31_32 spl_fixpt_epsilon = { 1LL };
+static const struct spl_fixed31_32 spl_fixpt_half = { 0x80000000LL };
+static const struct spl_fixed31_32 spl_fixpt_one = { 0x100000000LL };
+
+/*
+ * @brief
+ * Initialization routines
+ */
+
+/*
+ * @brief
+ * result = numerator / denominator
+ */
+struct spl_fixed31_32 spl_fixpt_from_fraction(long long numerator, long long denominator);
+
+/*
+ * @brief
+ * result = arg
+ */
+static inline struct spl_fixed31_32 spl_fixpt_from_int(int arg)
+{
+ struct spl_fixed31_32 res;
+
+ res.value = (long long) arg << FIXED31_32_BITS_PER_FRACTIONAL_PART;
+
+ return res;
+}
+
+/*
+ * @brief
+ * Unary operators
+ */
+
+/*
+ * @brief
+ * result = -arg
+ */
+static inline struct spl_fixed31_32 spl_fixpt_neg(struct spl_fixed31_32 arg)
+{
+ struct spl_fixed31_32 res;
+
+ res.value = -arg.value;
+
+ return res;
+}
+
+/*
+ * @brief
+ * result = abs(arg) := (arg >= 0) ? arg : -arg
+ */
+static inline struct spl_fixed31_32 spl_fixpt_abs(struct spl_fixed31_32 arg)
+{
+ if (arg.value < 0)
+ return spl_fixpt_neg(arg);
+ else
+ return arg;
+}
+
+/*
+ * @brief
+ * Binary relational operators
+ */
+
+/*
+ * @brief
+ * result = arg1 < arg2
+ */
+static inline bool spl_fixpt_lt(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
+{
+ return arg1.value < arg2.value;
+}
+
+/*
+ * @brief
+ * result = arg1 <= arg2
+ */
+static inline bool spl_fixpt_le(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
+{
+ return arg1.value <= arg2.value;
+}
+
+/*
+ * @brief
+ * result = arg1 == arg2
+ */
+static inline bool spl_fixpt_eq(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
+{
+ return arg1.value == arg2.value;
+}
+
+/*
+ * @brief
+ * result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2
+ */
+static inline struct spl_fixed31_32 spl_fixpt_min(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
+{
+ if (arg1.value <= arg2.value)
+ return arg1;
+ else
+ return arg2;
+}
+
+/*
+ * @brief
+ * result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1
+ */
+static inline struct spl_fixed31_32 spl_fixpt_max(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
+{
+ if (arg1.value <= arg2.value)
+ return arg2;
+ else
+ return arg1;
+}
+
+/*
+ * @brief
+ * | min_value, when arg <= min_value
+ * result = | arg, when min_value < arg < max_value
+ * | max_value, when arg >= max_value
+ */
+static inline struct spl_fixed31_32 spl_fixpt_clamp(
+ struct spl_fixed31_32 arg,
+ struct spl_fixed31_32 min_value,
+ struct spl_fixed31_32 max_value)
+{
+ if (spl_fixpt_le(arg, min_value))
+ return min_value;
+ else if (spl_fixpt_le(max_value, arg))
+ return max_value;
+ else
+ return arg;
+}
+
+/*
+ * @brief
+ * Binary shift operators
+ */
+
+/*
+ * @brief
+ * result = arg << shift
+ */
+static inline struct spl_fixed31_32 spl_fixpt_shl(struct spl_fixed31_32 arg, unsigned char shift)
+{
+ ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) ||
+ ((arg.value < 0) && (arg.value >= ~(LLONG_MAX >> shift))));
+
+ arg.value = arg.value << shift;
+
+ return arg;
+}
+
+/*
+ * @brief
+ * result = arg >> shift
+ */
+static inline struct spl_fixed31_32 spl_fixpt_shr(struct spl_fixed31_32 arg, unsigned char shift)
+{
+ bool negative = arg.value < 0;
+
+ if (negative)
+ arg.value = -arg.value;
+ arg.value = arg.value >> shift;
+ if (negative)
+ arg.value = -arg.value;
+ return arg;
+}
+
+/*
+ * @brief
+ * Binary additive operators
+ */
+
+/*
+ * @brief
+ * result = arg1 + arg2
+ */
+static inline struct spl_fixed31_32 spl_fixpt_add(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
+{
+ struct spl_fixed31_32 res;
+
+ ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) ||
+ ((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value)));
+
+ res.value = arg1.value + arg2.value;
+
+ return res;
+}
+
+/*
+ * @brief
+ * result = arg1 + arg2
+ */
+static inline struct spl_fixed31_32 spl_fixpt_add_int(struct spl_fixed31_32 arg1, int arg2)
+{
+ return spl_fixpt_add(arg1, spl_fixpt_from_int(arg2));
+}
+
+/*
+ * @brief
+ * result = arg1 - arg2
+ */
+static inline struct spl_fixed31_32 spl_fixpt_sub(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
+{
+ struct spl_fixed31_32 res;
+
+ ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) ||
+ ((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value)));
+
+ res.value = arg1.value - arg2.value;
+
+ return res;
+}
+
+/*
+ * @brief
+ * result = arg1 - arg2
+ */
+static inline struct spl_fixed31_32 spl_fixpt_sub_int(struct spl_fixed31_32 arg1, int arg2)
+{
+ return spl_fixpt_sub(arg1, spl_fixpt_from_int(arg2));
+}
+
+
+/*
+ * @brief
+ * Binary multiplicative operators
+ */
+
+/*
+ * @brief
+ * result = arg1 * arg2
+ */
+struct spl_fixed31_32 spl_fixpt_mul(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2);
+
+
+/*
+ * @brief
+ * result = arg1 * arg2
+ */
+static inline struct spl_fixed31_32 spl_fixpt_mul_int(struct spl_fixed31_32 arg1, int arg2)
+{
+ return spl_fixpt_mul(arg1, spl_fixpt_from_int(arg2));
+}
+
+/*
+ * @brief
+ * result = square(arg) := arg * arg
+ */
+struct spl_fixed31_32 spl_fixpt_sqr(struct spl_fixed31_32 arg);
+
+/*
+ * @brief
+ * result = arg1 / arg2
+ */
+static inline struct spl_fixed31_32 spl_fixpt_div_int(struct spl_fixed31_32 arg1, long long arg2)
+{
+ return spl_fixpt_from_fraction(arg1.value, spl_fixpt_from_int((int)arg2).value);
+}
+
+/*
+ * @brief
+ * result = arg1 / arg2
+ */
+static inline struct spl_fixed31_32 spl_fixpt_div(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
+{
+ return spl_fixpt_from_fraction(arg1.value, arg2.value);
+}
+
+/*
+ * @brief
+ * Reciprocal function
+ */
+
+/*
+ * @brief
+ * result = reciprocal(arg) := 1 / arg
+ *
+ * @note
+ * No special actions taken in case argument is zero.
+ */
+struct spl_fixed31_32 spl_fixpt_recip(struct spl_fixed31_32 arg);
+
+/*
+ * @brief
+ * Trigonometric functions
+ */
+
+/*
+ * @brief
+ * result = sinc(arg) := sin(arg) / arg
+ *
+ * @note
+ * Argument specified in radians,
+ * internally it's normalized to [-2pi...2pi] range.
+ */
+struct spl_fixed31_32 spl_fixpt_sinc(struct spl_fixed31_32 arg);
+
+/*
+ * @brief
+ * result = sin(arg)
+ *
+ * @note
+ * Argument specified in radians,
+ * internally it's normalized to [-2pi...2pi] range.
+ */
+struct spl_fixed31_32 spl_fixpt_sin(struct spl_fixed31_32 arg);
+
+/*
+ * @brief
+ * result = cos(arg)
+ *
+ * @note
+ * Argument specified in radians
+ * and should be in [-2pi...2pi] range -
+ * passing arguments outside that range
+ * will cause incorrect result!
+ */
+struct spl_fixed31_32 spl_fixpt_cos(struct spl_fixed31_32 arg);
+
+/*
+ * @brief
+ * Transcendent functions
+ */
+
+/*
+ * @brief
+ * result = exp(arg)
+ *
+ * @note
+ * Currently, function is verified for abs(arg) <= 1.
+ */
+struct spl_fixed31_32 spl_fixpt_exp(struct spl_fixed31_32 arg);
+
+/*
+ * @brief
+ * result = log(arg)
+ *
+ * @note
+ * Currently, abs(arg) should be less than 1.
+ * No normalization is done.
+ * Currently, no special actions taken
+ * in case of invalid argument(s). Take care!
+ */
+struct spl_fixed31_32 spl_fixpt_log(struct spl_fixed31_32 arg);
+
+/*
+ * @brief
+ * Power function
+ */
+
+/*
+ * @brief
+ * result = pow(arg1, arg2)
+ *
+ * @note
+ * Currently, abs(arg1) should be less than 1. Take care!
+ */
+static inline struct spl_fixed31_32 spl_fixpt_pow(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
+{
+ if (arg1.value == 0)
+ return arg2.value == 0 ? spl_fixpt_one : spl_fixpt_zero;
+
+ return spl_fixpt_exp(
+ spl_fixpt_mul(
+ spl_fixpt_log(arg1),
+ arg2));
+}
+
+/*
+ * @brief
+ * Rounding functions
+ */
+
+/*
+ * @brief
+ * result = floor(arg) := greatest integer lower than or equal to arg
+ */
+static inline int spl_fixpt_floor(struct spl_fixed31_32 arg)
+{
+ unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
+
+ if (arg.value >= 0)
+ return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
+ else
+ return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
+}
+
+/*
+ * @brief
+ * result = round(arg) := integer nearest to arg
+ */
+static inline int spl_fixpt_round(struct spl_fixed31_32 arg)
+{
+ unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
+
+ const long long summand = spl_fixpt_half.value;
+
+ ASSERT(LLONG_MAX - (long long)arg_value >= summand);
+
+ arg_value += summand;
+
+ if (arg.value >= 0)
+ return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
+ else
+ return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
+}
+
+/*
+ * @brief
+ * result = ceil(arg) := lowest integer greater than or equal to arg
+ */
+static inline int spl_fixpt_ceil(struct spl_fixed31_32 arg)
+{
+ unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
+
+ const long long summand = spl_fixpt_one.value -
+ spl_fixpt_epsilon.value;
+
+ ASSERT(LLONG_MAX - (long long)arg_value >= summand);
+
+ arg_value += summand;
+
+ if (arg.value >= 0)
+ return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
+ else
+ return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
+}
+
+/* the following two function are used in scaler hw programming to convert fixed
+ * point value to format 2 bits from integer part and 19 bits from fractional
+ * part. The same applies for u0d19, 0 bits from integer part and 19 bits from
+ * fractional
+ */
+
+unsigned int spl_fixpt_u4d19(struct spl_fixed31_32 arg);
+
+unsigned int spl_fixpt_u3d19(struct spl_fixed31_32 arg);
+
+unsigned int spl_fixpt_u2d19(struct spl_fixed31_32 arg);
+
+unsigned int spl_fixpt_u0d19(struct spl_fixed31_32 arg);
+
+unsigned int spl_fixpt_clamp_u0d14(struct spl_fixed31_32 arg);
+
+unsigned int spl_fixpt_clamp_u0d10(struct spl_fixed31_32 arg);
+
+int spl_fixpt_s4d19(struct spl_fixed31_32 arg);
+
+static inline struct spl_fixed31_32 spl_fixpt_truncate(struct spl_fixed31_32 arg, unsigned int frac_bits)
+{
+ bool negative = arg.value < 0;
+
+ if (frac_bits >= FIXED31_32_BITS_PER_FRACTIONAL_PART) {
+ ASSERT(frac_bits == FIXED31_32_BITS_PER_FRACTIONAL_PART);
+ return arg;
+ }
+
+ if (negative)
+ arg.value = -arg.value;
+ arg.value &= (~0ULL) << (FIXED31_32_BITS_PER_FRACTIONAL_PART - frac_bits);
+ if (negative)
+ arg.value = -arg.value;
+ return arg;
+}
+
+struct spl_fixed31_32 spl_fixpt_from_ux_dy(unsigned int value, unsigned int integer_bits, unsigned int fractional_bits);
+struct spl_fixed31_32 spl_fixpt_from_int_dy(unsigned int int_value,
+ unsigned int frac_value,
+ unsigned int integer_bits,
+ unsigned int fractional_bits);
+
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/spl/spl_os_types.h b/drivers/gpu/drm/amd/display/dc/spl/spl_os_types.h
new file mode 100644
index 000000000000..709706ed4f2c
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/spl/spl_os_types.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: MIT */
+
+/* Copyright 2024 Advanced Micro Devices, Inc. */
+/* Copyright 2019 Raptor Engineering, LLC */
+
+#ifndef _SPL_OS_TYPES_H_
+#define _SPL_OS_TYPES_H_
+
+#include <linux/slab.h>
+#include <linux/kgdb.h>
+#include <linux/kref.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+
+/*
+ *
+ * general debug capabilities
+ *
+ */
+#define SPL_BREAK_TO_DEBUGGER() ASSERT(0)
+
+static inline uint64_t spl_div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
+{
+ return div_u64_rem(dividend, divisor, remainder);
+}
+
+static inline uint64_t spl_div_u64(uint64_t dividend, uint32_t divisor)
+{
+ return div_u64(dividend, divisor);
+}
+
+static inline uint64_t spl_div64_u64(uint64_t dividend, uint64_t divisor)
+{
+ return div64_u64(dividend, divisor);
+}
+
+static inline uint64_t spl_div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder)
+{
+ return div64_u64_rem(dividend, divisor, remainder);
+}
+
+static inline int64_t spl_div64_s64(int64_t dividend, int64_t divisor)
+{
+ return div64_s64(dividend, divisor);
+}
+
+#define spl_swap(a, b) \
+ do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
+
+#ifndef spl_min
+#define spl_min(a, b) (((a) < (b)) ? (a):(b))
+#endif
+
+#endif /* _SPL_OS_TYPES_H_ */
diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
index 6589bb9aea6b..cd70453aeae0 100644
--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
@@ -330,6 +330,9 @@ struct dmub_diagnostic_data {
uint32_t inbox0_rptr;
uint32_t inbox0_wptr;
uint32_t inbox0_size;
+ uint32_t outbox1_rptr;
+ uint32_t outbox1_wptr;
+ uint32_t outbox1_size;
uint32_t gpint_datain0;
struct dmub_srv_debug timeout_info;
uint8_t is_dmcub_enabled : 1;
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index 5ff0a865705f..e20c220aa8b4 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -111,7 +111,7 @@
#define DMUB_MAX_PHANTOM_PLANES ((DMUB_MAX_PLANES) / 2)
/* Trace buffer offset for entry */
-#define TRACE_BUFFER_ENTRY_OFFSET 16
+#define TRACE_BUFFER_ENTRY_OFFSET 16
/**
* Maximum number of dirty rects supported by FW.
@@ -336,6 +336,10 @@ union dmub_psr_debug_flags {
*/
uint32_t back_to_back_flip : 1;
+ /**
+ * Enable visual confirm for IPS
+ */
+ uint32_t enable_ips_visual_confirm : 1;
} bitfields;
/**
@@ -1875,7 +1879,12 @@ enum dmub_cmd_idle_opt_type {
/**
* DCN hardware notify idle.
*/
- DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE = 2
+ DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE = 2,
+
+ /**
+ * DCN hardware notify power state.
+ */
+ DMUB_CMD__IDLE_OPT_SET_DC_POWER_STATE = 3,
};
/**
@@ -1903,6 +1912,33 @@ struct dmub_rb_cmd_idle_opt_dcn_notify_idle {
};
/**
+ * enum dmub_idle_opt_dc_power_state - DC power states.
+ */
+enum dmub_idle_opt_dc_power_state {
+ DMUB_IDLE_OPT_DC_POWER_STATE_UNKNOWN = 0,
+ DMUB_IDLE_OPT_DC_POWER_STATE_D0 = 1,
+ DMUB_IDLE_OPT_DC_POWER_STATE_D1 = 2,
+ DMUB_IDLE_OPT_DC_POWER_STATE_D2 = 4,
+ DMUB_IDLE_OPT_DC_POWER_STATE_D3 = 8,
+};
+
+/**
+ * struct dmub_idle_opt_set_dc_power_state_data - Data passed to FW in a DMUB_CMD__IDLE_OPT_SET_DC_POWER_STATE command.
+ */
+struct dmub_idle_opt_set_dc_power_state_data {
+ uint8_t power_state; /**< power state */
+ uint8_t pad[3]; /**< padding */
+};
+
+/**
+ * struct dmub_rb_cmd_idle_opt_set_dc_power_state - Data passed to FW in a DMUB_CMD__IDLE_OPT_SET_DC_POWER_STATE command.
+ */
+struct dmub_rb_cmd_idle_opt_set_dc_power_state {
+ struct dmub_cmd_header header; /**< header */
+ struct dmub_idle_opt_set_dc_power_state_data data;
+};
+
+/**
* struct dmub_clocks - Clock update notification.
*/
struct dmub_clocks {
@@ -3024,14 +3060,6 @@ struct dmub_cmd_update_dirty_rect_data {
* Currently the support is only for 0 or 1
*/
uint8_t panel_inst;
- /**
- * 16-bit value dicated by driver that indicates the coasting vtotal high byte part.
- */
- uint16_t coasting_vtotal_high;
- /**
- * Explicit padding to 4 byte boundary.
- */
- uint8_t pad[2];
};
/**
@@ -5302,6 +5330,10 @@ union dmub_rb_cmd {
* Definition of a DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE command.
*/
struct dmub_rb_cmd_idle_opt_dcn_notify_idle idle_opt_notify_idle;
+ /**
+ * Definition of a DMUB_CMD__IDLE_OPT_SET_DC_POWER_STATE command.
+ */
+ struct dmub_rb_cmd_idle_opt_set_dc_power_state idle_opt_set_dc_power_state;
/*
* Definition of a DMUB_CMD__REPLAY_COPY_SETTINGS command.
*/
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
index 662c34e9495c..d9f31b191c69 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
@@ -449,6 +449,10 @@ void dmub_dcn31_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti
diag_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR);
diag_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE);
+ diag_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR);
+ diag_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR);
+ diag_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE);
+
REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled);
diag_data->is_dmcub_enabled = is_dmub_enabled;
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c
index e1da270502cc..9600b7f858b0 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c
@@ -459,6 +459,10 @@ void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti
diag_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR);
diag_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE);
+ diag_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR);
+ diag_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR);
+ diag_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE);
+
REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled);
diag_data->is_dmcub_enabled = is_dmub_enabled;
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c
index 916ed022e96b..746696b6f09a 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c
@@ -502,6 +502,10 @@ void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti
diag_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR);
diag_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE);
+ diag_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR);
+ diag_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR);
+ diag_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE);
+
REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled);
diag_data->is_dmcub_enabled = is_dmub_enabled;
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c
index cf139e9cc20e..39a8cb6d7523 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c
@@ -444,6 +444,10 @@ void dmub_dcn401_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnost
diag_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR);
diag_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE);
+ diag_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR);
+ diag_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR);
+ diag_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE);
+
REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled);
diag_data->is_dmcub_enabled = is_dmub_enabled;
diff --git a/drivers/gpu/drm/amd/display/include/fixed31_32.h b/drivers/gpu/drm/amd/display/include/fixed31_32.h
index d4cf7ead1d87..990fa1f19c22 100644
--- a/drivers/gpu/drm/amd/display/include/fixed31_32.h
+++ b/drivers/gpu/drm/amd/display/include/fixed31_32.h
@@ -531,4 +531,10 @@ static inline struct fixed31_32 dc_fixpt_truncate(struct fixed31_32 arg, unsigne
return arg;
}
+struct fixed31_32 dc_fixpt_from_ux_dy(unsigned int value, unsigned int integer_bits, unsigned int fractional_bits);
+struct fixed31_32 dc_fixpt_from_int_dy(unsigned int int_value,
+ unsigned int frac_value,
+ unsigned int integer_bits,
+ unsigned int fractional_bits);
+
#endif
diff --git a/drivers/gpu/drm/amd/display/include/logger_types.h b/drivers/gpu/drm/amd/display/include/logger_types.h
index 83479951732a..a48d564d1660 100644
--- a/drivers/gpu/drm/amd/display/include/logger_types.h
+++ b/drivers/gpu/drm/amd/display/include/logger_types.h
@@ -61,6 +61,7 @@
#define DC_LOG_ALL_TF_CHANNELS(...) pr_debug("[GAMMA]:"__VA_ARGS__)
#define DC_LOG_DSC(...) drm_dbg_dp((DC_LOGGER)->dev, __VA_ARGS__)
#define DC_LOG_SMU(...) pr_debug("[SMU_MSG]:"__VA_ARGS__)
+#define DC_LOG_MALL(...) pr_debug("[MALL]:"__VA_ARGS__)
#define DC_LOG_DWB(...) drm_dbg((DC_LOGGER)->dev, __VA_ARGS__)
#define DC_LOG_DP2(...) drm_dbg_dp((DC_LOGGER)->dev, __VA_ARGS__)
#define DC_LOG_AUTO_DPM_TEST(...) pr_debug("[AutoDPMTest]: "__VA_ARGS__)
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
index 1e495e884484..8bc377560787 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
@@ -432,18 +432,18 @@ static enum mod_hdcp_status authenticated_dp(struct mod_hdcp *hdcp,
goto out;
}
- if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
+ mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
&input->bstatus_read, &status,
- hdcp, "bstatus_read"))
- goto out;
- if (!mod_hdcp_execute_and_set(check_link_integrity_dp,
+ hdcp, "bstatus_read");
+
+ mod_hdcp_execute_and_set(check_link_integrity_dp,
&input->link_integrity_check, &status,
- hdcp, "link_integrity_check"))
- goto out;
- if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
+ hdcp, "link_integrity_check");
+
+ mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
&input->reauth_request_check, &status,
- hdcp, "reauth_request_check"))
- goto out;
+ hdcp, "reauth_request_check");
+
out:
return status;
}