From 44810f8de2fb335f2888b6f00a3cd17ab3b1a38a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 17 Dec 2024 09:01:59 -0500 Subject: drm/amd/display/dc: add a new helper to fetch the OEM ddc_service This is the i2c bus used by OEMs for board specific i2c features like RGB. Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c | 6 ++++++ drivers/gpu/drm/amd/display/dc/dc.h | 3 +++ 2 files changed, 9 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index c1b79b379447..261c3bc4d46e 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -150,6 +150,12 @@ bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx) return link->dc->link_srv->update_dsc_config(pipe_ctx); } +struct ddc_service * +dc_get_oem_i2c_device(struct dc *dc) +{ + return dc->res_pool->oem_device; +} + bool dc_is_oem_i2c_device_present( struct dc *dc, size_t slave_address) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 053481ab69ef..0c2c0fc45ae5 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1947,6 +1947,9 @@ int dc_link_aux_transfer_raw(struct ddc_service *ddc, struct aux_payload *payload, enum aux_return_code_type *operation_result); +struct ddc_service * +dc_get_oem_i2c_device(struct dc *dc); + bool dc_is_oem_i2c_device_present( struct dc *dc, size_t slave_address -- cgit v1.2.3 From d957d4a3f8f200b5642f65832896efeb82eea860 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 19 Dec 2024 14:20:56 -0500 Subject: drm/amd/display/dc: add support for oem i2c in atom_firmware_info_v3_1 The fields are marked as reserved in atom_firmware_info_v3_1, but thet contain valid data in all of the vbios images I've looked at so add parse these fields as per atom_firmware_info_v3_2. The offsets are the same and the reset of the structure is the same. v2: squash in NULL checks Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index a62f6c51301c..04eb647acc4e 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -1778,6 +1778,7 @@ static enum bp_result get_firmware_info_v3_1( struct dc_firmware_info *info) { struct atom_firmware_info_v3_1 *firmware_info; + struct atom_firmware_info_v3_2 *firmware_info32; struct atom_display_controller_info_v4_1 *dce_info = NULL; if (!info) @@ -1785,11 +1786,13 @@ static enum bp_result get_firmware_info_v3_1( firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1, DATA_TABLES(firmwareinfo)); + firmware_info32 = GET_IMAGE(struct atom_firmware_info_v3_2, + DATA_TABLES(firmwareinfo)); dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1, DATA_TABLES(dce_info)); - if (!firmware_info || !dce_info) + if (!firmware_info || !firmware_info32 || !dce_info) return BP_RESULT_BADBIOSTABLE; memset(info, 0, sizeof(*info)); @@ -1817,7 +1820,15 @@ static enum bp_result get_firmware_info_v3_1( bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10; } - info->oem_i2c_present = false; + /* These fields are marked as reserved in v3_1, but they appear to be populated + * properly. + */ + if (firmware_info32 && firmware_info32->board_i2c_feature_id == 0x2) { + info->oem_i2c_present = true; + info->oem_i2c_obj_id = firmware_info32->board_i2c_feature_gpio_id; + } else { + info->oem_i2c_present = false; + } return BP_RESULT_OK; } -- cgit v1.2.3 From 2ed83f2cc41e8f7ced1c0610ec2b0821c5522ed5 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 17 Dec 2024 16:49:48 -0500 Subject: drm/amd/display/dc: enable oem i2c support for DCE 12.x Use the value pulled from the vbios just like newer chips. Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- .../amd/display/dc/resource/dce120/dce120_resource.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c index c63c59623433..eb1e158d3436 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c @@ -67,6 +67,7 @@ #include "reg_helper.h" #include "dce100/dce100_resource.h" +#include "link.h" #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f @@ -659,6 +660,12 @@ static void dce120_resource_destruct(struct dce110_resource_pool *pool) if (pool->base.dmcu != NULL) dce_dmcu_destroy(&pool->base.dmcu); + + if (pool->base.oem_device != NULL) { + struct dc *dc = pool->base.oem_device->ctx->dc; + + dc->link_srv->destroy_ddc_service(&pool->base.oem_device); + } } static void read_dce_straps( @@ -1054,6 +1061,7 @@ static bool dce120_resource_construct( struct dc *dc, struct dce110_resource_pool *pool) { + struct ddc_service_init_data ddc_init_data = {0}; unsigned int i; int j; struct dc_context *ctx = dc->ctx; @@ -1257,6 +1265,15 @@ static bool dce120_resource_construct( bw_calcs_data_update_from_pplib(dc); + if (dc->ctx->dc_bios->fw_info.oem_i2c_present) { + ddc_init_data.ctx = dc->ctx; + ddc_init_data.link = NULL; + ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id; + ddc_init_data.id.enum_id = 0; + ddc_init_data.id.type = OBJECT_TYPE_GENERIC; + pool->base.oem_device = dc->link_srv->create_ddc_service(&ddc_init_data); + } + return true; irqs_create_fail: -- cgit v1.2.3 From 9bbb556868c340fbf6f7d77cb215a37f06483f4b Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 15 Jan 2025 11:35:52 +0000 Subject: drm/amd/display: remove extraneous ; after statements There are a couple of statements with two following semicolons, replace these with just one semicolon. Signed-off-by: Colin Ian King Signed-off-by: Alex Deucher --- .../amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 8ed49a9df378..ad4cf1f3d7ea 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 @@ -3894,8 +3894,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) -- cgit v1.2.3 From 6eb4c13a38457c7ff41bbfa7638f34cfda29c662 Mon Sep 17 00:00:00 2001 From: Yan Li Date: Tue, 7 Jan 2025 09:28:16 -0500 Subject: drm/amd/display: Support "Broadcast RGB" drm property [WHY] The source device outputs a full RGB signal, but TV may be set to use limited RGB. The mismatch in color range leads to a degradation in image quality. Display driver should have the ability to switch between the full and limited RGB to match TV's settings. [HOW] Add support of the linux DRM "Broadcast RGB" property, which indicates the Quantization Range (Full vs Limited) used. User space can set this property to be "Automatic", "Full" or "Limited 16:235" to adjust the output color range. Reviewed-by: Jerry Zuo Reviewed-by: Harry Wentland Signed-off-by: Yan Li Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index f84e795e35f5..edf7e3b52b28 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2834,10 +2834,13 @@ static enum surface_update_type check_update_surfaces_for_stream( if (stream_update->sharpening_required) su_flags->bits.sharpening_required = 1; + if (stream_update->output_color_space) + su_flags->bits.out_csc = 1; + if (su_flags->raw != 0) overall_type = UPDATE_TYPE_FULL; - if (stream_update->output_csc_transform || stream_update->output_color_space) + if (stream_update->output_csc_transform) su_flags->bits.out_csc = 1; /* Output transfer function changes do not require bandwidth recalculation, -- cgit v1.2.3 From 06b0a4ad7162b9dd7e52dbec320ea9d080d9e551 Mon Sep 17 00:00:00 2001 From: Josip Pavic Date: Tue, 7 Jan 2025 11:00:11 -0500 Subject: drm/amd/display: log destination of vertical interrupt [Why] Knowing the destination of OTG's vertical interrupt 2 is useful for debugging, but it is not currently included in the OTG state readback logic [How] Read the OTG interrupt destination register to get the vertical interrupt 2 destination on ASICs that have this register when reading back the OTG state from hardware Reviewed-by: Sung Lee Reviewed-by: Aric Cyr Signed-off-by: Josip Pavic Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../display/dc/dcn10/dcn10_hw_sequencer_debug.c | 7 ++- .../drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 3 +- drivers/gpu/drm/amd/display/dc/inc/hw/optc.h | 30 +-------- .../drm/amd/display/dc/inc/hw/timing_generator.h | 30 +++++++++ .../gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.c | 7 ++- .../gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h | 2 + .../gpu/drm/amd/display/dc/optc/dcn20/dcn20_optc.c | 1 + .../drm/amd/display/dc/optc/dcn201/dcn201_optc.c | 1 + .../gpu/drm/amd/display/dc/optc/dcn30/dcn30_optc.c | 1 + .../drm/amd/display/dc/optc/dcn301/dcn301_optc.c | 1 + .../gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.c | 71 ++++++++++++++++++++++ .../gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h | 7 ++- .../drm/amd/display/dc/optc/dcn314/dcn314_optc.c | 1 + .../drm/amd/display/dc/optc/dcn314/dcn314_optc.h | 4 +- .../gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c | 1 + .../gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h | 3 +- .../gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c | 1 + .../gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h | 3 +- .../drm/amd/display/dc/optc/dcn401/dcn401_optc.c | 1 + .../drm/amd/display/dc/optc/dcn401/dcn401_optc.h | 3 +- .../amd/display/dc/resource/dcn32/dcn32_resource.h | 3 +- .../amd/display/dc/resource/dcn35/dcn35_resource.h | 3 +- .../display/dc/resource/dcn401/dcn401_resource.h | 3 +- 23 files changed, 145 insertions(+), 42 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c index 88cf47a5ea75..baf663b661c8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c @@ -429,7 +429,9 @@ static unsigned int dcn10_get_otg_states(struct dc *dc, char *pBuf, unsigned int struct dcn_otg_state s = {0}; int pix_clk = 0; - optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s); + if (tg->funcs->read_otg_state) + tg->funcs->read_otg_state(tg, &s); + pix_clk = dc->current_state->res_ctx.pipe_ctx[i].stream_res.pix_clk_params.requested_pix_clk_100hz / 10; //only print if OTG master is enabled @@ -495,7 +497,8 @@ static void dcn10_clear_otpc_underflow(struct dc *dc) struct timing_generator *tg = pool->timing_generators[i]; struct dcn_otg_state s = {0}; - optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s); + if (tg->funcs->read_otg_state) + tg->funcs->read_otg_state(tg, &s); if (s.otg_enabled & 1) tg->funcs->clear_optc_underflow(tg); 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 44e405e9bc97..c3cf2706b6ba 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 @@ -415,7 +415,8 @@ void dcn10_log_hw_state(struct dc *dc, struct timing_generator *tg = pool->timing_generators[i]; struct dcn_otg_state s = {0}; /* Read shared OTG state registers for all DCNx */ - optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s); + if (tg->funcs->read_otg_state) + tg->funcs->read_otg_state(tg, &s); /* * For DCN2 and greater, a register on the OPP is used to 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 6fdc9809280c..7f371cbb35cd 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/optc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/optc.h @@ -70,35 +70,7 @@ struct optc { enum signal_type signal; }; -struct dcn_otg_state { - uint32_t v_blank_start; - uint32_t v_blank_end; - uint32_t v_sync_a_pol; - uint32_t v_total; - uint32_t v_total_max; - uint32_t v_total_min; - uint32_t v_total_min_sel; - uint32_t v_total_max_sel; - uint32_t v_sync_a_start; - uint32_t v_sync_a_end; - uint32_t h_blank_start; - uint32_t h_blank_end; - uint32_t h_sync_a_start; - uint32_t h_sync_a_end; - uint32_t h_sync_a_pol; - uint32_t h_total; - uint32_t underflow_occurred_status; - uint32_t otg_enabled; - uint32_t blank_enabled; - uint32_t vertical_interrupt1_en; - uint32_t vertical_interrupt1_line; - uint32_t vertical_interrupt2_en; - uint32_t vertical_interrupt2_line; - uint32_t otg_master_update_lock; - uint32_t otg_double_buffer_control; -}; - -void optc1_read_otg_state(struct optc *optc1, struct dcn_otg_state *s); +void optc1_read_otg_state(struct timing_generator *optc, struct dcn_otg_state *s); bool optc1_get_hw_timing(struct timing_generator *tg, struct dc_crtc_timing *hw_crtc_timing); 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 9885cb3c310f..267ace4eef8a 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 @@ -146,6 +146,35 @@ struct crc_params { bool reset; }; +struct dcn_otg_state { + uint32_t v_blank_start; + uint32_t v_blank_end; + uint32_t v_sync_a_pol; + uint32_t v_total; + uint32_t v_total_max; + uint32_t v_total_min; + uint32_t v_total_min_sel; + uint32_t v_total_max_sel; + uint32_t v_sync_a_start; + uint32_t v_sync_a_end; + uint32_t h_blank_start; + uint32_t h_blank_end; + uint32_t h_sync_a_start; + uint32_t h_sync_a_end; + uint32_t h_sync_a_pol; + uint32_t h_total; + uint32_t underflow_occurred_status; + uint32_t otg_enabled; + uint32_t blank_enabled; + uint32_t vertical_interrupt1_en; + uint32_t vertical_interrupt1_line; + uint32_t vertical_interrupt2_en; + uint32_t vertical_interrupt2_line; + uint32_t vertical_interrupt2_dest; + uint32_t otg_master_update_lock; + uint32_t otg_double_buffer_control; +}; + /** * struct timing_generator - Entry point to Output Timing Generator feature. */ @@ -350,6 +379,7 @@ struct timing_generator_funcs { bool (*get_pipe_update_pending)(struct timing_generator *tg); void (*set_vupdate_keepout)(struct timing_generator *tg, bool enable); bool (*wait_update_lock_status)(struct timing_generator *tg, bool locked); + void (*read_otg_state)(struct timing_generator *tg, struct dcn_otg_state *s); }; #endif 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 19d5ebc6763c..6f7b0f816f2a 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 @@ -1312,7 +1312,7 @@ bool optc1_get_hw_timing(struct timing_generator *tg, if (tg == NULL || hw_crtc_timing == NULL) return false; - optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s); + optc1_read_otg_state(tg, &s); hw_crtc_timing->h_total = s.h_total + 1; hw_crtc_timing->h_addressable = s.h_total - ((s.h_total - s.h_blank_start) + s.h_blank_end); @@ -1328,9 +1328,11 @@ bool optc1_get_hw_timing(struct timing_generator *tg, } -void optc1_read_otg_state(struct optc *optc1, +void optc1_read_otg_state(struct timing_generator *optc, struct dcn_otg_state *s) { + struct optc *optc1 = DCN10TG_FROM_TG(optc); + REG_GET(OTG_CONTROL, OTG_MASTER_EN, &s->otg_enabled); @@ -1663,6 +1665,7 @@ static const struct timing_generator_funcs dcn10_tg_funcs = { .setup_manual_trigger = optc1_setup_manual_trigger, .get_hw_timing = optc1_get_hw_timing, .is_two_pixels_per_container = optc1_is_two_pixels_per_container, + .read_otg_state = optc1_read_otg_state, }; void dcn10_timing_generator_init(struct optc *optc1) 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 159172178d51..82b91b9bc9c2 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 @@ -209,6 +209,7 @@ struct dcn_optc_registers { uint32_t OPTC_WIDTH_CONTROL2; uint32_t OTG_PSTATE_REGISTER; uint32_t OTG_PIPE_UPDATE_STATUS; + uint32_t INTERRUPT_DEST; }; #define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\ @@ -591,6 +592,7 @@ struct dcn_optc_registers { type OTG_DC_REG_UPDATE_PENDING;\ type OTG_CURSOR_UPDATE_PENDING;\ type OTG_VUPDATE_KEEPOUT_STATUS;\ + type OTG0_IHC_OTG_VERTICAL_INTERRUPT2_DEST; #define TG_REG_FIELD_LIST_DCN3_2(type) \ type OTG_H_TIMING_DIV_MODE_MANUAL; diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn20/dcn20_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn20/dcn20_optc.c index b4694985a40a..81857ce6d68d 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn20/dcn20_optc.c +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn20/dcn20_optc.c @@ -562,6 +562,7 @@ static struct timing_generator_funcs dcn20_tg_funcs = { .get_hw_timing = optc1_get_hw_timing, .align_vblanks = optc2_align_vblanks, .is_two_pixels_per_container = optc1_is_two_pixels_per_container, + .read_otg_state = optc1_read_otg_state, }; void dcn20_timing_generator_init(struct optc *optc1) diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn201/dcn201_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn201/dcn201_optc.c index 49c2efdfa403..f2415eebdc09 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn201/dcn201_optc.c +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn201/dcn201_optc.c @@ -180,6 +180,7 @@ static struct timing_generator_funcs dcn201_tg_funcs = { .setup_manual_trigger = optc2_setup_manual_trigger, .get_hw_timing = optc1_get_hw_timing, .is_two_pixels_per_container = optc1_is_two_pixels_per_container, + .read_otg_state = optc1_read_otg_state, }; void dcn201_timing_generator_init(struct optc *optc1) diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn30/dcn30_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn30/dcn30_optc.c index 4c95c0958612..78b58a449fa4 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn30/dcn30_optc.c +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn30/dcn30_optc.c @@ -420,6 +420,7 @@ static struct timing_generator_funcs dcn30_tg_funcs = { .get_optc_double_buffer_pending = optc3_get_optc_double_buffer_pending, .get_otg_double_buffer_pending = optc3_get_otg_update_pending, .get_pipe_update_pending = optc3_get_pipe_update_pending, + .read_otg_state = optc1_read_otg_state, }; void dcn30_timing_generator_init(struct optc *optc1) diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn301/dcn301_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn301/dcn301_optc.c index d7a45ef2d01b..65e9089b7f31 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn301/dcn301_optc.c +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn301/dcn301_optc.c @@ -172,6 +172,7 @@ static struct timing_generator_funcs dcn30_tg_funcs = { .get_optc_double_buffer_pending = optc3_get_optc_double_buffer_pending, .get_otg_double_buffer_pending = optc3_get_otg_update_pending, .get_pipe_update_pending = optc3_get_pipe_update_pending, + .read_otg_state = optc1_read_otg_state, }; void dcn301_timing_generator_init(struct optc *optc1) 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 4b6446ed4ce4..ef536f37b4ed 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 @@ -245,6 +245,76 @@ void optc3_init_odm(struct timing_generator *optc) optc1->opp_count = 1; } +void optc31_read_otg_state(struct timing_generator *optc, + struct dcn_otg_state *s) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + REG_GET(OTG_CONTROL, + OTG_MASTER_EN, &s->otg_enabled); + + REG_GET_2(OTG_V_BLANK_START_END, + OTG_V_BLANK_START, &s->v_blank_start, + OTG_V_BLANK_END, &s->v_blank_end); + + REG_GET(OTG_V_SYNC_A_CNTL, + OTG_V_SYNC_A_POL, &s->v_sync_a_pol); + + REG_GET(OTG_V_TOTAL, + OTG_V_TOTAL, &s->v_total); + + REG_GET(OTG_V_TOTAL_MAX, + OTG_V_TOTAL_MAX, &s->v_total_max); + + REG_GET(OTG_V_TOTAL_MIN, + OTG_V_TOTAL_MIN, &s->v_total_min); + + REG_GET(OTG_V_TOTAL_CONTROL, + OTG_V_TOTAL_MAX_SEL, &s->v_total_max_sel); + + REG_GET(OTG_V_TOTAL_CONTROL, + OTG_V_TOTAL_MIN_SEL, &s->v_total_min_sel); + + REG_GET_2(OTG_V_SYNC_A, + OTG_V_SYNC_A_START, &s->v_sync_a_start, + OTG_V_SYNC_A_END, &s->v_sync_a_end); + + REG_GET_2(OTG_H_BLANK_START_END, + OTG_H_BLANK_START, &s->h_blank_start, + OTG_H_BLANK_END, &s->h_blank_end); + + REG_GET_2(OTG_H_SYNC_A, + OTG_H_SYNC_A_START, &s->h_sync_a_start, + OTG_H_SYNC_A_END, &s->h_sync_a_end); + + REG_GET(OTG_H_SYNC_A_CNTL, + OTG_H_SYNC_A_POL, &s->h_sync_a_pol); + + REG_GET(OTG_H_TOTAL, + OTG_H_TOTAL, &s->h_total); + + REG_GET(OPTC_INPUT_GLOBAL_CONTROL, + OPTC_UNDERFLOW_OCCURRED_STATUS, &s->underflow_occurred_status); + + REG_GET(OTG_VERTICAL_INTERRUPT1_CONTROL, + OTG_VERTICAL_INTERRUPT1_INT_ENABLE, &s->vertical_interrupt1_en); + + REG_GET(OTG_VERTICAL_INTERRUPT1_POSITION, + OTG_VERTICAL_INTERRUPT1_LINE_START, &s->vertical_interrupt1_line); + + REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL, + OTG_VERTICAL_INTERRUPT2_INT_ENABLE, &s->vertical_interrupt2_en); + + REG_GET(OTG_VERTICAL_INTERRUPT2_POSITION, + OTG_VERTICAL_INTERRUPT2_LINE_START, &s->vertical_interrupt2_line); + + REG_GET(INTERRUPT_DEST, + OTG0_IHC_OTG_VERTICAL_INTERRUPT2_DEST, &s->vertical_interrupt2_dest); + + s->otg_master_update_lock = REG_READ(OTG_MASTER_UPDATE_LOCK); + s->otg_double_buffer_control = REG_READ(OTG_DOUBLE_BUFFER_CONTROL); +} + static struct timing_generator_funcs dcn31_tg_funcs = { .validate_timing = optc1_validate_timing, .program_timing = optc1_program_timing, @@ -306,6 +376,7 @@ static struct timing_generator_funcs dcn31_tg_funcs = { .get_hw_timing = optc1_get_hw_timing, .init_odm = optc3_init_odm, .is_two_pixels_per_container = optc1_is_two_pixels_per_container, + .read_otg_state = optc31_read_otg_state, }; void dcn31_timing_generator_init(struct optc *optc1) diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h index fbbe86d00c2e..0f72c274f40b 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h @@ -100,7 +100,8 @@ SRI(OTG_CRC_CNTL2, OTG, inst),\ SR(DWB_SOURCE_SELECT),\ SRI(OTG_DRR_CONTROL, OTG, inst),\ - SRI(OTG_PIPE_UPDATE_STATUS, OTG, inst) + SRI(OTG_PIPE_UPDATE_STATUS, OTG, inst),\ + SRI(INTERRUPT_DEST, OTG, inst) #define OPTC_COMMON_MASK_SH_LIST_DCN3_1(mask_sh)\ SF(OTG0_OTG_VSTARTUP_PARAM, VSTARTUP_START, mask_sh),\ @@ -260,6 +261,7 @@ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_DC_REG_UPDATE_PENDING, mask_sh),\ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_CURSOR_UPDATE_PENDING, mask_sh),\ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh),\ + SF(OTG0_INTERRUPT_DEST, OTG0_IHC_OTG_VERTICAL_INTERRUPT2_DEST, mask_sh) void dcn31_timing_generator_init(struct optc *optc1); @@ -269,4 +271,7 @@ void optc31_set_drr(struct timing_generator *optc, const struct drr_params *para void optc3_init_odm(struct timing_generator *optc); +void optc31_read_otg_state(struct timing_generator *optc, + struct dcn_otg_state *s); + #endif /* __DC_OPTC_DCN31_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.c index 633d62addd4d..0e603bad0d12 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.c +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.c @@ -255,6 +255,7 @@ static struct timing_generator_funcs dcn314_tg_funcs = { .set_odm_combine = optc314_set_odm_combine, .set_h_timing_div_manual_mode = optc314_set_h_timing_div_manual_mode, .is_two_pixels_per_container = optc1_is_two_pixels_per_container, + .read_otg_state = optc31_read_otg_state, }; void dcn314_timing_generator_init(struct optc *optc1) diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.h index 0ff72b97b465..6bfdee3fcf5f 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.h +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.h @@ -99,7 +99,8 @@ SRI(OPTC_WIDTH_CONTROL, ODM, inst),\ SRI(OPTC_MEMORY_CONFIG, ODM, inst),\ SRI(OTG_DRR_CONTROL, OTG, inst),\ - SRI(OTG_PIPE_UPDATE_STATUS, OTG, inst) + SRI(OTG_PIPE_UPDATE_STATUS, OTG, inst),\ + SRI(INTERRUPT_DEST, OTG, inst) #define OPTC_COMMON_MASK_SH_LIST_DCN3_14(mask_sh)\ SF(OTG0_OTG_VSTARTUP_PARAM, VSTARTUP_START, mask_sh),\ @@ -254,6 +255,7 @@ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_DC_REG_UPDATE_PENDING, mask_sh),\ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_CURSOR_UPDATE_PENDING, mask_sh),\ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh),\ + SF(OTG0_INTERRUPT_DEST, OTG0_IHC_OTG_VERTICAL_INTERRUPT2_DEST, mask_sh) void dcn314_timing_generator_init(struct optc *optc1); diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c index c217f653b3c8..2cdd19ba634b 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c @@ -364,6 +364,7 @@ static struct timing_generator_funcs dcn32_tg_funcs = { .get_optc_double_buffer_pending = optc3_get_optc_double_buffer_pending, .get_otg_double_buffer_pending = optc3_get_otg_update_pending, .get_pipe_update_pending = optc3_get_pipe_update_pending, + .read_otg_state = optc31_read_otg_state, }; void dcn32_timing_generator_init(struct optc *optc1) diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h index 0b0964a9da74..d159e3ed3bb3 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h @@ -181,7 +181,8 @@ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_FLIP_PENDING, mask_sh),\ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_DC_REG_UPDATE_PENDING, mask_sh),\ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_CURSOR_UPDATE_PENDING, mask_sh),\ - SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh) + SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh),\ + SF(OTG0_INTERRUPT_DEST, OTG0_IHC_OTG_VERTICAL_INTERRUPT2_DEST, mask_sh) void dcn32_timing_generator_init(struct optc *optc1); void optc32_set_h_timing_div_manual_mode(struct timing_generator *optc, bool manual_mode); diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c index d21e82b927d0..b86fe2b094f8 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c @@ -492,6 +492,7 @@ static struct timing_generator_funcs dcn35_tg_funcs = { .init_odm = optc3_init_odm, .set_long_vtotal = optc35_set_long_vtotal, .is_two_pixels_per_container = optc1_is_two_pixels_per_container, + .read_otg_state = optc31_read_otg_state, }; void dcn35_timing_generator_init(struct optc *optc1) diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h index be749ab41dce..733a2f149d9a 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h @@ -71,7 +71,8 @@ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_FLIP_PENDING, mask_sh),\ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_DC_REG_UPDATE_PENDING, mask_sh),\ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_CURSOR_UPDATE_PENDING, mask_sh),\ - SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh) + SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh),\ + SF(OTG0_INTERRUPT_DEST, OTG0_IHC_OTG_VERTICAL_INTERRUPT2_DEST, mask_sh) void dcn35_timing_generator_init(struct optc *optc1); 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 338a0cad23a5..bf921d1f500b 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 @@ -527,6 +527,7 @@ static struct timing_generator_funcs dcn401_tg_funcs = { .get_pipe_update_pending = optc3_get_pipe_update_pending, .set_vupdate_keepout = optc401_set_vupdate_keepout, .wait_update_lock_status = optc401_wait_update_lock_status, + .read_otg_state = optc31_read_otg_state, }; void dcn401_timing_generator_init(struct optc *optc1) 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 1be89571986f..69ad21084fbb 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 @@ -163,7 +163,8 @@ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_FLIP_PENDING, mask_sh),\ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_DC_REG_UPDATE_PENDING, mask_sh),\ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_CURSOR_UPDATE_PENDING, mask_sh),\ - SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh) + SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh),\ + SF(OTG0_INTERRUPT_DEST, OTG0_IHC_OTG_VERTICAL_INTERRUPT2_DEST, mask_sh) void dcn401_timing_generator_init(struct optc *optc1); 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 86c6e5e8c42e..1aa4ced29291 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 @@ -1055,7 +1055,8 @@ unsigned int dcn32_calculate_mall_ways_from_bytes(const struct dc *dc, unsigned SRI_ARR(OPTC_WIDTH_CONTROL, ODM, inst), \ SRI_ARR(OPTC_MEMORY_CONFIG, ODM, inst), \ SRI_ARR(OTG_DRR_CONTROL, OTG, inst), \ - SRI_ARR(OTG_PIPE_UPDATE_STATUS, OTG, inst) + SRI_ARR(OTG_PIPE_UPDATE_STATUS, OTG, inst), \ + SRI_ARR(INTERRUPT_DEST, OTG, inst) /* HUBP */ diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.h b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.h index 9d03a55d90cf..9c56ae76e0c7 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.h +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.h @@ -305,7 +305,8 @@ struct resource_pool *dcn35_create_resource_pool( SRI_ARR(OPTC_WIDTH_CONTROL, ODM, inst),\ SRI_ARR(OPTC_MEMORY_CONFIG, ODM, inst),\ SRI_ARR(OTG_DRR_CONTROL, OTG, inst),\ - SRI2_ARR(OPTC_CLOCK_CONTROL, OPTC, inst) + SRI2_ARR(OPTC_CLOCK_CONTROL, OPTC, inst),\ + SRI_ARR(INTERRUPT_DEST, OTG, inst) /* DPP */ #define DPP_REG_LIST_DCN35_RI(id)\ 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 19568c359669..4c259745d519 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 @@ -538,7 +538,8 @@ void dcn401_prepare_mcache_programming(struct dc *dc, struct dc_state *context); SRI_ARR(OPTC_MEMORY_CONFIG, ODM, inst), \ SRI_ARR(OTG_DRR_CONTROL, OTG, inst), \ SRI_ARR(OTG_PSTATE_REGISTER, OTG, inst), \ - SRI_ARR(OTG_PIPE_UPDATE_STATUS, OTG, inst) + SRI_ARR(OTG_PIPE_UPDATE_STATUS, OTG, inst), \ + SRI_ARR(INTERRUPT_DEST, OTG, inst) /* HUBBUB */ #define HUBBUB_REG_LIST_DCN4_01_RI(id) \ -- cgit v1.2.3 From ae36501515e253556f85f55d83b8e1d473b55424 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Tue, 8 Oct 2024 13:08:23 +0800 Subject: drm/amd/display: Add AS SDP programming for UHBR link rate. Add SDP programming for UHB link as well. Reviewed-by: Wenjing Liu Signed-off-by: Ian Chen Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') 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 03ba01f4ace1..f698062f1e90 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 @@ -396,6 +396,11 @@ void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx) pipe_ctx->stream_res.stream_enc, &pipe_ctx->stream_res.encoder_info_frame); else if (pipe_ctx->stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { + if (pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->update_dp_info_packets_sdp_line_num) + pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->update_dp_info_packets_sdp_line_num( + pipe_ctx->stream_res.hpo_dp_stream_enc, + &pipe_ctx->stream_res.encoder_info_frame); + pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->update_dp_info_packets( pipe_ctx->stream_res.hpo_dp_stream_enc, &pipe_ctx->stream_res.encoder_info_frame); -- cgit v1.2.3 From 5f0d1ef6f16e150ee46cc00b8d233d9d271fe39e Mon Sep 17 00:00:00 2001 From: Dillon Varone Date: Wed, 8 Jan 2025 15:25:41 -0500 Subject: drm/amd/display: Populate register address for dentist for dcn401 [WHY&HOW] Address was not previously populated which can result in incorrect clock frequencies being read on boot. Reviewed-by: Alvin Lee Signed-off-by: Dillon Varone Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c | 2 ++ drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') 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 8082bb877611..a3b8e3d4a429 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 @@ -24,6 +24,8 @@ #include "dml/dcn401/dcn401_fpu.h" +#define DCN_BASE__INST0_SEG1 0x000000C0 + #define mmCLK01_CLK0_CLK_PLL_REQ 0x16E37 #define mmCLK01_CLK0_CLK0_DFS_CNTL 0x16E69 #define mmCLK01_CLK0_CLK1_DFS_CNTL 0x16E6C 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 7a1ca1e98059..221645c023b5 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 @@ -221,6 +221,7 @@ enum dentist_divider_range { CLK_SF(CLK0_CLK_PLL_REQ, FbMult_frac, mask_sh) #define CLK_REG_LIST_DCN401() \ + SR(DENTIST_DISPCLK_CNTL), \ CLK_SR_DCN401(CLK0_CLK_PLL_REQ, CLK01, 0), \ CLK_SR_DCN401(CLK0_CLK0_DFS_CNTL, CLK01, 0), \ CLK_SR_DCN401(CLK0_CLK1_DFS_CNTL, CLK01, 0), \ -- cgit v1.2.3 From 41df56b1fc24cc36fffb10e437385b3a49fbb5e2 Mon Sep 17 00:00:00 2001 From: Austin Zheng Date: Tue, 7 Jan 2025 17:49:36 -0500 Subject: drm/amd/display: Use Nominal vBlank If Provided Instead Of Capping It [Why/How] vBlank used to determine the max vStartup is based on the smallest between the vblank provided by the timing and vblank in ip_caps. Extra vblank time is not considered if the vblank provided by the timing ends up being higher than what's defined by the ip_caps Use 1 less than the vblank size in case the timing is interlaced so vstartup will always be less than vblank_nom. Reviewed-by: Dillon Varone Signed-off-by: Austin Zheng Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 ad4cf1f3d7ea..51b457b6d66f 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 @@ -3709,13 +3709,12 @@ static unsigned int CalculateMaxVStartup( double line_time_us = (double)timing->h_total / ((double)timing->pixel_clock_khz / 1000); unsigned int vblank_actual = timing->v_total - timing->v_active; unsigned int vblank_nom_default_in_line = (unsigned int)math_floor2((double)vblank_nom_default_us / line_time_us, 1.0); - unsigned int vblank_nom_input = (unsigned int)math_min2(timing->vblank_nom, vblank_nom_default_in_line); - unsigned int vblank_avail = (vblank_nom_input == 0) ? vblank_nom_default_in_line : vblank_nom_input; + unsigned int vblank_avail = (timing->vblank_nom == 0) ? vblank_nom_default_in_line : (unsigned int)timing->vblank_nom; vblank_size = (unsigned int)math_min2(vblank_actual, vblank_avail); if (timing->interlaced && !ptoi_supported) - max_vstartup_lines = (unsigned int)(math_floor2(vblank_size / 2.0, 1.0)); + max_vstartup_lines = (unsigned int)(math_floor2((vblank_size - 1) / 2.0, 1.0)); else max_vstartup_lines = vblank_size - (unsigned int)math_max2(1.0, math_ceil2(write_back_delay_us / line_time_us, 1.0)); #ifdef __DML_VBA_DEBUG__ -- cgit v1.2.3 From 3a7810c212bcf2f722671dadf4b23ff70a7d23ee Mon Sep 17 00:00:00 2001 From: Joshua Aberback Date: Wed, 8 Jan 2025 12:03:23 -0500 Subject: drm/amd/display: Increase block_sequence array size [Why] It's possible to generate more than 50 steps in hwss_build_fast_sequence, for example with a 6-pipe asic where all pipes are in one MPC chain. This overflows the block_sequence buffer and corrupts block_sequence_steps, causing a crash. [How] Expand block_sequence to 100 items. A naive upper bound on the possible number of steps for a 6-pipe asic, ignoring the potential for steps to be mutually exclusive, is 91 with current code, therefore 100 is sufficient. Reviewed-by: Alvin Lee Signed-off-by: Joshua Aberback Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/inc/core_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 d558efc6e12f..652d52040f4e 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -627,7 +627,7 @@ struct dc_state { */ struct bw_context bw_ctx; - struct block_sequence block_sequence[50]; + struct block_sequence block_sequence[100]; unsigned int block_sequence_steps; struct dc_dmub_cmd dc_dmub_cmd[10]; unsigned int dmub_cmd_count; -- cgit v1.2.3 From b9e124a565c9df9508e49f1cdeaf9a3b5acff665 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Fri, 10 Jan 2025 10:45:03 -0500 Subject: drm/amd/display: Exclude clkoffset and ips setting for dcn351 specific Exclude clock offset and IPS setting for dcn351 specific only. Reviewed-by: Syed Hassan Reviewed-by: Nicholas Kazlauskas Signed-off-by: Charlene Liu Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 1648226586e2..56800c573a71 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 @@ -1249,7 +1249,7 @@ void dcn35_clk_mgr_construct( clk_mgr->base.dprefclk_ss_divider = 1000; clk_mgr->base.ss_on_dprefclk = false; clk_mgr->base.dfs_ref_freq_khz = 48000; - if (ctx->dce_version == DCN_VERSION_3_5) { + if (ctx->dce_version != DCN_VERSION_3_51) { clk_mgr->base.regs = &clk_mgr_regs_dcn35; clk_mgr->base.clk_mgr_shift = &clk_mgr_shift_dcn35; clk_mgr->base.clk_mgr_mask = &clk_mgr_mask_dcn35; @@ -1401,7 +1401,7 @@ void dcn35_clk_mgr_construct( /* Disable dynamic IPS2 in older PMFW (93.12) for Z8 interop. */ if (ctx->dc->config.disable_ips == DMUB_IPS_ENABLE && - ctx->dce_version == DCN_VERSION_3_5 && + ctx->dce_version != DCN_VERSION_3_51 && ((clk_mgr->base.smu_ver & 0x00FFFFFF) <= 0x005d0c00)) ctx->dc->config.disable_ips = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF; } else { -- cgit v1.2.3 From 3c50bf2196aaddcaffe2c7a1a7080470380cbfdd Mon Sep 17 00:00:00 2001 From: Peterson Guo Date: Thu, 5 Dec 2024 18:51:25 -0500 Subject: drm/amd/display: Reverse the visual confirm recouts [WHY] When checking if a pipe can disable cursor to prevent duplicate cursors, having visual confirm on will prevent disabling cursors on planes which cover the bottom of the screen. [HOW] When checking if a plane can disable visual confirm, the pipe first reverses these calculations before doing the checks. Reviewed-by: Alvin Lee Signed-off-by: Peterson Guo Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 67 ++++++++++++++++++++++ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 50 +--------------- .../drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 48 +--------------- .../drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 48 +--------------- drivers/gpu/drm/amd/display/dc/inc/resource.h | 2 + 5 files changed, 73 insertions(+), 142 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 520a34a42827..72c88fdeb28c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -941,6 +941,17 @@ static void calculate_adjust_recout_for_visual_confirm(struct pipe_ctx *pipe_ctx *base_offset = VISUAL_CONFIRM_BASE_DEFAULT; } +static void reverse_adjust_recout_for_visual_confirm(struct rect *recout, + struct pipe_ctx *pipe_ctx) +{ + int dpp_offset, base_offset; + + calculate_adjust_recout_for_visual_confirm(pipe_ctx, &base_offset, + &dpp_offset); + recout->height += base_offset; + recout->height += dpp_offset; +} + static void adjust_recout_for_visual_confirm(struct rect *recout, struct pipe_ctx *pipe_ctx) { @@ -1641,6 +1652,62 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) return res; } +bool resource_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) +{ + struct pipe_ctx *test_pipe, *split_pipe; + struct rect r1 = pipe_ctx->plane_res.scl_data.recout; + int r1_right, r1_bottom; + int cur_layer = pipe_ctx->plane_state->layer_index; + + reverse_adjust_recout_for_visual_confirm(&r1, pipe_ctx); + r1_right = r1.x + r1.width; + r1_bottom = r1.y + r1.height; + + /** + * Disable the cursor if there's another pipe above this with a + * plane that contains this pipe's viewport to prevent double cursor + * and incorrect scaling artifacts. + */ + for (test_pipe = pipe_ctx->top_pipe; test_pipe; + test_pipe = test_pipe->top_pipe) { + struct rect r2; + int r2_right, r2_bottom; + // Skip invisible layer and pipe-split plane on same layer + if (!test_pipe->plane_state || + !test_pipe->plane_state->visible || + test_pipe->plane_state->layer_index == cur_layer) + continue; + + r2 = test_pipe->plane_res.scl_data.recout; + reverse_adjust_recout_for_visual_confirm(&r2, test_pipe); + r2_right = r2.x + r2.width; + r2_bottom = r2.y + r2.height; + + /** + * There is another half plane on same layer because of + * pipe-split, merge together per same height. + */ + for (split_pipe = pipe_ctx->top_pipe; split_pipe; + split_pipe = split_pipe->top_pipe) + if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) { + struct rect r2_half; + + r2_half = split_pipe->plane_res.scl_data.recout; + reverse_adjust_recout_for_visual_confirm(&r2_half, split_pipe); + r2.x = min(r2_half.x, r2.x); + r2.width = r2.width + r2_half.width; + r2_right = r2.x + r2.width; + r2_bottom = min(r2_bottom, r2_half.y + r2_half.height); + break; + } + + if (r1.x >= r2.x && r1.y >= r2.y && r1_right <= r2_right && r1_bottom <= r2_bottom) + return true; + } + + return false; +} + enum dc_status resource_build_scaling_params_for_context( const struct dc *dc, 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 44ff9abe2880..87b4c2793df3 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -991,57 +991,11 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv) DC_LOG_DEBUG(" is_cw6_en : %d", diag_data.is_cw6_enabled); } -static bool dc_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) -{ - struct pipe_ctx *test_pipe, *split_pipe; - const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data; - struct rect r1 = scl_data->recout, r2, r2_half; - int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b; - int cur_layer = pipe_ctx->plane_state->layer_index; - - /** - * Disable the cursor if there's another pipe above this with a - * plane that contains this pipe's viewport to prevent double cursor - * and incorrect scaling artifacts. - */ - for (test_pipe = pipe_ctx->top_pipe; test_pipe; - test_pipe = test_pipe->top_pipe) { - // Skip invisible layer and pipe-split plane on same layer - if (!test_pipe->plane_state->visible || test_pipe->plane_state->layer_index == cur_layer) - continue; - - r2 = test_pipe->plane_res.scl_data.recout; - r2_r = r2.x + r2.width; - r2_b = r2.y + r2.height; - - /** - * There is another half plane on same layer because of - * pipe-split, merge together per same height. - */ - for (split_pipe = pipe_ctx->top_pipe; split_pipe; - split_pipe = split_pipe->top_pipe) - if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) { - r2_half = split_pipe->plane_res.scl_data.recout; - r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x; - r2.width = r2.width + r2_half.width; - r2_r = r2.x + r2.width; - break; - } - - if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= r2_b) - return true; - } - - return false; -} - static bool dc_dmub_should_update_cursor_data(struct pipe_ctx *pipe_ctx) { if (pipe_ctx->plane_state != NULL) { - if (pipe_ctx->plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) - return false; - - if (dc_can_pipe_disable_cursor(pipe_ctx)) + if (pipe_ctx->plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE || + resource_can_pipe_disable_cursor(pipe_ctx)) return false; } 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 c3cf2706b6ba..906934128912 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 @@ -3432,52 +3432,6 @@ void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data) hubbub->funcs->update_dchub(hubbub, dh_data); } -static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) -{ - struct pipe_ctx *test_pipe, *split_pipe; - const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data; - struct rect r1 = scl_data->recout, r2, r2_half; - int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b; - int cur_layer = pipe_ctx->plane_state->layer_index; - - /** - * Disable the cursor if there's another pipe above this with a - * plane that contains this pipe's viewport to prevent double cursor - * and incorrect scaling artifacts. - */ - for (test_pipe = pipe_ctx->top_pipe; test_pipe; - test_pipe = test_pipe->top_pipe) { - // Skip invisible layer and pipe-split plane on same layer - if (!test_pipe->plane_state || - !test_pipe->plane_state->visible || - test_pipe->plane_state->layer_index == cur_layer) - continue; - - r2 = test_pipe->plane_res.scl_data.recout; - r2_r = r2.x + r2.width; - r2_b = r2.y + r2.height; - - /** - * There is another half plane on same layer because of - * pipe-split, merge together per same height. - */ - for (split_pipe = pipe_ctx->top_pipe; split_pipe; - split_pipe = split_pipe->top_pipe) - if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) { - r2_half = split_pipe->plane_res.scl_data.recout; - r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x; - r2.width = r2.width + r2_half.width; - r2_r = r2.x + r2.width; - break; - } - - if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= r2_b) - return true; - } - - return false; -} - void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) { struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; @@ -3577,7 +3531,7 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) pos_cpy.enable = false; - if (pos_cpy.enable && dcn10_can_pipe_disable_cursor(pipe_ctx)) + if (pos_cpy.enable && resource_can_pipe_disable_cursor(pipe_ctx)) pos_cpy.enable = false; 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 555a9f590cd7..92bb820817b9 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 @@ -972,52 +972,6 @@ void dcn401_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable) REG_UPDATE(HPO_TOP_HW_CONTROL, HPO_IO_EN, enable); } -static bool dcn401_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) -{ - struct pipe_ctx *test_pipe, *split_pipe; - const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data; - struct rect r1 = scl_data->recout, r2, r2_half; - int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b; - int cur_layer = pipe_ctx->plane_state->layer_index; - - /** - * Disable the cursor if there's another pipe above this with a - * plane that contains this pipe's viewport to prevent double cursor - * and incorrect scaling artifacts. - */ - for (test_pipe = pipe_ctx->top_pipe; test_pipe; - test_pipe = test_pipe->top_pipe) { - // Skip invisible layer and pipe-split plane on same layer - if (!test_pipe->plane_state || - !test_pipe->plane_state->visible || - test_pipe->plane_state->layer_index == cur_layer) - continue; - - r2 = test_pipe->plane_res.scl_data.recout; - r2_r = r2.x + r2.width; - r2_b = r2.y + r2.height; - - /** - * There is another half plane on same layer because of - * pipe-split, merge together per same height. - */ - for (split_pipe = pipe_ctx->top_pipe; split_pipe; - split_pipe = split_pipe->top_pipe) - if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) { - r2_half = split_pipe->plane_res.scl_data.recout; - r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x; - r2.width = r2.width + r2_half.width; - r2_r = r2.x + r2.width; - break; - } - - if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= r2_b) - return true; - } - - return false; -} - void adjust_hotspot_between_slices_for_2x_magnify(uint32_t cursor_width, struct dc_cursor_position *pos_cpy) { if (cursor_width <= 128) { @@ -1208,7 +1162,7 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx) pos_cpy.x = (uint32_t)x_pos; pos_cpy.y = (uint32_t)y_pos; - if (pos_cpy.enable && dcn401_can_pipe_disable_cursor(pipe_ctx)) + if (pos_cpy.enable && resource_can_pipe_disable_cursor(pipe_ctx)) pos_cpy.enable = false; x_pos = pos_cpy.x - param.recout.x; diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index cd1157d225ab..b32d07ce0f08 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -152,6 +152,8 @@ bool resource_attach_surfaces_to_context( struct dc_state *context, const struct resource_pool *pool); +bool resource_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx); + #define FREE_PIPE_INDEX_NOT_FOUND -1 /* -- cgit v1.2.3 From 7597d8f2e567daa02ca44e74fac2395bec120f3a Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Sun, 12 Jan 2025 20:44:53 -0500 Subject: drm/amd/display: 3.2.317 This version brings along following fixes: - Reverse the visual confirm recouts - Exclude clkoffset and ips setting for dcn351 specific - Fix cursor programming problems - Increase block_sequence array size - Use Nominal vBlank to determine vstartup if Provided - Fix clock frequencies incorrect problems for dcn401 - Add SDP programming for UHBR link as well - Support "Broadcast RGB" drm property Acked-by: Tom Chung Signed-off-by: Aric Cyr Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 0c2c0fc45ae5..019459dfd6fe 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.316" +#define DC_VER "3.2.317" #define MAX_SURFACES 4 #define MAX_PLANES 6 -- cgit v1.2.3 From 091e301c2b412f74795c1c65b97d49984ae2e211 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 20 Jan 2025 13:49:00 -0600 Subject: drm/amd/display: Add debug messages for dc_validate_boot_timing() dc_validate_boot_timing() runs through an exhaustive list of checks to determine whether a boot stream can be marked as seamless. When the checks fail, a user will be left guessing what the reason was Add debug statements that will be helpful to validate the specific reason. Reviewed-by: Harry Wentland Link: https://lore.kernel.org/r/20250120194903.1048811-1-superm1@kernel.org Signed-off-by: Mario Limonciello Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 114 +++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 28 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index edf7e3b52b28..ba3a34fad26a 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1720,17 +1720,23 @@ bool dc_validate_boot_timing(const struct dc *dc, return false; } - if (dc->debug.force_odm_combine) + if (dc->debug.force_odm_combine) { + DC_LOG_DEBUG("boot timing validation failed due to force_odm_combine\n"); return false; + } /* Check for enabled DIG to identify enabled display */ - if (!link->link_enc->funcs->is_dig_enabled(link->link_enc)) + if (!link->link_enc->funcs->is_dig_enabled(link->link_enc)) { + DC_LOG_DEBUG("boot timing validation failed due to disabled DIG\n"); return false; + } enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc); - if (enc_inst == ENGINE_ID_UNKNOWN) + if (enc_inst == ENGINE_ID_UNKNOWN) { + DC_LOG_DEBUG("boot timing validation failed due to unknown DIG engine ID\n"); return false; + } for (i = 0; i < dc->res_pool->stream_enc_count; i++) { if (dc->res_pool->stream_enc[i]->id == enc_inst) { @@ -1744,62 +1750,98 @@ bool dc_validate_boot_timing(const struct dc *dc, } // tg_inst not found - if (i == dc->res_pool->stream_enc_count) + if (i == dc->res_pool->stream_enc_count) { + DC_LOG_DEBUG("boot timing validation failed due to timing generator instance not found\n"); return false; + } - if (tg_inst >= dc->res_pool->timing_generator_count) + if (tg_inst >= dc->res_pool->timing_generator_count) { + DC_LOG_DEBUG("boot timing validation failed due to invalid timing generator count\n"); return false; + } - if (tg_inst != link->link_enc->preferred_engine) + if (tg_inst != link->link_enc->preferred_engine) { + DC_LOG_DEBUG("boot timing validation failed due to non-preferred timing generator\n"); return false; + } tg = dc->res_pool->timing_generators[tg_inst]; - if (!tg->funcs->get_hw_timing) + if (!tg->funcs->get_hw_timing) { + DC_LOG_DEBUG("boot timing validation failed due to missing get_hw_timing callback\n"); return false; + } - if (!tg->funcs->get_hw_timing(tg, &hw_crtc_timing)) + if (!tg->funcs->get_hw_timing(tg, &hw_crtc_timing)) { + DC_LOG_DEBUG("boot timing validation failed due to failed get_hw_timing return\n"); return false; + } - if (crtc_timing->h_total != hw_crtc_timing.h_total) + if (crtc_timing->h_total != hw_crtc_timing.h_total) { + DC_LOG_DEBUG("boot timing validation failed due to h_total mismatch\n"); return false; + } - if (crtc_timing->h_border_left != hw_crtc_timing.h_border_left) + if (crtc_timing->h_border_left != hw_crtc_timing.h_border_left) { + DC_LOG_DEBUG("boot timing validation failed due to h_border_left mismatch\n"); return false; + } - if (crtc_timing->h_addressable != hw_crtc_timing.h_addressable) + if (crtc_timing->h_addressable != hw_crtc_timing.h_addressable) { + DC_LOG_DEBUG("boot timing validation failed due to h_addressable mismatch\n"); return false; + } - if (crtc_timing->h_border_right != hw_crtc_timing.h_border_right) + if (crtc_timing->h_border_right != hw_crtc_timing.h_border_right) { + DC_LOG_DEBUG("boot timing validation failed due to h_border_right mismatch\n"); return false; + } - if (crtc_timing->h_front_porch != hw_crtc_timing.h_front_porch) + if (crtc_timing->h_front_porch != hw_crtc_timing.h_front_porch) { + DC_LOG_DEBUG("boot timing validation failed due to h_front_porch mismatch\n"); return false; + } - if (crtc_timing->h_sync_width != hw_crtc_timing.h_sync_width) + if (crtc_timing->h_sync_width != hw_crtc_timing.h_sync_width) { + DC_LOG_DEBUG("boot timing validation failed due to h_sync_width mismatch\n"); return false; + } - if (crtc_timing->v_total != hw_crtc_timing.v_total) + if (crtc_timing->v_total != hw_crtc_timing.v_total) { + DC_LOG_DEBUG("boot timing validation failed due to v_total mismatch\n"); return false; + } - if (crtc_timing->v_border_top != hw_crtc_timing.v_border_top) + if (crtc_timing->v_border_top != hw_crtc_timing.v_border_top) { + DC_LOG_DEBUG("boot timing validation failed due to v_border_top mismatch\n"); return false; + } - if (crtc_timing->v_addressable != hw_crtc_timing.v_addressable) + if (crtc_timing->v_addressable != hw_crtc_timing.v_addressable) { + DC_LOG_DEBUG("boot timing validation failed due to v_addressable mismatch\n"); return false; + } - if (crtc_timing->v_border_bottom != hw_crtc_timing.v_border_bottom) + if (crtc_timing->v_border_bottom != hw_crtc_timing.v_border_bottom) { + DC_LOG_DEBUG("boot timing validation failed due to v_border_bottom mismatch\n"); return false; + } - if (crtc_timing->v_front_porch != hw_crtc_timing.v_front_porch) + if (crtc_timing->v_front_porch != hw_crtc_timing.v_front_porch) { + DC_LOG_DEBUG("boot timing validation failed due to v_front_porch mismatch\n"); return false; + } - if (crtc_timing->v_sync_width != hw_crtc_timing.v_sync_width) + if (crtc_timing->v_sync_width != hw_crtc_timing.v_sync_width) { + DC_LOG_DEBUG("boot timing validation failed due to v_sync_width mismatch\n"); return false; + } /* block DSC for now, as VBIOS does not currently support DSC timings */ - if (crtc_timing->flags.DSC) + if (crtc_timing->flags.DSC) { + DC_LOG_DEBUG("boot timing validation failed due to DSC\n"); return false; + } if (dc_is_dp_signal(link->connector_signal)) { unsigned int pix_clk_100hz = 0; @@ -1821,39 +1863,55 @@ bool dc_validate_boot_timing(const struct dc *dc, } 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) + if (pixels_per_cycle != 1 && !dc->debug.enable_dp_dig_pixel_rate_div_policy) { + pr_info("boot timing validation failed due to pixels_per_cycle\n"); 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. - if (crtc_timing->pix_clk_100hz != pix_clk_100hz) + if (crtc_timing->pix_clk_100hz != pix_clk_100hz) { + DC_LOG_DEBUG("boot timing validation failed due to pix_clk_100hz mismatch\n"); return false; + } - if (!se || !se->funcs->dp_get_pixel_format) + if (!se || !se->funcs->dp_get_pixel_format) { + DC_LOG_DEBUG("boot timing validation failed due to missing dp_get_pixel_format\n"); return false; + } if (!se->funcs->dp_get_pixel_format( se, &hw_crtc_timing.pixel_encoding, - &hw_crtc_timing.display_color_depth)) + &hw_crtc_timing.display_color_depth)) { + DC_LOG_DEBUG("boot timing validation failed due to dp_get_pixel_format failure\n"); return false; + } - if (hw_crtc_timing.display_color_depth != crtc_timing->display_color_depth) + if (hw_crtc_timing.display_color_depth != crtc_timing->display_color_depth) { + DC_LOG_DEBUG("boot timing validation failed due to display_color_depth mismatch\n"); return false; + } - if (hw_crtc_timing.pixel_encoding != crtc_timing->pixel_encoding) + if (hw_crtc_timing.pixel_encoding != crtc_timing->pixel_encoding) { + DC_LOG_DEBUG("boot timing validation failed due to pixel_encoding mismatch\n"); return false; + } } + if (link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED) { + DC_LOG_DEBUG("boot timing validation failed due to VSC SDP colorimetry\n"); return false; } - if (link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) + if (link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) { + DC_LOG_DEBUG("boot timing validation failed due to DP 128b/132b\n"); return false; + } if (dc->link_srv->edp_is_ilr_optimization_required(link, crtc_timing)) { DC_LOG_EVENT_LINK_TRAINING("Seamless boot disabled to optimize eDP link rate\n"); -- cgit v1.2.3 From 16ca828617109666d23921d6568ae8b9802fe212 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 20 Jan 2025 13:49:03 -0600 Subject: drm/amd/display: Refactor mark_seamless_boot_stream() mark_seamless_boot_stream() can be called multiple times to run the more expensive checks in dc_validate_boot_timing(). Refactor the function so that if those have already passed once the function isn't called again. Also add a message the first time that they have passed to let the user know the stream will be used for seamless boot. Reviewed-by: Harry Wentland Link: https://lore.kernel.org/r/20250120194903.1048811-4-superm1@kernel.org Signed-off-by: Mario Limonciello Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 72c88fdeb28c..7251587c3fb6 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -3592,16 +3592,20 @@ static int acquire_resource_from_hw_enabled_state( return -1; } -static void mark_seamless_boot_stream( - const struct dc *dc, - struct dc_stream_state *stream) +static void mark_seamless_boot_stream(const struct dc *dc, + struct dc_stream_state *stream) { struct dc_bios *dcb = dc->ctx->dc_bios; - if (dc->config.allow_seamless_boot_optimization && - !dcb->funcs->is_accelerated_mode(dcb)) { - if (dc_validate_boot_timing(dc, stream->sink, &stream->timing)) - stream->apply_seamless_boot_optimization = true; + if (stream->apply_seamless_boot_optimization) + return; + if (!dc->config.allow_seamless_boot_optimization) + return; + if (dcb->funcs->is_accelerated_mode(dcb)) + return; + if (dc_validate_boot_timing(dc, stream->sink, &stream->timing)) { + stream->apply_seamless_boot_optimization = true; + DC_LOG_INFO("Marked stream for seamless boot optimization\n"); } } -- cgit v1.2.3 From d8c782cac5007e68e7484d420168f12d3490def6 Mon Sep 17 00:00:00 2001 From: Tom Chung Date: Mon, 13 Jan 2025 14:22:31 +0800 Subject: drm/amd/display: Initial psr_version with correct setting [Why & How] The initial setting for psr_version is not correct while create a virtual link. The default psr_version should be DC_PSR_VERSION_UNSUPPORTED. Reviewed-by: Roman Li Signed-off-by: Tom Chung Signed-off-by: Zaeem Mohamed Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index ba3a34fad26a..f08d3d467372 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -276,6 +276,7 @@ static bool create_links( link->link_id.type = OBJECT_TYPE_CONNECTOR; link->link_id.id = CONNECTOR_ID_VIRTUAL; link->link_id.enum_id = ENUM_ID_1; + link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; link->link_enc = kzalloc(sizeof(*link->link_enc), GFP_KERNEL); if (!link->link_enc) { -- cgit v1.2.3 From 6a7fde433231c18164c117592d3e18ced648ad58 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 10 Jan 2025 11:35:46 -0500 Subject: drm/amd/display: Update CR AUX RD interval interpretation [Why] DP spec updated to have the CR AUX RD interval match the EQ AUX RD interval interpretation of DPCD 0000Eh/0220Eh for 8b/10b non-LTTPR mode and LTTPR transparent mode cases. [How] Update interpretation of DPCD 0000Eh/0220Eh for CR AUX RD interval during 8b/10b link training. Reviewed-by: Michael Strauss Reviewed-by: Wenjing Liu Signed-off-by: George Shen Signed-off-by: Zaeem Mohamed Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c index 3bdce32a85e3..ae95ec48e572 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c @@ -36,7 +36,8 @@ link->ctx->logger static int32_t get_cr_training_aux_rd_interval(struct dc_link *link, - const struct dc_link_settings *link_settings) + const struct dc_link_settings *link_settings, + enum lttpr_mode lttpr_mode) { union training_aux_rd_interval training_rd_interval; uint32_t wait_in_micro_secs = 100; @@ -49,6 +50,8 @@ static int32_t get_cr_training_aux_rd_interval(struct dc_link *link, DP_TRAINING_AUX_RD_INTERVAL, (uint8_t *)&training_rd_interval, sizeof(training_rd_interval)); + if (lttpr_mode != LTTPR_MODE_NON_TRANSPARENT) + wait_in_micro_secs = 400; if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL) wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000; } @@ -110,7 +113,6 @@ void decide_8b_10b_training_settings( */ lt_settings->link_settings.link_spread = link->dp_ss_off ? LINK_SPREAD_DISABLED : LINK_SPREAD_05_DOWNSPREAD_30KHZ; - lt_settings->cr_pattern_time = get_cr_training_aux_rd_interval(link, link_setting); lt_settings->eq_pattern_time = get_eq_training_aux_rd_interval(link, link_setting); lt_settings->pattern_for_cr = decide_cr_training_pattern(link_setting); lt_settings->pattern_for_eq = decide_eq_training_pattern(link, link_setting); @@ -119,6 +121,7 @@ void decide_8b_10b_training_settings( lt_settings->disallow_per_lane_settings = true; lt_settings->always_match_dpcd_with_hw_lane_settings = true; lt_settings->lttpr_mode = dp_decide_8b_10b_lttpr_mode(link); + lt_settings->cr_pattern_time = get_cr_training_aux_rd_interval(link, link_setting, lt_settings->lttpr_mode); dp_hw_to_dpcd_lane_settings(lt_settings, lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); } -- cgit v1.2.3 From 4a4077b4b63a8404efd6d37fc2926f03fb25bace Mon Sep 17 00:00:00 2001 From: Zhikai Zhai Date: Thu, 9 Jan 2025 16:11:48 +0800 Subject: drm/amd/display: Update Cursor request mode to the beginning prefetch always [Why] The double buffer cursor registers is updated by the cursor vupdate event. There is a gap between vupdate and cursor data fetch if cursor fetch data reletive to cursor position. Cursor corruption will happen if we update the cursor surface in this gap. [How] Modify the cursor request mode to the beginning prefetch always and avoid wraparound calculation issues. Reviewed-by: Nicholas Kazlauskas Signed-off-by: Zhikai Zhai Signed-off-by: Zaeem Mohamed Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c | 2 +- .../drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 22 +++++++++------------- 2 files changed, 10 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c index c2900c79a2d3..7fd582a8a4ba 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c @@ -44,7 +44,7 @@ void hubp31_set_unbounded_requesting(struct hubp *hubp, bool enable) struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); REG_UPDATE(DCHUBP_CNTL, HUBP_UNBOUNDED_REQ_MODE, enable); - REG_UPDATE(CURSOR_CONTROL, CURSOR_REQ_MODE, enable); + REG_UPDATE(CURSOR_CONTROL, CURSOR_REQ_MODE, 1); } void hubp31_soft_reset(struct hubp *hubp, bool reset) 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 906934128912..35c0d101d7c8 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 @@ -1993,20 +1993,11 @@ static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx) dc->hwss.get_position(&pipe_ctx, 1, &position); vpos = position.vertical_count; - /* Avoid wraparound calculation issues */ - vupdate_start += stream->timing.v_total; - vupdate_end += stream->timing.v_total; - vpos += stream->timing.v_total; - if (vpos <= vupdate_start) { /* VPOS is in VACTIVE or back porch. */ lines_to_vupdate = vupdate_start - vpos; - } else if (vpos > vupdate_end) { - /* VPOS is in the front porch. */ - return; } else { - /* VPOS is in VUPDATE. */ - lines_to_vupdate = 0; + lines_to_vupdate = stream->timing.v_total - vpos + vupdate_start; } /* Calculate time until VUPDATE in microseconds. */ @@ -2014,13 +2005,18 @@ static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx) stream->timing.h_total * 10000u / stream->timing.pix_clk_100hz; us_to_vupdate = lines_to_vupdate * us_per_line; + /* Stall out until the cursor update completes. */ + if (vupdate_end < vupdate_start) + vupdate_end += stream->timing.v_total; + + /* Position is in the range of vupdate start and end*/ + if (lines_to_vupdate > stream->timing.v_total - vupdate_end + vupdate_start) + us_to_vupdate = 0; + /* 70 us is a conservative estimate of cursor update time*/ if (us_to_vupdate > 70) return; - /* Stall out until the cursor update completes. */ - if (vupdate_end < vupdate_start) - vupdate_end += stream->timing.v_total; us_vupdate = (vupdate_end - vupdate_start + 1) * us_per_line; udelay(us_to_vupdate + us_vupdate); } -- cgit v1.2.3 From 36681f15bb12b5c01df924379cdab9234259825c Mon Sep 17 00:00:00 2001 From: Austin Zheng Date: Mon, 13 Jan 2025 14:13:51 -0500 Subject: drm/amd/display: Account For OTO Prefetch Bandwidth When Calculating Urgent Bandwidth [Why] 1) The current calculations for OTO prefetch bandwidth do not consider the number of DPP pipes in use. As a result, OTO prefetch bandwidth may be larger than the vactive bandwidth if multiple DPP pipes are used. OTO prefetch bandwidth should never exceed the vactive bandwidth. 2) Mode programming may be mismatched with mode support In cases where mode support has chosen to use the equalized (equ) prefetch schedule, mode programming may end up using oto prefetch schedule instead. The bandwidth required to do the oto schedule may end up being higher than the equ schedule. This can cause the required urgent bandwidth to exceed the available urgent bandwidth. [How] Output the oto prefetch bandwidth and incorperate it into the urgent bandwidth calculations even if the prefetch schedule being used is not the oto schedule. Reviewed-by: Dillon Varone Signed-off-by: Austin Zheng Signed-off-by: Zaeem Mohamed Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../dml21/src/dml2_core/dml2_core_dcn4_calcs.c | 25 +++++++++++++++++++++- .../dml21/src/dml2_core/dml2_core_shared_types.h | 5 +++++ 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 51b457b6d66f..e96a13dc43d4 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 @@ -4909,6 +4909,7 @@ static double get_urgent_bandwidth_required( double ReadBandwidthChroma[], double PrefetchBandwidthLuma[], double PrefetchBandwidthChroma[], + double PrefetchBandwidthOto[], double excess_vactive_fill_bw_l[], double excess_vactive_fill_bw_c[], double cursor_bw[], @@ -4972,8 +4973,9 @@ static double get_urgent_bandwidth_required( 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->flip_and_prefetch_bw_oto = l->per_plane_flip_bw[k] + NumberOfDPP[k] * (PrefetchBandwidthOto[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); + surface_required_bw[k] = math_max5(l->vm_row_bw, l->flip_and_active_bw, l->flip_and_prefetch_bw, l->active_and_excess_bw, l->flip_and_prefetch_bw_oto); /* export peak required bandwidth for the surface */ surface_peak_required_bw[k] = math_max2(surface_required_bw[k], surface_peak_required_bw[k]); @@ -5171,6 +5173,7 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch s->Tsw_est3 = 0.0; s->cursor_prefetch_bytes = 0; *p->prefetch_cursor_bw = 0; + *p->RequiredPrefetchBWOTO = 0.0; dcc_mrq_enable = (p->dcc_enable && p->mrq_present); @@ -5384,6 +5387,9 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch s->prefetch_bw_oto += (p->swath_width_chroma_ub * p->myPipe->BytePerPixelC) / s->LineTime; } + /* oto prefetch bw should be always be less than total vactive bw */ + DML2_ASSERT(s->prefetch_bw_oto < s->per_pipe_vactive_sw_bw * p->myPipe->DPPPerSurface); + s->prefetch_bw_oto = math_max2(s->per_pipe_vactive_sw_bw, s->prefetch_bw_oto) * p->mall_prefetch_sdp_overhead_factor; s->prefetch_bw_oto = math_min2(s->prefetch_bw_oto, *p->prefetch_sw_bytes/(s->min_Lsw_oto*s->LineTime)); @@ -5394,6 +5400,12 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch 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)); + /* oto bw needs to be outputted even if the oto schedule isn't being used to avoid ms/mp mismatch. + * mp will fail if ms decides to use equ schedule and mp decides to use oto schedule + * and the required bandwidth increases when going from ms to mp + */ + *p->RequiredPrefetchBWOTO = s->prefetch_bw_oto; + #ifdef __DML_VBA_DEBUG__ dml2_printf("DML::%s: vactive_sw_bw_l = %f\n", __func__, p->vactive_sw_bw_l); dml2_printf("DML::%s: vactive_sw_bw_c = %f\n", __func__, p->vactive_sw_bw_c); @@ -6154,6 +6166,7 @@ static void calculate_peak_bandwidth_required( p->surface_read_bandwidth_c, l->zero_array, //PrefetchBandwidthLuma, l->zero_array, //PrefetchBandwidthChroma, + l->zero_array, //PrefetchBWOTO l->zero_array, l->zero_array, l->zero_array, @@ -6190,6 +6203,7 @@ static void calculate_peak_bandwidth_required( p->surface_read_bandwidth_c, l->zero_array, //PrefetchBandwidthLuma, l->zero_array, //PrefetchBandwidthChroma, + l->zero_array, //PrefetchBWOTO p->excess_vactive_fill_bw_l, p->excess_vactive_fill_bw_c, p->cursor_bw, @@ -6226,6 +6240,7 @@ static void calculate_peak_bandwidth_required( p->surface_read_bandwidth_c, p->prefetch_bandwidth_l, p->prefetch_bandwidth_c, + p->prefetch_bandwidth_oto, // to prevent ms/mp mismatch when oto bw > total vactive bw p->excess_vactive_fill_bw_l, p->excess_vactive_fill_bw_c, p->cursor_bw, @@ -6262,6 +6277,7 @@ static void calculate_peak_bandwidth_required( p->surface_read_bandwidth_c, p->prefetch_bandwidth_l, p->prefetch_bandwidth_c, + p->prefetch_bandwidth_oto, // to prevent ms/mp mismatch when oto bw > total vactive bw p->excess_vactive_fill_bw_l, p->excess_vactive_fill_bw_c, p->cursor_bw, @@ -6298,6 +6314,7 @@ static void calculate_peak_bandwidth_required( p->surface_read_bandwidth_c, p->prefetch_bandwidth_l, p->prefetch_bandwidth_c, + p->prefetch_bandwidth_oto, // to prevent ms/mp mismatch when oto bw > total vactive bw p->excess_vactive_fill_bw_l, p->excess_vactive_fill_bw_c, p->cursor_bw, @@ -9060,6 +9077,7 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out CalculatePrefetchSchedule_params->VRatioPrefetchC = &mode_lib->ms.VRatioPreC[k]; CalculatePrefetchSchedule_params->RequiredPrefetchPixelDataBWLuma = &mode_lib->ms.RequiredPrefetchPixelDataBWLuma[k]; // prefetch_sw_bw_l CalculatePrefetchSchedule_params->RequiredPrefetchPixelDataBWChroma = &mode_lib->ms.RequiredPrefetchPixelDataBWChroma[k]; // prefetch_sw_bw_c + CalculatePrefetchSchedule_params->RequiredPrefetchBWOTO = &mode_lib->ms.RequiredPrefetchBWOTO[k]; CalculatePrefetchSchedule_params->NotEnoughTimeForDynamicMetadata = &mode_lib->ms.NoTimeForDynamicMetadata[k]; CalculatePrefetchSchedule_params->Tno_bw = &mode_lib->ms.Tno_bw[k]; CalculatePrefetchSchedule_params->Tno_bw_flip = &mode_lib->ms.Tno_bw_flip[k]; @@ -9204,6 +9222,7 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out calculate_peak_bandwidth_params->surface_read_bandwidth_c = mode_lib->ms.vactive_sw_bw_c; calculate_peak_bandwidth_params->prefetch_bandwidth_l = mode_lib->ms.RequiredPrefetchPixelDataBWLuma; calculate_peak_bandwidth_params->prefetch_bandwidth_c = mode_lib->ms.RequiredPrefetchPixelDataBWChroma; + calculate_peak_bandwidth_params->prefetch_bandwidth_oto = mode_lib->ms.RequiredPrefetchBWOTO; calculate_peak_bandwidth_params->excess_vactive_fill_bw_l = mode_lib->ms.excess_vactive_fill_bw_l; calculate_peak_bandwidth_params->excess_vactive_fill_bw_c = mode_lib->ms.excess_vactive_fill_bw_c; calculate_peak_bandwidth_params->cursor_bw = mode_lib->ms.cursor_bw; @@ -9370,6 +9389,7 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out calculate_peak_bandwidth_params->surface_read_bandwidth_c = mode_lib->ms.vactive_sw_bw_c; calculate_peak_bandwidth_params->prefetch_bandwidth_l = mode_lib->ms.RequiredPrefetchPixelDataBWLuma; calculate_peak_bandwidth_params->prefetch_bandwidth_c = mode_lib->ms.RequiredPrefetchPixelDataBWChroma; + calculate_peak_bandwidth_params->prefetch_bandwidth_oto = mode_lib->ms.RequiredPrefetchBWOTO; calculate_peak_bandwidth_params->excess_vactive_fill_bw_l = mode_lib->ms.excess_vactive_fill_bw_l; calculate_peak_bandwidth_params->excess_vactive_fill_bw_c = mode_lib->ms.excess_vactive_fill_bw_c; calculate_peak_bandwidth_params->cursor_bw = mode_lib->ms.cursor_bw; @@ -11286,6 +11306,7 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex CalculatePrefetchSchedule_params->VRatioPrefetchC = &mode_lib->mp.VRatioPrefetchC[k]; CalculatePrefetchSchedule_params->RequiredPrefetchPixelDataBWLuma = &mode_lib->mp.RequiredPrefetchPixelDataBWLuma[k]; CalculatePrefetchSchedule_params->RequiredPrefetchPixelDataBWChroma = &mode_lib->mp.RequiredPrefetchPixelDataBWChroma[k]; + CalculatePrefetchSchedule_params->RequiredPrefetchBWOTO = &s->dummy_single_array[0][k]; CalculatePrefetchSchedule_params->NotEnoughTimeForDynamicMetadata = &mode_lib->mp.NotEnoughTimeForDynamicMetadata[k]; CalculatePrefetchSchedule_params->Tno_bw = &mode_lib->mp.Tno_bw[k]; CalculatePrefetchSchedule_params->Tno_bw_flip = &mode_lib->mp.Tno_bw_flip[k]; @@ -11428,6 +11449,7 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex calculate_peak_bandwidth_params->surface_read_bandwidth_c = mode_lib->mp.vactive_sw_bw_c; calculate_peak_bandwidth_params->prefetch_bandwidth_l = mode_lib->mp.RequiredPrefetchPixelDataBWLuma; calculate_peak_bandwidth_params->prefetch_bandwidth_c = mode_lib->mp.RequiredPrefetchPixelDataBWChroma; + calculate_peak_bandwidth_params->prefetch_bandwidth_oto = s->dummy_single_array[0]; calculate_peak_bandwidth_params->excess_vactive_fill_bw_l = mode_lib->mp.excess_vactive_fill_bw_l; calculate_peak_bandwidth_params->excess_vactive_fill_bw_c = mode_lib->mp.excess_vactive_fill_bw_c; calculate_peak_bandwidth_params->cursor_bw = mode_lib->mp.cursor_bw; @@ -11560,6 +11582,7 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex calculate_peak_bandwidth_params->surface_read_bandwidth_c = mode_lib->mp.vactive_sw_bw_c; calculate_peak_bandwidth_params->prefetch_bandwidth_l = mode_lib->mp.RequiredPrefetchPixelDataBWLuma; calculate_peak_bandwidth_params->prefetch_bandwidth_c = mode_lib->mp.RequiredPrefetchPixelDataBWChroma; + calculate_peak_bandwidth_params->prefetch_bandwidth_oto = s->dummy_single_array[k]; calculate_peak_bandwidth_params->excess_vactive_fill_bw_l = mode_lib->mp.excess_vactive_fill_bw_l; calculate_peak_bandwidth_params->excess_vactive_fill_bw_c = mode_lib->mp.excess_vactive_fill_bw_c; calculate_peak_bandwidth_params->cursor_bw = mode_lib->mp.cursor_bw; 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 23c0fca5515f..b7cb017b59ba 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 @@ -484,6 +484,8 @@ struct dml2_core_internal_mode_support { double WriteBandwidth[DML2_MAX_PLANES][DML2_MAX_WRITEBACK]; double RequiredPrefetchPixelDataBWLuma[DML2_MAX_PLANES]; double RequiredPrefetchPixelDataBWChroma[DML2_MAX_PLANES]; + /* oto bw should also be considered when calculating urgent bw to avoid situations oto/equ mismatches between ms and mp */ + double RequiredPrefetchBWOTO[DML2_MAX_PLANES]; double cursor_bw[DML2_MAX_PLANES]; double prefetch_cursor_bw[DML2_MAX_PLANES]; double prefetch_vmrow_bw[DML2_MAX_PLANES]; @@ -1381,6 +1383,7 @@ struct dml2_core_shared_get_urgent_bandwidth_required_locals { double vm_row_bw; double flip_and_active_bw; double flip_and_prefetch_bw; + double flip_and_prefetch_bw_oto; double active_and_excess_bw; }; @@ -1792,6 +1795,7 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_params { double *VRatioPrefetchC; double *RequiredPrefetchPixelDataBWLuma; double *RequiredPrefetchPixelDataBWChroma; + double *RequiredPrefetchBWOTO; bool *NotEnoughTimeForDynamicMetadata; double *Tno_bw; double *Tno_bw_flip; @@ -2025,6 +2029,7 @@ struct dml2_core_calcs_calculate_peak_bandwidth_required_params { double *surface_read_bandwidth_c; double *prefetch_bandwidth_l; double *prefetch_bandwidth_c; + double *prefetch_bandwidth_oto; double *excess_vactive_fill_bw_l; double *excess_vactive_fill_bw_c; double *cursor_bw; -- cgit v1.2.3 From cbd97d621ece1d92c3542e52f8af7c04cd2c6afb Mon Sep 17 00:00:00 2001 From: Dillon Varone Date: Tue, 14 Jan 2025 12:14:26 -0500 Subject: drm/amd/display: Ammend DCPG IP control sequences to align with HW guidance [WHY&HOW] IP_REQUEST_CNTL should only be toggled off when it was originally, never unconditionally. Reviewed-by: Alvin Lee Signed-off-by: Dillon Varone Signed-off-by: Zaeem Mohamed Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 14 ++++++--- .../drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 34 ++++++++++++++++++++++ .../drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h | 3 ++ .../drm/amd/display/dc/hwss/dcn401/dcn401_init.c | 2 +- 4 files changed, 48 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 a5e18ab72394..dec732c0c59c 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 @@ -1266,14 +1266,18 @@ static void dcn20_power_on_plane_resources( struct dce_hwseq *hws, struct pipe_ctx *pipe_ctx) { + uint32_t org_ip_request_cntl = 0; + DC_LOGGER_INIT(hws->ctx->logger); if (hws->funcs.dpp_root_clock_control) hws->funcs.dpp_root_clock_control(hws, pipe_ctx->plane_res.dpp->inst, true); if (REG(DC_IP_REQUEST_CNTL)) { - REG_SET(DC_IP_REQUEST_CNTL, 0, - IP_REQUEST_EN, 1); + REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); + if (org_ip_request_cntl == 0) + REG_SET(DC_IP_REQUEST_CNTL, 0, + IP_REQUEST_EN, 1); if (hws->funcs.dpp_pg_control) hws->funcs.dpp_pg_control(hws, pipe_ctx->plane_res.dpp->inst, true); @@ -1281,8 +1285,10 @@ static void dcn20_power_on_plane_resources( if (hws->funcs.hubp_pg_control) hws->funcs.hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, true); - REG_SET(DC_IP_REQUEST_CNTL, 0, - IP_REQUEST_EN, 0); + if (org_ip_request_cntl == 0) + REG_SET(DC_IP_REQUEST_CNTL, 0, + IP_REQUEST_EN, 0); + DC_LOG_DEBUG( "Un-gated front end for pipe %d\n", pipe_ctx->plane_res.hubp->inst); } 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 92bb820817b9..8ad0ff669b7a 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 @@ -2610,3 +2610,37 @@ void dcn401_detect_pipe_changes(struct dc_state *old_state, new_pipe->update_flags.bits.test_pattern_changed = 1; } } + +void dcn401_plane_atomic_power_down(struct dc *dc, + struct dpp *dpp, + struct hubp *hubp) +{ + struct dce_hwseq *hws = dc->hwseq; + uint32_t org_ip_request_cntl = 0; + + DC_LOGGER_INIT(dc->ctx->logger); + + REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); + if (org_ip_request_cntl == 0) + REG_SET(DC_IP_REQUEST_CNTL, 0, + IP_REQUEST_EN, 1); + + if (hws->funcs.dpp_pg_control) + hws->funcs.dpp_pg_control(hws, dpp->inst, false); + + if (hws->funcs.hubp_pg_control) + hws->funcs.hubp_pg_control(hws, hubp->inst, false); + + hubp->funcs->hubp_reset(hubp); + dpp->funcs->dpp_reset(dpp); + + if (org_ip_request_cntl == 0) + REG_SET(DC_IP_REQUEST_CNTL, 0, + IP_REQUEST_EN, 0); + + DC_LOG_DEBUG( + "Power gated front end %d\n", hubp->inst); + + if (hws->funcs.dpp_root_clock_control) + hws->funcs.dpp_root_clock_control(hws, dpp->inst, false); +} 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 17cea748789e..dbd69d215b8b 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 @@ -102,4 +102,7 @@ void dcn401_detect_pipe_changes( struct dc_state *new_state, struct pipe_ctx *old_pipe, struct pipe_ctx *new_pipe); +void dcn401_plane_atomic_power_down(struct dc *dc, + struct dpp *dpp, + struct hubp *hubp); #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 44cb376f97c1..a4e3501fadbb 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 @@ -123,7 +123,7 @@ static const struct hwseq_private_funcs dcn401_private_funcs = { .disable_vga = dcn20_disable_vga, .bios_golden_init = dcn10_bios_golden_init, .plane_atomic_disable = dcn20_plane_atomic_disable, - .plane_atomic_power_down = dcn10_plane_atomic_power_down, + .plane_atomic_power_down = dcn401_plane_atomic_power_down, .enable_power_gating_plane = dcn32_enable_power_gating_plane, .hubp_pg_control = dcn32_hubp_pg_control, .program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree, -- cgit v1.2.3 From c87d202692de34ee71d1fd4679a549a29095658a Mon Sep 17 00:00:00 2001 From: Sung Lee Date: Thu, 16 Jan 2025 09:45:54 -0500 Subject: drm/amd/display: Guard Possible Null Pointer Dereference [WHY] In some situations, dc->res_pool may be null. [HOW] Check if pointer is null before dereference. Reviewed-by: Joshua Aberback Signed-off-by: Sung Lee Signed-off-by: Zaeem Mohamed Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index f08d3d467372..ce917714c7e0 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -5611,9 +5611,11 @@ void dc_allow_idle_optimizations_internal(struct dc *dc, bool allow, char const if (dc->clk_mgr != NULL && dc->clk_mgr->funcs->get_hard_min_memclk) idle_dramclk_khz = dc->clk_mgr->funcs->get_hard_min_memclk(dc->clk_mgr); - for (i = 0; i < dc->res_pool->pipe_count; i++) { - pipe = &context->res_ctx.pipe_ctx[i]; - subvp_pipe_type[i] = dc_state_get_pipe_subvp_type(context, pipe); + if (dc->res_pool && context) { + for (i = 0; i < dc->res_pool->pipe_count; i++) { + pipe = &context->res_ctx.pipe_ctx[i]; + subvp_pipe_type[i] = dc_state_get_pipe_subvp_type(context, pipe); + } } DC_LOG_DC("%s: allow_idle=%d\n HardMinUClk_Khz=%d HardMinDramclk_Khz=%d\n Pipe_0=%d Pipe_1=%d Pipe_2=%d Pipe_3=%d Pipe_4=%d Pipe_5=%d (caller=%s)\n", -- cgit v1.2.3 From a1d79eae960ce1642aed476d98e311aae46bfb82 Mon Sep 17 00:00:00 2001 From: Peichen Huang Date: Mon, 23 Dec 2024 11:09:52 +0800 Subject: drm/amd/display: refactor dio link encoder assigning [WHY] We would like to have new dio encoder assigning flow. Which should be aligned with hpo assigning and have simple logic and data representation. [HOW} 1. A new config option to enable/disable the new code. 2. Encoder-link mapping is in res_ctx and assigned encoder. is accessed through pipe_ctx. 3. assign dio encoder when add stream to ctx Reviewed-by: Jun Lei Reviewed-by: Meenakshikumar Somasundaram Signed-off-by: Peichen Huang Signed-off-by: Zaeem Mohamed Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 2 +- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 202 +++++++++++++++++++++- drivers/gpu/drm/amd/display/dc/dc.h | 2 + drivers/gpu/drm/amd/display/dc/inc/core_types.h | 3 + 4 files changed, 206 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index ce917714c7e0..a2b0331ef579 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2325,7 +2325,7 @@ enum dc_status dc_commit_streams(struct dc *dc, struct dc_commit_streams_params /* * Only update link encoder to stream assignment after bandwidth validation passed. */ - if (res == DC_OK && dc->res_pool->funcs->link_encs_assign) + if (res == DC_OK && dc->res_pool->funcs->link_encs_assign && !dc->config.unify_link_enc_assignment) dc->res_pool->funcs->link_encs_assign( dc, context, context->streams, context->stream_count); 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 7251587c3fb6..f59722e17abd 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -2683,6 +2683,162 @@ static void remove_hpo_dp_link_enc_from_ctx(struct resource_context *res_ctx, } } +static inline int find_acquired_dio_link_enc_for_link( + const struct resource_context *res_ctx, + const struct dc_link *link) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(res_ctx->dio_link_enc_ref_cnts); i++) + if (res_ctx->dio_link_enc_ref_cnts[i] > 0 && + res_ctx->dio_link_enc_to_link_idx[i] == link->link_index) + return i; + + return -1; +} + +static inline int find_fixed_dio_link_enc(const struct dc_link *link) +{ + /* the 8b10b dp phy can only use fixed link encoder */ + return link->eng_id; +} + +static inline int find_free_dio_link_enc(const struct resource_context *res_ctx, + const struct dc_link *link, const struct resource_pool *pool) +{ + int i; + int enc_count = pool->dig_link_enc_count; + + /* for dpia, check preferred encoder first and then the next one */ + for (i = 0; i < enc_count; i++) + if (res_ctx->dio_link_enc_ref_cnts[(link->dpia_preferred_eng_id + i) % enc_count] == 0) + break; + + return (i >= 0 && i < enc_count) ? (link->dpia_preferred_eng_id + i) % enc_count : -1; +} + +static inline void acquire_dio_link_enc( + struct resource_context *res_ctx, + unsigned int link_index, + int enc_index) +{ + res_ctx->dio_link_enc_to_link_idx[enc_index] = link_index; + res_ctx->dio_link_enc_ref_cnts[enc_index] = 1; +} + +static inline void retain_dio_link_enc( + struct resource_context *res_ctx, + int enc_index) +{ + res_ctx->dio_link_enc_ref_cnts[enc_index]++; +} + +static inline void release_dio_link_enc( + struct resource_context *res_ctx, + int enc_index) +{ + ASSERT(res_ctx->dio_link_enc_ref_cnts[enc_index] > 0); + res_ctx->dio_link_enc_ref_cnts[enc_index]--; +} + +static bool is_dio_enc_acquired_by_other_link(const struct dc_link *link, + int enc_index, + int *link_index) +{ + const struct dc *dc = link->dc; + const struct resource_context *res_ctx = &dc->current_state->res_ctx; + + /* pass the link_index that acquired the enc_index */ + if (res_ctx->dio_link_enc_ref_cnts[enc_index] > 0 && + res_ctx->dio_link_enc_to_link_idx[enc_index] != link->link_index) { + *link_index = res_ctx->dio_link_enc_to_link_idx[enc_index]; + return true; + } + + return false; +} + +static void swap_dio_link_enc_to_muxable_ctx(struct dc_state *context, + const struct resource_pool *pool, + int new_encoder, + int old_encoder) +{ + struct resource_context *res_ctx = &context->res_ctx; + int stream_count = context->stream_count; + int i = 0; + + res_ctx->dio_link_enc_ref_cnts[new_encoder] = res_ctx->dio_link_enc_ref_cnts[old_encoder]; + res_ctx->dio_link_enc_to_link_idx[new_encoder] = res_ctx->dio_link_enc_to_link_idx[old_encoder]; + res_ctx->dio_link_enc_ref_cnts[old_encoder] = 0; + + for (i = 0; i < stream_count; i++) { + struct dc_stream_state *stream = context->streams[i]; + struct pipe_ctx *pipe_ctx = resource_get_otg_master_for_stream(&context->res_ctx, stream); + + if (pipe_ctx && pipe_ctx->link_res.dio_link_enc == pool->link_encoders[old_encoder]) + pipe_ctx->link_res.dio_link_enc = pool->link_encoders[new_encoder]; + } +} + +static bool add_dio_link_enc_to_ctx(const struct dc *dc, + struct dc_state *context, + const struct resource_pool *pool, + struct pipe_ctx *pipe_ctx, + struct dc_stream_state *stream) +{ + struct resource_context *res_ctx = &context->res_ctx; + int enc_index; + + enc_index = find_acquired_dio_link_enc_for_link(res_ctx, stream->link); + + if (enc_index >= 0) { + retain_dio_link_enc(res_ctx, enc_index); + } else { + if (stream->link->is_dig_mapping_flexible) + enc_index = find_free_dio_link_enc(res_ctx, stream->link, pool); + else { + int link_index = 0; + + enc_index = find_fixed_dio_link_enc(stream->link); + /* Fixed mapping link can only use its fixed link encoder. + * If the encoder is acquired by other link then get a new free encoder and swap the new + * one into the acquiring link. + */ + if (enc_index >= 0 && is_dio_enc_acquired_by_other_link(stream->link, enc_index, &link_index)) { + int new_enc_index = find_free_dio_link_enc(res_ctx, dc->links[link_index], pool); + + if (new_enc_index >= 0) + swap_dio_link_enc_to_muxable_ctx(context, pool, new_enc_index, enc_index); + else + return false; + } + } + + if (enc_index >= 0) + acquire_dio_link_enc(res_ctx, stream->link->link_index, enc_index); + } + + if (enc_index >= 0) + pipe_ctx->link_res.dio_link_enc = pool->link_encoders[enc_index]; + + return pipe_ctx->link_res.dio_link_enc != NULL; +} + +static void remove_dio_link_enc_from_ctx(struct resource_context *res_ctx, + struct pipe_ctx *pipe_ctx, + struct dc_stream_state *stream) +{ + int enc_index = -1; + + if (stream->link) + enc_index = find_acquired_dio_link_enc_for_link(res_ctx, stream->link); + + if (enc_index >= 0) { + release_dio_link_enc(res_ctx, enc_index); + pipe_ctx->link_res.dio_link_enc = NULL; + } +} + static int get_num_of_free_pipes(const struct resource_pool *pool, const struct dc_state *context) { int i; @@ -2730,6 +2886,10 @@ void resource_remove_otg_master_for_stream_output(struct dc_state *context, remove_hpo_dp_link_enc_from_ctx( &context->res_ctx, otg_master, stream); } + + if (stream->ctx->dc->config.unify_link_enc_assignment) + remove_dio_link_enc_from_ctx(&context->res_ctx, otg_master, stream); + if (otg_master->stream_res.audio) update_audio_usage( &context->res_ctx, @@ -2744,6 +2904,7 @@ void resource_remove_otg_master_for_stream_output(struct dc_state *context, if (pool->funcs->remove_stream_from_ctx) pool->funcs->remove_stream_from_ctx( stream->ctx->dc, context, stream); + memset(otg_master, 0, sizeof(*otg_master)); } @@ -3716,6 +3877,7 @@ enum dc_status resource_map_pool_resources( struct pipe_ctx *pipe_ctx = NULL; int pipe_idx = -1; bool acquired = false; + bool is_dio_encoder = true; calculate_phy_pix_clks(stream); @@ -3781,6 +3943,10 @@ enum dc_status resource_map_pool_resources( } } + if (dc->config.unify_link_enc_assignment && is_dio_encoder) + if (!add_dio_link_enc_to_ctx(dc, context, pool, pipe_ctx, stream)) + return DC_NO_LINK_ENC_RESOURCE; + /* TODO: Add check if ASIC support and EDID audio */ if (!stream->converter_disable_audio && dc_is_audio_capable_signal(pipe_ctx->stream->signal) && @@ -5017,6 +5183,28 @@ void get_audio_check(struct audio_info *aud_modes, } } +static struct link_encoder *get_temp_dio_link_enc( + const struct resource_context *res_ctx, + const struct resource_pool *const pool, + const struct dc_link *link) +{ + struct link_encoder *link_enc = NULL; + int enc_index; + + if (link->is_dig_mapping_flexible) + enc_index = find_acquired_dio_link_enc_for_link(res_ctx, link); + else + enc_index = link->eng_id; + + if (enc_index < 0) + enc_index = find_free_dio_link_enc(res_ctx, link, pool); + + if (enc_index >= 0) + link_enc = pool->link_encoders[enc_index]; + + return link_enc; +} + static struct hpo_dp_link_encoder *get_temp_hpo_dp_link_enc( const struct resource_context *res_ctx, const struct resource_pool *const pool, @@ -5046,11 +5234,17 @@ bool get_temp_dp_link_res(struct dc_link *link, memset(link_res, 0, sizeof(*link_res)); if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING) { - link_res->hpo_dp_link_enc = get_temp_hpo_dp_link_enc(res_ctx, - dc->res_pool, link); + link_res->hpo_dp_link_enc = get_temp_hpo_dp_link_enc(res_ctx, dc->res_pool, link); if (!link_res->hpo_dp_link_enc) return false; + } else if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING && + dc->config.unify_link_enc_assignment) { + link_res->dio_link_enc = get_temp_dio_link_enc(res_ctx, + dc->res_pool, link); + if (!link_res->dio_link_enc) + return false; } + return true; } @@ -5322,6 +5516,10 @@ enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc, remove_hpo_dp_link_enc_from_ctx(&context->res_ctx, pipe_ctx, pipe_ctx->stream); } + if (pipe_ctx->link_res.dio_link_enc == NULL && dc->config.unify_link_enc_assignment) + if (!add_dio_link_enc_to_ctx(dc, context, dc->res_pool, pipe_ctx, pipe_ctx->stream)) + return DC_NO_LINK_ENC_RESOURCE; + return DC_OK; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 019459dfd6fe..06d9cf0a7edc 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -473,6 +473,7 @@ struct dc_config { bool consolidated_dpia_dp_lt; bool set_pipe_unlock_order; bool enable_dpia_pre_training; + bool unify_link_enc_assignment; }; enum visual_confirm { @@ -778,6 +779,7 @@ union dpia_debug_options { uint32_t disable_usb4_pm_support:1; /* bit 5 */ uint32_t enable_consolidated_dpia_dp_lt:1; /* bit 6 */ uint32_t enable_dpia_pre_training:1; /* bit 7 */ + uint32_t unify_link_enc_assignment:1; /* bit 8 */ uint32_t reserved:24; } bits; uint32_t raw; 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 652d52040f4e..37632be09e09 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -376,6 +376,7 @@ struct plane_resource { /* all mappable hardware resources used to enable a link */ struct link_resource { + struct link_encoder *dio_link_enc; struct hpo_dp_link_encoder *hpo_dp_link_enc; }; @@ -500,6 +501,8 @@ struct resource_context { uint8_t dp_clock_source_ref_count; bool is_dsc_acquired[MAX_PIPES]; struct link_enc_cfg_context link_enc_cfg_ctx; + unsigned int dio_link_enc_to_link_idx[MAX_DIG_LINK_ENCODERS]; + int dio_link_enc_ref_cnts[MAX_DIG_LINK_ENCODERS]; bool is_hpo_dp_stream_enc_acquired[MAX_HPO_DP2_ENCODERS]; unsigned int hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS]; int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS]; -- cgit v1.2.3 From 942bd112c92a13611899cdb075944b6e0a3b4165 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Sun, 19 Jan 2025 21:45:59 -0500 Subject: drm/amd/display: 3.2.318 This version brings along the following fixes: - Fixes on psr_version, dcn35 register address, DCPG OP control sequences - Imporvements to CR AUX RD interval interpretation, dio link encoder - Disable PSR-SU on some OLED panels Acked-by: Aurabindo Pillai Signed-off-by: Aric Cyr Signed-off-by: Zaeem Mohamed Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 06d9cf0a7edc..559446dcd431 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.317" +#define DC_VER "3.2.318" #define MAX_SURFACES 4 #define MAX_PLANES 6 -- cgit v1.2.3 From c909a49128a31bced8cfbd2dfb0a4fe56e01a6d0 Mon Sep 17 00:00:00 2001 From: Dillon Varone Date: Fri, 17 Jan 2025 17:49:41 -0500 Subject: drm/amd/display: Fixes for mcache programming in DML21 [WHY & HOW] - Fix indexing phantom planes for mcache programming in the wrapper - Fix phantom mcache allocations to align with HW guidance - Fix mcache assignment for chroma plane for multi-planar formats Reviewed-by: Austin Zheng Signed-off-by: Dillon Varone Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dml2/dml21/dml21_utils.c | 1 - .../drm/amd/display/dc/dml2/dml21/dml21_wrapper.c | 14 ++++++++++ .../amd/display/dc/dml2/dml21/inc/dml_top_types.h | 1 + .../dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c | 30 +++++++++++++++++++++- .../dml21/src/dml2_core/dml2_core_dcn4_calcs.c | 3 +++ .../dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c | 21 +++++++++++++++ .../dc/dml2/dml21/src/dml2_top/dml2_top_soc15.c | 8 ------ 7 files changed, 68 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 1e56d995cd0e..930e86cdb88a 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 @@ -232,7 +232,6 @@ void dml21_program_dc_pipe(struct dml2_context *dml_ctx, struct dc_state *contex 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); 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 fb80ba9287b6..be54f0e696ce 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 @@ -124,6 +124,7 @@ static void dml21_calculate_rq_and_dlg_params(const struct dc *dc, struct dc_sta struct pipe_ctx *dc_main_pipes[__DML2_WRAPPER_MAX_STREAMS_PLANES__]; struct pipe_ctx *dc_phantom_pipes[__DML2_WRAPPER_MAX_STREAMS_PLANES__] = {0}; int num_pipes; + unsigned int dml_phantom_prog_idx; context->bw_ctx.bw.dcn.clk.dppclk_khz = 0; @@ -137,6 +138,9 @@ static void dml21_calculate_rq_and_dlg_params(const struct dc *dc, struct dc_sta context->bw_ctx.bw.dcn.mall_ss_psr_active_size_bytes = 0; context->bw_ctx.bw.dcn.mall_subvp_size_bytes = 0; + /* phantom's start after main planes */ + dml_phantom_prog_idx = in_ctx->v21.mode_programming.programming->display_config.num_planes; + for (dml_prog_idx = 0; dml_prog_idx < DML2_MAX_PLANES; dml_prog_idx++) { pln_prog = &in_ctx->v21.mode_programming.programming->plane_programming[dml_prog_idx]; @@ -162,6 +166,16 @@ static void dml21_calculate_rq_and_dlg_params(const struct dc *dc, struct dc_sta dml21_program_dc_pipe(in_ctx, context, dc_phantom_pipes[dc_pipe_index], pln_prog, stream_prog); } } + + /* copy per plane mcache allocation */ + memcpy(&context->bw_ctx.bw.dcn.mcache_allocations[dml_prog_idx], &pln_prog->mcache_allocation, sizeof(struct dml2_mcache_surface_allocation)); + if (pln_prog->phantom_plane.valid) { + memcpy(&context->bw_ctx.bw.dcn.mcache_allocations[dml_phantom_prog_idx], + &pln_prog->phantom_plane.mcache_allocation, + sizeof(struct dml2_mcache_surface_allocation)); + + dml_phantom_prog_idx++; + } } /* assign global clocks */ 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 d2d053f2354d..0ab19cf4d242 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 @@ -245,6 +245,7 @@ struct dml2_per_plane_programming { struct { bool valid; struct dml2_plane_parameters descriptor; + struct dml2_mcache_surface_allocation mcache_allocation; struct dml2_dchub_per_pipe_register_set *pipe_regs[DML2_MAX_PLANES]; } phantom_plane; }; 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 d68b4567e218..ec0beb139200 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 @@ -254,7 +254,8 @@ static void expand_implict_subvp(const struct display_configuation_with_meta *di static void pack_mode_programming_params_with_implicit_subvp(struct dml2_core_instance *core, const struct display_configuation_with_meta *display_cfg, const struct dml2_display_cfg *svp_expanded_display_cfg, struct dml2_display_cfg_programming *programming, struct dml2_core_scratch *scratch) { - unsigned int stream_index, plane_index, pipe_offset, stream_already_populated_mask, main_plane_index; + unsigned int stream_index, plane_index, pipe_offset, stream_already_populated_mask, main_plane_index, mcache_index; + unsigned int total_main_mcaches_required = 0; int total_pipe_regs_copied = 0; int dml_internal_pipe_index = 0; const struct dml2_plane_parameters *main_plane; @@ -325,6 +326,13 @@ static void pack_mode_programming_params_with_implicit_subvp(struct dml2_core_in dml2_core_calcs_get_mall_allocation(&core->clean_me_up.mode_lib, &programming->plane_programming[plane_index].surface_size_mall_bytes, dml_internal_pipe_index); + memcpy(&programming->plane_programming[plane_index].mcache_allocation, + &display_cfg->stage2.mcache_allocations[plane_index], + sizeof(struct dml2_mcache_surface_allocation)); + total_main_mcaches_required += programming->plane_programming[plane_index].mcache_allocation.num_mcaches_plane0 + + programming->plane_programming[plane_index].mcache_allocation.num_mcaches_plane1 - + (programming->plane_programming[plane_index].mcache_allocation.last_slice_sharing.plane0_plane1 ? 1 : 0); + for (pipe_offset = 0; pipe_offset < programming->plane_programming[plane_index].num_dpps_required; pipe_offset++) { // Assign storage for this pipe's register values programming->plane_programming[plane_index].pipe_regs[pipe_offset] = &programming->pipe_regs[total_pipe_regs_copied]; @@ -363,6 +371,22 @@ static void pack_mode_programming_params_with_implicit_subvp(struct dml2_core_in memcpy(&programming->plane_programming[main_plane_index].phantom_plane.descriptor, phantom_plane, sizeof(struct dml2_plane_parameters)); dml2_core_calcs_get_mall_allocation(&core->clean_me_up.mode_lib, &programming->plane_programming[main_plane_index].svp_size_mall_bytes, dml_internal_pipe_index); + + /* generate mcache allocation, phantoms use identical mcache configuration, but in the MALL set and unique mcache ID's beginning after all main ID's */ + memcpy(&programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation, + &programming->plane_programming[main_plane_index].mcache_allocation, + sizeof(struct dml2_mcache_surface_allocation)); + for (mcache_index = 0; mcache_index < programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.num_mcaches_plane0; mcache_index++) { + programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane0[mcache_index] += total_main_mcaches_required; + programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_mall_plane0[mcache_index] = + programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane0[mcache_index]; + } + for (mcache_index = 0; mcache_index < programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.num_mcaches_plane1; mcache_index++) { + programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane1[mcache_index] += total_main_mcaches_required; + programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_mall_plane1[mcache_index] = + programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane1[mcache_index]; + } + for (pipe_offset = 0; pipe_offset < programming->plane_programming[main_plane_index].num_dpps_required; pipe_offset++) { // Assign storage for this pipe's register values programming->plane_programming[main_plane_index].phantom_plane.pipe_regs[pipe_offset] = &programming->pipe_regs[total_pipe_regs_copied]; @@ -572,6 +596,10 @@ bool core_dcn4_mode_programming(struct dml2_core_mode_programming_in_out *in_out 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); + memcpy(&in_out->programming->plane_programming[plane_index].mcache_allocation, + &in_out->display_cfg->stage2.mcache_allocations[plane_index], + sizeof(struct dml2_mcache_surface_allocation)); + for (pipe_offset = 0; pipe_offset < in_out->programming->plane_programming[plane_index].num_dpps_required; pipe_offset++) { in_out->programming->plane_programming[plane_index].plane_descriptor = &in_out->programming->display_config.plane_descriptors[plane_index]; 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 e96a13dc43d4..47872c6f657e 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 @@ -2637,6 +2637,9 @@ static void calculate_mcache_setting( // Luma/Chroma combine in the last mcache // In the case of Luma/Chroma combine-mCache (with lc_comb_mcache==1), all mCaches except the last segment are filled as much as possible, when stay aligned to mvmpg boundary if (*p->lc_comb_mcache && l->is_dual_plane) { + /* if luma and chroma planes share an mcache, increase total chroma mcache count */ + *p->num_mcaches_c = *p->num_mcaches_c + 1; + for (n = 0; n < *p->num_mcaches_l - 1; n++) p->mcache_offsets_l[n] = (n + 1) * l->mvmpg_per_mcache_lb_l * l->mvmpg_access_width_l; p->mcache_offsets_l[*p->num_mcaches_l - 1] = l->full_vp_access_width_l; 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 a3324f7b9ba6..15c906c42ec4 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 @@ -1082,12 +1082,21 @@ static bool all_timings_support_svp(const struct dml2_pmo_instance *pmo, const struct dml2_fams2_meta *stream_fams2_meta; unsigned int microschedule_vlines; unsigned int i; + unsigned int mcaches_per_plane; + unsigned int total_mcaches_required = 0; unsigned int num_planes_per_stream[DML2_MAX_PLANES] = { 0 }; /* confirm timing it is not a centered timing */ for (i = 0; i < display_config->display_config.num_planes; i++) { plane_descriptor = &display_config->display_config.plane_descriptors[i]; + mcaches_per_plane = 0; + + if (plane_descriptor->surface.dcc.enable) { + mcaches_per_plane += display_config->stage2.mcache_allocations[i].num_mcaches_plane0 + + display_config->stage2.mcache_allocations[i].num_mcaches_plane1 - + (display_config->stage2.mcache_allocations[i].last_slice_sharing.plane0_plane1 ? 1 : 0); + } if (is_bit_set_in_bitfield(mask, (unsigned char)plane_descriptor->stream_index)) { num_planes_per_stream[plane_descriptor->stream_index]++; @@ -1098,7 +1107,19 @@ static bool all_timings_support_svp(const struct dml2_pmo_instance *pmo, plane_descriptor->composition.rotation_angle != dml2_rotation_0) { return false; } + + /* phantom requires same number of mcaches as main */ + if (plane_descriptor->surface.dcc.enable) { + mcaches_per_plane *= 2; + } } + + total_mcaches_required += mcaches_per_plane; + } + + if (total_mcaches_required > pmo->soc_bb->num_dcc_mcaches) { + /* too many mcaches required */ + return false; } for (i = 0; i < DML2_MAX_PLANES; i++) { diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_soc15.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_soc15.c index a8f58f8448e4..dc2ce5e77f57 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_soc15.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_soc15.c @@ -831,7 +831,6 @@ static bool dml2_top_soc15_build_mode_programming(struct dml2_build_mode_program bool uclk_pstate_success = false; bool vmin_success = false; bool stutter_success = false; - unsigned int i; memset(l, 0, sizeof(struct dml2_build_mode_programming_locals)); memset(in_out->programming, 0, sizeof(struct dml2_display_cfg_programming)); @@ -976,13 +975,6 @@ static bool dml2_top_soc15_build_mode_programming(struct dml2_build_mode_program l->base_display_config_with_meta.stage5.success = true; } - /* - * Populate mcache programming - */ - for (i = 0; i < in_out->display_config->num_planes; i++) { - in_out->programming->plane_programming[i].mcache_allocation = l->base_display_config_with_meta.stage2.mcache_allocations[i]; - } - /* * Call DPMM to map all requirements to minimum clock state */ -- cgit v1.2.3 From be704e5ef4bd66dee9bb3f876964327e3a247d31 Mon Sep 17 00:00:00 2001 From: Brandon Syu Date: Tue, 21 Jan 2025 13:29:51 +0800 Subject: Revert "drm/amd/display: Exit idle optimizations before attempt to access PHY" This reverts commit de612738e9771bd66aeb20044486c457c512f684. Reason to revert: screen flashes or gray screen appeared half of the screen after resume from S4/S5. Reviewed-by: Charlene Liu Signed-off-by: Brandon Syu Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 81f4c386c287..e033e6476fe5 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 @@ -1890,7 +1890,6 @@ 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(); @@ -1967,8 +1966,6 @@ 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*/ - 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); @@ -1981,8 +1978,6 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) 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); - 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); } -- cgit v1.2.3 From 3a5fa55455db6a11248a25f24570c365f9246144 Mon Sep 17 00:00:00 2001 From: Martin Tsai Date: Mon, 20 Jan 2025 11:21:46 +0800 Subject: drm/amd/display: Support multiple options during psr entry. [WHY] Some panels may not handle idle pattern properly during PSR entry. [HOW] Add a condition to allow multiple options on power down sequence during PSR1 entry. Reviewed-by: Anthony Koo Signed-off-by: Martin Tsai Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_types.h | 7 +++++++ drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 4 ++++ 2 files changed, 11 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 0c2aa91f0a11..e60898c2df01 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -1033,6 +1033,13 @@ struct psr_settings { unsigned int psr_sdp_transmit_line_num_deadline; uint8_t force_ffu_mode; unsigned int psr_power_opt; + + /** + * Some panels cannot handle idle pattern during PSR entry. + * To power down phy before disable stream to avoid sending + * idle pattern. + */ + uint8_t power_down_phy_before_disable_stream; }; enum replay_coasting_vtotal_type { 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 88c75c243bf8..ff3b8244ba3d 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -418,6 +418,10 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub, copy_settings_data->relock_delay_frame_cnt = 0; if (link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_001CF8) copy_settings_data->relock_delay_frame_cnt = 2; + + copy_settings_data->power_down_phy_before_disable_stream = + link->psr_settings.power_down_phy_before_disable_stream; + copy_settings_data->dsc_slice_height = psr_context->dsc_slice_height; dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT); -- cgit v1.2.3 From 503d67484e3a56a31227556c26ad560f9475f621 Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Date: Tue, 21 Jan 2025 16:24:04 -0500 Subject: drm/amd/display: Enable odm 4:1 when debug key is set [WHAT] odm 4to1 is enabled when debug key is set. Reviewed-by: Charlene Liu Reviewed-by: Alvin Lee Signed-off-by: Muhammad Ahmed Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c index 21f637ae4add..5ed117e11aa2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c @@ -409,6 +409,9 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192; } + if (dc->debug.force_odm_combine_4to1) + context->bw_ctx.dml.ip.odm_combine_4to1_supported = true; + for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; -- cgit v1.2.3 From 2739bd123782f9bedc39285b3965ff2b4b3e6411 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Fri, 25 Oct 2024 10:31:18 -0400 Subject: drm/amd/display: Allow reuse of of DCN4x code Remove the static qualifier to make it available for code sharing with other components. Reviewed-by: Charlene Liu Signed-off-by: Dmytro Signed-off-by: Charlene Liu Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c | 24 ++++++------- .../drm/amd/display/dc/dccg/dcn401/dcn401_dccg.h | 40 +++++++++++++++++++++- .../dc/dio/dcn30/dcn30_dio_stream_encoder.c | 2 +- .../dc/dio/dcn30/dcn30_dio_stream_encoder.h | 6 +++- .../dc/dio/dcn401/dcn401_dio_stream_encoder.c | 12 +++---- .../dc/dio/dcn401/dcn401_dio_stream_encoder.h | 18 ++++++++++ drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c | 5 ++- .../gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c | 19 ++++------ .../gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h | 7 ++++ .../dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.c | 2 +- .../dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.h | 1 + .../drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c | 14 ++++---- .../drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.h | 16 +++++++++ .../gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h | 5 ++- .../gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c | 2 +- .../gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.h | 1 + .../gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h | 8 +++++ .../drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 3 +- .../drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 3 +- drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile | 2 +- drivers/gpu/drm/amd/display/dc/mpc/Makefile | 2 +- .../gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c | 4 +-- .../gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h | 5 ++- .../gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h | 14 ++++++-- .../drm/amd/display/dc/optc/dcn401/dcn401_optc.c | 22 ++++++------ .../drm/amd/display/dc/optc/dcn401/dcn401_optc.h | 19 ++++++++++ 26 files changed, 188 insertions(+), 68 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 d3e46c3cfa57..332094ad2b05 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 @@ -116,7 +116,7 @@ static void dccg401_wait_for_dentist_change_done( REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000); } -static void dccg401_get_pixel_rate_div( +void dccg401_get_pixel_rate_div( struct dccg *dccg, uint32_t otg_inst, uint32_t *tmds_div, @@ -154,7 +154,7 @@ static void dccg401_get_pixel_rate_div( *tmds_div = val_tmds_div == 0 ? PIXEL_RATE_DIV_BY_2 : PIXEL_RATE_DIV_BY_4; } -static void dccg401_set_pixel_rate_div( +void dccg401_set_pixel_rate_div( struct dccg *dccg, uint32_t otg_inst, enum pixel_rate_div tmds_div, @@ -209,7 +209,7 @@ static void dccg401_set_pixel_rate_div( } -static void dccg401_set_dtbclk_p_src( +void dccg401_set_dtbclk_p_src( struct dccg *dccg, enum streamclk_source src, uint32_t otg_inst) @@ -348,7 +348,7 @@ void dccg401_set_physymclk( } } -static void dccg401_get_dccg_ref_freq(struct dccg *dccg, +void dccg401_get_dccg_ref_freq(struct dccg *dccg, unsigned int xtalin_freq_inKhz, unsigned int *dccg_ref_freq_inKhz) { @@ -378,7 +378,7 @@ static void dccg401_otg_drop_pixel(struct dccg *dccg, OTG_DROP_PIXEL[otg_inst], 1); } -static void dccg401_enable_symclk32_le( +void dccg401_enable_symclk32_le( struct dccg *dccg, int hpo_le_inst, enum phyd32clk_clock_source phyd32clk) @@ -429,7 +429,7 @@ static void dccg401_enable_symclk32_le( } } -static void dccg401_disable_symclk32_le( +void dccg401_disable_symclk32_le( struct dccg *dccg, int hpo_le_inst) { @@ -574,7 +574,7 @@ static void dccg401_disable_dpstreamclk(struct dccg *dccg, int dp_hpo_inst) } } -static void dccg401_set_dpstreamclk( +void dccg401_set_dpstreamclk( struct dccg *dccg, enum streamclk_source src, int otg_inst, @@ -587,7 +587,7 @@ static void dccg401_set_dpstreamclk( dccg401_enable_dpstreamclk(dccg, otg_inst, dp_hpo_inst); } -static void dccg401_set_dp_dto( +void dccg401_set_dp_dto( struct dccg *dccg, const struct dp_dto_params *params) { @@ -727,7 +727,7 @@ void dccg401_init(struct dccg *dccg) } } -static void dccg401_set_dto_dscclk(struct dccg *dccg, uint32_t inst) +void dccg401_set_dto_dscclk(struct dccg *dccg, uint32_t inst) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); @@ -763,7 +763,7 @@ static void dccg401_set_dto_dscclk(struct dccg *dccg, uint32_t inst) } } -static void dccg401_set_ref_dscclk(struct dccg *dccg, +void dccg401_set_ref_dscclk(struct dccg *dccg, uint32_t dsc_inst) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); @@ -798,7 +798,7 @@ static void dccg401_set_ref_dscclk(struct dccg *dccg, } } -static void dccg401_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst) +void dccg401_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); @@ -834,7 +834,7 @@ static void dccg401_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst } } -static void dccg401_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst) +void dccg401_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 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 a196ce9e8127..b9905c73e754 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 @@ -193,10 +193,48 @@ void dccg401_init(struct dccg *dccg); void dccg401_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk); - +void dccg401_get_dccg_ref_freq(struct dccg *dccg, + unsigned int xtalin_freq_inKhz, + unsigned int *dccg_ref_freq_inKhz); +void dccg401_set_dpstreamclk( + struct dccg *dccg, + enum streamclk_source src, + int otg_inst, + int dp_hpo_inst); +void dccg401_enable_symclk32_le( + struct dccg *dccg, + int hpo_le_inst, + enum phyd32clk_clock_source phyd32clk); +void dccg401_disable_symclk32_le( + struct dccg *dccg, + int hpo_le_inst); +void dccg401_set_ref_dscclk(struct dccg *dccg, + uint32_t dsc_inst); void dccg401_set_src_sel( struct dccg *dccg, const struct dtbclk_dto_params *params); +void dccg401_set_pixel_rate_div( + struct dccg *dccg, + uint32_t otg_inst, + enum pixel_rate_div tmds_div, + enum pixel_rate_div unused); +void dccg401_get_pixel_rate_div( + struct dccg *dccg, + uint32_t otg_inst, + uint32_t *tmds_div, + uint32_t *dp_dto_int); +void dccg401_set_dp_dto( + struct dccg *dccg, + const struct dp_dto_params *params); +void dccg401_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst); +void dccg401_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst); + +void dccg401_set_dto_dscclk(struct dccg *dccg, uint32_t inst); +void dccg401_set_dtbclk_p_src( + struct dccg *dccg, + enum streamclk_source src, + uint32_t otg_inst); + struct dccg *dccg401_create( struct dc_context *ctx, diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn30/dcn30_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/dcn30/dcn30_dio_stream_encoder.c index 425b830b88d2..e93be7b6d9b0 100644 --- a/drivers/gpu/drm/amd/display/dc/dio/dcn30/dcn30_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dio/dcn30/dcn30_dio_stream_encoder.c @@ -47,7 +47,7 @@ enc1->base.ctx -static void enc3_update_hdmi_info_packet( +void enc3_update_hdmi_info_packet( struct dcn10_stream_encoder *enc1, uint32_t packet_index, const struct dc_info_packet *info_packet) diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn30/dcn30_dio_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dio/dcn30/dcn30_dio_stream_encoder.h index 06310973ded2..830ce7e47035 100644 --- a/drivers/gpu/drm/amd/display/dc/dio/dcn30/dcn30_dio_stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dio/dcn30/dcn30_dio_stream_encoder.h @@ -322,6 +322,10 @@ void enc3_dp_set_dsc_pps_info_packet( struct stream_encoder *enc, bool enable, uint8_t *dsc_packed_pps, - bool immediate_update); + bool immediate_update); +void enc3_update_hdmi_info_packet( + struct dcn10_stream_encoder *enc1, + uint32_t packet_index, + const struct dc_info_packet *info_packet); #endif /* __DC_DIO_STREAM_ENCODER_DCN30_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.c index 098c2a01a850..334fb5e2c003 100644 --- a/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.c @@ -60,7 +60,7 @@ static void enc401_dp_set_odm_combine( } /* setup stream encoder in dvi mode */ -static void enc401_stream_encoder_dvi_set_stream_attribute( +void enc401_stream_encoder_dvi_set_stream_attribute( struct stream_encoder *enc, struct dc_crtc_timing *crtc_timing, bool is_dual_link) @@ -229,7 +229,7 @@ static void enc401_stream_encoder_hdmi_set_stream_attribute( REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, 0); } -static void enc401_set_dig_input_mode(struct stream_encoder *enc, unsigned int pix_per_container) +void enc401_set_dig_input_mode(struct stream_encoder *enc, unsigned int pix_per_container) { struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); @@ -260,7 +260,7 @@ static bool is_two_pixels_per_containter(const struct dc_crtc_timing *timing) return two_pix; } -static void enc401_stream_encoder_dp_unblank( +void enc401_stream_encoder_dp_unblank( struct dc_link *link, struct stream_encoder *enc, const struct encoder_unblank_param *param) @@ -376,7 +376,7 @@ static void enc401_stream_encoder_dp_unblank( /* this function read dsc related register fields to be logged later in dcn10_log_hw_state * into a dcn_dsc_state struct. */ -static void enc401_read_state(struct stream_encoder *enc, struct enc_state *s) +void enc401_read_state(struct stream_encoder *enc, struct enc_state *s) { struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); @@ -394,7 +394,7 @@ static void enc401_read_state(struct stream_encoder *enc, struct enc_state *s) } } -static void enc401_stream_encoder_enable( +void enc401_stream_encoder_enable( struct stream_encoder *enc, enum signal_type signal, bool enable) @@ -704,7 +704,7 @@ void enc401_stream_encoder_dp_set_stream_attribute( DP_SST_SDP_SPLITTING, enable_sdp_splitting); } -static void enc401_stream_encoder_map_to_link( +void enc401_stream_encoder_map_to_link( struct stream_encoder *enc, uint32_t stream_enc_inst, uint32_t link_enc_inst) diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.h index d751839598f8..25cc8f72d8d3 100644 --- a/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.h @@ -214,4 +214,22 @@ void enc401_stream_encoder_dp_set_stream_attribute( enum dc_color_space output_color_space, bool use_vsc_sdp_for_colorimetry, uint32_t enable_sdp_splitting); +void enc401_stream_encoder_dvi_set_stream_attribute( + struct stream_encoder *enc, + struct dc_crtc_timing *crtc_timing, + bool is_dual_link); +void enc401_stream_encoder_dp_unblank( + struct dc_link *link, + struct stream_encoder *enc, + const struct encoder_unblank_param *param); +void enc401_stream_encoder_enable( + struct stream_encoder *enc, + enum signal_type signal, + bool enable); +void enc401_set_dig_input_mode(struct stream_encoder *enc, unsigned int pix_per_container); +void enc401_stream_encoder_map_to_link( + struct stream_encoder *enc, + uint32_t stream_enc_inst, + uint32_t link_enc_inst); +void enc401_read_state(struct stream_encoder *enc, struct enc_state *s); #endif /* __DC_DIO_STREAM_ENCODER_DCN401_H__ */ 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 68b882d28195..556a780466ce 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c @@ -785,7 +785,10 @@ static void dml2_init(const struct dc *in_dc, const struct dml2_configuration_op bool dml2_create(const struct dc *in_dc, const struct dml2_configuration_options *config, struct dml2_context **dml2) { - if ((in_dc->debug.using_dml21) && (in_dc->ctx->dce_version == DCN_VERSION_4_01)) + // TODO : Temporarily add DCN_VERSION_3_2 for N-1 validation. Remove DCN_VERSION_3_2 after N-1 validation phase is complete. + if ((in_dc->debug.using_dml21) + && (in_dc->ctx->dce_version == DCN_VERSION_4_01 + )) return dml21_create(in_dc, dml2, config); // Allocate Mode Lib Ctx 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 61678b0a5a1e..4893b793fec0 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 @@ -16,14 +16,7 @@ static void dsc_write_to_registers(struct display_stream_compressor *dsc, const /* Object I/F functions */ //static void dsc401_get_enc_caps(struct dsc_enc_caps *dsc_enc_caps, int pixel_clock_100Hz); -static void dsc401_read_state(struct display_stream_compressor *dsc, struct dcn_dsc_state *s); -static bool dsc401_validate_stream(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg); -static void dsc401_set_config(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg, - struct dsc_optc_config *dsc_optc_cfg); //static bool dsc401_get_packed_pps(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg, uint8_t *dsc_packed_pps); -static void dsc401_enable(struct display_stream_compressor *dsc, int opp_pipe); -static void dsc401_disable(struct display_stream_compressor *dsc); -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); @@ -117,7 +110,7 @@ static void dsc401_get_enc_caps(struct dsc_enc_caps *dsc_enc_caps, int pixel_clo /* this function read dsc related register fields to be logged later in dcn10_log_hw_state * into a dcn_dsc_state struct. */ -static void dsc401_read_state(struct display_stream_compressor *dsc, struct dcn_dsc_state *s) +void dsc401_read_state(struct display_stream_compressor *dsc, struct dcn_dsc_state *s) { struct dcn401_dsc *dsc401 = TO_DCN401_DSC(dsc); @@ -134,7 +127,7 @@ static void dsc401_read_state(struct display_stream_compressor *dsc, struct dcn_ } -static bool dsc401_validate_stream(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg) +bool dsc401_validate_stream(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg) { struct dsc_optc_config dsc_optc_cfg; struct dcn401_dsc *dsc401 = TO_DCN401_DSC(dsc); @@ -145,7 +138,7 @@ static bool dsc401_validate_stream(struct display_stream_compressor *dsc, const return dsc_prepare_config(dsc_cfg, &dsc401->reg_vals, &dsc_optc_cfg); } -static void dsc401_set_config(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg, +void dsc401_set_config(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg, struct dsc_optc_config *dsc_optc_cfg) { bool is_config_ok; @@ -160,7 +153,7 @@ static void dsc401_set_config(struct display_stream_compressor *dsc, const struc dsc_write_to_registers(dsc, &dsc401->reg_vals); } -static void dsc401_enable(struct display_stream_compressor *dsc, int opp_pipe) +void dsc401_enable(struct display_stream_compressor *dsc, int opp_pipe) { struct dcn401_dsc *dsc401 = TO_DCN401_DSC(dsc); int dsc_clock_en; @@ -185,7 +178,7 @@ static void dsc401_enable(struct display_stream_compressor *dsc, int opp_pipe) } -static void dsc401_disable(struct display_stream_compressor *dsc) +void dsc401_disable(struct display_stream_compressor *dsc) { struct dcn401_dsc *dsc401 = TO_DCN401_DSC(dsc); int dsc_clock_en; @@ -211,7 +204,7 @@ static void dsc401_wait_disconnect_pending_clear(struct display_stream_compresso REG_WAIT(DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_FORWARD_EN_STATUS, 0, 2, 50000); } -static void dsc401_disconnect(struct display_stream_compressor *dsc) +void dsc401_disconnect(struct display_stream_compressor *dsc) { struct dcn401_dsc *dsc401 = TO_DCN401_DSC(dsc); diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h b/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h index 3c9fa8988974..e3ca70058e64 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h +++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h @@ -334,5 +334,12 @@ void dsc401_construct(struct dcn401_dsc *dsc, void dsc401_set_fgcg(struct dcn401_dsc *dsc401, bool enable); +void dsc401_read_state(struct display_stream_compressor *dsc, struct dcn_dsc_state *s); +bool dsc401_validate_stream(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg); +void dsc401_set_config(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg, + struct dsc_optc_config *dsc_optc_cfg); +void dsc401_enable(struct display_stream_compressor *dsc, int opp_pipe); +void dsc401_disable(struct display_stream_compressor *dsc); +void dsc401_disconnect(struct display_stream_compressor *dsc); #endif diff --git a/drivers/gpu/drm/amd/display/dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.c b/drivers/gpu/drm/amd/display/dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.c index 8af01f579690..de3ec4fcade2 100644 --- a/drivers/gpu/drm/amd/display/dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.c @@ -41,7 +41,7 @@ #define CTX \ enc3->base.ctx -static bool dcn32_hpo_dp_link_enc_is_in_alt_mode( +bool dcn32_hpo_dp_link_enc_is_in_alt_mode( struct hpo_dp_link_encoder *enc) { struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc); diff --git a/drivers/gpu/drm/amd/display/dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.h b/drivers/gpu/drm/amd/display/dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.h index 176b1537d2a1..48ef3d29b370 100644 --- a/drivers/gpu/drm/amd/display/dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.h @@ -54,6 +54,7 @@ SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_VC_RATE_CNTL0, STREAM_VC_RATE_Y, mask_sh),\ SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_SAT_UPDATE, SAT_UPDATE, mask_sh) +bool dcn32_hpo_dp_link_enc_is_in_alt_mode(struct hpo_dp_link_encoder *enc); void hpo_dp_link_encoder32_construct(struct dcn31_hpo_dp_link_encoder *enc31, struct dc_context *ctx, uint32_t inst, diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c index dce7269959ce..6d41953011f5 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c @@ -46,7 +46,7 @@ #define DCN35_CRB_SEGMENT_SIZE_KB 64 -static void dcn35_init_crb(struct hubbub *hubbub) +void dcn35_init_crb(struct hubbub *hubbub) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); @@ -71,7 +71,7 @@ static void dcn35_init_crb(struct hubbub *hubbub) REG_UPDATE(DCHUBBUB_DEBUG_CTRL_0, DET_DEPTH, 0x5FF); } -static void dcn35_program_compbuf_size(struct hubbub *hubbub, unsigned int compbuf_size_kb, bool safe_to_increase) +void dcn35_program_compbuf_size(struct hubbub *hubbub, unsigned int compbuf_size_kb, bool safe_to_increase) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); unsigned int compbuf_size_segments = (compbuf_size_kb + DCN35_CRB_SEGMENT_SIZE_KB - 1) / DCN35_CRB_SEGMENT_SIZE_KB; @@ -255,7 +255,7 @@ static bool hubbub35_program_stutter_z8_watermarks( return wm_pending; } -static void hubbub35_get_dchub_ref_freq(struct hubbub *hubbub, +void hubbub35_get_dchub_ref_freq(struct hubbub *hubbub, unsigned int dccg_ref_freq_inKhz, unsigned int *dchub_ref_freq_inKhz) { @@ -295,7 +295,7 @@ static void hubbub35_get_dchub_ref_freq(struct hubbub *hubbub, } -static bool hubbub35_program_watermarks( +bool hubbub35_program_watermarks( struct hubbub *hubbub, union dcn_watermark_set *watermarks, unsigned int refclk_mhz, @@ -335,7 +335,7 @@ static bool hubbub35_program_watermarks( } /* Copy values from WM set A to all other sets */ -static void hubbub35_init_watermarks(struct hubbub *hubbub) +void hubbub35_init_watermarks(struct hubbub *hubbub) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); uint32_t reg; @@ -397,7 +397,7 @@ static void hubbub35_init_watermarks(struct hubbub *hubbub) } -static void hubbub35_wm_read_state(struct hubbub *hubbub, +void hubbub35_wm_read_state(struct hubbub *hubbub, struct dcn_hubbub_wm *wm) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); @@ -514,7 +514,7 @@ static void hubbub35_set_fgcg(struct dcn20_hubbub *hubbub2, bool enable) REG_UPDATE(DCHUBBUB_CLOCK_CNTL, DCHUBBUB_FGCG_REP_DIS, !enable); } -static void hubbub35_init(struct hubbub *hubbub) +void hubbub35_init(struct hubbub *hubbub) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); /*Enable clock gaters*/ diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.h b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.h index 54cf00ffceb8..23fecf88556c 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.h @@ -152,4 +152,20 @@ void hubbub35_construct(struct dcn20_hubbub *hubbub2, int det_size_kb, int pixel_chunk_size_kb, int config_return_buffer_size_kb); + +void hubbub35_wm_read_state(struct hubbub *hubbub, + struct dcn_hubbub_wm *wm); +void hubbub35_get_dchub_ref_freq(struct hubbub *hubbub, + unsigned int dccg_ref_freq_inKhz, + unsigned int *dchub_ref_freq_inKhz); +bool hubbub35_program_watermarks( + struct hubbub *hubbub, + union dcn_watermark_set *watermarks, + unsigned int refclk_mhz, + bool safe_to_lower); +void hubbub35_init_watermarks(struct hubbub *hubbub); +void dcn35_program_compbuf_size(struct hubbub *hubbub, + unsigned int compbuf_size_kb, bool safe_to_increase); +void dcn35_init_crb(struct hubbub *hubbub); +void hubbub35_init(struct hubbub *hubbub); #endif diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h index 6968087a3605..62369be070ea 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h @@ -280,9 +280,8 @@ type MCACHEID_MALL_PREF_1H_P0;\ type MCACHEID_MALL_PREF_2H_P0;\ type MCACHEID_MALL_PREF_1H_P1;\ - type MCACHEID_MALL_PREF_2H_P1 - - + type MCACHEID_MALL_PREF_2H_P1;\ + type HUBP_FGCG_REP_DIS struct dcn_hubp2_registers { DCN401_HUBP_REG_COMMON_VARIABLE_LIST; 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 5661d7a80d54..6d060ba12da8 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 @@ -45,7 +45,7 @@ void hubp35_set_fgcg(struct hubp *hubp, bool enable) REG_UPDATE(HUBP_CLK_CNTL, HUBP_FGCG_REP_DIS, !enable); } -static void hubp35_init(struct hubp *hubp) +void hubp35_init(struct hubp *hubp) { hubp3_init(hubp); diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.h b/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.h index d913f80b3130..934836717f32 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.h @@ -72,4 +72,5 @@ void hubp35_program_surface_config( bool horizontal_mirror, unsigned int compat_level); +void hubp35_init(struct hubp *hubp); #endif /* __DC_HUBP_DCN35_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h index 84c8f8707c5d..09049aa3c4f3 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h @@ -644,10 +644,18 @@ struct dce_hwseq_registers { uint32_t DPP_TOP0_DPP_CRC_CTRL; uint32_t DPP_TOP0_DPP_CRC_VAL_R_G; uint32_t DPP_TOP0_DPP_CRC_VAL_B_A; + uint32_t DPP_TOP0_DPP_CRC_VAL_R; + uint32_t DPP_TOP0_DPP_CRC_VAL_G; + uint32_t DPP_TOP0_DPP_CRC_VAL_B; + uint32_t DPP_TOP0_DPP_CRC_VAL_A; uint32_t MPC_CRC_CTRL; uint32_t MPC_CRC_RESULT_GB; uint32_t MPC_CRC_RESULT_C; uint32_t MPC_CRC_RESULT_AR; + uint32_t MPC_CRC_RESULT_R; + uint32_t MPC_CRC_RESULT_G; + uint32_t MPC_CRC_RESULT_B; + uint32_t MPC_CRC_RESULT_A; uint32_t D1VGA_CONTROL; uint32_t D2VGA_CONTROL; uint32_t D3VGA_CONTROL; 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 dec732c0c59c..b158eb1045a1 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 @@ -2778,7 +2778,8 @@ void dcn20_unblank_stream(struct pipe_ctx *pipe_ctx, } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) { if (is_two_pixels_per_container || params.opp_cnt > 1) params.timing.pix_clk_100hz /= 2; - pipe_ctx->stream_res.stream_enc->funcs->dp_set_odm_combine( + if (pipe_ctx->stream_res.stream_enc->funcs->dp_set_odm_combine) + pipe_ctx->stream_res.stream_enc->funcs->dp_set_odm_combine( pipe_ctx->stream_res.stream_enc, params.opp_cnt > 1); pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, ¶ms); } 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 ee4de9ddfef4..dd46db67d033 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 @@ -1322,7 +1322,8 @@ void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx, params.timing.pix_clk_100hz /= 2; params.pix_per_cycle = 2; } - pipe_ctx->stream_res.stream_enc->funcs->dp_set_odm_combine( + if (pipe_ctx->stream_res.stream_enc->funcs->dp_set_odm_combine) + pipe_ctx->stream_res.stream_enc->funcs->dp_set_odm_combine( pipe_ctx->stream_res.stream_enc, params.pix_per_cycle > 1); pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, ¶ms); } diff --git a/drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile b/drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile index eab196c57c6c..2d4b7a85847d 100644 --- a/drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile +++ b/drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile @@ -50,5 +50,5 @@ MMHUBBUB_DCN35 = dcn35_mmhubbub.o AMD_DAL_MMHUBBUB_DCN35 = $(addprefix $(AMDDALPATH)/dc/mmhubbub/dcn35/,$(MMHUBBUB_DCN35)) AMD_DISPLAY_FILES += $(AMD_DAL_MMHUBBUB_DCN35) - endif + diff --git a/drivers/gpu/drm/amd/display/dc/mpc/Makefile b/drivers/gpu/drm/amd/display/dc/mpc/Makefile index 5402c3529f5e..1e2e66508192 100644 --- a/drivers/gpu/drm/amd/display/dc/mpc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/mpc/Makefile @@ -68,5 +68,5 @@ MPC_DCN401 = dcn401_mpc.o AMD_DAL_MPC_DCN401 = $(addprefix $(AMDDALPATH)/dc/mpc/dcn401/,$(MPC_DCN401)) AMD_DISPLAY_FILES += $(AMD_DAL_MPC_DCN401) - endif + diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c index 37ab5a4eefc7..ad67197557ca 100644 --- a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c @@ -40,14 +40,14 @@ #define FN(reg_name, field_name) \ mpc401->mpc_shift->field_name, mpc401->mpc_mask->field_name -static void mpc401_update_3dlut_fast_load_select(struct mpc *mpc, int mpcc_id, int hubp_idx) +void mpc401_update_3dlut_fast_load_select(struct mpc *mpc, int mpcc_id, int hubp_idx) { struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); REG_SET(MPCC_MCM_3DLUT_FAST_LOAD_SELECT[mpcc_id], 0, MPCC_MCM_3DLUT_FL_SEL, hubp_idx); } -static void mpc401_get_3dlut_fast_load_status(struct mpc *mpc, int mpcc_id, uint32_t *done, uint32_t *soft_underflow, uint32_t *hard_underflow) +void mpc401_get_3dlut_fast_load_status(struct mpc *mpc, int mpcc_id, uint32_t *done, uint32_t *soft_underflow, uint32_t *hard_underflow) { struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h index af44054c2477..9267cdf88e9a 100644 --- a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h +++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h @@ -63,7 +63,8 @@ uint32_t MPC_MCM_SECOND_GAMUT_REMAP_C31_C32_B[MAX_MPCC]; \ uint32_t MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_B[MAX_MPCC]; \ uint32_t MPCC_MCM_3DLUT_FAST_LOAD_SELECT[MAX_MPCC]; \ - uint32_t MPCC_MCM_3DLUT_FAST_LOAD_STATUS[MAX_MPCC] + uint32_t MPCC_MCM_3DLUT_FAST_LOAD_STATUS[MAX_MPCC]; \ + uint32_t MPCC_CONTROL2[MAX_MPCC] #define MPC_COMMON_MASK_SH_LIST_DCN4_01(mask_sh) \ MPC_COMMON_MASK_SH_LIST_DCN32(mask_sh), \ @@ -235,5 +236,7 @@ void mpc401_get_gamut_remap( struct mpc *mpc, int mpcc_id, struct mpc_grph_gamut_adjustment *adjust); +void mpc401_update_3dlut_fast_load_select(struct mpc *mpc, int mpcc_id, int hubp_idx); +void mpc401_get_3dlut_fast_load_status(struct mpc *mpc, int mpcc_id, uint32_t *done, uint32_t *soft_underflow, uint32_t *hard_underflow); #endif 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 82b91b9bc9c2..a6d4dbe82c13 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 @@ -168,13 +168,21 @@ struct dcn_optc_registers { uint32_t OTG_CRC_CNTL; uint32_t OTG_CRC_CNTL2; uint32_t OTG_CRC0_DATA_RG; + uint32_t OTG_CRC1_DATA_RG; + uint32_t OTG_CRC2_DATA_RG; + uint32_t OTG_CRC3_DATA_RG; uint32_t OTG_CRC0_DATA_B; uint32_t OTG_CRC1_DATA_B; uint32_t OTG_CRC2_DATA_B; uint32_t OTG_CRC3_DATA_B; - uint32_t OTG_CRC1_DATA_RG; - uint32_t OTG_CRC2_DATA_RG; - uint32_t OTG_CRC3_DATA_RG; + uint32_t OTG_CRC0_DATA_R; + uint32_t OTG_CRC1_DATA_R; + uint32_t OTG_CRC2_DATA_R; + uint32_t OTG_CRC3_DATA_R; + uint32_t OTG_CRC0_DATA_G; + uint32_t OTG_CRC1_DATA_G; + uint32_t OTG_CRC2_DATA_G; + uint32_t OTG_CRC3_DATA_G; uint32_t OTG_CRC0_WINDOWA_X_CONTROL; uint32_t OTG_CRC0_WINDOWA_Y_CONTROL; uint32_t OTG_CRC0_WINDOWB_X_CONTROL; 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 bf921d1f500b..382ac18e7854 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 @@ -101,7 +101,7 @@ static uint32_t decide_odm_mem_bit_map(int *opp_id, int opp_cnt, int h_active) return memory_bit_map; } -static void optc401_set_odm_combine(struct timing_generator *optc, int *opp_id, +void optc401_set_odm_combine(struct timing_generator *optc, int *opp_id, int opp_cnt, int segment_width, int last_segment_width) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -162,7 +162,7 @@ static void optc401_set_odm_combine(struct timing_generator *optc, int *opp_id, optc1->opp_count = opp_cnt; } -static void optc401_set_h_timing_div_manual_mode(struct timing_generator *optc, bool manual_mode) +void optc401_set_h_timing_div_manual_mode(struct timing_generator *optc, bool manual_mode) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -177,7 +177,7 @@ static void optc401_set_h_timing_div_manual_mode(struct timing_generator *optc, * * Return: Always returns true */ -static bool optc401_enable_crtc(struct timing_generator *optc) +bool optc401_enable_crtc(struct timing_generator *optc) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -203,7 +203,7 @@ static bool optc401_enable_crtc(struct timing_generator *optc) } /* disable_crtc */ -static bool optc401_disable_crtc(struct timing_generator *optc) +bool optc401_disable_crtc(struct timing_generator *optc) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -234,7 +234,7 @@ static bool optc401_disable_crtc(struct timing_generator *optc) return true; } -static void optc401_phantom_crtc_post_enable(struct timing_generator *optc) +void optc401_phantom_crtc_post_enable(struct timing_generator *optc) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -245,7 +245,7 @@ static void optc401_phantom_crtc_post_enable(struct timing_generator *optc) REG_WAIT(OTG_CLOCK_CONTROL, OTG_BUSY, 0, 1, 100000); } -static void optc401_disable_phantom_otg(struct timing_generator *optc) +void optc401_disable_phantom_otg(struct timing_generator *optc) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -259,7 +259,7 @@ static void optc401_disable_phantom_otg(struct timing_generator *optc) REG_UPDATE(OTG_CONTROL, OTG_MASTER_EN, 0); } -static void optc401_set_odm_bypass(struct timing_generator *optc, +void optc401_set_odm_bypass(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -365,7 +365,7 @@ void optc401_set_drr( } } -static void optc401_set_out_mux(struct timing_generator *optc, enum otg_out_mux_dest dest) +void optc401_set_out_mux(struct timing_generator *optc, enum otg_out_mux_dest dest) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -396,7 +396,7 @@ void optc401_set_vtotal_min_max(struct timing_generator *optc, int vtotal_min, i } } -static void optc401_program_global_sync( +void optc401_program_global_sync( struct timing_generator *optc, int vready_offset, int vstartup_start, @@ -430,7 +430,7 @@ static void optc401_program_global_sync( REG_UPDATE(OTG_PSTATE_REGISTER, OTG_PSTATE_KEEPOUT_START, pstate_keepout); } -static void optc401_set_vupdate_keepout(struct timing_generator *tg, bool enable) +void optc401_set_vupdate_keepout(struct timing_generator *tg, bool enable) { struct optc *optc1 = DCN10TG_FROM_TG(tg); @@ -442,7 +442,7 @@ static void optc401_set_vupdate_keepout(struct timing_generator *tg, bool enable return; } -static bool optc401_wait_update_lock_status(struct timing_generator *tg, bool locked) +bool optc401_wait_update_lock_status(struct timing_generator *tg, bool locked) { struct optc *optc1 = DCN10TG_FROM_TG(tg); uint32_t lock_status = 0; 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 69ad21084fbb..fa62737b5b1b 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 @@ -173,5 +173,24 @@ void optc401_set_drr( const struct drr_params *params); void optc401_set_vtotal_min_max(struct timing_generator *optc, int vtotal_min, int vtotal_max); void optc401_setup_manual_trigger(struct timing_generator *optc); +void optc401_program_global_sync( + struct timing_generator *optc, + int vready_offset, + int vstartup_start, + int vupdate_offset, + int vupdate_width, + int pstate_keepout); +bool optc401_enable_crtc(struct timing_generator *optc); +bool optc401_disable_crtc(struct timing_generator *optc); +void optc401_phantom_crtc_post_enable(struct timing_generator *optc); +void optc401_disable_phantom_otg(struct timing_generator *optc); +void optc401_set_odm_bypass(struct timing_generator *optc, + const struct dc_crtc_timing *dc_crtc_timing); +void optc401_set_odm_combine(struct timing_generator *optc, int *opp_id, + int opp_cnt, int segment_width, int last_segment_width); +void optc401_set_h_timing_div_manual_mode(struct timing_generator *optc, bool manual_mode); +void optc401_set_out_mux(struct timing_generator *optc, enum otg_out_mux_dest dest); +bool optc401_wait_update_lock_status(struct timing_generator *tg, bool locked); +void optc401_set_vupdate_keepout(struct timing_generator *tg, bool enable); #endif /* __DC_OPTC_DCN401_H__ */ -- cgit v1.2.3 From 13437c91606c9232c747475e202fe3827cd53264 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Thu, 23 Jan 2025 16:39:52 -0500 Subject: drm/amd/display: Request HW cursor on DCN3.2 with SubVP [WHY] When SubVP is active the HW cursor size is limited to 64x64, and anything larger will force composition which is bad for gaming on DCN3.2 if the game uses a larger cursor. [HOW] If HW cursor is requested, typically by a fullscreen game, do not enable SubVP so that up to 256x256 cursor sizes are available for DCN3.2. Reviewed-by: Dillon Varone Signed-off-by: Aric Cyr Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/display/dc') 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 6f490d8d7038..56dda686e299 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 @@ -626,6 +626,7 @@ static bool dcn32_assign_subvp_pipe(struct dc *dc, * - Not TMZ surface */ if (pipe->plane_state && !pipe->top_pipe && !pipe->prev_odm_pipe && !dcn32_is_center_timing(pipe) && + !pipe->stream->hw_cursor_req && !(pipe->stream->timing.pix_clk_100hz / 10000 > DCN3_2_MAX_SUBVP_PIXEL_RATE_MHZ) && (!dcn32_is_psr_capable(pipe) || (context->stream_count == 1 && dc->caps.dmub_caps.subvp_psr)) && dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_NONE && -- cgit v1.2.3 From 5c06c1df3582102e837dc7d6e8a462323277e57b Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Thu, 23 Jan 2025 14:36:57 -0500 Subject: drm/amd/display: Move SPL to a new path [WHY & HOW] - Move SPL from dc/spl to dc/sspl - Update build files and header paths - Remove dc/spl files Reviewed-by: George Zhang Signed-off-by: Samson Tam Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/Makefile | 2 +- drivers/gpu/drm/amd/display/dc/dc.h | 2 - drivers/gpu/drm/amd/display/dc/dc_spl_translate.c | 1 - .../gpu/drm/amd/display/dc/dpp/dcn20/dcn20_dpp.h | 1 - .../gpu/drm/amd/display/dc/dpp/dcn32/dcn32_dpp.h | 1 - drivers/gpu/drm/amd/display/dc/inc/core_types.h | 2 +- drivers/gpu/drm/amd/display/dc/inc/hw/transform.h | 2 +- drivers/gpu/drm/amd/display/dc/inc/resource.h | 1 - .../display/dc/resource/dcn401/dcn401_resource.c | 4 +- drivers/gpu/drm/amd/display/dc/spl/Makefile | 33 - drivers/gpu/drm/amd/display/dc/spl/dc_spl.c | 1874 -------------------- drivers/gpu/drm/amd/display/dc/spl/dc_spl.h | 18 - .../gpu/drm/amd/display/dc/spl/dc_spl_filters.c | 15 - .../gpu/drm/amd/display/dc/spl/dc_spl_filters.h | 15 - .../drm/amd/display/dc/spl/dc_spl_isharp_filters.c | 757 -------- .../drm/amd/display/dc/spl/dc_spl_isharp_filters.h | 50 - .../amd/display/dc/spl/dc_spl_scl_easf_filters.c | 1726 ------------------ .../amd/display/dc/spl/dc_spl_scl_easf_filters.h | 38 - .../drm/amd/display/dc/spl/dc_spl_scl_filters.c | 1451 --------------- .../drm/amd/display/dc/spl/dc_spl_scl_filters.h | 22 - drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h | 543 ------ .../gpu/drm/amd/display/dc/spl/spl_custom_float.c | 151 -- .../gpu/drm/amd/display/dc/spl/spl_custom_float.h | 29 - drivers/gpu/drm/amd/display/dc/spl/spl_debug.h | 30 - .../gpu/drm/amd/display/dc/spl/spl_fixpt31_32.c | 497 ------ .../gpu/drm/amd/display/dc/spl/spl_fixpt31_32.h | 522 ------ drivers/gpu/drm/amd/display/dc/spl/spl_os_types.h | 56 - drivers/gpu/drm/amd/display/dc/sspl/Makefile | 33 + drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c | 1874 ++++++++++++++++++++ drivers/gpu/drm/amd/display/dc/sspl/dc_spl.h | 18 + .../gpu/drm/amd/display/dc/sspl/dc_spl_filters.c | 15 + .../gpu/drm/amd/display/dc/sspl/dc_spl_filters.h | 15 + .../amd/display/dc/sspl/dc_spl_isharp_filters.c | 757 ++++++++ .../amd/display/dc/sspl/dc_spl_isharp_filters.h | 50 + .../amd/display/dc/sspl/dc_spl_scl_easf_filters.c | 1726 ++++++++++++++++++ .../amd/display/dc/sspl/dc_spl_scl_easf_filters.h | 38 + .../drm/amd/display/dc/sspl/dc_spl_scl_filters.c | 1451 +++++++++++++++ .../drm/amd/display/dc/sspl/dc_spl_scl_filters.h | 22 + drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h | 543 ++++++ .../gpu/drm/amd/display/dc/sspl/spl_custom_float.c | 151 ++ .../gpu/drm/amd/display/dc/sspl/spl_custom_float.h | 29 + drivers/gpu/drm/amd/display/dc/sspl/spl_debug.h | 30 + .../gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c | 497 ++++++ .../gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.h | 522 ++++++ drivers/gpu/drm/amd/display/dc/sspl/spl_os_types.h | 56 + 45 files changed, 7832 insertions(+), 7838 deletions(-) delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/Makefile delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/dc_spl.c delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/dc_spl.h delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.c delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.h delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.c delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.h delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.c delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.h delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.c delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.h delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.c delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.h delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/spl_debug.h delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.c delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.h delete mode 100644 drivers/gpu/drm/amd/display/dc/spl/spl_os_types.h create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/Makefile create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/dc_spl.h create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/dc_spl_filters.c create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/dc_spl_filters.h create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.h create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.c create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.h create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.c create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.h create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/spl_custom_float.c create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/spl_custom_float.h create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/spl_debug.h create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.h create mode 100644 drivers/gpu/drm/amd/display/dc/sspl/spl_os_types.h (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile index 8992e697759f..3e1f5b689718 100644 --- a/drivers/gpu/drm/amd/display/dc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/Makefile @@ -52,7 +52,7 @@ endif DC_LIBS += hdcp ifdef CONFIG_DRM_AMD_DC_FP -DC_LIBS += spl +DC_LIBS += sspl DC_SPL_TRANS += dc_spl_translate.o endif diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 559446dcd431..9ac299fb1034 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -46,8 +46,6 @@ #include "dmub/inc/dmub_cmd.h" -#include "spl/dc_spl_types.h" - struct abm_save_restore; /* forward declaration */ 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 3518eb1b8cd1..e3a8283b4098 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c +++ b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c @@ -3,7 +3,6 @@ // Copyright 2024 Advanced Micro Devices, Inc. #include "dc_spl_translate.h" -#include "spl/dc_spl_types.h" #include "dcn20/dcn20_dpp.h" #include "dcn32/dcn32_dpp.h" #include "dcn401/dcn401_dpp.h" diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn20/dcn20_dpp.h b/drivers/gpu/drm/amd/display/dc/dpp/dcn20/dcn20_dpp.h index f09cba8e29cc..85f359b5da67 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn20/dcn20_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn20/dcn20_dpp.h @@ -26,7 +26,6 @@ #define __DCN20_DPP_H__ #include "dcn10/dcn10_dpp.h" -#include "spl/dc_spl_types.h" #define TO_DCN20_DPP(dpp)\ container_of(dpp, struct dcn20_dpp, base) diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn32/dcn32_dpp.h b/drivers/gpu/drm/amd/display/dc/dpp/dcn32/dcn32_dpp.h index 992df172378c..f33dddbfcc31 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn32/dcn32_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn32/dcn32_dpp.h @@ -27,7 +27,6 @@ #include "dcn20/dcn20_dpp.h" #include "dcn30/dcn30_dpp.h" -#include "spl/dc_spl_types.h" bool dpp32_construct(struct dcn3_dpp *dpp3, struct dc_context *ctx, 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 37632be09e09..d0021f25f3d8 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -39,7 +39,7 @@ #include "panel_cntl.h" #include "dmub/inc/dmub_cmd.h" #include "pg_cntl.h" -#include "spl/dc_spl.h" +#include "sspl/dc_spl.h" #define MAX_CLOCK_SOURCES 7 #define MAX_SVP_PHANTOM_STREAMS 2 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 45262cba675e..5a1d9b708a9d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h @@ -29,7 +29,7 @@ #include "hw_shared.h" #include "dc_hw_types.h" #include "fixed31_32.h" -#include "spl/dc_spl_types.h" +#include "sspl/dc_spl_types.h" #define CSC_TEMPERATURE_MATRIX_SIZE 12 diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index b32d07ce0f08..042e04f924a2 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -29,7 +29,6 @@ #include "core_status.h" #include "dal_asic_id.h" #include "dm_pp_smu.h" -#include "spl/dc_spl.h" #define MEMORY_TYPE_MULTIPLIER_CZ 4 #define MEMORY_TYPE_HBM 2 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 c1ebc6b1c937..5cb0e0191a16 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,8 +76,8 @@ #include "dml2/dml2_wrapper.h" -#include "spl/dc_spl_scl_easf_filters.h" -#include "spl/dc_spl_isharp_filters.h" +#include "sspl/dc_spl_scl_easf_filters.h" +#include "sspl/dc_spl_isharp_filters.h" #define DC_LOGGER_INIT(logger) diff --git a/drivers/gpu/drm/amd/display/dc/spl/Makefile b/drivers/gpu/drm/amd/display/dc/spl/Makefile deleted file mode 100644 index 5edf3c6cf3e2..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright 2017 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. -# -# -# 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_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)) - -AMD_DISPLAY_FILES += $(AMD_DAL_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 deleted file mode 100644 index 38a9a0d68058..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c +++ /dev/null @@ -1,1874 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright 2024 Advanced Micro Devices, Inc. - -#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) (spl_fixpt_u2d19(ratio) == (1 << 19)) -#define MIN_VIEWPORT_SIZE 12 - -static bool spl_is_yuv420(enum spl_pixel_format format) -{ - 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; -} - -static bool spl_is_video_format(enum spl_pixel_format format) -{ - if (format >= SPL_PIXEL_FORMAT_VIDEO_BEGIN - && format <= SPL_PIXEL_FORMAT_VIDEO_END) - return true; - else - return false; -} - -static bool spl_is_subsampled_format(enum spl_pixel_format format) -{ - if (format >= SPL_PIXEL_FORMAT_SUBSAMPLED_BEGIN - && format <= SPL_PIXEL_FORMAT_SUBSAMPLED_END) - return true; - else - return false; -} - -static struct spl_rect intersect_rec(const struct spl_rect *r0, const struct spl_rect *r1) -{ - struct spl_rect rec; - int r0_x_end = r0->x + r0->width; - int r1_x_end = r1->x + r1->width; - int r0_y_end = r0->y + r0->height; - int r1_y_end = r1->y + r1->height; - - rec.x = r0->x > r1->x ? r0->x : r1->x; - rec.width = r0_x_end > r1_x_end ? r1_x_end - rec.x : r0_x_end - rec.x; - rec.y = r0->y > r1->y ? r0->y : r1->y; - rec.height = r0_y_end > r1_y_end ? r1_y_end - rec.y : r0_y_end - rec.y; - - /* in case that there is no intersection */ - if (rec.width < 0 || rec.height < 0) - memset(&rec, 0, sizeof(rec)); - - return rec; -} - -static struct spl_rect shift_rec(const struct spl_rect *rec_in, int x, int y) -{ - struct spl_rect rec_out = *rec_in; - - rec_out.x += x; - rec_out.y += y; - - return rec_out; -} - -static struct spl_rect calculate_plane_rec_in_timing_active( - struct spl_in *spl_in, - const struct spl_rect *rec_in) -{ - /* - * The following diagram shows an example where we map a 1920x1200 - * desktop to a 2560x1440 timing with a plane rect in the middle - * of the screen. To map a plane rect from Stream Source to Timing - * Active space, we first multiply stream scaling ratios (i.e 2304/1920 - * horizontal and 1440/1200 vertical) to the plane's x and y, then - * we add stream destination offsets (i.e 128 horizontal, 0 vertical). - * This will give us a plane rect's position in Timing Active. However - * we have to remove the fractional. The rule is that we find left/right - * and top/bottom positions and round the value to the adjacent integer. - * - * Stream Source Space - * ------------ - * __________________________________________________ - * |Stream Source (1920 x 1200) ^ | - * | y | - * | <------- w --------|> | - * | __________________V | - * |<-- x -->|Plane//////////////| ^ | - * | |(pre scale)////////| | | - * | |///////////////////| | | - * | |///////////////////| h | - * | |///////////////////| | | - * | |///////////////////| | | - * | |///////////////////| V | - * | | - * | | - * |__________________________________________________| - * - * - * Timing Active Space - * --------------------------------- - * - * Timing Active (2560 x 1440) - * __________________________________________________ - * |*****| Stteam Destination (2304 x 1440) |*****| - * |*****| |*****| - * |<128>| |*****| - * |*****| __________________ |*****| - * |*****| |Plane/////////////| |*****| - * |*****| |(post scale)//////| |*****| - * |*****| |//////////////////| |*****| - * |*****| |//////////////////| |*****| - * |*****| |//////////////////| |*****| - * |*****| |//////////////////| |*****| - * |*****| |*****| - * |*****| |*****| - * |*****| |*****| - * |*****|______________________________________|*****| - * - * So the resulting formulas are shown below: - * - * recout_x = 128 + round(plane_x * 2304 / 1920) - * recout_w = 128 + round((plane_x + plane_w) * 2304 / 1920) - recout_x - * recout_y = 0 + round(plane_y * 1440 / 1200) - * recout_h = 0 + round((plane_y + plane_h) * 1440 / 1200) - recout_y - * - * NOTE: fixed point division is not error free. To reduce errors - * introduced by fixed point division, we divide only after - * multiplication is complete. - */ - 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 spl_fixed31_32 temp; - - - temp = spl_fixpt_from_fraction(rec_in->x * (long long)stream_dst->width, - stream_src->width); - rec_out.x = stream_dst->x + spl_fixpt_round(temp); - - 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 + spl_fixpt_round(temp) - rec_out.x; - - temp = spl_fixpt_from_fraction(rec_in->y * (long long)stream_dst->height, - stream_src->height); - rec_out.y = stream_dst->y + spl_fixpt_round(temp); - - 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 + spl_fixpt_round(temp) - rec_out.y; - - return rec_out; -} - -static struct spl_rect calculate_mpc_slice_in_timing_active( - struct spl_in *spl_in, - struct spl_rect *plane_clip_rec) -{ - bool use_recout_width_aligned = - spl_in->basic_in.num_h_slices_recout_width_align.use_recout_width_aligned; - int mpc_slice_count = - spl_in->basic_in.num_h_slices_recout_width_align.num_slices_recout_width.mpc_num_h_slices; - int recout_width_align = - spl_in->basic_in.num_h_slices_recout_width_align.num_slices_recout_width.mpc_recout_width_align; - int mpc_slice_idx = spl_in->basic_in.mpc_h_slice_index; - int epimo = mpc_slice_count - plane_clip_rec->width % mpc_slice_count - 1; - struct spl_rect mpc_rec; - - if (use_recout_width_aligned) { - mpc_rec.width = recout_width_align; - if ((mpc_rec.width * (mpc_slice_idx + 1)) > plane_clip_rec->width) { - mpc_rec.width = plane_clip_rec->width % recout_width_align; - mpc_rec.x = plane_clip_rec->x + recout_width_align * mpc_slice_idx; - } else - 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; - - } else { - mpc_rec.width = plane_clip_rec->width / mpc_slice_count; - 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; - } - SPL_ASSERT(mpc_slice_count == 1 || - spl_in->basic_out.view_format != SPL_VIEW_3D_SIDE_BY_SIDE || - mpc_rec.width % 2 == 0); - - /* extra pixels in the division remainder need to go to pipes after - * the extra pixel index minus one(epimo) defined here as: - */ - if (mpc_slice_idx > epimo) { - mpc_rec.x += mpc_slice_idx - epimo - 1; - mpc_rec.width += 1; - } - - if (spl_in->basic_out.view_format == SPL_VIEW_3D_TOP_AND_BOTTOM) { - SPL_ASSERT(mpc_rec.height % 2 == 0); - mpc_rec.height /= 2; - } - return mpc_rec; -} - -static struct spl_rect calculate_odm_slice_in_timing_active(struct spl_in *spl_in) -{ - int odm_slice_count = spl_in->basic_out.odm_combine_factor; - int odm_slice_idx = spl_in->odm_slice_index; - bool is_last_odm_slice = (odm_slice_idx + 1) == odm_slice_count; - int h_active = spl_in->basic_out.output_size.width; - int v_active = spl_in->basic_out.output_size.height; - int odm_slice_width; - struct spl_rect odm_rec; - - if (spl_in->basic_out.odm_combine_factor > 0) { - odm_slice_width = h_active / odm_slice_count; - /* - * deprecated, caller must pass in odm slice rect i.e OPP input - * rect in timing active for the new interface. - */ - if (spl_in->basic_out.use_two_pixels_per_container && (odm_slice_width % 2)) - odm_slice_width++; - - odm_rec.x = odm_slice_width * odm_slice_idx; - odm_rec.width = is_last_odm_slice ? - /* last slice width is the reminder of h_active */ - h_active - odm_slice_width * (odm_slice_count - 1) : - /* odm slice width is the floor of h_active / count */ - odm_slice_width; - odm_rec.y = 0; - odm_rec.height = v_active; - - return odm_rec; - } - - return spl_in->basic_out.odm_slice_rect; -} - -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 - * Source Space. Stream Source is the destination where all planes are - * blended (i.e. positioned, scaled and overlaid). It is a canvas where - * all planes associated with the current stream are drawn together. - * After Stream Source is completed, we will further scale and - * reposition the entire canvas of the stream source to Stream - * Destination in Timing Active Space. This could be due to display - * overscan adjustment where we will need to rescale and reposition all - * the planes so they can fit into a TV with overscan or downscale - * upscale features such as GPU scaling or VSR. - * - * This two step blending is a virtual procedure in software. In - * hardware there is no such thing as Stream Source. all planes are - * blended once in Timing Active Space. Software virtualizes a Stream - * Source space to decouple the math complicity so scaling param - * calculation focuses on one step at a time. - * - * In the following two diagrams, user applied 10% overscan adjustment - * so the Stream Source needs to be scaled down a little before mapping - * to Timing Active Space. As a result the Plane Clip is also scaled - * down by the same ratio, Plane Clip position (i.e. x and y) with - * respect to Stream Source is also scaled down. To map it in Timing - * Active Space additional x and y offsets from Stream Destination are - * added to Plane Clip as well. - * - * Stream Source Space - * ------------ - * __________________________________________________ - * |Stream Source (3840 x 2160) ^ | - * | y | - * | | | - * | __________________V | - * |<-- x -->|Plane Clip/////////| | - * | |(pre scale)////////| | - * | |///////////////////| | - * | |///////////////////| | - * | |///////////////////| | - * | |///////////////////| | - * | |///////////////////| | - * | | - * | | - * |__________________________________________________| - * - * - * Timing Active Space (3840 x 2160) - * --------------------------------- - * - * Timing Active - * __________________________________________________ - * | y_____________________________________________ | - * |x |Stream Destination (3456 x 1944) | | - * | | | | - * | | __________________ | | - * | | |Plane Clip////////| | | - * | | |(post scale)//////| | | - * | | |//////////////////| | | - * | | |//////////////////| | | - * | | |//////////////////| | | - * | | |//////////////////| | | - * | | | | - * | | | | - * | |____________________________________________| | - * |__________________________________________________| - * - * - * In Timing Active Space a plane clip could be further sliced into - * pieces called MPC slices. Each Pipe Context is responsible for - * processing only one MPC slice so the plane processing workload can be - * distributed to multiple DPP Pipes. MPC slices could be blended - * together to a single ODM slice. Each ODM slice is responsible for - * processing a portion of Timing Active divided horizontally so the - * output pixel processing workload can be distributed to multiple OPP - * pipes. All ODM slices are mapped together in ODM block so all MPC - * slices belong to different ODM slices could be pieced together to - * form a single image in Timing Active. MPC slices must belong to - * single ODM slice. If an MPC slice goes across ODM slice boundary, it - * needs to be divided into two MPC slices one for each ODM slice. - * - * In the following diagram the output pixel processing workload is - * divided horizontally into two ODM slices one for each OPP blend tree. - * OPP0 blend tree is responsible for processing left half of Timing - * Active, while OPP2 blend tree is responsible for processing right - * half. - * - * The plane has two MPC slices. However since the right MPC slice goes - * across ODM boundary, two DPP pipes are needed one for each OPP blend - * tree. (i.e. DPP1 for OPP0 blend tree and DPP2 for OPP2 blend tree). - * - * Assuming that we have a Pipe Context associated with OPP0 and DPP1 - * working on processing the plane in the diagram. We want to know the - * width and height of the shaded rectangle and its relative position - * with respect to the ODM slice0. This is called the recout of the pipe - * context. - * - * Planes can be at arbitrary size and position and there could be an - * arbitrary number of MPC and ODM slices. The algorithm needs to take - * all scenarios into account. - * - * Timing Active Space (3840 x 2160) - * --------------------------------- - * - * Timing Active - * __________________________________________________ - * |OPP0(ODM slice0)^ |OPP2(ODM slice1) | - * | y | | - * | | <- w -> | - * | _____V________|____ | - * | |DPP0 ^ |DPP1 |DPP2| | - * |<------ x |-----|->|/////| | | - * | | | |/////| | | - * | | h |/////| | | - * | | | |/////| | | - * | |_____V__|/////|____| | - * | | | - * | | | - * | | | - * |_________________________|________________________| - * - * - */ - struct spl_rect plane_clip; - struct spl_rect mpc_slice_of_plane_clip; - struct spl_rect odm_slice; - struct spl_rect overlapping_area; - - plane_clip = calculate_plane_rec_in_timing_active(spl_in, - &spl_in->basic_in.clip_rect); - /* guard plane clip from drawing beyond stream dst here */ - plane_clip = intersect_rec(&plane_clip, - &spl_in->basic_out.dst_rect); - mpc_slice_of_plane_clip = calculate_mpc_slice_in_timing_active( - spl_in, &plane_clip); - odm_slice = calculate_odm_slice_in_timing_active(spl_in); - overlapping_area = intersect_rec(&mpc_slice_of_plane_clip, &odm_slice); - - if (overlapping_area.height > 0 && - overlapping_area.width > 0) { - /* shift the overlapping area so it is with respect to current - * ODM slice's position - */ - spl_scratch->scl_data.recout = shift_rec( - &overlapping_area, - -odm_slice.x, -odm_slice.y); - spl_scratch->scl_data.recout.height -= - spl_in->debug.visual_confirm_base_offset; - spl_scratch->scl_data.recout.height -= - spl_in->debug.visual_confirm_dpp_offset; - } else - /* if there is no overlap, zero recout */ - 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_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; - const int out_w = spl_in->basic_out.dst_rect.width; - const int out_h = spl_in->basic_out.dst_rect.height; - struct spl_rect surf_src = spl_in->basic_in.src_rect; - - /*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) - spl_swap(surf_src.height, surf_src.width); - - spl_scratch->scl_data.ratios.horz = spl_fixpt_from_fraction( - surf_src.width, - spl_in->basic_in.dst_rect.width); - 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_scratch->scl_data.ratios.horz.value *= 2; - else if (spl_in->basic_out.view_format == SPL_VIEW_3D_TOP_AND_BOTTOM) - spl_scratch->scl_data.ratios.vert.value *= 2; - - 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_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_is_yuv420(spl_in->basic_in.format)) { - spl_scratch->scl_data.ratios.horz_c.value /= 2; - spl_scratch->scl_data.ratios.vert_c.value /= 2; - } - 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_scratch *spl_scratch) -{ - 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) { - 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, - bool *flip_vert_scan_dir, - bool *flip_horz_scan_dir) -{ - *orthogonal_rotation = false; - *flip_vert_scan_dir = false; - *flip_horz_scan_dir = false; - if (rotation == SPL_ROTATION_ANGLE_180) { - *flip_vert_scan_dir = true; - *flip_horz_scan_dir = true; - } else if (rotation == SPL_ROTATION_ANGLE_90) { - *orthogonal_rotation = true; - *flip_horz_scan_dir = true; - } else if (rotation == SPL_ROTATION_ANGLE_270) { - *orthogonal_rotation = true; - *flip_vert_scan_dir = true; - } - - 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. - */ -static void spl_calculate_init_and_vp(bool flip_scan_dir, - int recout_offset_within_recout_full, - int recout_size, - int src_size, - int taps, - struct spl_fixed31_32 ratio, - struct spl_fixed31_32 init_adj, - struct spl_fixed31_32 *init, - int *vp_offset, - int *vp_size) -{ - struct spl_fixed31_32 temp; - int int_part; - - /* - * First of the taps starts sampling pixel number corresponding to recout - * pixel 1. Next recout pixel samples int part of and so on. - * All following calculations are based on this logic. - * - * Init calculated according to formula: - * init = (scaling_ratio + number_of_taps + 1) / 2 - * init_bot = init + scaling_ratio - * to get pixel perfect combine add the fraction from calculating vp offset - */ - temp = spl_fixpt_mul_int(ratio, recout_offset_within_recout_full); - *vp_offset = spl_fixpt_floor(temp); - temp.value &= 0xffffffff; - *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 = 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 = 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 = 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; - - /* We did all the math assuming we are scanning same direction as display does, - * however mirror/rotation changes how vp scans vs how it is offset. If scan direction - * is flipped we simply need to calculate offset from the other side of plane. - * Note that outside of viewport all scaling hardware works in recout space. - */ - if (flip_scan_dir) - *vp_offset = src_size - *vp_offset - *vp_size; -} - -/*Calculate inits and viewport */ -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; - struct spl_rect recout_clip_in_active_timing; - struct spl_rect recout_clip_in_recout_dst; - struct spl_rect overlap_in_active_timing; - struct spl_rect odm_slice = calculate_odm_slice_in_timing_active(spl_in); - int vpc_div = spl_is_subsampled_format(spl_in->basic_in.format) ? 2 : 1; - bool orthogonal_rotation, flip_vert_scan_dir, flip_horz_scan_dir; - 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_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, - &recout_dst_in_active_timing); - if (overlap_in_active_timing.width > 0 && - overlap_in_active_timing.height > 0) - recout_clip_in_recout_dst = shift_rec(&overlap_in_active_timing, - -recout_dst_in_active_timing.x, - -recout_dst_in_active_timing.y); - else - memset(&recout_clip_in_recout_dst, 0, sizeof(struct spl_rect)); - /* - * Work in recout rotation since that requires less transformations - */ - spl_get_vp_scan_direction( - spl_in->basic_in.rotation, - spl_in->basic_in.horizontal_mirror, - &orthogonal_rotation, - &flip_vert_scan_dir, - &flip_horz_scan_dir); - - if (spl_is_subsampled_format(spl_in->basic_in.format)) { - /* this gives the direction of the cositing (negative will move - * left, right otherwise) - */ - int sign = 1; - - switch (spl_in->basic_in.cositing) { - - case CHROMA_COSITING_TOPLEFT: - init_adj_h = spl_fixpt_from_fraction(sign, 4); - init_adj_v = spl_fixpt_from_fraction(sign, 4); - break; - case CHROMA_COSITING_LEFT: - init_adj_h = spl_fixpt_from_fraction(sign, 4); - init_adj_v = spl_fixpt_zero; - break; - case CHROMA_COSITING_NONE: - default: - init_adj_h = spl_fixpt_zero; - init_adj_v = spl_fixpt_zero; - break; - } - } - - if (orthogonal_rotation) { - spl_swap(src.width, src.height); - spl_swap(flip_vert_scan_dir, flip_horz_scan_dir); - spl_swap(init_adj_h, init_adj_v); - } - - spl_calculate_init_and_vp( - flip_horz_scan_dir, - recout_clip_in_recout_dst.x, - spl_scratch->scl_data.recout.width, - src.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_scratch->scl_data.recout.width, - src.width / vpc_div, - spl_scratch->scl_data.taps.h_taps_c, - spl_scratch->scl_data.ratios.horz_c, - init_adj_h, - &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_scratch->scl_data.recout.height, - src.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_scratch->scl_data.recout.height, - src.height / vpc_div, - spl_scratch->scl_data.taps.v_taps_c, - spl_scratch->scl_data.ratios.vert_c, - init_adj_v, - &spl_scratch->scl_data.inits.v_c, - &spl_scratch->scl_data.viewport_c.y, - &spl_scratch->scl_data.viewport_c.height); - if (orthogonal_rotation) { - 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_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) -{ - /* - * Handle side by side and top bottom 3d recout offsets after vp calculation - * since 3d is special and needs to calculate vp as if there is no recout offset - * This may break with rotation, good thing we aren't mixing hw rotation and 3d - */ - if (spl_in->basic_in.mpc_h_slice_index) { - 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) - recout->y += recout->height; - else if (spl_in->basic_out.view_format == SPL_VIEW_3D_SIDE_BY_SIDE) - recout->x += recout->width; - } -} - -static void spl_clamp_viewport(struct spl_rect *viewport) -{ - /* Clamp minimum viewport size */ - if (viewport->height < MIN_VIEWPORT_SIZE) - viewport->height = MIN_VIEWPORT_SIZE; - if (viewport->width < MIN_VIEWPORT_SIZE) - viewport->width = MIN_VIEWPORT_SIZE; -} - -static enum scl_mode spl_get_dscl_mode(const struct spl_in *spl_in, - const struct spl_scaler_data *data, - bool enable_isharp, bool enable_easf) -{ - 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 - && !enable_isharp) - return SCL_MODE_SCALING_444_BYPASS; - - if (!spl_is_subsampled_format(pixel_format)) { - if (spl_is_video_format(pixel_format)) - return SCL_MODE_SCALING_444_YCBCR_ENABLE; - else - return SCL_MODE_SCALING_444_RGB_ENABLE; - } - - /* - * Bypass YUV if Y is 1:1 with no ISHARP - * Do not bypass UV at 1:1 for cositing to be applied - */ - if (!enable_isharp) { - if (data->ratios.horz.value == one && data->ratios.vert.value == one) - return SCL_MODE_SCALING_420_LUMA_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_video_format(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; -} - -/* Check if video is in fullscreen mode */ -static bool spl_is_video_fullscreen(struct spl_in *spl_in) -{ - if (spl_is_video_format(spl_in->basic_in.format) && spl_in->is_fullscreen) - return true; - return false; -} - -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; - bool fullscreen = spl_is_video_fullscreen(spl_in); - - /* 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 RGB and YUV (NV12/P010) - * surfaces based on policy setting - */ - if (!spl_is_video_format(spl_in->basic_in.format) && - (spl_in->sharpen_policy == SHARPEN_YUV)) - return enable_isharp; - else if ((spl_is_video_format(spl_in->basic_in.format) && !fullscreen) && - (spl_in->sharpen_policy == SHARPEN_RGB_FULLSCREEN_YUV)) - return enable_isharp; - else if (!spl_in->is_fullscreen && - spl_in->sharpen_policy == SHARPEN_FULLSCREEN_ALL) - return enable_isharp; - - /* - * 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 number of tap with adaptive scaling off */ -static void spl_get_taps_non_adaptive_scaler( - struct spl_scratch *spl_scratch, const struct spl_taps *in_taps) -{ - 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(2 * spl_fixpt_ceil( - spl_scratch->scl_data.ratios.vert), 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(2 * spl_fixpt_ceil( - spl_scratch->scl_data.ratios.vert_c), 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_scratch->scl_data.taps.h_taps_c = in_taps->h_taps_c; - - if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz)) - spl_scratch->scl_data.taps.h_taps = 1; - if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert)) - 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; - -} - -/* 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_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; - bool is_subsampled = spl_is_subsampled_format(spl_in->basic_in.format); - - if (spl_scratch->scl_data.viewport.width > spl_scratch->scl_data.h_active && - max_downscale_src_width != 0 && - spl_scratch->scl_data.viewport.width > max_downscale_src_width) { - spl_get_taps_non_adaptive_scaler(spl_scratch, in_taps); - *enable_easf_v = false; - *enable_easf_h = false; - *enable_isharp = false; - return false; - } - - /* Disable adaptive scaler and sharpener when integer scaling is enabled */ - if (spl_in->scaling_quality.integer_scaling) { - spl_get_taps_non_adaptive_scaler(spl_scratch, in_taps); - *enable_easf_v = false; - *enable_easf_h = false; - *enable_isharp = false; - return true; - } - - /* 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 (skip_easf) - spl_get_taps_non_adaptive_scaler(spl_scratch, in_taps); - else { - if (spl_is_video_format(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 = 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_is_yuv420(spl_in->basic_in.format)) - lb_config = LB_MEMORY_CONFIG_3; - else - lb_config = LB_MEMORY_CONFIG_0; - // Determine max vtap support by calculating how much line buffer can fit - spl_in->callbacks.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 (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 (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; - - if (max_taps_y < min_taps_y) - return false; - else if (max_taps_c < min_taps_c) - return false; - - 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_video_format(spl_in->basic_in.format)) { - if (spl_scratch->scl_data.taps.h_taps <= 4) { - *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) && - (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 - - /* Sharpener requires scaler to be enabled, including for 1:1 - * Check if ISHARP can be enabled - * If ISHARP is not enabled, set taps to 1 if ratio is 1:1 - * except for chroma taps. Keep previous taps so it can - * handle cositing - */ - - *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) && !is_subsampled) - spl_scratch->scl_data.taps.h_taps_c = 1; - - if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert_c) && !is_subsampled) - 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))) - spl_scratch->scl_data.taps.h_taps = 1; - - if ((!*enable_easf_v) && - (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert))) - spl_scratch->scl_data.taps.v_taps = 1; - - if ((!*enable_easf_h) && !is_subsampled && - (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz_c))) - spl_scratch->scl_data.taps.h_taps_c = 1; - - if ((!*enable_easf_v) && !is_subsampled && - (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) -{ - bool ycbcr = spl_is_video_format(format); - if (ycbcr) { - scl_black_color->offset_rgb_y = BLACK_OFFSET_RGB_Y; - scl_black_color->offset_rgb_cbcr = BLACK_OFFSET_CBCR; - } else { - scl_black_color->offset_rgb_y = 0x0; - scl_black_color->offset_rgb_cbcr = 0x0; - } -} - -static void spl_set_manual_ratio_init_data(struct dscl_prog_data *dscl_prog_data, - const struct spl_scaler_data *scl_data) -{ - struct spl_fixed31_32 bot; - - 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 = - spl_fixpt_u0d19(scl_data->inits.h) << 5; - dscl_prog_data->init.h_filter_init_int = - spl_fixpt_floor(scl_data->inits.h); - dscl_prog_data->init.h_filter_init_frac_c = - spl_fixpt_u0d19(scl_data->inits.h_c) << 5; - dscl_prog_data->init.h_filter_init_int_c = - spl_fixpt_floor(scl_data->inits.h_c); - dscl_prog_data->init.v_filter_init_frac = - spl_fixpt_u0d19(scl_data->inits.v) << 5; - dscl_prog_data->init.v_filter_init_int = - spl_fixpt_floor(scl_data->inits.v); - dscl_prog_data->init.v_filter_init_frac_c = - spl_fixpt_u0d19(scl_data->inits.v_c) << 5; - dscl_prog_data->init.v_filter_init_int_c = - 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, - const struct spl_scaler_data *scl_data) -{ - dscl_prog_data->taps.v_taps = scl_data->taps.v_taps - 1; - dscl_prog_data->taps.h_taps = scl_data->taps.h_taps - 1; - 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; -} - -/* 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_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_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_scratch->scl_data.recout; - // Set values for MPC Size - 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, enable_isharp, - enable_easf); - - // SCL_BLACK_COLOR - spl_set_black_color_data(spl_in->basic_in.format, scl_black_color); - - /* Manually calculate scale ratio and init values */ - spl_set_manual_ratio_init_data(dscl_prog_data, data); - - // Set HTaps/VTaps - spl_set_taps_data(dscl_prog_data, data); - // Set viewport - dscl_prog_data->viewport = spl_scratch->scl_data.viewport; - // Set viewport_c - dscl_prog_data->viewport_c = spl_scratch->scl_data.viewport_c; - // Set filters data - spl_set_filters_data(dscl_prog_data, data, enable_easf_v, enable_easf_h); -} - -/* Calculate C0-C3 coefficients based on HDR_mult */ -static void spl_calculate_c0_c3_hdr(struct dscl_prog_data *dscl_prog_data, uint32_t sdr_white_level_nits) -{ - 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; - uint32_t hdr_multx100_int; - - if ((sdr_white_level_nits >= 80) && (sdr_white_level_nits <= 480)) - hdr_multx100_int = sdr_white_level_nits * 100 / 80; - else - hdr_multx100_int = 100; /* default for 80 nits otherwise */ - - hdr_mult = spl_fixpt_from_fraction((long long)hdr_multx100_int, 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 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 sdr_white_level_nits) -{ - 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 = 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 - /* 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 = - 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 = - 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 = - 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 = - 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 = - 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 = - 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 = - 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 = - 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 = - 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 = - 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 - 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 - dscl_prog_data->easf_v_bf3_pwl_in_set1 = - 0x0B37; // FP0.6.6, BF3 Input value PWL Segment 1 (0.0078125 * 125^3) - dscl_prog_data->easf_v_bf3_pwl_base_set1 = 62; // S0.6, BF3 Base PWL Segment 1 - dscl_prog_data->easf_v_bf3_pwl_slope_set1 = - 0x13B8; // FP1.6.6, BF3 Slope PWL Segment 1 - dscl_prog_data->easf_v_bf3_pwl_in_set2 = - 0x0BB7; // FP0.6.6, BF3 Input value PWL Segment 2 (0.03125 * 125^3) - dscl_prog_data->easf_v_bf3_pwl_base_set2 = 20; // S0.6, BF3 Base PWL Segment 2 - dscl_prog_data->easf_v_bf3_pwl_slope_set2 = - 0x1356; // FP1.6.6, BF3 Slope PWL Segment 2 - dscl_prog_data->easf_v_bf3_pwl_in_set3 = - 0x0BF7; // FP0.6.6, BF3 Input value PWL Segment 3 (0.0625 * 125^3) - dscl_prog_data->easf_v_bf3_pwl_base_set3 = 0; // S0.6, BF3 Base PWL Segment 3 - dscl_prog_data->easf_v_bf3_pwl_slope_set3 = - 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 = 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 = 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 - dscl_prog_data->easf_v_bf3_pwl_in_set1 = - 0x06C0; // FP0.6.6, BF3 Input value PWL Segment 1 (0.0625) - dscl_prog_data->easf_v_bf3_pwl_base_set1 = 63; // S0.6, BF3 Base PWL Segment 1 - dscl_prog_data->easf_v_bf3_pwl_slope_set1 = 0x1896; // FP1.6.6, BF3 Slope PWL Segment 1 - dscl_prog_data->easf_v_bf3_pwl_in_set2 = - 0x0700; // FP0.6.6, BF3 Input value PWL Segment 2 (0.125) - dscl_prog_data->easf_v_bf3_pwl_base_set2 = 20; // S0.6, BF3 Base PWL Segment 2 - dscl_prog_data->easf_v_bf3_pwl_slope_set2 = 0x1810; // FP1.6.6, BF3 Slope PWL Segment 2 - dscl_prog_data->easf_v_bf3_pwl_in_set3 = - 0x0740; // FP0.6.6, BF3 Input value PWL Segment 3 (0.25) - dscl_prog_data->easf_v_bf3_pwl_base_set3 = 0; // S0.6, BF3 Base PWL Segment 3 - dscl_prog_data->easf_v_bf3_pwl_slope_set3 = - 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 = 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 = 0x41; // S0.6, BF3 Base PWL Segment 5 = -63 - } - } else - dscl_prog_data->easf_v_en = false; - - 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 = 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 - /* 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 = - 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 = - 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 = - 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 = - 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 - 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 - dscl_prog_data->easf_h_bf3_pwl_in_set1 = - 0x0B37; // FP0.6.6, BF3 Input value PWL Segment 1 (0.0078125 * 125^3) - dscl_prog_data->easf_h_bf3_pwl_base_set1 = 62; // S0.6, BF3 Base PWL Segment 1 - dscl_prog_data->easf_h_bf3_pwl_slope_set1 = 0x13B8; // FP1.6.6, BF3 Slope PWL Segment 1 - dscl_prog_data->easf_h_bf3_pwl_in_set2 = - 0x0BB7; // FP0.6.6, BF3 Input value PWL Segment 2 (0.03125 * 125^3) - dscl_prog_data->easf_h_bf3_pwl_base_set2 = 20; // S0.6, BF3 Base PWL Segment 2 - dscl_prog_data->easf_h_bf3_pwl_slope_set2 = 0x1356; // FP1.6.6, BF3 Slope PWL Segment 2 - dscl_prog_data->easf_h_bf3_pwl_in_set3 = - 0x0BF7; // FP0.6.6, BF3 Input value PWL Segment 3 (0.0625 * 125^3) - dscl_prog_data->easf_h_bf3_pwl_base_set3 = 0; // S0.6, BF3 Base PWL Segment 3 - 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 = 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 = 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 - dscl_prog_data->easf_h_bf3_pwl_in_set1 = - 0x06C0; // FP0.6.6, BF3 Input value PWL Segment 1 (0.0625) - dscl_prog_data->easf_h_bf3_pwl_base_set1 = 63; // S0.6, BF3 Base PWL Segment 1 - dscl_prog_data->easf_h_bf3_pwl_slope_set1 = 0x1896; // FP1.6.6, BF3 Slope PWL Segment 1 - dscl_prog_data->easf_h_bf3_pwl_in_set2 = - 0x0700; // FP0.6.6, BF3 Input value PWL Segment 2 (0.125) - dscl_prog_data->easf_h_bf3_pwl_base_set2 = 20; // S0.6, BF3 Base PWL Segment 2 - dscl_prog_data->easf_h_bf3_pwl_slope_set2 = 0x1810; // FP1.6.6, BF3 Slope PWL Segment 2 - dscl_prog_data->easf_h_bf3_pwl_in_set3 = - 0x0740; // FP0.6.6, BF3 Input value PWL Segment 3 (0.25) - dscl_prog_data->easf_h_bf3_pwl_base_set3 = 0; // S0.6, BF3 Base PWL Segment 3 - 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 = 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 = 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 - if ((setup == HDR_L) && (spl_is_rgb8(format))) { - /* Calculate C0-C3 coefficients based on HDR multiplier */ - spl_calculate_c0_c3_hdr(dscl_prog_data, sdr_white_level_nits); - } 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 = - 0x3434; // fp1.5.10, C0 coefficient (LN_BT2020: 0.262695312500000) - dscl_prog_data->easf_matrix_c1 = - 0x396D; // fp1.5.10, C1 coefficient (LN_BT2020: 0.678222656250000) - dscl_prog_data->easf_matrix_c2 = - 0x2B97; // fp1.5.10, C2 coefficient (LN_BT2020: 0.059295654296875) - dscl_prog_data->easf_matrix_c3 = - 0x0; // fp1.5.10, C3 coefficient - } - - if (spl_is_subsampled_format(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, - const struct spl_scaler_data *data) -{ - // ISHARP_NOISEDET_MODE - // 0: 3x5 as VxH - // 1: 4x5 as VxH - // 2: - // 3: 5x5 as VxH - 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, struct spl_fixed31_32 ratio, - enum system_setup setup, enum scale_to_sharpness_policy scale_to_sharpness_policy) -{ - /* Turn off sharpener if not required */ - if (!enable_isharp) { - dscl_prog_data->isharp_en = 0; - return; - } - - spl_build_isharp_1dlut_from_reference_curve(ratio, setup, adp_sharpness, - scale_to_sharpness_policy); - memcpy(dscl_prog_data->isharp_delta, spl_get_pregen_filter_isharp_1D_lut(setup), - sizeof(uint32_t) * ISHARP_LUT_TABLE_SIZE); - dscl_prog_data->sharpness_level = adp_sharpness.sharpness_level; - - dscl_prog_data->isharp_en = 1; // ISHARP_EN - // Set ISHARP_NOISEDET_MODE if htaps = 6-tap - 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 - // Program noise detection gain - dscl_prog_data->isharp_noise_det.pwl_start_in = 3; // ISHARP_NOISEDET_PWL_START_IN - 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) /* 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 - - 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 - } - - // 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 */ - dscl_prog_data->isharp_nldelta_sclip.pivot_p = 0; /* ISHARP_NLDELTA_SCLIP_PIVOT_P */ - dscl_prog_data->isharp_nldelta_sclip.slope_p = 0; /* ISHARP_NLDELTA_SCLIP_SLOPE_P */ - dscl_prog_data->isharp_nldelta_sclip.enable_n = 1; /* ISHARP_NLDELTA_SCLIP_EN_N */ - dscl_prog_data->isharp_nldelta_sclip.pivot_n = 71; /* ISHARP_NLDELTA_SCLIP_PIVOT_N */ - dscl_prog_data->isharp_nldelta_sclip.slope_n = 16; /* ISHARP_NLDELTA_SCLIP_SLOPE_N */ - } else { - dscl_prog_data->isharp_nldelta_sclip.enable_p = 1; /* ISHARP_NLDELTA_SCLIP_EN_P */ - dscl_prog_data->isharp_nldelta_sclip.pivot_p = 70; /* ISHARP_NLDELTA_SCLIP_PIVOT_P */ - dscl_prog_data->isharp_nldelta_sclip.slope_p = 24; /* ISHARP_NLDELTA_SCLIP_SLOPE_P */ - dscl_prog_data->isharp_nldelta_sclip.enable_n = 1; /* ISHARP_NLDELTA_SCLIP_EN_N */ - dscl_prog_data->isharp_nldelta_sclip.pivot_n = 70; /* ISHARP_NLDELTA_SCLIP_PIVOT_N */ - dscl_prog_data->isharp_nldelta_sclip.slope_n = 24; /* ISHARP_NLDELTA_SCLIP_SLOPE_N */ - } - - // Set the values as per lookup table - spl_set_blur_scale_data(dscl_prog_data, data); -} - -/* Calculate recout, scaling ratio, and viewport, then get optimal number of taps */ -static bool spl_calculate_number_of_taps(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) -{ - bool res = false; - - 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_scratch, spl_out); - /* depends on pixel format */ - 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_scratch); - - res = spl_get_optimal_number_of_taps( - spl_in->basic_out.max_downscale_src_width, spl_in, - spl_scratch, &spl_in->scaling_quality, enable_easf_v, - enable_easf_h, enable_isharp); - return res; -} - -/* Calculate scaler parameters */ -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; - 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; - - res = spl_calculate_number_of_taps(spl_in, &spl_scratch, spl_out, - &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_scratch); - // Handle 3d recout - spl_handle_3d_recout(spl_in, &spl_scratch.scl_data.recout); - // Clamp - spl_clamp_viewport(&spl_scratch.scl_data.viewport); - - // Save all calculated parameters in dscl_prog_data structure to program hw registers - spl_set_dscl_prog_data(spl_in, &spl_scratch, spl_out, enable_easf_v, enable_easf_h, enable_isharp); - - if (!res) - return res; - - if (spl_in->lls_pref == LLS_PREF_YES) { - if (spl_in->is_hdr_on) - setup = HDR_L; - else - setup = SDR_L; - } else { - if (spl_in->is_hdr_on) - setup = HDR_NL; - else - setup = SDR_NL; - } - - // Set EASF - 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->sdr_white_level_nits); - - // Set iSHARP - 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, isharp_scale_ratio, setup, - spl_in->debug.scale_to_sharpness_policy); - - return res; -} - -/* External interface to get number of taps only */ -bool spl_get_number_of_taps(struct spl_in *spl_in, struct spl_out *spl_out) -{ - bool res = false; - bool enable_easf_v = false; - bool enable_easf_h = false; - bool enable_isharp = false; - struct spl_scratch spl_scratch; - struct dscl_prog_data *dscl_prog_data = spl_out->dscl_prog_data; - const struct spl_scaler_data *data = &spl_scratch.scl_data; - - res = spl_calculate_number_of_taps(spl_in, &spl_scratch, spl_out, - &enable_easf_v, &enable_easf_h, &enable_isharp); - spl_set_taps_data(dscl_prog_data, data); - 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 deleted file mode 100644 index 02a2d6725ed5..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.h +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright 2024 Advanced Micro Devices, Inc. - -#ifndef __DC_SPL_H__ -#define __DC_SPL_H__ - -#include "dc_spl_types.h" -#define BLACK_OFFSET_RGB_Y 0x0 -#define BLACK_OFFSET_CBCR 0x8000 - -/* SPL interfaces */ - -bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out); - -bool spl_get_number_of_taps(struct spl_in *spl_in, struct spl_out *spl_out); - -#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 deleted file mode 100644 index 99238644e0a1..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.c +++ /dev/null @@ -1,15 +0,0 @@ -// 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 deleted file mode 100644 index 20439cdbdb10..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.h +++ /dev/null @@ -1,15 +0,0 @@ -/* 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 deleted file mode 100644 index e0572252c640..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.c +++ /dev/null @@ -1,757 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright 2024 Advanced Micro Devices, Inc. - -#include "spl_debug.h" -#include "dc_spl_filters.h" -#include "dc_spl_isharp_filters.h" - -//======================================== -// Delta Gain 1DLUT -// LUT content is packed as 4-bytes into one DWORD/entry -// A_start = 0.000000 -// A_end = 10.000000 -// A_gain = 2.000000 -// B_start = 11.000000 -// B_end = 86.000000 -// C_start = 40.000000 -// C_end = 64.000000 -//======================================== -static const uint32_t filter_isharp_1D_lut_0[ISHARP_LUT_TABLE_SIZE] = { -0x02010000, -0x0A070503, -0x1614100D, -0x1C1B1918, -0x22211F1E, -0x27262423, -0x2A2A2928, -0x2D2D2C2B, -0x302F2F2E, -0x31313030, -0x31313131, -0x31313131, -0x30303031, -0x292D2F2F, -0x191D2125, -0x050A0F14, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -}; -//======================================== -// Delta Gain 1DLUT -// LUT content is packed as 4-bytes into one DWORD/entry -// A_start = 0.000000 -// A_end = 10.000000 -// A_gain = 0.500000 -// B_start = 11.000000 -// B_end = 127.000000 -// C_start = 96.000000 -// C_end = 127.000000 -//======================================== - -static const uint32_t filter_isharp_1D_lut_0p5x[ISHARP_LUT_TABLE_SIZE] = { -0x00000000, -0x02020101, -0x06050403, -0x07070606, -0x09080808, -0x0A0A0A09, -0x0C0B0B0B, -0x0D0D0C0C, -0x0E0E0D0D, -0x0F0F0E0E, -0x100F0F0F, -0x10101010, -0x11111010, -0x11111111, -0x11111111, -0x11111111, -0x11111111, -0x11111111, -0x11111111, -0x10101111, -0x10101010, -0x0F0F0F10, -0x0E0E0F0F, -0x0D0D0E0E, -0x0C0C0D0D, -0x0B0B0B0C, -0x090A0A0A, -0x08080809, -0x06060707, -0x04050506, -0x02030304, -0x00010102, -}; -//======================================== -// Delta Gain 1DLUT -// LUT content is packed as 4-bytes into one DWORD/entry -// A_start = 0.000000 -// A_end = 10.000000 -// A_gain = 1.000000 -// B_start = 11.000000 -// B_end = 127.000000 -// C_start = 96.000000 -// C_end = 127.000000 -//======================================== -static const uint32_t filter_isharp_1D_lut_1p0x[ISHARP_LUT_TABLE_SIZE] = { -0x01000000, -0x05040302, -0x0B0A0806, -0x0E0E0D0C, -0x1211100F, -0x15141312, -0x17171615, -0x1A191918, -0x1C1B1B1A, -0x1E1D1D1C, -0x1F1F1E1E, -0x2020201F, -0x21212121, -0x22222222, -0x23232222, -0x23232323, -0x23232323, -0x22222323, -0x22222222, -0x21212121, -0x1F202020, -0x1E1E1F1F, -0x1C1D1D1E, -0x1A1B1B1C, -0x1819191A, -0x15161717, -0x12131415, -0x0F101112, -0x0C0D0E0E, -0x08090A0B, -0x04050607, -0x00010203, -}; -//======================================== -// Delta Gain 1DLUT -// LUT content is packed as 4-bytes into one DWORD/entry -// A_start = 0.000000 -// A_end = 10.000000 -// A_gain = 1.500000 -// B_start = 11.000000 -// B_end = 127.000000 -// C_start = 96.000000 -// C_end = 127.000000 -//======================================== -static const uint32_t filter_isharp_1D_lut_1p5x[ISHARP_LUT_TABLE_SIZE] = { -0x01010000, -0x07050402, -0x110F0C0A, -0x16141312, -0x1B191817, -0x1F1E1D1C, -0x23222120, -0x26262524, -0x2A292827, -0x2C2C2B2A, -0x2F2E2E2D, -0x3130302F, -0x32323131, -0x33333332, -0x34343433, -0x34343434, -0x34343434, -0x33343434, -0x32333333, -0x31313232, -0x2F303031, -0x2D2E2E2F, -0x2A2B2C2C, -0x2728292A, -0x24252626, -0x20212223, -0x1C1D1E1F, -0x1718191B, -0x12131416, -0x0C0E0F10, -0x0608090B, -0x00020305 -}; -//======================================== -// Delta Gain 1DLUT -// LUT content is packed as 4-bytes into one DWORD/entry -// A_start = 0.000000 -// A_end = 10.000000 -// A_gain = 2.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_2p0x[ISHARP_LUT_TABLE_SIZE] = { -0x02010000, -0x0A070503, -0x1614100D, -0x1D1B1A18, -0x2322201F, -0x29282625, -0x2F2D2C2B, -0x33323130, -0x38373534, -0x3B3A3938, -0x3E3E3D3C, -0x4140403F, -0x43424241, -0x44444443, -0x45454545, -0x46454545, -0x45454546, -0x45454545, -0x43444444, -0x41424243, -0x3F404041, -0x3C3D3E3E, -0x38393A3B, -0x34353738, -0x30313233, -0x2B2C2D2F, -0x25262829, -0x1F202223, -0x181A1B1D, -0x10121416, -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 -//======================================================== -// gen_scaler_coeffs.m -// 15-Dec-2021 -// 6t_64p_LanczosEd_p_1_p_10qb_ -// 6 -// 64 -// LanczosEd -// S1.10 -//======================================================== -static const uint16_t filter_isharp_wide_6tap_64p[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 -}; -// Blur and scale coefficients -//======================================================== -// gen_BlurScale_coeffs.m -// 25-Apr-2022 -// 4 -// 64 -// Blur & Scale LPF -// S1.10 -//======================================================== -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, -0x0000, 0x00D0, 0x0235, 0x00FA, 0x0001, 0x0000, -0x0000, 0x00C9, 0x0234, 0x0101, 0x0002, 0x0000, -0x0000, 0x00C2, 0x0233, 0x0108, 0x0003, 0x0000, -0x0000, 0x00BB, 0x0232, 0x0110, 0x0003, 0x0000, -0x0000, 0x00B5, 0x0230, 0x0117, 0x0004, 0x0000, -0x0000, 0x00AE, 0x022E, 0x011F, 0x0005, 0x0000, -0x0000, 0x00A8, 0x022C, 0x0126, 0x0006, 0x0000, -0x0000, 0x00A2, 0x022A, 0x012D, 0x0007, 0x0000, -0x0000, 0x009C, 0x0228, 0x0134, 0x0008, 0x0000, -0x0000, 0x0096, 0x0225, 0x013C, 0x0009, 0x0000, -0x0000, 0x0090, 0x0222, 0x0143, 0x000B, 0x0000, -0x0000, 0x008A, 0x021F, 0x014B, 0x000C, 0x0000, -0x0000, 0x0085, 0x021C, 0x0151, 0x000E, 0x0000, -0x0000, 0x007F, 0x0218, 0x015A, 0x000F, 0x0000, -0x0000, 0x007A, 0x0215, 0x0160, 0x0011, 0x0000, -0x0000, 0x0074, 0x0211, 0x0168, 0x0013, 0x0000, -0x0000, 0x006F, 0x020D, 0x016F, 0x0015, 0x0000, -0x0000, 0x006A, 0x0209, 0x0176, 0x0017, 0x0000, -0x0000, 0x0065, 0x0204, 0x017E, 0x0019, 0x0000, -0x0000, 0x0060, 0x0200, 0x0185, 0x001B, 0x0000, -0x0000, 0x005C, 0x01FB, 0x018C, 0x001D, 0x0000, -0x0000, 0x0057, 0x01F6, 0x0193, 0x0020, 0x0000, -0x0000, 0x0053, 0x01F1, 0x019A, 0x0022, 0x0000, -0x0000, 0x004E, 0x01EC, 0x01A1, 0x0025, 0x0000, -0x0000, 0x004A, 0x01E6, 0x01A8, 0x0028, 0x0000, -0x0000, 0x0046, 0x01E1, 0x01AF, 0x002A, 0x0000, -0x0000, 0x0042, 0x01DB, 0x01B6, 0x002D, 0x0000, -0x0000, 0x003F, 0x01D5, 0x01BB, 0x0031, 0x0000, -0x0000, 0x003B, 0x01CF, 0x01C2, 0x0034, 0x0000, -0x0000, 0x0037, 0x01C9, 0x01C9, 0x0037, 0x0000 -}; -//======================================================== -// gen_BlurScale_coeffs.m -// 25-Apr-2022 -// 4 -// 64 -// Blur & Scale LPF -// 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, -}; -//======================================================== -// gen_BlurScale_coeffs.m -// 09-Jun-2022 -// 3 -// 64 -// Blur & Scale LPF -// 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, - } - }, -}; - -struct scale_ratio_to_sharpness_level_adj sharpness_level_adj[NUM_SHARPNESS_ADJ_LEVELS] = { - {1125, 1000, 0}, - {11, 10, 1}, - {1075, 1000, 2}, - {105, 100, 3}, - {1025, 1000, 4}, - {1, 1, 5}, -}; - -const uint32_t *spl_get_filter_isharp_1D_lut_0(void) -{ - return filter_isharp_1D_lut_0; -} -const uint32_t *spl_get_filter_isharp_1D_lut_0p5x(void) -{ - return filter_isharp_1D_lut_0p5x; -} -const uint32_t *spl_get_filter_isharp_1D_lut_1p0x(void) -{ - return filter_isharp_1D_lut_1p0x; -} -const uint32_t *spl_get_filter_isharp_1D_lut_1p5x(void) -{ - return filter_isharp_1D_lut_1p5x; -} -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; -} -uint16_t *spl_get_filter_isharp_bs_4tap_in_6_64p(void) -{ - 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_adj(struct spl_fixed31_32 ratio) -{ - int j; - struct spl_fixed31_32 ratio_level; - struct scale_ratio_to_sharpness_level_adj *lookup_ptr; - unsigned int sharpness_level_down_adj; - - /* - * Adjust sharpness level based on current scaling ratio - * - * We have 5 discrete scaling ratios which we will use to adjust the - * sharpness level down by 1 as we pass each ratio. The ratios - * are - * - * 1.125 upscale and higher - no adj - * 1.100 - under 1.125 - adj level down 1 - * 1.075 - under 1.100 - adj level down 2 - * 1.050 - under 1.075 - adj level down 3 - * 1.025 - under 1.050 - adj level down 4 - * 1.000 - under 1.025 - adj level down 5 - * - */ - j = 0; - sharpness_level_down_adj = 0; - lookup_ptr = sharpness_level_adj; - while (j < NUM_SHARPNESS_ADJ_LEVELS) { - ratio_level = spl_fixpt_from_fraction(lookup_ptr->ratio_numer, - lookup_ptr->ratio_denom); - if (ratio.value >= ratio_level.value) { - sharpness_level_down_adj = lookup_ptr->level_down_adj; - break; - } - lookup_ptr++; - j++; - } - return sharpness_level_down_adj; -} - -static unsigned int spl_calculate_sharpness_level(struct spl_fixed31_32 ratio, - int discrete_sharpness_level, enum system_setup setup, - struct spl_sharpness_range sharpness_range, - enum scale_to_sharpness_policy scale_to_sharpness_policy) -{ - unsigned int sharpness_level = 0; - unsigned int sharpness_level_down_adj = 0; - - int min_sharpness, max_sharpness, mid_sharpness; - - /* - * Adjust sharpness level if policy requires we adjust it based on - * scale ratio. Based on scale ratio, we may adjust the sharpness - * level down by a certain number of steps. We will not select - * a sharpness value of 0 so the lowest sharpness level will be - * 0 or 1 depending on what the min_sharpness is - * - * If the policy is no required, this code maybe removed at a later - * date - */ - 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; - if (scale_to_sharpness_policy == SCALE_TO_SHARPNESS_ADJ_ALL) - sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio); - 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; - if (scale_to_sharpness_policy >= SCALE_TO_SHARPNESS_ADJ_YUV) - sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio); - 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; - if (scale_to_sharpness_policy == SCALE_TO_SHARPNESS_ADJ_ALL) - sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio); - break; - } - - if ((min_sharpness == 0) && (sharpness_level_down_adj >= discrete_sharpness_level)) - discrete_sharpness_level = 1; - else if (sharpness_level_down_adj >= discrete_sharpness_level) - discrete_sharpness_level = 0; - else - discrete_sharpness_level -= sharpness_level_down_adj; - - 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, enum scale_to_sharpness_policy scale_to_sharpness_policy) -{ - 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(ratio, - sharpness.sharpness_level, setup, - sharpness.sharpness_range, scale_to_sharpness_policy); - 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 deleted file mode 100644 index 89af91e19b6c..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.h +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright 2024 Advanced Micro Devices, Inc. - -#ifndef __DC_SPL_ISHARP_FILTERS_H__ -#define __DC_SPL_ISHARP_FILTERS_H__ - -#include "dc_spl_types.h" - -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 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); - -#define NUM_SHARPNESS_ADJ_LEVELS 6 -struct scale_ratio_to_sharpness_level_adj { - unsigned int ratio_numer; - unsigned int ratio_denom; - unsigned int level_down_adj; /* adjust sharpness level down */ -}; - -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, enum scale_to_sharpness_policy scale_to_sharpness_policy); -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 deleted file mode 100644 index 09bf82f7d468..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.c +++ /dev/null @@ -1,1726 +0,0 @@ -// 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" - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 3t_64p_LanczosEd_p_0.3_p_10qb_ -// 3 -// 64 -// input/output = 0.300000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 3t_64p_LanczosEd_p_0.4_p_10qb_ -// 3 -// 64 -// input/output = 0.400000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 3t_64p_LanczosEd_p_0.5_p_10qb_ -// 3 -// 64 -// input/output = 0.500000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 3t_64p_LanczosEd_p_0.6_p_10qb_ -// 3 -// 64 -// input/output = 0.600000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 3t_64p_LanczosEd_p_0.7_p_10qb_ -// 3 -// 64 -// input/output = 0.700000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 3t_64p_LanczosEd_p_0.8_p_10qb_ -// 3 -// 64 -// input/output = 0.800000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 3t_64p_LanczosEd_p_0.9_p_10qb_ -// 3 -// 64 -// input/output = 0.900000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 3t_64p_LanczosEd_p_1_p_10qb_ -// 3 -// 64 -// input/output = 1.000000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 4t_64p_LanczosEd_p_0.3_p_10qb_ -// 4 -// 64 -// input/output = 0.300000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 4t_64p_LanczosEd_p_0.4_p_10qb_ -// 4 -// 64 -// input/output = 0.400000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 4t_64p_LanczosEd_p_0.5_p_10qb_ -// 4 -// 64 -// input/output = 0.500000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 4t_64p_LanczosEd_p_0.6_p_10qb_ -// 4 -// 64 -// input/output = 0.600000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 4t_64p_LanczosEd_p_0.7_p_10qb_ -// 4 -// 64 -// input/output = 0.700000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 4t_64p_LanczosEd_p_0.8_p_10qb_ -// 4 -// 64 -// input/output = 0.800000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 4t_64p_LanczosEd_p_0.9_p_10qb_ -// 4 -// 64 -// input/output = 0.900000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 03-Apr-2024 -// 4t_64p_LanczosEd_p_1_p_10qb_ -// 4 -// 64 -// input/output = 1.000000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 02-Apr-2024 -// 6t_64p_LanczosEd_p_0.3_p_10qb_ -// 6 -// 64 -// input/output = 0.300000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 02-Apr-2024 -// 6t_64p_LanczosEd_p_0.4_p_10qb_ -// 6 -// 64 -// input/output = 0.400000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 02-Apr-2024 -// 6t_64p_LanczosEd_p_0.5_p_10qb_ -// 6 -// 64 -// input/output = 0.500000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 02-Apr-2024 -// 6t_64p_LanczosEd_p_0.6_p_10qb_ -// 6 -// 64 -// input/output = 0.600000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 02-Apr-2024 -// 6t_64p_LanczosEd_p_0.7_p_10qb_ -// 6 -// 64 -// input/output = 0.700000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 02-Apr-2024 -// 6t_64p_LanczosEd_p_0.8_p_10qb_ -// 6 -// 64 -// input/output = 0.800000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 02-Apr-2024 -// 6t_64p_LanczosEd_p_0.9_p_10qb_ -// 6 -// 64 -// input/output = 0.900000000000 -// LanczosEd -// 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, -}; - -//======================================================== -// gen_scaler_coeffs_cnf_file.m -// make_test_script.m -// 02-Apr-2024 -// 6t_64p_LanczosEd_p_1_p_10qb_ -// 6 -// 64 -// input/output = 1.000000000000 -// LanczosEd -// 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 deleted file mode 100644 index 8bb2b8108e38..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.h +++ /dev/null @@ -1,38 +0,0 @@ -/* 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 deleted file mode 100644 index b02c7b0b262b..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.c +++ /dev/null @@ -1,1451 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright 2024 Advanced Micro Devices, Inc. - -#include "spl_debug.h" -#include "dc_spl_scl_filters.h" -//========================================= -// = 2 -// = 16 -// = 0.833333 (input/output) -// = 0 -// = ModifiedLanczos -// = s1.10 -// = s1.12 -//========================================= -static const uint16_t filter_2tap_16p[18] = { - 0x1000, 0x0000, - 0x0FF0, 0x0010, - 0x0FB0, 0x0050, - 0x0F34, 0x00CC, - 0x0E68, 0x0198, - 0x0D44, 0x02BC, - 0x0BC4, 0x043C, - 0x09FC, 0x0604, - 0x0800, 0x0800 -}; - -//========================================= -// = 3 -// = 16 -// = 0.83333 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_3tap_16p_upscale[27] = { - 0x0804, 0x07FC, 0x0000, - 0x06AC, 0x0978, 0x3FDC, - 0x055C, 0x0AF0, 0x3FB4, - 0x0420, 0x0C50, 0x3F90, - 0x0300, 0x0D88, 0x3F78, - 0x0200, 0x0E90, 0x3F70, - 0x0128, 0x0F5C, 0x3F7C, - 0x007C, 0x0FD8, 0x3FAC, - 0x0000, 0x1000, 0x0000 -}; - -//========================================= -// = 3 -// = 16 -// = 1.16666 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_3tap_16p_116[27] = { - 0x0804, 0x07FC, 0x0000, - 0x0700, 0x0914, 0x3FEC, - 0x0604, 0x0A1C, 0x3FE0, - 0x050C, 0x0B14, 0x3FE0, - 0x041C, 0x0BF4, 0x3FF0, - 0x0340, 0x0CB0, 0x0010, - 0x0274, 0x0D3C, 0x0050, - 0x01C0, 0x0D94, 0x00AC, - 0x0128, 0x0DB4, 0x0124 -}; - -//========================================= -// = 3 -// = 16 -// = 1.49999 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_3tap_16p_149[27] = { - 0x0804, 0x07FC, 0x0000, - 0x0730, 0x08CC, 0x0004, - 0x0660, 0x098C, 0x0014, - 0x0590, 0x0A3C, 0x0034, - 0x04C4, 0x0AD4, 0x0068, - 0x0400, 0x0B54, 0x00AC, - 0x0348, 0x0BB0, 0x0108, - 0x029C, 0x0BEC, 0x0178, - 0x0200, 0x0C00, 0x0200 -}; - -//========================================= -// = 3 -// = 16 -// = 1.83332 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_3tap_16p_183[27] = { - 0x0804, 0x07FC, 0x0000, - 0x0754, 0x0880, 0x002C, - 0x06A8, 0x08F0, 0x0068, - 0x05FC, 0x0954, 0x00B0, - 0x0550, 0x09AC, 0x0104, - 0x04A8, 0x09F0, 0x0168, - 0x0408, 0x0A20, 0x01D8, - 0x036C, 0x0A40, 0x0254, - 0x02DC, 0x0A48, 0x02DC -}; - -//========================================= -// = 4 -// = 16 -// = 0.83333 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_4tap_16p_upscale[36] = { - 0x0000, 0x1000, 0x0000, 0x0000, - 0x3F74, 0x0FDC, 0x00B4, 0x3FFC, - 0x3F0C, 0x0F70, 0x0194, 0x3FF0, - 0x3ECC, 0x0EC4, 0x0298, 0x3FD8, - 0x3EAC, 0x0DE4, 0x03B8, 0x3FB8, - 0x3EA4, 0x0CD8, 0x04F4, 0x3F90, - 0x3EB8, 0x0BA0, 0x0644, 0x3F64, - 0x3ED8, 0x0A54, 0x07A0, 0x3F34, - 0x3F00, 0x08FC, 0x0900, 0x3F04 -}; - -//========================================= -// = 4 -// = 16 -// = 1.16666 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_4tap_16p_116[36] = { - 0x01A8, 0x0CB4, 0x01A4, 0x0000, - 0x0110, 0x0CB0, 0x0254, 0x3FEC, - 0x0090, 0x0C80, 0x031C, 0x3FD4, - 0x0024, 0x0C2C, 0x03F4, 0x3FBC, - 0x3FD8, 0x0BAC, 0x04DC, 0x3FA0, - 0x3F9C, 0x0B14, 0x05CC, 0x3F84, - 0x3F70, 0x0A60, 0x06C4, 0x3F6C, - 0x3F5C, 0x098C, 0x07BC, 0x3F5C, - 0x3F54, 0x08AC, 0x08AC, 0x3F54 -}; - -//========================================= -// = 4 -// = 16 -// = 1.49999 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_4tap_16p_149[36] = { - 0x02B8, 0x0A90, 0x02B8, 0x0000, - 0x0230, 0x0A90, 0x0350, 0x3FF0, - 0x01B8, 0x0A78, 0x03F0, 0x3FE0, - 0x0148, 0x0A48, 0x049C, 0x3FD4, - 0x00E8, 0x0A00, 0x054C, 0x3FCC, - 0x0098, 0x09A0, 0x0600, 0x3FC8, - 0x0054, 0x0928, 0x06B4, 0x3FD0, - 0x001C, 0x08A4, 0x0760, 0x3FE0, - 0x3FFC, 0x0804, 0x0804, 0x3FFC -}; - -//========================================= -// = 4 -// = 16 -// = 1.83332 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_4tap_16p_183[36] = { - 0x03B0, 0x08A0, 0x03B0, 0x0000, - 0x0348, 0x0898, 0x041C, 0x0004, - 0x02DC, 0x0884, 0x0490, 0x0010, - 0x0278, 0x0864, 0x0500, 0x0024, - 0x021C, 0x0838, 0x0570, 0x003C, - 0x01C8, 0x07FC, 0x05E0, 0x005C, - 0x0178, 0x07B8, 0x064C, 0x0084, - 0x0130, 0x076C, 0x06B0, 0x00B4, - 0x00F0, 0x0714, 0x0710, 0x00EC -}; - -//========================================= -// = 2 -// = 64 -// = 0.833333 (input/output) -// = 0 -// = ModifiedLanczos -// = s1.10 -// = s1.12 -//========================================= -static const uint16_t filter_2tap_64p[66] = { - 0x1000, 0x0000, - 0x1000, 0x0000, - 0x0FFC, 0x0004, - 0x0FF8, 0x0008, - 0x0FF0, 0x0010, - 0x0FE4, 0x001C, - 0x0FD8, 0x0028, - 0x0FC4, 0x003C, - 0x0FB0, 0x0050, - 0x0F98, 0x0068, - 0x0F7C, 0x0084, - 0x0F58, 0x00A8, - 0x0F34, 0x00CC, - 0x0F08, 0x00F8, - 0x0ED8, 0x0128, - 0x0EA4, 0x015C, - 0x0E68, 0x0198, - 0x0E28, 0x01D8, - 0x0DE4, 0x021C, - 0x0D98, 0x0268, - 0x0D44, 0x02BC, - 0x0CEC, 0x0314, - 0x0C90, 0x0370, - 0x0C2C, 0x03D4, - 0x0BC4, 0x043C, - 0x0B58, 0x04A8, - 0x0AE8, 0x0518, - 0x0A74, 0x058C, - 0x09FC, 0x0604, - 0x0980, 0x0680, - 0x0900, 0x0700, - 0x0880, 0x0780, - 0x0800, 0x0800 -}; - -//========================================= -// = 3 -// = 64 -// = 0.83333 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_3tap_64p_upscale[99] = { - 0x0804, 0x07FC, 0x0000, - 0x07A8, 0x0860, 0x3FF8, - 0x0754, 0x08BC, 0x3FF0, - 0x0700, 0x0918, 0x3FE8, - 0x06AC, 0x0978, 0x3FDC, - 0x0654, 0x09D8, 0x3FD4, - 0x0604, 0x0A34, 0x3FC8, - 0x05B0, 0x0A90, 0x3FC0, - 0x055C, 0x0AF0, 0x3FB4, - 0x050C, 0x0B48, 0x3FAC, - 0x04BC, 0x0BA0, 0x3FA4, - 0x0470, 0x0BF4, 0x3F9C, - 0x0420, 0x0C50, 0x3F90, - 0x03D8, 0x0C9C, 0x3F8C, - 0x038C, 0x0CF0, 0x3F84, - 0x0344, 0x0D40, 0x3F7C, - 0x0300, 0x0D88, 0x3F78, - 0x02BC, 0x0DD0, 0x3F74, - 0x027C, 0x0E14, 0x3F70, - 0x023C, 0x0E54, 0x3F70, - 0x0200, 0x0E90, 0x3F70, - 0x01C8, 0x0EC8, 0x3F70, - 0x0190, 0x0EFC, 0x3F74, - 0x015C, 0x0F2C, 0x3F78, - 0x0128, 0x0F5C, 0x3F7C, - 0x00FC, 0x0F7C, 0x3F88, - 0x00CC, 0x0FA4, 0x3F90, - 0x00A4, 0x0FC0, 0x3F9C, - 0x007C, 0x0FD8, 0x3FAC, - 0x0058, 0x0FE8, 0x3FC0, - 0x0038, 0x0FF4, 0x3FD4, - 0x0018, 0x1000, 0x3FE8, - 0x0000, 0x1000, 0x0000 -}; - -//========================================= -// = 3 -// = 64 -// = 1.16666 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_3tap_64p_116[99] = { - 0x0804, 0x07FC, 0x0000, - 0x07C0, 0x0844, 0x3FFC, - 0x0780, 0x0888, 0x3FF8, - 0x0740, 0x08D0, 0x3FF0, - 0x0700, 0x0914, 0x3FEC, - 0x06C0, 0x0958, 0x3FE8, - 0x0684, 0x0998, 0x3FE4, - 0x0644, 0x09DC, 0x3FE0, - 0x0604, 0x0A1C, 0x3FE0, - 0x05C4, 0x0A5C, 0x3FE0, - 0x0588, 0x0A9C, 0x3FDC, - 0x0548, 0x0ADC, 0x3FDC, - 0x050C, 0x0B14, 0x3FE0, - 0x04CC, 0x0B54, 0x3FE0, - 0x0490, 0x0B8C, 0x3FE4, - 0x0458, 0x0BC0, 0x3FE8, - 0x041C, 0x0BF4, 0x3FF0, - 0x03E0, 0x0C28, 0x3FF8, - 0x03A8, 0x0C58, 0x0000, - 0x0374, 0x0C88, 0x0004, - 0x0340, 0x0CB0, 0x0010, - 0x0308, 0x0CD8, 0x0020, - 0x02D8, 0x0CFC, 0x002C, - 0x02A0, 0x0D20, 0x0040, - 0x0274, 0x0D3C, 0x0050, - 0x0244, 0x0D58, 0x0064, - 0x0214, 0x0D70, 0x007C, - 0x01E8, 0x0D84, 0x0094, - 0x01C0, 0x0D94, 0x00AC, - 0x0198, 0x0DA0, 0x00C8, - 0x0170, 0x0DAC, 0x00E4, - 0x014C, 0x0DB0, 0x0104, - 0x0128, 0x0DB4, 0x0124 -}; - -//========================================= -// = 3 -// = 64 -// = 1.49999 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_3tap_64p_149[99] = { - 0x0804, 0x07FC, 0x0000, - 0x07CC, 0x0834, 0x0000, - 0x0798, 0x0868, 0x0000, - 0x0764, 0x089C, 0x0000, - 0x0730, 0x08CC, 0x0004, - 0x0700, 0x08FC, 0x0004, - 0x06CC, 0x092C, 0x0008, - 0x0698, 0x095C, 0x000C, - 0x0660, 0x098C, 0x0014, - 0x062C, 0x09B8, 0x001C, - 0x05FC, 0x09E4, 0x0020, - 0x05C4, 0x0A10, 0x002C, - 0x0590, 0x0A3C, 0x0034, - 0x055C, 0x0A64, 0x0040, - 0x0528, 0x0A8C, 0x004C, - 0x04F8, 0x0AB0, 0x0058, - 0x04C4, 0x0AD4, 0x0068, - 0x0490, 0x0AF8, 0x0078, - 0x0460, 0x0B18, 0x0088, - 0x0430, 0x0B38, 0x0098, - 0x0400, 0x0B54, 0x00AC, - 0x03D0, 0x0B6C, 0x00C4, - 0x03A0, 0x0B88, 0x00D8, - 0x0374, 0x0B9C, 0x00F0, - 0x0348, 0x0BB0, 0x0108, - 0x0318, 0x0BC4, 0x0124, - 0x02EC, 0x0BD4, 0x0140, - 0x02C4, 0x0BE0, 0x015C, - 0x029C, 0x0BEC, 0x0178, - 0x0274, 0x0BF4, 0x0198, - 0x024C, 0x0BFC, 0x01B8, - 0x0228, 0x0BFC, 0x01DC, - 0x0200, 0x0C00, 0x0200 -}; - -//========================================= -// = 3 -// = 64 -// = 1.83332 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_3tap_64p_183[99] = { - 0x0804, 0x07FC, 0x0000, - 0x07D4, 0x0824, 0x0008, - 0x07AC, 0x0840, 0x0014, - 0x0780, 0x0860, 0x0020, - 0x0754, 0x0880, 0x002C, - 0x0728, 0x089C, 0x003C, - 0x0700, 0x08B8, 0x0048, - 0x06D4, 0x08D4, 0x0058, - 0x06A8, 0x08F0, 0x0068, - 0x067C, 0x090C, 0x0078, - 0x0650, 0x0924, 0x008C, - 0x0628, 0x093C, 0x009C, - 0x05FC, 0x0954, 0x00B0, - 0x05D0, 0x096C, 0x00C4, - 0x05A8, 0x0980, 0x00D8, - 0x0578, 0x0998, 0x00F0, - 0x0550, 0x09AC, 0x0104, - 0x0528, 0x09BC, 0x011C, - 0x04FC, 0x09D0, 0x0134, - 0x04D4, 0x09E0, 0x014C, - 0x04A8, 0x09F0, 0x0168, - 0x0480, 0x09FC, 0x0184, - 0x045C, 0x0A08, 0x019C, - 0x0434, 0x0A14, 0x01B8, - 0x0408, 0x0A20, 0x01D8, - 0x03E0, 0x0A2C, 0x01F4, - 0x03B8, 0x0A34, 0x0214, - 0x0394, 0x0A38, 0x0234, - 0x036C, 0x0A40, 0x0254, - 0x0348, 0x0A44, 0x0274, - 0x0324, 0x0A48, 0x0294, - 0x0300, 0x0A48, 0x02B8, - 0x02DC, 0x0A48, 0x02DC -}; - -//========================================= -// = 4 -// = 64 -// = 0.83333 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_4tap_64p_upscale[132] = { - 0x0000, 0x1000, 0x0000, 0x0000, - 0x3FDC, 0x0FFC, 0x0028, 0x0000, - 0x3FB4, 0x0FF8, 0x0054, 0x0000, - 0x3F94, 0x0FE8, 0x0084, 0x0000, - 0x3F74, 0x0FDC, 0x00B4, 0x3FFC, - 0x3F58, 0x0FC4, 0x00E8, 0x3FFC, - 0x3F3C, 0x0FAC, 0x0120, 0x3FF8, - 0x3F24, 0x0F90, 0x0158, 0x3FF4, - 0x3F0C, 0x0F70, 0x0194, 0x3FF0, - 0x3EF8, 0x0F4C, 0x01D0, 0x3FEC, - 0x3EE8, 0x0F20, 0x0210, 0x3FE8, - 0x3ED8, 0x0EF4, 0x0254, 0x3FE0, - 0x3ECC, 0x0EC4, 0x0298, 0x3FD8, - 0x3EC0, 0x0E90, 0x02DC, 0x3FD4, - 0x3EB8, 0x0E58, 0x0324, 0x3FCC, - 0x3EB0, 0x0E20, 0x036C, 0x3FC4, - 0x3EAC, 0x0DE4, 0x03B8, 0x3FB8, - 0x3EA8, 0x0DA4, 0x0404, 0x3FB0, - 0x3EA4, 0x0D60, 0x0454, 0x3FA8, - 0x3EA4, 0x0D1C, 0x04A4, 0x3F9C, - 0x3EA4, 0x0CD8, 0x04F4, 0x3F90, - 0x3EA8, 0x0C88, 0x0548, 0x3F88, - 0x3EAC, 0x0C3C, 0x059C, 0x3F7C, - 0x3EB0, 0x0BF0, 0x05F0, 0x3F70, - 0x3EB8, 0x0BA0, 0x0644, 0x3F64, - 0x3EBC, 0x0B54, 0x0698, 0x3F58, - 0x3EC4, 0x0B00, 0x06F0, 0x3F4C, - 0x3ECC, 0x0AAC, 0x0748, 0x3F40, - 0x3ED8, 0x0A54, 0x07A0, 0x3F34, - 0x3EE0, 0x0A04, 0x07F8, 0x3F24, - 0x3EEC, 0x09AC, 0x0850, 0x3F18, - 0x3EF8, 0x0954, 0x08A8, 0x3F0C, - 0x3F00, 0x08FC, 0x0900, 0x3F04 -}; - -//========================================= -// = 4 -// = 64 -// = 1.16666 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_4tap_64p_116[132] = { - 0x01A8, 0x0CB4, 0x01A4, 0x0000, - 0x017C, 0x0CB8, 0x01D0, 0x3FFC, - 0x0158, 0x0CB8, 0x01F8, 0x3FF8, - 0x0130, 0x0CB4, 0x0228, 0x3FF4, - 0x0110, 0x0CB0, 0x0254, 0x3FEC, - 0x00EC, 0x0CA8, 0x0284, 0x3FE8, - 0x00CC, 0x0C9C, 0x02B4, 0x3FE4, - 0x00AC, 0x0C90, 0x02E8, 0x3FDC, - 0x0090, 0x0C80, 0x031C, 0x3FD4, - 0x0070, 0x0C70, 0x0350, 0x3FD0, - 0x0058, 0x0C5C, 0x0384, 0x3FC8, - 0x003C, 0x0C48, 0x03BC, 0x3FC0, - 0x0024, 0x0C2C, 0x03F4, 0x3FBC, - 0x0010, 0x0C10, 0x042C, 0x3FB4, - 0x3FFC, 0x0BF4, 0x0464, 0x3FAC, - 0x3FE8, 0x0BD4, 0x04A0, 0x3FA4, - 0x3FD8, 0x0BAC, 0x04DC, 0x3FA0, - 0x3FC4, 0x0B8C, 0x0518, 0x3F98, - 0x3FB4, 0x0B68, 0x0554, 0x3F90, - 0x3FA8, 0x0B40, 0x0590, 0x3F88, - 0x3F9C, 0x0B14, 0x05CC, 0x3F84, - 0x3F90, 0x0AEC, 0x0608, 0x3F7C, - 0x3F84, 0x0ABC, 0x0648, 0x3F78, - 0x3F7C, 0x0A90, 0x0684, 0x3F70, - 0x3F70, 0x0A60, 0x06C4, 0x3F6C, - 0x3F6C, 0x0A2C, 0x0700, 0x3F68, - 0x3F64, 0x09F8, 0x0740, 0x3F64, - 0x3F60, 0x09C4, 0x077C, 0x3F60, - 0x3F5C, 0x098C, 0x07BC, 0x3F5C, - 0x3F58, 0x0958, 0x07F8, 0x3F58, - 0x3F58, 0x091C, 0x0834, 0x3F58, - 0x3F54, 0x08E4, 0x0870, 0x3F58, - 0x3F54, 0x08AC, 0x08AC, 0x3F54 -}; - -//========================================= -// = 4 -// = 64 -// = 1.49999 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_4tap_64p_149[132] = { - 0x02B8, 0x0A90, 0x02B8, 0x0000, - 0x0294, 0x0A94, 0x02DC, 0x3FFC, - 0x0274, 0x0A94, 0x0300, 0x3FF8, - 0x0250, 0x0A94, 0x0328, 0x3FF4, - 0x0230, 0x0A90, 0x0350, 0x3FF0, - 0x0214, 0x0A8C, 0x0374, 0x3FEC, - 0x01F0, 0x0A88, 0x03A0, 0x3FE8, - 0x01D4, 0x0A80, 0x03C8, 0x3FE4, - 0x01B8, 0x0A78, 0x03F0, 0x3FE0, - 0x0198, 0x0A70, 0x041C, 0x3FDC, - 0x0180, 0x0A64, 0x0444, 0x3FD8, - 0x0164, 0x0A54, 0x0470, 0x3FD8, - 0x0148, 0x0A48, 0x049C, 0x3FD4, - 0x0130, 0x0A38, 0x04C8, 0x3FD0, - 0x0118, 0x0A24, 0x04F4, 0x3FD0, - 0x0100, 0x0A14, 0x0520, 0x3FCC, - 0x00E8, 0x0A00, 0x054C, 0x3FCC, - 0x00D4, 0x09E8, 0x057C, 0x3FC8, - 0x00C0, 0x09D0, 0x05A8, 0x3FC8, - 0x00AC, 0x09B8, 0x05D4, 0x3FC8, - 0x0098, 0x09A0, 0x0600, 0x3FC8, - 0x0084, 0x0984, 0x0630, 0x3FC8, - 0x0074, 0x0964, 0x065C, 0x3FCC, - 0x0064, 0x0948, 0x0688, 0x3FCC, - 0x0054, 0x0928, 0x06B4, 0x3FD0, - 0x0044, 0x0908, 0x06E0, 0x3FD4, - 0x0038, 0x08E8, 0x070C, 0x3FD4, - 0x002C, 0x08C4, 0x0738, 0x3FD8, - 0x001C, 0x08A4, 0x0760, 0x3FE0, - 0x0014, 0x087C, 0x078C, 0x3FE4, - 0x0008, 0x0858, 0x07B4, 0x3FEC, - 0x0000, 0x0830, 0x07DC, 0x3FF4, - 0x3FFC, 0x0804, 0x0804, 0x3FFC -}; - -//========================================= -// = 4 -// = 64 -// = 1.83332 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_4tap_64p_183[132] = { - 0x03B0, 0x08A0, 0x03B0, 0x0000, - 0x0394, 0x08A0, 0x03CC, 0x0000, - 0x037C, 0x089C, 0x03E8, 0x0000, - 0x0360, 0x089C, 0x0400, 0x0004, - 0x0348, 0x0898, 0x041C, 0x0004, - 0x032C, 0x0894, 0x0438, 0x0008, - 0x0310, 0x0890, 0x0454, 0x000C, - 0x02F8, 0x0888, 0x0474, 0x000C, - 0x02DC, 0x0884, 0x0490, 0x0010, - 0x02C4, 0x087C, 0x04AC, 0x0014, - 0x02AC, 0x0874, 0x04C8, 0x0018, - 0x0290, 0x086C, 0x04E4, 0x0020, - 0x0278, 0x0864, 0x0500, 0x0024, - 0x0264, 0x0858, 0x051C, 0x0028, - 0x024C, 0x084C, 0x0538, 0x0030, - 0x0234, 0x0844, 0x0554, 0x0034, - 0x021C, 0x0838, 0x0570, 0x003C, - 0x0208, 0x0828, 0x058C, 0x0044, - 0x01F0, 0x081C, 0x05A8, 0x004C, - 0x01DC, 0x080C, 0x05C4, 0x0054, - 0x01C8, 0x07FC, 0x05E0, 0x005C, - 0x01B4, 0x07EC, 0x05FC, 0x0064, - 0x019C, 0x07DC, 0x0618, 0x0070, - 0x018C, 0x07CC, 0x0630, 0x0078, - 0x0178, 0x07B8, 0x064C, 0x0084, - 0x0164, 0x07A8, 0x0664, 0x0090, - 0x0150, 0x0794, 0x0680, 0x009C, - 0x0140, 0x0780, 0x0698, 0x00A8, - 0x0130, 0x076C, 0x06B0, 0x00B4, - 0x0120, 0x0758, 0x06C8, 0x00C0, - 0x0110, 0x0740, 0x06E0, 0x00D0, - 0x0100, 0x072C, 0x06F8, 0x00DC, - 0x00F0, 0x0714, 0x0710, 0x00EC -}; - -//========================================= -// = 5 -// = 64 -// = 0.83333 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_5tap_64p_upscale[165] = { - 0x3E40, 0x09C0, 0x09C0, 0x3E40, 0x0000, - 0x3E50, 0x0964, 0x0A18, 0x3E34, 0x0000, - 0x3E5C, 0x0908, 0x0A6C, 0x3E2C, 0x0004, - 0x3E6C, 0x08AC, 0x0AC0, 0x3E20, 0x0008, - 0x3E78, 0x0850, 0x0B14, 0x3E18, 0x000C, - 0x3E88, 0x07F4, 0x0B60, 0x3E14, 0x0010, - 0x3E98, 0x0798, 0x0BB0, 0x3E0C, 0x0014, - 0x3EA8, 0x073C, 0x0C00, 0x3E08, 0x0014, - 0x3EB8, 0x06E4, 0x0C48, 0x3E04, 0x0018, - 0x3ECC, 0x0684, 0x0C90, 0x3E04, 0x001C, - 0x3EDC, 0x062C, 0x0CD4, 0x3E04, 0x0020, - 0x3EEC, 0x05D4, 0x0D1C, 0x3E04, 0x0020, - 0x3EFC, 0x057C, 0x0D5C, 0x3E08, 0x0024, - 0x3F0C, 0x0524, 0x0D98, 0x3E10, 0x0028, - 0x3F20, 0x04CC, 0x0DD8, 0x3E14, 0x0028, - 0x3F30, 0x0478, 0x0E14, 0x3E1C, 0x0028, - 0x3F40, 0x0424, 0x0E48, 0x3E28, 0x002C, - 0x3F50, 0x03D4, 0x0E7C, 0x3E34, 0x002C, - 0x3F60, 0x0384, 0x0EAC, 0x3E44, 0x002C, - 0x3F6C, 0x0338, 0x0EDC, 0x3E54, 0x002C, - 0x3F7C, 0x02E8, 0x0F08, 0x3E68, 0x002C, - 0x3F8C, 0x02A0, 0x0F2C, 0x3E7C, 0x002C, - 0x3F98, 0x0258, 0x0F50, 0x3E94, 0x002C, - 0x3FA4, 0x0210, 0x0F74, 0x3EB0, 0x0028, - 0x3FB0, 0x01CC, 0x0F90, 0x3ECC, 0x0028, - 0x3FC0, 0x018C, 0x0FA8, 0x3EE8, 0x0024, - 0x3FC8, 0x014C, 0x0FC0, 0x3F0C, 0x0020, - 0x3FD4, 0x0110, 0x0FD4, 0x3F2C, 0x001C, - 0x3FE0, 0x00D4, 0x0FE0, 0x3F54, 0x0018, - 0x3FE8, 0x009C, 0x0FF0, 0x3F7C, 0x0010, - 0x3FF0, 0x0064, 0x0FFC, 0x3FA4, 0x000C, - 0x3FFC, 0x0030, 0x0FFC, 0x3FD4, 0x0004, - 0x0000, 0x0000, 0x1000, 0x0000, 0x0000 -}; - -//========================================= -// = 5 -// = 64 -// = 1.16666 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_5tap_64p_116[165] = { - 0x3EDC, 0x0924, 0x0924, 0x3EDC, 0x0000, - 0x3ED8, 0x08EC, 0x095C, 0x3EE0, 0x0000, - 0x3ED4, 0x08B0, 0x0994, 0x3EE8, 0x0000, - 0x3ED0, 0x0878, 0x09C8, 0x3EF0, 0x0000, - 0x3ED0, 0x083C, 0x09FC, 0x3EF8, 0x0000, - 0x3ED0, 0x0800, 0x0A2C, 0x3F04, 0x0000, - 0x3ED0, 0x07C4, 0x0A5C, 0x3F10, 0x0000, - 0x3ED0, 0x0788, 0x0A8C, 0x3F1C, 0x0000, - 0x3ED0, 0x074C, 0x0AC0, 0x3F28, 0x3FFC, - 0x3ED4, 0x0710, 0x0AE8, 0x3F38, 0x3FFC, - 0x3ED8, 0x06D0, 0x0B18, 0x3F48, 0x3FF8, - 0x3EDC, 0x0694, 0x0B3C, 0x3F5C, 0x3FF8, - 0x3EE0, 0x0658, 0x0B68, 0x3F6C, 0x3FF4, - 0x3EE4, 0x061C, 0x0B90, 0x3F80, 0x3FF0, - 0x3EEC, 0x05DC, 0x0BB4, 0x3F98, 0x3FEC, - 0x3EF0, 0x05A0, 0x0BD8, 0x3FB0, 0x3FE8, - 0x3EF8, 0x0564, 0x0BF8, 0x3FC8, 0x3FE4, - 0x3EFC, 0x0528, 0x0C1C, 0x3FE0, 0x3FE0, - 0x3F04, 0x04EC, 0x0C38, 0x3FFC, 0x3FDC, - 0x3F0C, 0x04B4, 0x0C54, 0x0014, 0x3FD8, - 0x3F14, 0x047C, 0x0C70, 0x0030, 0x3FD0, - 0x3F1C, 0x0440, 0x0C88, 0x0050, 0x3FCC, - 0x3F24, 0x0408, 0x0CA0, 0x0070, 0x3FC4, - 0x3F2C, 0x03D0, 0x0CB0, 0x0094, 0x3FC0, - 0x3F34, 0x0398, 0x0CC4, 0x00B8, 0x3FB8, - 0x3F3C, 0x0364, 0x0CD4, 0x00DC, 0x3FB0, - 0x3F48, 0x032C, 0x0CE0, 0x0100, 0x3FAC, - 0x3F50, 0x02F8, 0x0CEC, 0x0128, 0x3FA4, - 0x3F58, 0x02C4, 0x0CF8, 0x0150, 0x3F9C, - 0x3F60, 0x0290, 0x0D00, 0x017C, 0x3F94, - 0x3F68, 0x0260, 0x0D04, 0x01A8, 0x3F8C, - 0x3F74, 0x0230, 0x0D04, 0x01D4, 0x3F84, - 0x3F7C, 0x0200, 0x0D08, 0x0200, 0x3F7C -}; - -//========================================= -// = 5 -// = 64 -// = 1.49999 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_5tap_64p_149[165] = { - 0x3FF4, 0x080C, 0x080C, 0x3FF4, 0x0000, - 0x3FE8, 0x07E8, 0x0830, 0x0000, 0x0000, - 0x3FDC, 0x07C8, 0x0850, 0x0010, 0x3FFC, - 0x3FD0, 0x07A4, 0x0878, 0x001C, 0x3FF8, - 0x3FC4, 0x0780, 0x0898, 0x0030, 0x3FF4, - 0x3FB8, 0x075C, 0x08B8, 0x0040, 0x3FF4, - 0x3FB0, 0x0738, 0x08D8, 0x0050, 0x3FF0, - 0x3FA8, 0x0710, 0x08F8, 0x0064, 0x3FEC, - 0x3FA0, 0x06EC, 0x0914, 0x0078, 0x3FE8, - 0x3F98, 0x06C4, 0x0934, 0x008C, 0x3FE4, - 0x3F90, 0x06A0, 0x094C, 0x00A4, 0x3FE0, - 0x3F8C, 0x0678, 0x0968, 0x00B8, 0x3FDC, - 0x3F84, 0x0650, 0x0984, 0x00D0, 0x3FD8, - 0x3F80, 0x0628, 0x099C, 0x00E8, 0x3FD4, - 0x3F7C, 0x0600, 0x09B8, 0x0100, 0x3FCC, - 0x3F78, 0x05D8, 0x09D0, 0x0118, 0x3FC8, - 0x3F74, 0x05B0, 0x09E4, 0x0134, 0x3FC4, - 0x3F70, 0x0588, 0x09F8, 0x0150, 0x3FC0, - 0x3F70, 0x0560, 0x0A08, 0x016C, 0x3FBC, - 0x3F6C, 0x0538, 0x0A20, 0x0188, 0x3FB4, - 0x3F6C, 0x0510, 0x0A30, 0x01A4, 0x3FB0, - 0x3F6C, 0x04E8, 0x0A3C, 0x01C4, 0x3FAC, - 0x3F6C, 0x04C0, 0x0A48, 0x01E4, 0x3FA8, - 0x3F6C, 0x0498, 0x0A58, 0x0200, 0x3FA4, - 0x3F6C, 0x0470, 0x0A60, 0x0224, 0x3FA0, - 0x3F6C, 0x0448, 0x0A70, 0x0244, 0x3F98, - 0x3F70, 0x0420, 0x0A78, 0x0264, 0x3F94, - 0x3F70, 0x03F8, 0x0A80, 0x0288, 0x3F90, - 0x3F74, 0x03D4, 0x0A84, 0x02A8, 0x3F8C, - 0x3F74, 0x03AC, 0x0A8C, 0x02CC, 0x3F88, - 0x3F78, 0x0384, 0x0A90, 0x02F0, 0x3F84, - 0x3F7C, 0x0360, 0x0A90, 0x0314, 0x3F80, - 0x3F7C, 0x033C, 0x0A90, 0x033C, 0x3F7C -}; - -//========================================= -// = 5 -// = 64 -// = 1.83332 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_5tap_64p_183[165] = { - 0x0168, 0x069C, 0x0698, 0x0164, 0x0000, - 0x0154, 0x068C, 0x06AC, 0x0174, 0x0000, - 0x0144, 0x0674, 0x06C0, 0x0188, 0x0000, - 0x0138, 0x0664, 0x06D0, 0x0198, 0x3FFC, - 0x0128, 0x0654, 0x06E0, 0x01A8, 0x3FFC, - 0x0118, 0x0640, 0x06F0, 0x01BC, 0x3FFC, - 0x010C, 0x0630, 0x0700, 0x01CC, 0x3FF8, - 0x00FC, 0x061C, 0x0710, 0x01E0, 0x3FF8, - 0x00F0, 0x060C, 0x071C, 0x01F0, 0x3FF8, - 0x00E4, 0x05F4, 0x072C, 0x0204, 0x3FF8, - 0x00D8, 0x05E4, 0x0738, 0x0218, 0x3FF4, - 0x00CC, 0x05D0, 0x0744, 0x022C, 0x3FF4, - 0x00C0, 0x05B8, 0x0754, 0x0240, 0x3FF4, - 0x00B4, 0x05A4, 0x0760, 0x0254, 0x3FF4, - 0x00A8, 0x0590, 0x076C, 0x0268, 0x3FF4, - 0x009C, 0x057C, 0x0778, 0x027C, 0x3FF4, - 0x0094, 0x0564, 0x0780, 0x0294, 0x3FF4, - 0x0088, 0x0550, 0x0788, 0x02A8, 0x3FF8, - 0x0080, 0x0538, 0x0794, 0x02BC, 0x3FF8, - 0x0074, 0x0524, 0x079C, 0x02D4, 0x3FF8, - 0x006C, 0x0510, 0x07A4, 0x02E8, 0x3FF8, - 0x0064, 0x04F4, 0x07AC, 0x0300, 0x3FFC, - 0x005C, 0x04E4, 0x07B0, 0x0314, 0x3FFC, - 0x0054, 0x04C8, 0x07B8, 0x032C, 0x0000, - 0x004C, 0x04B4, 0x07C0, 0x0340, 0x0000, - 0x0044, 0x04A0, 0x07C4, 0x0358, 0x0000, - 0x003C, 0x0488, 0x07C8, 0x0370, 0x0004, - 0x0038, 0x0470, 0x07CC, 0x0384, 0x0008, - 0x0030, 0x045C, 0x07D0, 0x039C, 0x0008, - 0x002C, 0x0444, 0x07D0, 0x03B4, 0x000C, - 0x0024, 0x042C, 0x07D4, 0x03CC, 0x0010, - 0x0020, 0x0414, 0x07D4, 0x03E0, 0x0018, - 0x001C, 0x03FC, 0x07D4, 0x03F8, 0x001C -}; - -//========================================= -// = 6 -// = 64 -// = 0.83333 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_6tap_64p_upscale[198] = { - 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, - 0x000C, 0x3FD0, 0x0FFC, 0x0034, 0x3FF4, 0x0000, - 0x0018, 0x3F9C, 0x0FF8, 0x006C, 0x3FE8, 0x0000, - 0x0024, 0x3F6C, 0x0FF0, 0x00A8, 0x3FD8, 0x0000, - 0x002C, 0x3F44, 0x0FE4, 0x00E4, 0x3FC8, 0x0000, - 0x0038, 0x3F18, 0x0FD4, 0x0124, 0x3FB8, 0x0000, - 0x0040, 0x3EF0, 0x0FC0, 0x0164, 0x3FA8, 0x0004, - 0x0048, 0x3EC8, 0x0FAC, 0x01A8, 0x3F98, 0x0004, - 0x0050, 0x3EA8, 0x0F94, 0x01EC, 0x3F84, 0x0004, - 0x0058, 0x3E84, 0x0F74, 0x0234, 0x3F74, 0x0008, - 0x0060, 0x3E68, 0x0F54, 0x027C, 0x3F60, 0x0008, - 0x0064, 0x3E4C, 0x0F30, 0x02C8, 0x3F4C, 0x000C, - 0x006C, 0x3E30, 0x0F04, 0x0314, 0x3F3C, 0x0010, - 0x0070, 0x3E18, 0x0EDC, 0x0360, 0x3F28, 0x0014, - 0x0074, 0x3E04, 0x0EB0, 0x03B0, 0x3F14, 0x0014, - 0x0078, 0x3DF0, 0x0E80, 0x0400, 0x3F00, 0x0018, - 0x0078, 0x3DE0, 0x0E4C, 0x0454, 0x3EEC, 0x001C, - 0x007C, 0x3DD0, 0x0E14, 0x04A8, 0x3ED8, 0x0020, - 0x007C, 0x3DC4, 0x0DDC, 0x04FC, 0x3EC4, 0x0024, - 0x007C, 0x3DBC, 0x0DA0, 0x0550, 0x3EB0, 0x0028, - 0x0080, 0x3DB4, 0x0D5C, 0x05A8, 0x3E9C, 0x002C, - 0x0080, 0x3DAC, 0x0D1C, 0x0600, 0x3E88, 0x0030, - 0x007C, 0x3DA8, 0x0CDC, 0x0658, 0x3E74, 0x0034, - 0x007C, 0x3DA4, 0x0C94, 0x06B0, 0x3E64, 0x0038, - 0x007C, 0x3DA4, 0x0C48, 0x0708, 0x3E50, 0x0040, - 0x0078, 0x3DA4, 0x0C00, 0x0760, 0x3E40, 0x0044, - 0x0078, 0x3DA8, 0x0BB4, 0x07B8, 0x3E2C, 0x0048, - 0x0074, 0x3DAC, 0x0B68, 0x0810, 0x3E1C, 0x004C, - 0x0070, 0x3DB4, 0x0B18, 0x0868, 0x3E0C, 0x0050, - 0x006C, 0x3DBC, 0x0AC4, 0x08C4, 0x3DFC, 0x0054, - 0x0068, 0x3DC4, 0x0A74, 0x0918, 0x3DF0, 0x0058, - 0x0068, 0x3DCC, 0x0A20, 0x0970, 0x3DE0, 0x005C, - 0x0064, 0x3DD4, 0x09C8, 0x09C8, 0x3DD4, 0x0064 -}; - -//========================================= -// = 6 -// = 64 -// = 1.16666 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_6tap_64p_116[198] = { - 0x3F0C, 0x0240, 0x0D68, 0x0240, 0x3F0C, 0x0000, - 0x3F18, 0x0210, 0x0D64, 0x0274, 0x3F00, 0x0000, - 0x3F24, 0x01E0, 0x0D58, 0x02A8, 0x3EF8, 0x0004, - 0x3F2C, 0x01B0, 0x0D58, 0x02DC, 0x3EEC, 0x0004, - 0x3F38, 0x0180, 0x0D50, 0x0310, 0x3EE0, 0x0008, - 0x3F44, 0x0154, 0x0D40, 0x0348, 0x3ED8, 0x0008, - 0x3F50, 0x0128, 0x0D34, 0x037C, 0x3ECC, 0x000C, - 0x3F5C, 0x00FC, 0x0D20, 0x03B4, 0x3EC4, 0x0010, - 0x3F64, 0x00D4, 0x0D14, 0x03EC, 0x3EB8, 0x0010, - 0x3F70, 0x00AC, 0x0CFC, 0x0424, 0x3EB0, 0x0014, - 0x3F78, 0x0084, 0x0CE8, 0x0460, 0x3EA8, 0x0014, - 0x3F84, 0x0060, 0x0CCC, 0x0498, 0x3EA0, 0x0018, - 0x3F90, 0x003C, 0x0CB4, 0x04D0, 0x3E98, 0x0018, - 0x3F98, 0x0018, 0x0C9C, 0x050C, 0x3E90, 0x0018, - 0x3FA0, 0x3FFC, 0x0C78, 0x0548, 0x3E88, 0x001C, - 0x3FAC, 0x3FDC, 0x0C54, 0x0584, 0x3E84, 0x001C, - 0x3FB4, 0x3FBC, 0x0C3C, 0x05BC, 0x3E7C, 0x001C, - 0x3FBC, 0x3FA0, 0x0C14, 0x05F8, 0x3E78, 0x0020, - 0x3FC4, 0x3F84, 0x0BF0, 0x0634, 0x3E74, 0x0020, - 0x3FCC, 0x3F68, 0x0BCC, 0x0670, 0x3E70, 0x0020, - 0x3FD4, 0x3F50, 0x0BA4, 0x06AC, 0x3E6C, 0x0020, - 0x3FDC, 0x3F38, 0x0B78, 0x06E8, 0x3E6C, 0x0020, - 0x3FE0, 0x3F24, 0x0B50, 0x0724, 0x3E68, 0x0020, - 0x3FE8, 0x3F0C, 0x0B24, 0x0760, 0x3E68, 0x0020, - 0x3FF0, 0x3EFC, 0x0AF4, 0x0798, 0x3E68, 0x0020, - 0x3FF4, 0x3EE8, 0x0AC8, 0x07D4, 0x3E68, 0x0020, - 0x3FFC, 0x3ED8, 0x0A94, 0x0810, 0x3E6C, 0x001C, - 0x0000, 0x3EC8, 0x0A64, 0x0848, 0x3E70, 0x001C, - 0x0000, 0x3EB8, 0x0A38, 0x0880, 0x3E74, 0x001C, - 0x0004, 0x3EAC, 0x0A04, 0x08BC, 0x3E78, 0x0018, - 0x0008, 0x3EA4, 0x09D0, 0x08F4, 0x3E7C, 0x0014, - 0x000C, 0x3E98, 0x0998, 0x092C, 0x3E84, 0x0014, - 0x0010, 0x3E90, 0x0964, 0x0960, 0x3E8C, 0x0010 -}; - -//========================================= -// = 6 -// = 64 -// = 1.49999 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_6tap_64p_149[198] = { - 0x3F14, 0x0394, 0x0AB0, 0x0394, 0x3F14, 0x0000, - 0x3F18, 0x036C, 0x0AB0, 0x03B8, 0x3F14, 0x0000, - 0x3F18, 0x0348, 0x0AAC, 0x03E0, 0x3F14, 0x0000, - 0x3F1C, 0x0320, 0x0AAC, 0x0408, 0x3F10, 0x0000, - 0x3F20, 0x02FC, 0x0AA8, 0x042C, 0x3F10, 0x0000, - 0x3F24, 0x02D8, 0x0AA0, 0x0454, 0x3F10, 0x0000, - 0x3F28, 0x02B4, 0x0A98, 0x047C, 0x3F10, 0x0000, - 0x3F28, 0x0290, 0x0A90, 0x04A4, 0x3F14, 0x0000, - 0x3F30, 0x026C, 0x0A84, 0x04CC, 0x3F14, 0x0000, - 0x3F34, 0x024C, 0x0A7C, 0x04F4, 0x3F14, 0x3FFC, - 0x3F38, 0x0228, 0x0A70, 0x051C, 0x3F18, 0x3FFC, - 0x3F3C, 0x0208, 0x0A64, 0x0544, 0x3F1C, 0x3FF8, - 0x3F40, 0x01E8, 0x0A54, 0x056C, 0x3F20, 0x3FF8, - 0x3F44, 0x01C8, 0x0A48, 0x0594, 0x3F24, 0x3FF4, - 0x3F4C, 0x01A8, 0x0A34, 0x05BC, 0x3F28, 0x3FF4, - 0x3F50, 0x0188, 0x0A28, 0x05E4, 0x3F2C, 0x3FF0, - 0x3F54, 0x016C, 0x0A10, 0x060C, 0x3F34, 0x3FF0, - 0x3F5C, 0x014C, 0x09FC, 0x0634, 0x3F3C, 0x3FEC, - 0x3F60, 0x0130, 0x09EC, 0x065C, 0x3F40, 0x3FE8, - 0x3F68, 0x0114, 0x09D0, 0x0684, 0x3F48, 0x3FE8, - 0x3F6C, 0x00F8, 0x09B8, 0x06AC, 0x3F54, 0x3FE4, - 0x3F74, 0x00E0, 0x09A0, 0x06D0, 0x3F5C, 0x3FE0, - 0x3F78, 0x00C4, 0x098C, 0x06F8, 0x3F64, 0x3FDC, - 0x3F7C, 0x00AC, 0x0970, 0x0720, 0x3F70, 0x3FD8, - 0x3F84, 0x0094, 0x0954, 0x0744, 0x3F7C, 0x3FD4, - 0x3F88, 0x007C, 0x093C, 0x0768, 0x3F88, 0x3FD0, - 0x3F90, 0x0064, 0x091C, 0x0790, 0x3F94, 0x3FCC, - 0x3F94, 0x0050, 0x08FC, 0x07B4, 0x3FA4, 0x3FC8, - 0x3F98, 0x003C, 0x08E0, 0x07D8, 0x3FB0, 0x3FC4, - 0x3FA0, 0x0024, 0x08C0, 0x07FC, 0x3FC0, 0x3FC0, - 0x3FA4, 0x0014, 0x08A4, 0x081C, 0x3FD0, 0x3FB8, - 0x3FAC, 0x0000, 0x0880, 0x0840, 0x3FE0, 0x3FB4, - 0x3FB0, 0x3FF0, 0x0860, 0x0860, 0x3FF0, 0x3FB0 -}; - -//========================================= -// = 6 -// = 64 -// = 1.83332 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_6tap_64p_183[198] = { - 0x002C, 0x0420, 0x076C, 0x041C, 0x002C, 0x0000, - 0x0028, 0x040C, 0x0768, 0x0430, 0x0034, 0x0000, - 0x0020, 0x03F8, 0x0768, 0x0448, 0x003C, 0x3FFC, - 0x0018, 0x03E4, 0x0768, 0x045C, 0x0044, 0x3FFC, - 0x0014, 0x03D0, 0x0768, 0x0470, 0x004C, 0x3FF8, - 0x000C, 0x03BC, 0x0764, 0x0484, 0x0058, 0x3FF8, - 0x0008, 0x03A4, 0x0764, 0x049C, 0x0060, 0x3FF4, - 0x0004, 0x0390, 0x0760, 0x04B0, 0x0068, 0x3FF4, - 0x0000, 0x037C, 0x0760, 0x04C4, 0x0070, 0x3FF0, - 0x3FFC, 0x0364, 0x075C, 0x04D8, 0x007C, 0x3FF0, - 0x3FF8, 0x0350, 0x0758, 0x04F0, 0x0084, 0x3FEC, - 0x3FF4, 0x033C, 0x0750, 0x0504, 0x0090, 0x3FEC, - 0x3FF0, 0x0328, 0x074C, 0x0518, 0x009C, 0x3FE8, - 0x3FEC, 0x0314, 0x0744, 0x052C, 0x00A8, 0x3FE8, - 0x3FE8, 0x0304, 0x0740, 0x0540, 0x00B0, 0x3FE4, - 0x3FE4, 0x02EC, 0x073C, 0x0554, 0x00BC, 0x3FE4, - 0x3FE0, 0x02DC, 0x0734, 0x0568, 0x00C8, 0x3FE0, - 0x3FE0, 0x02C4, 0x072C, 0x057C, 0x00D4, 0x3FE0, - 0x3FDC, 0x02B4, 0x0724, 0x058C, 0x00E4, 0x3FDC, - 0x3FDC, 0x02A0, 0x0718, 0x05A0, 0x00F0, 0x3FDC, - 0x3FD8, 0x028C, 0x0714, 0x05B4, 0x00FC, 0x3FD8, - 0x3FD8, 0x0278, 0x0704, 0x05C8, 0x010C, 0x3FD8, - 0x3FD4, 0x0264, 0x0700, 0x05D8, 0x0118, 0x3FD8, - 0x3FD4, 0x0254, 0x06F0, 0x05EC, 0x0128, 0x3FD4, - 0x3FD0, 0x0244, 0x06E8, 0x05FC, 0x0134, 0x3FD4, - 0x3FD0, 0x0230, 0x06DC, 0x060C, 0x0144, 0x3FD4, - 0x3FD0, 0x021C, 0x06D0, 0x0620, 0x0154, 0x3FD0, - 0x3FD0, 0x0208, 0x06C4, 0x0630, 0x0164, 0x3FD0, - 0x3FD0, 0x01F8, 0x06B8, 0x0640, 0x0170, 0x3FD0, - 0x3FCC, 0x01E8, 0x06AC, 0x0650, 0x0180, 0x3FD0, - 0x3FCC, 0x01D8, 0x069C, 0x0660, 0x0190, 0x3FD0, - 0x3FCC, 0x01C4, 0x068C, 0x0670, 0x01A4, 0x3FD0, - 0x3FCC, 0x01B8, 0x0680, 0x067C, 0x01B4, 0x3FCC -}; - -//========================================= -// = 7 -// = 64 -// = 0.83333 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_7tap_64p_upscale[231] = { - 0x00B0, 0x3D98, 0x09BC, 0x09B8, 0x3D94, 0x00B0, 0x0000, - 0x00AC, 0x3DA0, 0x0968, 0x0A10, 0x3D88, 0x00B4, 0x0000, - 0x00A8, 0x3DAC, 0x0914, 0x0A60, 0x3D80, 0x00B8, 0x0000, - 0x00A4, 0x3DB8, 0x08C0, 0x0AB4, 0x3D78, 0x00BC, 0x3FFC, - 0x00A0, 0x3DC8, 0x0868, 0x0B00, 0x3D74, 0x00C0, 0x3FFC, - 0x0098, 0x3DD8, 0x0818, 0x0B54, 0x3D6C, 0x00C0, 0x3FF8, - 0x0094, 0x3DE8, 0x07C0, 0x0B9C, 0x3D6C, 0x00C4, 0x3FF8, - 0x008C, 0x3DFC, 0x0768, 0x0BEC, 0x3D68, 0x00C4, 0x3FF8, - 0x0088, 0x3E0C, 0x0714, 0x0C38, 0x3D68, 0x00C4, 0x3FF4, - 0x0080, 0x3E20, 0x06BC, 0x0C80, 0x3D6C, 0x00C4, 0x3FF4, - 0x0078, 0x3E34, 0x0668, 0x0CC4, 0x3D70, 0x00C4, 0x3FF4, - 0x0074, 0x3E48, 0x0610, 0x0D08, 0x3D78, 0x00C4, 0x3FF0, - 0x006C, 0x3E5C, 0x05BC, 0x0D48, 0x3D80, 0x00C4, 0x3FF0, - 0x0068, 0x3E74, 0x0568, 0x0D84, 0x3D88, 0x00C0, 0x3FF0, - 0x0060, 0x3E88, 0x0514, 0x0DC8, 0x3D94, 0x00BC, 0x3FEC, - 0x0058, 0x3E9C, 0x04C0, 0x0E04, 0x3DA4, 0x00B8, 0x3FEC, - 0x0054, 0x3EB4, 0x046C, 0x0E38, 0x3DB4, 0x00B4, 0x3FEC, - 0x004C, 0x3ECC, 0x0418, 0x0E6C, 0x3DC8, 0x00B0, 0x3FEC, - 0x0044, 0x3EE0, 0x03C8, 0x0EA4, 0x3DDC, 0x00A8, 0x3FEC, - 0x0040, 0x3EF8, 0x0378, 0x0ED0, 0x3DF4, 0x00A0, 0x3FEC, - 0x0038, 0x3F0C, 0x032C, 0x0EFC, 0x3E10, 0x0098, 0x3FEC, - 0x0034, 0x3F24, 0x02DC, 0x0F24, 0x3E2C, 0x0090, 0x3FEC, - 0x002C, 0x3F38, 0x0294, 0x0F4C, 0x3E48, 0x0088, 0x3FEC, - 0x0028, 0x3F50, 0x0248, 0x0F68, 0x3E6C, 0x007C, 0x3FF0, - 0x0020, 0x3F64, 0x0200, 0x0F88, 0x3E90, 0x0074, 0x3FF0, - 0x001C, 0x3F7C, 0x01B8, 0x0FA4, 0x3EB4, 0x0068, 0x3FF0, - 0x0018, 0x3F90, 0x0174, 0x0FBC, 0x3EDC, 0x0058, 0x3FF4, - 0x0014, 0x3FA4, 0x0130, 0x0FD0, 0x3F08, 0x004C, 0x3FF4, - 0x000C, 0x3FB8, 0x00F0, 0x0FE4, 0x3F34, 0x003C, 0x3FF8, - 0x0008, 0x3FCC, 0x00B0, 0x0FF0, 0x3F64, 0x0030, 0x3FF8, - 0x0004, 0x3FDC, 0x0070, 0x0FFC, 0x3F98, 0x0020, 0x3FFC, - 0x0000, 0x3FF0, 0x0038, 0x0FFC, 0x3FCC, 0x0010, 0x0000, - 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000 -}; - -//========================================= -// = 7 -// = 64 -// = 1.16666 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_7tap_64p_116[231] = { - 0x0020, 0x3E58, 0x0988, 0x0988, 0x3E58, 0x0020, 0x0000, - 0x0024, 0x3E4C, 0x0954, 0x09C0, 0x3E64, 0x0018, 0x0000, - 0x002C, 0x3E44, 0x091C, 0x09F4, 0x3E70, 0x0010, 0x0000, - 0x0030, 0x3E3C, 0x08E8, 0x0A24, 0x3E80, 0x0008, 0x0000, - 0x0034, 0x3E34, 0x08AC, 0x0A5C, 0x3E90, 0x0000, 0x0000, - 0x003C, 0x3E30, 0x0870, 0x0A84, 0x3EA0, 0x3FFC, 0x0004, - 0x0040, 0x3E28, 0x0838, 0x0AB4, 0x3EB4, 0x3FF4, 0x0004, - 0x0044, 0x3E24, 0x07FC, 0x0AE4, 0x3EC8, 0x3FEC, 0x0004, - 0x0048, 0x3E24, 0x07C4, 0x0B08, 0x3EDC, 0x3FE4, 0x0008, - 0x0048, 0x3E20, 0x0788, 0x0B3C, 0x3EF4, 0x3FD8, 0x0008, - 0x004C, 0x3E20, 0x074C, 0x0B60, 0x3F0C, 0x3FD0, 0x000C, - 0x0050, 0x3E20, 0x0710, 0x0B8C, 0x3F24, 0x3FC4, 0x000C, - 0x0050, 0x3E20, 0x06D4, 0x0BB0, 0x3F40, 0x3FBC, 0x0010, - 0x0054, 0x3E24, 0x0698, 0x0BD4, 0x3F5C, 0x3FB0, 0x0010, - 0x0054, 0x3E24, 0x065C, 0x0BFC, 0x3F78, 0x3FA4, 0x0014, - 0x0054, 0x3E28, 0x0624, 0x0C1C, 0x3F98, 0x3F98, 0x0014, - 0x0058, 0x3E2C, 0x05E4, 0x0C3C, 0x3FB8, 0x3F8C, 0x0018, - 0x0058, 0x3E34, 0x05A8, 0x0C58, 0x3FD8, 0x3F80, 0x001C, - 0x0058, 0x3E38, 0x0570, 0x0C78, 0x3FF8, 0x3F74, 0x001C, - 0x0058, 0x3E40, 0x0534, 0x0C94, 0x0018, 0x3F68, 0x0020, - 0x0058, 0x3E48, 0x04F4, 0x0CAC, 0x0040, 0x3F5C, 0x0024, - 0x0058, 0x3E50, 0x04BC, 0x0CC4, 0x0064, 0x3F50, 0x0024, - 0x0054, 0x3E58, 0x0484, 0x0CD8, 0x008C, 0x3F44, 0x0028, - 0x0054, 0x3E60, 0x0448, 0x0CEC, 0x00B4, 0x3F38, 0x002C, - 0x0054, 0x3E68, 0x0410, 0x0CFC, 0x00E0, 0x3F28, 0x0030, - 0x0054, 0x3E74, 0x03D4, 0x0D0C, 0x010C, 0x3F1C, 0x0030, - 0x0050, 0x3E7C, 0x03A0, 0x0D18, 0x0138, 0x3F10, 0x0034, - 0x0050, 0x3E88, 0x0364, 0x0D24, 0x0164, 0x3F04, 0x0038, - 0x004C, 0x3E94, 0x0330, 0x0D30, 0x0194, 0x3EF4, 0x0038, - 0x004C, 0x3EA0, 0x02F8, 0x0D34, 0x01C4, 0x3EE8, 0x003C, - 0x0048, 0x3EAC, 0x02C0, 0x0D3C, 0x01F4, 0x3EDC, 0x0040, - 0x0048, 0x3EB8, 0x0290, 0x0D3C, 0x0224, 0x3ED0, 0x0040, - 0x0044, 0x3EC4, 0x0258, 0x0D40, 0x0258, 0x3EC4, 0x0044 -}; - -//========================================= -// = 7 -// = 64 -// = 1.49999 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_7tap_64p_149[231] = { - 0x3F68, 0x3FEC, 0x08A8, 0x08AC, 0x3FF0, 0x3F68, 0x0000, - 0x3F70, 0x3FDC, 0x0888, 0x08CC, 0x0000, 0x3F60, 0x0000, - 0x3F74, 0x3FC8, 0x0868, 0x08F0, 0x0014, 0x3F58, 0x0000, - 0x3F7C, 0x3FB4, 0x0844, 0x0908, 0x002C, 0x3F54, 0x0004, - 0x3F84, 0x3FA4, 0x0820, 0x0924, 0x0044, 0x3F4C, 0x0004, - 0x3F88, 0x3F90, 0x0800, 0x0944, 0x005C, 0x3F44, 0x0004, - 0x3F90, 0x3F80, 0x07D8, 0x095C, 0x0074, 0x3F40, 0x0008, - 0x3F98, 0x3F70, 0x07B0, 0x097C, 0x008C, 0x3F38, 0x0008, - 0x3F9C, 0x3F60, 0x0790, 0x0994, 0x00A8, 0x3F30, 0x0008, - 0x3FA4, 0x3F54, 0x0764, 0x09B0, 0x00C4, 0x3F28, 0x0008, - 0x3FA8, 0x3F48, 0x0740, 0x09C4, 0x00DC, 0x3F24, 0x000C, - 0x3FB0, 0x3F38, 0x0718, 0x09DC, 0x00FC, 0x3F1C, 0x000C, - 0x3FB4, 0x3F2C, 0x06F0, 0x09F4, 0x0118, 0x3F18, 0x000C, - 0x3FBC, 0x3F24, 0x06C8, 0x0A08, 0x0134, 0x3F10, 0x000C, - 0x3FC0, 0x3F18, 0x06A0, 0x0A1C, 0x0154, 0x3F08, 0x0010, - 0x3FC8, 0x3F10, 0x0678, 0x0A2C, 0x0170, 0x3F04, 0x0010, - 0x3FCC, 0x3F04, 0x0650, 0x0A40, 0x0190, 0x3F00, 0x0010, - 0x3FD0, 0x3EFC, 0x0628, 0x0A54, 0x01B0, 0x3EF8, 0x0010, - 0x3FD4, 0x3EF4, 0x0600, 0x0A64, 0x01D0, 0x3EF4, 0x0010, - 0x3FDC, 0x3EEC, 0x05D8, 0x0A6C, 0x01F4, 0x3EF0, 0x0010, - 0x3FE0, 0x3EE8, 0x05B0, 0x0A7C, 0x0214, 0x3EE8, 0x0010, - 0x3FE4, 0x3EE0, 0x0588, 0x0A88, 0x0238, 0x3EE4, 0x0010, - 0x3FE8, 0x3EDC, 0x055C, 0x0A98, 0x0258, 0x3EE0, 0x0010, - 0x3FEC, 0x3ED8, 0x0534, 0x0AA0, 0x027C, 0x3EDC, 0x0010, - 0x3FF0, 0x3ED4, 0x050C, 0x0AAC, 0x02A0, 0x3ED8, 0x000C, - 0x3FF4, 0x3ED0, 0x04E4, 0x0AB4, 0x02C4, 0x3ED4, 0x000C, - 0x3FF4, 0x3ECC, 0x04C0, 0x0ABC, 0x02E8, 0x3ED0, 0x000C, - 0x3FF8, 0x3ECC, 0x0494, 0x0AC0, 0x030C, 0x3ED0, 0x000C, - 0x3FFC, 0x3EC8, 0x046C, 0x0AC8, 0x0334, 0x3ECC, 0x0008, - 0x0000, 0x3EC8, 0x0444, 0x0AC8, 0x0358, 0x3ECC, 0x0008, - 0x0000, 0x3EC8, 0x041C, 0x0ACC, 0x0380, 0x3EC8, 0x0008, - 0x0000, 0x3EC8, 0x03F4, 0x0AD0, 0x03A8, 0x3EC8, 0x0004, - 0x0004, 0x3EC8, 0x03CC, 0x0AD0, 0x03CC, 0x3EC8, 0x0004 -}; - -//========================================= -// = 7 -// = 64 -// = 1.83332 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_7tap_64p_183[231] = { - 0x3FA4, 0x01E8, 0x0674, 0x0674, 0x01E8, 0x3FA4, 0x0000, - 0x3FA4, 0x01D4, 0x0668, 0x0684, 0x01F8, 0x3FA4, 0x0000, - 0x3FA4, 0x01C4, 0x0658, 0x0690, 0x0208, 0x3FA8, 0x0000, - 0x3FA0, 0x01B4, 0x064C, 0x06A0, 0x021C, 0x3FA8, 0x3FFC, - 0x3FA0, 0x01A4, 0x063C, 0x06AC, 0x022C, 0x3FAC, 0x3FFC, - 0x3FA0, 0x0194, 0x0630, 0x06B4, 0x0240, 0x3FAC, 0x3FFC, - 0x3FA0, 0x0184, 0x0620, 0x06C4, 0x0250, 0x3FB0, 0x3FF8, - 0x3FA0, 0x0174, 0x0614, 0x06CC, 0x0264, 0x3FB0, 0x3FF8, - 0x3FA0, 0x0164, 0x0604, 0x06D8, 0x0278, 0x3FB4, 0x3FF4, - 0x3FA0, 0x0154, 0x05F4, 0x06E4, 0x0288, 0x3FB8, 0x3FF4, - 0x3FA0, 0x0148, 0x05E4, 0x06EC, 0x029C, 0x3FBC, 0x3FF0, - 0x3FA0, 0x0138, 0x05D4, 0x06F4, 0x02B0, 0x3FC0, 0x3FF0, - 0x3FA0, 0x0128, 0x05C4, 0x0704, 0x02C4, 0x3FC0, 0x3FEC, - 0x3FA0, 0x011C, 0x05B4, 0x0708, 0x02D8, 0x3FC4, 0x3FEC, - 0x3FA4, 0x010C, 0x05A4, 0x0714, 0x02E8, 0x3FC8, 0x3FE8, - 0x3FA4, 0x0100, 0x0590, 0x0718, 0x02FC, 0x3FD0, 0x3FE8, - 0x3FA4, 0x00F0, 0x0580, 0x0724, 0x0310, 0x3FD4, 0x3FE4, - 0x3FA4, 0x00E4, 0x056C, 0x072C, 0x0324, 0x3FD8, 0x3FE4, - 0x3FA8, 0x00D8, 0x055C, 0x0730, 0x0338, 0x3FDC, 0x3FE0, - 0x3FA8, 0x00CC, 0x0548, 0x0738, 0x034C, 0x3FE4, 0x3FDC, - 0x3FA8, 0x00BC, 0x0538, 0x0740, 0x0360, 0x3FE8, 0x3FDC, - 0x3FAC, 0x00B0, 0x0528, 0x0744, 0x0374, 0x3FEC, 0x3FD8, - 0x3FAC, 0x00A4, 0x0514, 0x0748, 0x0388, 0x3FF4, 0x3FD8, - 0x3FB0, 0x0098, 0x0500, 0x074C, 0x039C, 0x3FFC, 0x3FD4, - 0x3FB0, 0x0090, 0x04EC, 0x0750, 0x03B0, 0x0000, 0x3FD4, - 0x3FB0, 0x0084, 0x04DC, 0x0758, 0x03C4, 0x0004, 0x3FD0, - 0x3FB4, 0x0078, 0x04CC, 0x0758, 0x03D8, 0x000C, 0x3FCC, - 0x3FB4, 0x006C, 0x04B8, 0x075C, 0x03EC, 0x0014, 0x3FCC, - 0x3FB8, 0x0064, 0x04A0, 0x0760, 0x0400, 0x001C, 0x3FC8, - 0x3FB8, 0x0058, 0x0490, 0x0760, 0x0414, 0x0024, 0x3FC8, - 0x3FBC, 0x0050, 0x047C, 0x0760, 0x0428, 0x002C, 0x3FC4, - 0x3FBC, 0x0048, 0x0464, 0x0764, 0x043C, 0x0034, 0x3FC4, - 0x3FC0, 0x003C, 0x0454, 0x0764, 0x0450, 0x003C, 0x3FC0 -}; - -//========================================= -// = 8 -// = 64 -// = 0.83333 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_8tap_64p_upscale[264] = { - 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3FFC, 0x0014, 0x3FC8, 0x1000, 0x0038, 0x3FEC, 0x0004, 0x0000, - 0x3FF4, 0x0024, 0x3F94, 0x0FFC, 0x0074, 0x3FD8, 0x000C, 0x0000, - 0x3FF0, 0x0038, 0x3F60, 0x0FEC, 0x00B4, 0x3FC4, 0x0014, 0x0000, - 0x3FEC, 0x004C, 0x3F2C, 0x0FE4, 0x00F4, 0x3FAC, 0x0018, 0x0000, - 0x3FE4, 0x005C, 0x3F00, 0x0FD4, 0x0138, 0x3F94, 0x0020, 0x0000, - 0x3FE0, 0x006C, 0x3ED0, 0x0FC4, 0x017C, 0x3F7C, 0x0028, 0x0000, - 0x3FDC, 0x007C, 0x3EA8, 0x0FA4, 0x01C4, 0x3F68, 0x0030, 0x0000, - 0x3FD8, 0x0088, 0x3E80, 0x0F90, 0x020C, 0x3F50, 0x0038, 0x3FFC, - 0x3FD4, 0x0098, 0x3E58, 0x0F70, 0x0258, 0x3F38, 0x0040, 0x3FFC, - 0x3FD0, 0x00A4, 0x3E34, 0x0F54, 0x02A0, 0x3F1C, 0x004C, 0x3FFC, - 0x3FD0, 0x00B0, 0x3E14, 0x0F28, 0x02F0, 0x3F04, 0x0054, 0x3FFC, - 0x3FCC, 0x00BC, 0x3DF4, 0x0F08, 0x033C, 0x3EEC, 0x005C, 0x3FF8, - 0x3FC8, 0x00C8, 0x3DD8, 0x0EDC, 0x038C, 0x3ED4, 0x0064, 0x3FF8, - 0x3FC8, 0x00D0, 0x3DC0, 0x0EAC, 0x03E0, 0x3EBC, 0x006C, 0x3FF4, - 0x3FC4, 0x00D8, 0x3DA8, 0x0E7C, 0x0430, 0x3EA4, 0x0078, 0x3FF4, - 0x3FC4, 0x00E0, 0x3D94, 0x0E48, 0x0484, 0x3E8C, 0x0080, 0x3FF0, - 0x3FC4, 0x00E8, 0x3D80, 0x0E10, 0x04D8, 0x3E74, 0x0088, 0x3FF0, - 0x3FC4, 0x00F0, 0x3D70, 0x0DD8, 0x052C, 0x3E5C, 0x0090, 0x3FEC, - 0x3FC0, 0x00F4, 0x3D60, 0x0DA0, 0x0584, 0x3E44, 0x0098, 0x3FEC, - 0x3FC0, 0x00F8, 0x3D54, 0x0D68, 0x05D8, 0x3E2C, 0x00A0, 0x3FE8, - 0x3FC0, 0x00FC, 0x3D48, 0x0D20, 0x0630, 0x3E18, 0x00AC, 0x3FE8, - 0x3FC0, 0x0100, 0x3D40, 0x0CE0, 0x0688, 0x3E00, 0x00B4, 0x3FE4, - 0x3FC4, 0x0100, 0x3D3C, 0x0C98, 0x06DC, 0x3DEC, 0x00BC, 0x3FE4, - 0x3FC4, 0x0100, 0x3D38, 0x0C58, 0x0734, 0x3DD8, 0x00C0, 0x3FE0, - 0x3FC4, 0x0104, 0x3D38, 0x0C0C, 0x078C, 0x3DC4, 0x00C8, 0x3FDC, - 0x3FC4, 0x0100, 0x3D38, 0x0BC4, 0x07E4, 0x3DB0, 0x00D0, 0x3FDC, - 0x3FC4, 0x0100, 0x3D38, 0x0B78, 0x083C, 0x3DA0, 0x00D8, 0x3FD8, - 0x3FC8, 0x0100, 0x3D3C, 0x0B28, 0x0890, 0x3D90, 0x00DC, 0x3FD8, - 0x3FC8, 0x00FC, 0x3D40, 0x0ADC, 0x08E8, 0x3D80, 0x00E4, 0x3FD4, - 0x3FCC, 0x00FC, 0x3D48, 0x0A84, 0x093C, 0x3D74, 0x00E8, 0x3FD4, - 0x3FCC, 0x00F8, 0x3D50, 0x0A38, 0x0990, 0x3D64, 0x00F0, 0x3FD0, - 0x3FD0, 0x00F4, 0x3D58, 0x09E0, 0x09E4, 0x3D5C, 0x00F4, 0x3FD0 -}; - -//========================================= -// = 8 -// = 64 -// = 1.16666 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_8tap_64p_116[264] = { - 0x0080, 0x3E90, 0x0268, 0x0D14, 0x0264, 0x3E90, 0x0080, 0x0000, - 0x007C, 0x3E9C, 0x0238, 0x0D14, 0x0298, 0x3E84, 0x0080, 0x0000, - 0x0078, 0x3EAC, 0x0200, 0x0D10, 0x02D0, 0x3E78, 0x0084, 0x0000, - 0x0078, 0x3EB8, 0x01D0, 0x0D0C, 0x0304, 0x3E6C, 0x0084, 0x0000, - 0x0074, 0x3EC8, 0x01A0, 0x0D00, 0x033C, 0x3E60, 0x0088, 0x0000, - 0x0070, 0x3ED4, 0x0170, 0x0D00, 0x0374, 0x3E54, 0x0088, 0x3FFC, - 0x006C, 0x3EE4, 0x0140, 0x0CF8, 0x03AC, 0x3E48, 0x0088, 0x3FFC, - 0x006C, 0x3EF0, 0x0114, 0x0CE8, 0x03E4, 0x3E3C, 0x008C, 0x3FFC, - 0x0068, 0x3F00, 0x00E8, 0x0CD8, 0x041C, 0x3E34, 0x008C, 0x3FFC, - 0x0064, 0x3F10, 0x00BC, 0x0CCC, 0x0454, 0x3E28, 0x008C, 0x3FFC, - 0x0060, 0x3F1C, 0x0090, 0x0CBC, 0x0490, 0x3E20, 0x008C, 0x3FFC, - 0x005C, 0x3F2C, 0x0068, 0x0CA4, 0x04CC, 0x3E18, 0x008C, 0x3FFC, - 0x0058, 0x3F38, 0x0040, 0x0C94, 0x0504, 0x3E10, 0x008C, 0x3FFC, - 0x0054, 0x3F48, 0x001C, 0x0C7C, 0x0540, 0x3E08, 0x0088, 0x3FFC, - 0x0050, 0x3F54, 0x3FF8, 0x0C60, 0x057C, 0x3E04, 0x0088, 0x3FFC, - 0x004C, 0x3F64, 0x3FD4, 0x0C44, 0x05B8, 0x3DFC, 0x0088, 0x3FFC, - 0x0048, 0x3F70, 0x3FB4, 0x0C28, 0x05F4, 0x3DF8, 0x0084, 0x3FFC, - 0x0044, 0x3F80, 0x3F90, 0x0C0C, 0x0630, 0x3DF4, 0x0080, 0x3FFC, - 0x0040, 0x3F8C, 0x3F70, 0x0BE8, 0x066C, 0x3DF4, 0x0080, 0x3FFC, - 0x003C, 0x3F9C, 0x3F50, 0x0BC8, 0x06A8, 0x3DF0, 0x007C, 0x3FFC, - 0x0038, 0x3FA8, 0x3F34, 0x0BA0, 0x06E4, 0x3DF0, 0x0078, 0x0000, - 0x0034, 0x3FB4, 0x3F18, 0x0B80, 0x071C, 0x3DF0, 0x0074, 0x0000, - 0x0030, 0x3FC0, 0x3EFC, 0x0B5C, 0x0758, 0x3DF0, 0x0070, 0x0000, - 0x002C, 0x3FCC, 0x3EE4, 0x0B34, 0x0794, 0x3DF4, 0x0068, 0x0000, - 0x002C, 0x3FDC, 0x3ECC, 0x0B08, 0x07CC, 0x3DF4, 0x0064, 0x0000, - 0x0028, 0x3FE4, 0x3EB4, 0x0AE0, 0x0808, 0x3DF8, 0x0060, 0x0000, - 0x0024, 0x3FF0, 0x3EA0, 0x0AB0, 0x0840, 0x3E00, 0x0058, 0x0004, - 0x0020, 0x3FFC, 0x3E90, 0x0A84, 0x0878, 0x3E04, 0x0050, 0x0004, - 0x001C, 0x0004, 0x3E7C, 0x0A54, 0x08B0, 0x3E0C, 0x004C, 0x0008, - 0x0018, 0x000C, 0x3E68, 0x0A28, 0x08E8, 0x3E18, 0x0044, 0x0008, - 0x0018, 0x0018, 0x3E54, 0x09F4, 0x0920, 0x3E20, 0x003C, 0x000C, - 0x0014, 0x0020, 0x3E48, 0x09C0, 0x0954, 0x3E2C, 0x0034, 0x0010, - 0x0010, 0x002C, 0x3E3C, 0x098C, 0x0988, 0x3E38, 0x002C, 0x0010 -}; - -//========================================= -// = 8 -// = 64 -// = 1.49999 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_8tap_64p_149[264] = { - 0x0008, 0x3E8C, 0x03F8, 0x0AE8, 0x03F8, 0x3E8C, 0x0008, 0x0000, - 0x000C, 0x3E8C, 0x03D0, 0x0AE8, 0x0420, 0x3E90, 0x0000, 0x0000, - 0x000C, 0x3E8C, 0x03AC, 0x0AE8, 0x0444, 0x3E90, 0x0000, 0x0000, - 0x0010, 0x3E90, 0x0384, 0x0AE0, 0x046C, 0x3E94, 0x3FFC, 0x0000, - 0x0014, 0x3E90, 0x035C, 0x0ADC, 0x0494, 0x3E94, 0x3FF8, 0x0004, - 0x0018, 0x3E90, 0x0334, 0x0AD8, 0x04BC, 0x3E98, 0x3FF4, 0x0004, - 0x001C, 0x3E94, 0x0310, 0x0AD0, 0x04E4, 0x3E9C, 0x3FEC, 0x0004, - 0x0020, 0x3E98, 0x02E8, 0x0AC4, 0x050C, 0x3EA0, 0x3FE8, 0x0008, - 0x0020, 0x3E98, 0x02C4, 0x0AC0, 0x0534, 0x3EA4, 0x3FE4, 0x0008, - 0x0024, 0x3E9C, 0x02A0, 0x0AB4, 0x055C, 0x3EAC, 0x3FDC, 0x0008, - 0x0024, 0x3EA0, 0x027C, 0x0AA8, 0x0584, 0x3EB0, 0x3FD8, 0x000C, - 0x0028, 0x3EA4, 0x0258, 0x0A9C, 0x05AC, 0x3EB8, 0x3FD0, 0x000C, - 0x0028, 0x3EA8, 0x0234, 0x0A90, 0x05D4, 0x3EC0, 0x3FC8, 0x0010, - 0x002C, 0x3EAC, 0x0210, 0x0A80, 0x05FC, 0x3EC8, 0x3FC4, 0x0010, - 0x002C, 0x3EB4, 0x01F0, 0x0A70, 0x0624, 0x3ED0, 0x3FBC, 0x0010, - 0x002C, 0x3EB8, 0x01CC, 0x0A60, 0x064C, 0x3EDC, 0x3FB4, 0x0014, - 0x0030, 0x3EBC, 0x01A8, 0x0A50, 0x0674, 0x3EE4, 0x3FB0, 0x0014, - 0x0030, 0x3EC4, 0x0188, 0x0A38, 0x069C, 0x3EF0, 0x3FA8, 0x0018, - 0x0030, 0x3ECC, 0x0168, 0x0A28, 0x06C0, 0x3EFC, 0x3FA0, 0x0018, - 0x0030, 0x3ED0, 0x0148, 0x0A14, 0x06E8, 0x3F08, 0x3F98, 0x001C, - 0x0030, 0x3ED8, 0x012C, 0x0A00, 0x070C, 0x3F14, 0x3F90, 0x001C, - 0x0034, 0x3EE0, 0x0108, 0x09E4, 0x0734, 0x3F24, 0x3F8C, 0x001C, - 0x0034, 0x3EE4, 0x00EC, 0x09CC, 0x0758, 0x3F34, 0x3F84, 0x0020, - 0x0034, 0x3EEC, 0x00D0, 0x09B8, 0x077C, 0x3F40, 0x3F7C, 0x0020, - 0x0034, 0x3EF4, 0x00B4, 0x0998, 0x07A4, 0x3F50, 0x3F74, 0x0024, - 0x0030, 0x3EFC, 0x0098, 0x0980, 0x07C8, 0x3F64, 0x3F6C, 0x0024, - 0x0030, 0x3F04, 0x0080, 0x0968, 0x07E8, 0x3F74, 0x3F64, 0x0024, - 0x0030, 0x3F0C, 0x0060, 0x094C, 0x080C, 0x3F88, 0x3F5C, 0x0028, - 0x0030, 0x3F14, 0x0048, 0x0930, 0x0830, 0x3F98, 0x3F54, 0x0028, - 0x0030, 0x3F1C, 0x0030, 0x0914, 0x0850, 0x3FAC, 0x3F4C, 0x0028, - 0x0030, 0x3F24, 0x0018, 0x08F0, 0x0874, 0x3FC0, 0x3F44, 0x002C, - 0x002C, 0x3F2C, 0x0000, 0x08D4, 0x0894, 0x3FD8, 0x3F3C, 0x002C, - 0x002C, 0x3F34, 0x3FEC, 0x08B4, 0x08B4, 0x3FEC, 0x3F34, 0x002C -}; - -//========================================= -// = 8 -// = 64 -// = 1.83332 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_8tap_64p_183[264] = { - 0x3F88, 0x0048, 0x047C, 0x0768, 0x047C, 0x0048, 0x3F88, 0x0000, - 0x3F88, 0x003C, 0x0468, 0x076C, 0x0490, 0x0054, 0x3F84, 0x0000, - 0x3F8C, 0x0034, 0x0454, 0x0768, 0x04A4, 0x005C, 0x3F84, 0x0000, - 0x3F8C, 0x0028, 0x0444, 0x076C, 0x04B4, 0x0068, 0x3F80, 0x0000, - 0x3F90, 0x0020, 0x042C, 0x0768, 0x04C8, 0x0074, 0x3F80, 0x0000, - 0x3F90, 0x0018, 0x041C, 0x0764, 0x04DC, 0x0080, 0x3F7C, 0x0000, - 0x3F94, 0x0010, 0x0408, 0x075C, 0x04F0, 0x008C, 0x3F7C, 0x0000, - 0x3F94, 0x0004, 0x03F8, 0x0760, 0x0500, 0x0098, 0x3F7C, 0x3FFC, - 0x3F98, 0x0000, 0x03E0, 0x075C, 0x0514, 0x00A4, 0x3F78, 0x3FFC, - 0x3F9C, 0x3FF8, 0x03CC, 0x0754, 0x0528, 0x00B0, 0x3F78, 0x3FFC, - 0x3F9C, 0x3FF0, 0x03B8, 0x0754, 0x0538, 0x00BC, 0x3F78, 0x3FFC, - 0x3FA0, 0x3FE8, 0x03A4, 0x0750, 0x054C, 0x00CC, 0x3F74, 0x3FF8, - 0x3FA4, 0x3FE0, 0x0390, 0x074C, 0x055C, 0x00D8, 0x3F74, 0x3FF8, - 0x3FA4, 0x3FDC, 0x037C, 0x0744, 0x0570, 0x00E4, 0x3F74, 0x3FF8, - 0x3FA8, 0x3FD4, 0x0368, 0x0740, 0x0580, 0x00F4, 0x3F74, 0x3FF4, - 0x3FA8, 0x3FCC, 0x0354, 0x073C, 0x0590, 0x0104, 0x3F74, 0x3FF4, - 0x3FAC, 0x3FC8, 0x0340, 0x0730, 0x05A4, 0x0110, 0x3F74, 0x3FF4, - 0x3FB0, 0x3FC0, 0x0330, 0x0728, 0x05B4, 0x0120, 0x3F74, 0x3FF0, - 0x3FB0, 0x3FBC, 0x031C, 0x0724, 0x05C4, 0x0130, 0x3F70, 0x3FF0, - 0x3FB4, 0x3FB4, 0x0308, 0x0720, 0x05D4, 0x013C, 0x3F70, 0x3FF0, - 0x3FB8, 0x3FB0, 0x02F4, 0x0714, 0x05E4, 0x014C, 0x3F74, 0x3FEC, - 0x3FB8, 0x3FAC, 0x02E0, 0x0708, 0x05F8, 0x015C, 0x3F74, 0x3FEC, - 0x3FBC, 0x3FA8, 0x02CC, 0x0704, 0x0604, 0x016C, 0x3F74, 0x3FE8, - 0x3FC0, 0x3FA0, 0x02BC, 0x06F8, 0x0614, 0x017C, 0x3F74, 0x3FE8, - 0x3FC0, 0x3F9C, 0x02A8, 0x06F4, 0x0624, 0x018C, 0x3F74, 0x3FE4, - 0x3FC4, 0x3F98, 0x0294, 0x06E8, 0x0634, 0x019C, 0x3F74, 0x3FE4, - 0x3FC8, 0x3F94, 0x0284, 0x06D8, 0x0644, 0x01AC, 0x3F78, 0x3FE0, - 0x3FC8, 0x3F90, 0x0270, 0x06D4, 0x0650, 0x01BC, 0x3F78, 0x3FE0, - 0x3FCC, 0x3F8C, 0x025C, 0x06C8, 0x0660, 0x01D0, 0x3F78, 0x3FDC, - 0x3FCC, 0x3F8C, 0x024C, 0x06B8, 0x066C, 0x01E0, 0x3F7C, 0x3FDC, - 0x3FD0, 0x3F88, 0x0238, 0x06B0, 0x067C, 0x01F0, 0x3F7C, 0x3FD8, - 0x3FD4, 0x3F84, 0x0228, 0x069C, 0x0688, 0x0204, 0x3F80, 0x3FD8, - 0x3FD4, 0x3F84, 0x0214, 0x0694, 0x0694, 0x0214, 0x3F84, 0x3FD4 -}; - -const uint16_t *spl_get_filter_3tap_16p(struct spl_fixed31_32 ratio) -{ - if (ratio.value < spl_fixpt_one.value) - return filter_3tap_16p_upscale; - else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) - return filter_3tap_16p_116; - 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 spl_fixed31_32 ratio) -{ - if (ratio.value < spl_fixpt_one.value) - return filter_3tap_64p_upscale; - else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) - return filter_3tap_64p_116; - 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 spl_fixed31_32 ratio) -{ - if (ratio.value < spl_fixpt_one.value) - return filter_4tap_16p_upscale; - else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) - return filter_4tap_16p_116; - 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 spl_fixed31_32 ratio) -{ - if (ratio.value < spl_fixpt_one.value) - return filter_4tap_64p_upscale; - else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) - return filter_4tap_64p_116; - 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 spl_fixed31_32 ratio) -{ - if (ratio.value < spl_fixpt_one.value) - return filter_5tap_64p_upscale; - else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) - return filter_5tap_64p_116; - 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 spl_fixed31_32 ratio) -{ - if (ratio.value < spl_fixpt_one.value) - return filter_6tap_64p_upscale; - else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) - return filter_6tap_64p_116; - 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 spl_fixed31_32 ratio) -{ - if (ratio.value < spl_fixpt_one.value) - return filter_7tap_64p_upscale; - else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) - return filter_7tap_64p_116; - 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 spl_fixed31_32 ratio) -{ - if (ratio.value < spl_fixpt_one.value) - return filter_8tap_64p_upscale; - else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) - return filter_8tap_64p_116; - else if (ratio.value < spl_fixpt_from_fraction(5, 3).value) - return filter_8tap_64p_149; - else - return filter_8tap_64p_183; -} - -const uint16_t *spl_get_filter_2tap_16p(void) -{ - return filter_2tap_16p; -} - -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 deleted file mode 100644 index 48202bc4f81e..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_filters.h +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright 2024 Advanced Micro Devices, Inc. - -#ifndef __DC_SPL_SCL_FILTERS_H__ -#define __DC_SPL_SCL_FILTERS_H__ - -#include "dc_spl_types.h" - -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_dscl_get_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio); - -#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 deleted file mode 100644 index 467af9dd90de..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h +++ /dev/null @@ -1,543 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright 2024 Advanced Micro Devices, Inc. - -#ifndef __DC_SPL_TYPES_H__ -#define __DC_SPL_TYPES_H__ - -#include "spl_debug.h" -#include "spl_os_types.h" // swap -#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; - uint32_t height; -}; -struct spl_rect { - int x; - int y; - int width; - int height; -}; - -struct spl_ratios { - 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 spl_fixed31_32 h; - struct spl_fixed31_32 h_c; - struct spl_fixed31_32 v; - struct spl_fixed31_32 v_c; -}; - -struct spl_taps { - uint32_t v_taps; - uint32_t h_taps; - uint32_t v_taps_c; - uint32_t h_taps_c; - bool integer_scaling; -}; -enum spl_view_3d { - SPL_VIEW_3D_NONE = 0, - SPL_VIEW_3D_FRAME_SEQUENTIAL, - SPL_VIEW_3D_SIDE_BY_SIDE, - SPL_VIEW_3D_TOP_AND_BOTTOM, - SPL_VIEW_3D_COUNT, - SPL_VIEW_3D_FIRST = SPL_VIEW_3D_FRAME_SEQUENTIAL -}; -/* Pixel format */ -enum spl_pixel_format { - /*graph*/ - SPL_PIXEL_FORMAT_UNINITIALIZED, - SPL_PIXEL_FORMAT_INDEX8, - SPL_PIXEL_FORMAT_RGB565, - SPL_PIXEL_FORMAT_ARGB8888, - SPL_PIXEL_FORMAT_ARGB2101010, - SPL_PIXEL_FORMAT_ARGB2101010_XRBIAS, - SPL_PIXEL_FORMAT_FP16, - /*video*/ - SPL_PIXEL_FORMAT_420BPP8, - SPL_PIXEL_FORMAT_420BPP10, - /*end of pixel format definition*/ - SPL_PIXEL_FORMAT_GRPH_BEGIN = SPL_PIXEL_FORMAT_INDEX8, - SPL_PIXEL_FORMAT_GRPH_END = SPL_PIXEL_FORMAT_FP16, - SPL_PIXEL_FORMAT_SUBSAMPLED_BEGIN = SPL_PIXEL_FORMAT_420BPP8, - SPL_PIXEL_FORMAT_SUBSAMPLED_END = SPL_PIXEL_FORMAT_420BPP10, - SPL_PIXEL_FORMAT_VIDEO_BEGIN = SPL_PIXEL_FORMAT_420BPP8, - SPL_PIXEL_FORMAT_VIDEO_END = SPL_PIXEL_FORMAT_420BPP10, - SPL_PIXEL_FORMAT_INVALID, - 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, - SPL_ROTATION_ANGLE_90, - SPL_ROTATION_ANGLE_180, - SPL_ROTATION_ANGLE_270, - SPL_ROTATION_ANGLE_COUNT -}; -enum spl_color_space { - SPL_COLOR_SPACE_UNKNOWN, - SPL_COLOR_SPACE_SRGB, - SPL_COLOR_SPACE_XR_RGB, - SPL_COLOR_SPACE_SRGB_LIMITED, - SPL_COLOR_SPACE_MSREF_SCRGB, - SPL_COLOR_SPACE_YCBCR601, - SPL_COLOR_SPACE_YCBCR709, - SPL_COLOR_SPACE_XV_YCC_709, - SPL_COLOR_SPACE_XV_YCC_601, - SPL_COLOR_SPACE_YCBCR601_LIMITED, - SPL_COLOR_SPACE_YCBCR709_LIMITED, - SPL_COLOR_SPACE_2020_RGB_FULLRANGE, - SPL_COLOR_SPACE_2020_RGB_LIMITEDRANGE, - SPL_COLOR_SPACE_2020_YCBCR, - SPL_COLOR_SPACE_ADOBERGB, - SPL_COLOR_SPACE_DCIP3, - SPL_COLOR_SPACE_DISPLAYNATIVE, - SPL_COLOR_SPACE_DOLBYVISION, - SPL_COLOR_SPACE_APPCTRL, - SPL_COLOR_SPACE_CUSTOMPOINTS, - 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; - int v_active; - struct spl_taps taps; - struct spl_rect viewport; - struct spl_rect viewport_c; - struct spl_rect recout; - struct spl_ratios ratios; - struct spl_ratios recip_ratios; - struct spl_inits inits; -}; - -enum spl_transfer_func_type { - SPL_TF_TYPE_PREDEFINED, - SPL_TF_TYPE_DISTRIBUTED_POINTS, - SPL_TF_TYPE_BYPASS, - SPL_TF_TYPE_HWPWL -}; - -enum spl_transfer_func_predefined { - SPL_TRANSFER_FUNCTION_SRGB, - SPL_TRANSFER_FUNCTION_BT709, - SPL_TRANSFER_FUNCTION_PQ, - SPL_TRANSFER_FUNCTION_LINEAR, - SPL_TRANSFER_FUNCTION_UNITY, - SPL_TRANSFER_FUNCTION_HLG, - SPL_TRANSFER_FUNCTION_HLG12, - SPL_TRANSFER_FUNCTION_GAMMA22, - SPL_TRANSFER_FUNCTION_GAMMA24, - SPL_TRANSFER_FUNCTION_GAMMA26 -}; - -/*==============================================================*/ -/* Below structs are defined to hold hw register data */ - -// SPL output is used to set below registers - -// MPC_SIZE - set based on scl_data h_active and v_active -struct mpc_size { - uint32_t width; - uint32_t height; -}; -// SCL_MODE - set based on scl_data.ratios and always_scale -enum scl_mode { - SCL_MODE_SCALING_444_BYPASS = 0, - SCL_MODE_SCALING_444_RGB_ENABLE = 1, - SCL_MODE_SCALING_444_YCBCR_ENABLE = 2, - SCL_MODE_SCALING_420_YCBCR_ENABLE = 3, - SCL_MODE_SCALING_420_LUMA_BYPASS = 4, - SCL_MODE_SCALING_420_CHROMA_BYPASS = 5, - SCL_MODE_DSCL_BYPASS = 6 -}; -// SCL_BLACK_COLOR - set based on scl_data.format -struct scl_black_color { - uint32_t offset_rgb_y; - uint32_t offset_rgb_cbcr; -}; -// RATIO - set based on scl_data.ratios -struct ratio { - uint32_t h_scale_ratio; - uint32_t v_scale_ratio; - uint32_t h_scale_ratio_c; - uint32_t v_scale_ratio_c; -}; - -// INIT - set based on scl_data.init -struct init { - // SCL_HORZ_FILTER_INIT - uint32_t h_filter_init_frac; // SCL_H_INIT_FRAC - uint32_t h_filter_init_int; // SCL_H_INIT_INT - // SCL_HORZ_FILTER_INIT_C - uint32_t h_filter_init_frac_c; // SCL_H_INIT_FRAC_C - uint32_t h_filter_init_int_c; // SCL_H_INIT_INT_C - // SCL_VERT_FILTER_INIT - uint32_t v_filter_init_frac; // SCL_V_INIT_FRAC - uint32_t v_filter_init_int; // SCL_V_INIT_INT - // SCL_VERT_FILTER_INIT_C - uint32_t v_filter_init_frac_c; // SCL_V_INIT_FRAC_C - uint32_t v_filter_init_int_c; // SCL_V_INIT_INT_C - // SCL_VERT_FILTER_INIT_BOT - uint32_t v_filter_init_bot_frac; // SCL_V_INIT_FRAC_BOT - uint32_t v_filter_init_bot_int; // SCL_V_INIT_INT_BOT - // SCL_VERT_FILTER_INIT_BOT_C - uint32_t v_filter_init_bot_frac_c; // SCL_V_INIT_FRAC_BOT_C - uint32_t v_filter_init_bot_int_c; // SCL_V_INIT_INT_BOT_C -}; - -// FILTER - calculated based on scl_data ratios and taps - -// iSHARP -struct isharp_noise_det { - uint32_t enable; // ISHARP_NOISEDET_EN - uint32_t mode; // ISHARP_NOISEDET_MODE - uint32_t uthreshold; // ISHARP_NOISEDET_UTHRE - uint32_t dthreshold; // ISHARP_NOISEDET_DTHRE - uint32_t pwl_start_in; // ISHARP_NOISEDET_PWL_START_IN - uint32_t pwl_end_in; // ISHARP_NOISEDET_PWL_END_IN - uint32_t pwl_slope; // ISHARP_NOISEDET_PWL_SLOPE -}; -struct isharp_lba { - uint32_t mode; // ISHARP_LBA_MODE - uint32_t in_seg[6]; - uint32_t base_seg[6]; - uint32_t slope_seg[6]; -}; -struct isharp_fmt { - uint32_t mode; // ISHARP_FMT_MODE - uint32_t norm; // ISHARP_FMT_NORM -}; -struct isharp_nldelta_sclip { - uint32_t enable_p; // ISHARP_NLDELTA_SCLIP_EN_P - uint32_t pivot_p; // ISHARP_NLDELTA_SCLIP_PIVOT_P - uint32_t slope_p; // ISHARP_NLDELTA_SCLIP_SLOPE_P - uint32_t enable_n; // ISHARP_NLDELTA_SCLIP_EN_N - uint32_t pivot_n; // ISHARP_NLDELTA_SCLIP_PIVOT_N - uint32_t slope_n; // ISHARP_NLDELTA_SCLIP_SLOPE_N -}; -enum isharp_en { - ISHARP_DISABLE, - ISHARP_ENABLE -}; -#define ISHARP_LUT_TABLE_SIZE 32 -// Below struct holds values that can be directly used to program -// hardware registers. No conversion/clamping is required -struct dscl_prog_data { - struct spl_rect recout; // RECOUT - set based on scl_data.recout - struct mpc_size mpc_size; - uint32_t dscl_mode; - struct scl_black_color scl_black_color; - struct ratio ratios; - struct init init; - struct spl_taps taps; // TAPS - set based on scl_data.taps - struct spl_rect viewport; - struct spl_rect viewport_c; - // raw filter - const uint16_t *filter_h; - const uint16_t *filter_v; - const uint16_t *filter_h_c; - const uint16_t *filter_v_c; - // EASF registers - uint32_t easf_matrix_mode; - uint32_t easf_ltonl_en; - uint32_t easf_v_en; - uint32_t easf_v_sharp_factor; - uint32_t easf_v_ring; - uint32_t easf_v_bf1_en; - uint32_t easf_v_bf2_mode; - uint32_t easf_v_bf3_mode; - uint32_t easf_v_bf2_flat1_gain; - uint32_t easf_v_bf2_flat2_gain; - uint32_t easf_v_bf2_roc_gain; - uint32_t easf_v_ringest_3tap_dntilt_uptilt; - uint32_t easf_v_ringest_3tap_uptilt_max; - uint32_t easf_v_ringest_3tap_dntilt_slope; - uint32_t easf_v_ringest_3tap_uptilt1_slope; - uint32_t easf_v_ringest_3tap_uptilt2_slope; - uint32_t easf_v_ringest_3tap_uptilt2_offset; - uint32_t easf_v_ringest_eventap_reduceg1; - uint32_t easf_v_ringest_eventap_reduceg2; - uint32_t easf_v_ringest_eventap_gain1; - uint32_t easf_v_ringest_eventap_gain2; - uint32_t easf_v_bf_maxa; - uint32_t easf_v_bf_maxb; - uint32_t easf_v_bf_mina; - uint32_t easf_v_bf_minb; - uint32_t easf_v_bf1_pwl_in_seg0; - uint32_t easf_v_bf1_pwl_base_seg0; - uint32_t easf_v_bf1_pwl_slope_seg0; - uint32_t easf_v_bf1_pwl_in_seg1; - uint32_t easf_v_bf1_pwl_base_seg1; - uint32_t easf_v_bf1_pwl_slope_seg1; - uint32_t easf_v_bf1_pwl_in_seg2; - uint32_t easf_v_bf1_pwl_base_seg2; - uint32_t easf_v_bf1_pwl_slope_seg2; - uint32_t easf_v_bf1_pwl_in_seg3; - uint32_t easf_v_bf1_pwl_base_seg3; - uint32_t easf_v_bf1_pwl_slope_seg3; - uint32_t easf_v_bf1_pwl_in_seg4; - uint32_t easf_v_bf1_pwl_base_seg4; - uint32_t easf_v_bf1_pwl_slope_seg4; - uint32_t easf_v_bf1_pwl_in_seg5; - uint32_t easf_v_bf1_pwl_base_seg5; - uint32_t easf_v_bf1_pwl_slope_seg5; - uint32_t easf_v_bf1_pwl_in_seg6; - uint32_t easf_v_bf1_pwl_base_seg6; - uint32_t easf_v_bf1_pwl_slope_seg6; - uint32_t easf_v_bf1_pwl_in_seg7; - uint32_t easf_v_bf1_pwl_base_seg7; - uint32_t easf_v_bf3_pwl_in_set0; - uint32_t easf_v_bf3_pwl_base_set0; - uint32_t easf_v_bf3_pwl_slope_set0; - uint32_t easf_v_bf3_pwl_in_set1; - uint32_t easf_v_bf3_pwl_base_set1; - uint32_t easf_v_bf3_pwl_slope_set1; - uint32_t easf_v_bf3_pwl_in_set2; - uint32_t easf_v_bf3_pwl_base_set2; - uint32_t easf_v_bf3_pwl_slope_set2; - uint32_t easf_v_bf3_pwl_in_set3; - uint32_t easf_v_bf3_pwl_base_set3; - uint32_t easf_v_bf3_pwl_slope_set3; - uint32_t easf_v_bf3_pwl_in_set4; - uint32_t easf_v_bf3_pwl_base_set4; - uint32_t easf_v_bf3_pwl_slope_set4; - uint32_t easf_v_bf3_pwl_in_set5; - uint32_t easf_v_bf3_pwl_base_set5; - uint32_t easf_h_en; - uint32_t easf_h_sharp_factor; - uint32_t easf_h_ring; - uint32_t easf_h_bf1_en; - uint32_t easf_h_bf2_mode; - uint32_t easf_h_bf3_mode; - uint32_t easf_h_bf2_flat1_gain; - uint32_t easf_h_bf2_flat2_gain; - uint32_t easf_h_bf2_roc_gain; - uint32_t easf_h_ringest_eventap_reduceg1; - uint32_t easf_h_ringest_eventap_reduceg2; - uint32_t easf_h_ringest_eventap_gain1; - uint32_t easf_h_ringest_eventap_gain2; - uint32_t easf_h_bf_maxa; - uint32_t easf_h_bf_maxb; - uint32_t easf_h_bf_mina; - uint32_t easf_h_bf_minb; - uint32_t easf_h_bf1_pwl_in_seg0; - uint32_t easf_h_bf1_pwl_base_seg0; - uint32_t easf_h_bf1_pwl_slope_seg0; - uint32_t easf_h_bf1_pwl_in_seg1; - uint32_t easf_h_bf1_pwl_base_seg1; - uint32_t easf_h_bf1_pwl_slope_seg1; - uint32_t easf_h_bf1_pwl_in_seg2; - uint32_t easf_h_bf1_pwl_base_seg2; - uint32_t easf_h_bf1_pwl_slope_seg2; - uint32_t easf_h_bf1_pwl_in_seg3; - uint32_t easf_h_bf1_pwl_base_seg3; - uint32_t easf_h_bf1_pwl_slope_seg3; - uint32_t easf_h_bf1_pwl_in_seg4; - uint32_t easf_h_bf1_pwl_base_seg4; - uint32_t easf_h_bf1_pwl_slope_seg4; - uint32_t easf_h_bf1_pwl_in_seg5; - uint32_t easf_h_bf1_pwl_base_seg5; - uint32_t easf_h_bf1_pwl_slope_seg5; - uint32_t easf_h_bf1_pwl_in_seg6; - uint32_t easf_h_bf1_pwl_base_seg6; - uint32_t easf_h_bf1_pwl_slope_seg6; - uint32_t easf_h_bf1_pwl_in_seg7; - uint32_t easf_h_bf1_pwl_base_seg7; - uint32_t easf_h_bf3_pwl_in_set0; - uint32_t easf_h_bf3_pwl_base_set0; - uint32_t easf_h_bf3_pwl_slope_set0; - uint32_t easf_h_bf3_pwl_in_set1; - uint32_t easf_h_bf3_pwl_base_set1; - uint32_t easf_h_bf3_pwl_slope_set1; - uint32_t easf_h_bf3_pwl_in_set2; - uint32_t easf_h_bf3_pwl_base_set2; - uint32_t easf_h_bf3_pwl_slope_set2; - uint32_t easf_h_bf3_pwl_in_set3; - uint32_t easf_h_bf3_pwl_base_set3; - uint32_t easf_h_bf3_pwl_slope_set3; - uint32_t easf_h_bf3_pwl_in_set4; - uint32_t easf_h_bf3_pwl_base_set4; - uint32_t easf_h_bf3_pwl_slope_set4; - uint32_t easf_h_bf3_pwl_in_set5; - uint32_t easf_h_bf3_pwl_base_set5; - uint32_t easf_matrix_c0; - uint32_t easf_matrix_c1; - uint32_t easf_matrix_c2; - uint32_t easf_matrix_c3; - // iSharp - uint32_t isharp_en; // ISHARP_EN - struct isharp_noise_det isharp_noise_det; // ISHARP_NOISEDET - uint32_t isharp_nl_en; // ISHARP_NL_EN ? TODO:check this - struct isharp_lba isharp_lba; // ISHARP_LBA - struct isharp_fmt isharp_fmt; // ISHARP_FMT - uint32_t isharp_delta[ISHARP_LUT_TABLE_SIZE]; - struct isharp_nldelta_sclip isharp_nldelta_sclip; // ISHARP_NLDELTA_SCLIP - /* 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 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; -}; - -// end of SPL outputs - -// SPL inputs - -// Basic input information -struct basic_in { - enum spl_pixel_format format; // Pixel Format - enum chroma_cositing cositing; /* Chroma Subsampling Offset */ - struct spl_rect src_rect; // Source rect - struct spl_rect dst_rect; // Destination Rect - struct spl_rect clip_rect; // Clip rect - enum spl_rotation_angle rotation; // Rotation - bool horizontal_mirror; // Horizontal mirror - struct { // previous mpc_combine_h - split count - bool use_recout_width_aligned; - union { - int mpc_num_h_slices; - int mpc_recout_width_align; - } num_slices_recout_width; - } num_h_slices_recout_width_align; - int mpc_h_slice_index; // previous mpc_combine_v - split_idx - // Inputs for adaptive scaler - TODO - enum spl_transfer_func_type tf_type; /* Transfer function type */ - enum spl_transfer_func_predefined tf_predefined_type; /* Transfer function predefined type */ - // enum dc_transfer_func_predefined tf; - enum spl_color_space color_space; // Color Space - unsigned int max_luminance; // Max Luminance TODO: Is determined in dc_hw_sequencer.c is_sdr - bool film_grain_applied; // Film Grain Applied // TODO: To check from where to get this? -}; - -// Basic output information -struct basic_out { - struct spl_size output_size; // Output Size - struct spl_rect dst_rect; // Destination Rect - struct spl_rect src_rect; // Source rect - int odm_combine_factor; // deprecated - struct spl_rect odm_slice_rect; // OPP input rect in timing active - enum spl_view_3d view_format; // TODO: View format Check if it is chroma subsampling - bool always_scale; // Is always scale enabled? Required for getting SCL_MODE - int max_downscale_src_width; // Required to get optimal no of taps - bool alpha_en; - bool use_two_pixels_per_container; -}; -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; - int sharpness_level; - struct spl_sharpness_range sharpness_range; -}; -enum linear_light_scaling { // convert it in translation logic - LLS_PREF_DONT_CARE = 0, - LLS_PREF_YES, - LLS_PREF_NO -}; -enum sharpen_policy { - SHARPEN_ALWAYS = 0, - SHARPEN_YUV = 1, - SHARPEN_RGB_FULLSCREEN_YUV = 2, - SHARPEN_FULLSCREEN_ALL = 3 -}; -enum scale_to_sharpness_policy { - NO_SCALE_TO_SHARPNESS_ADJ = 0, - SCALE_TO_SHARPNESS_ADJ_YUV = 1, - SCALE_TO_SHARPNESS_ADJ_ALL = 2 -}; -struct spl_callbacks { - void (*spl_calc_lb_num_partitions) - (bool alpha_en, - const struct spl_scaler_data *scl_data, - enum lb_memory_config lb_config, - int *num_part_y, - int *num_part_c); -}; - -struct spl_debug { - int visual_confirm_base_offset; - int visual_confirm_dpp_offset; - enum scale_to_sharpness_policy scale_to_sharpness_policy; -}; - -struct spl_in { - struct basic_out basic_out; - struct basic_in basic_in; - // Basic slice information - int odm_slice_index; // ODM Slice Index using get_odm_split_index - struct spl_taps scaling_quality; // Explicit Scaling Quality - struct spl_callbacks callbacks; - // Inputs for isharp and EASF - struct adaptive_sharpness adaptive_sharpness; // Adaptive Sharpness - enum linear_light_scaling lls_pref; // Linear Light Scaling - bool prefer_easf; - bool disable_easf; - struct spl_debug debug; - bool is_fullscreen; - bool is_hdr_on; - int h_active; - int v_active; - int sdr_white_level_nits; - enum sharpen_policy sharpen_policy; -}; -// end of SPL inputs - -#endif /* __DC_SPL_TYPES_H__ */ 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 deleted file mode 100644 index be2f34d034c5..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.c +++ /dev/null @@ -1,151 +0,0 @@ -// 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 deleted file mode 100644 index cdc4e107b9de..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.h +++ /dev/null @@ -1,29 +0,0 @@ -/* 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 deleted file mode 100644 index a6f6132df241..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/spl_debug.h +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -/* Copyright 2024 Advanced Micro Devices, Inc. */ - -#ifndef SPL_DEBUG_H -#define SPL_DEBUG_H - -#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB) -#define SPL_ASSERT_CRITICAL(expr) do { \ - if (WARN_ON(!(expr))) { \ - kgdb_breakpoint(); \ - } \ -} while (0) -#else -#define SPL_ASSERT_CRITICAL(expr) do { \ - if (WARN_ON(!(expr))) { \ - ; \ - } \ -} while (0) -#endif /* CONFIG_HAVE_KGDB || CONFIG_KGDB */ - -#if defined(CONFIG_DEBUG_KERNEL_DC) -#define SPL_ASSERT(expr) SPL_ASSERT_CRITICAL(expr) -#else -#define SPL_ASSERT(expr) WARN_ON(!(expr)) -#endif /* CONFIG_DEBUG_KERNEL_DC */ - -#define SPL_BREAK_TO_DEBUGGER() SPL_ASSERT(0) - -#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 deleted file mode 100644 index 131f1e3949d3..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.c +++ /dev/null @@ -1,497 +0,0 @@ -// 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 spl_complete_integer_division_u64( - unsigned long long dividend, - unsigned long long divisor, - unsigned long long *remainder) -{ - unsigned long long result; - - SPL_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 = spl_complete_integer_division_u64( - arg1_value, arg2_value, &remainder); - - SPL_ASSERT(res_value <= (unsigned long long)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; - - SPL_ASSERT(res_value <= (unsigned long long)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; - - SPL_ASSERT(res.value <= (long long)LONG_MAX); - - res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART; - - tmp = arg1_int * arg2_fra; - - SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); - - res.value += tmp; - - tmp = arg2_int * arg1_fra; - - SPL_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); - - SPL_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; - - SPL_ASSERT(res.value <= (long long)LONG_MAX); - - res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART; - - tmp = arg_int * arg_fra; - - SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); - - res.value += tmp; - - SPL_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); - - SPL_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 - */ - - SPL_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 spl_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 */ - - SPL_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)); - - SPL_ASSERT(m != 0); - - SPL_ASSERT(spl_fixpt_lt( - spl_fixpt_abs(r), - spl_fixpt_one)); - - if (m > 0) - return spl_fixpt_shl( - spl_fixed31_32_exp_from_taylor_series(r), - (unsigned char)m); - else - return spl_fixpt_div_int( - spl_fixed31_32_exp_from_taylor_series(r), - 1LL << -m); - } else if (arg.value != 0) - return spl_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; - - SPL_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 spl_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 spl_clamp_ux_dy( - long long value, - unsigned int integer_bits, - unsigned int fractional_bits, - unsigned int min_clamp) -{ - unsigned int truncated_val = spl_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 spl_ux_dy(arg.value, 4, 19); -} - -unsigned int spl_fixpt_u3d19(struct spl_fixed31_32 arg) -{ - return spl_ux_dy(arg.value, 3, 19); -} - -unsigned int spl_fixpt_u2d19(struct spl_fixed31_32 arg) -{ - return spl_ux_dy(arg.value, 2, 19); -} - -unsigned int spl_fixpt_u0d19(struct spl_fixed31_32 arg) -{ - return spl_ux_dy(arg.value, 0, 19); -} - -unsigned int spl_fixpt_clamp_u0d14(struct spl_fixed31_32 arg) -{ - return spl_clamp_ux_dy(arg.value, 0, 14, 1); -} - -unsigned int spl_fixpt_clamp_u0d10(struct spl_fixed31_32 arg) -{ - return spl_clamp_ux_dy(arg.value, 0, 10, 1); -} - -int spl_fixpt_s4d19(struct spl_fixed31_32 arg) -{ - if (arg.value < 0) - return -(int)spl_ux_dy(spl_fixpt_abs(arg).value, 4, 19); - else - return spl_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 deleted file mode 100644 index ed2647f9a099..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.h +++ /dev/null @@ -1,522 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -/* Copyright 2024 Advanced Micro Devices, Inc. */ - -#ifndef __SPL_FIXED31_32_H__ -#define __SPL_FIXED31_32_H__ - -#include "spl_debug.h" -#include "spl_os_types.h" // swap - -#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) -{ - SPL_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; - - SPL_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; - - SPL_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; - - SPL_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; - - SPL_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) { - SPL_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 deleted file mode 100644 index 2e6ba71960ac..000000000000 --- a/drivers/gpu/drm/amd/display/dc/spl/spl_os_types.h +++ /dev/null @@ -1,56 +0,0 @@ -/* 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 "spl_debug.h" - -#include -#include -#include -#include -#include -#include - -/* - * - * general debug capabilities - * - */ - -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/dc/sspl/Makefile b/drivers/gpu/drm/amd/display/dc/sspl/Makefile new file mode 100644 index 000000000000..5e3e4aa13820 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/Makefile @@ -0,0 +1,33 @@ +# +# Copyright 2017 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. +# +# +# 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_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/sspl/,$(SPL)) + +AMD_DISPLAY_FILES += $(AMD_DAL_SPL) + + + diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c new file mode 100644 index 000000000000..38a9a0d68058 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c @@ -0,0 +1,1874 @@ +// SPDX-License-Identifier: MIT +// +// Copyright 2024 Advanced Micro Devices, Inc. + +#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) (spl_fixpt_u2d19(ratio) == (1 << 19)) +#define MIN_VIEWPORT_SIZE 12 + +static bool spl_is_yuv420(enum spl_pixel_format format) +{ + 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; +} + +static bool spl_is_video_format(enum spl_pixel_format format) +{ + if (format >= SPL_PIXEL_FORMAT_VIDEO_BEGIN + && format <= SPL_PIXEL_FORMAT_VIDEO_END) + return true; + else + return false; +} + +static bool spl_is_subsampled_format(enum spl_pixel_format format) +{ + if (format >= SPL_PIXEL_FORMAT_SUBSAMPLED_BEGIN + && format <= SPL_PIXEL_FORMAT_SUBSAMPLED_END) + return true; + else + return false; +} + +static struct spl_rect intersect_rec(const struct spl_rect *r0, const struct spl_rect *r1) +{ + struct spl_rect rec; + int r0_x_end = r0->x + r0->width; + int r1_x_end = r1->x + r1->width; + int r0_y_end = r0->y + r0->height; + int r1_y_end = r1->y + r1->height; + + rec.x = r0->x > r1->x ? r0->x : r1->x; + rec.width = r0_x_end > r1_x_end ? r1_x_end - rec.x : r0_x_end - rec.x; + rec.y = r0->y > r1->y ? r0->y : r1->y; + rec.height = r0_y_end > r1_y_end ? r1_y_end - rec.y : r0_y_end - rec.y; + + /* in case that there is no intersection */ + if (rec.width < 0 || rec.height < 0) + memset(&rec, 0, sizeof(rec)); + + return rec; +} + +static struct spl_rect shift_rec(const struct spl_rect *rec_in, int x, int y) +{ + struct spl_rect rec_out = *rec_in; + + rec_out.x += x; + rec_out.y += y; + + return rec_out; +} + +static struct spl_rect calculate_plane_rec_in_timing_active( + struct spl_in *spl_in, + const struct spl_rect *rec_in) +{ + /* + * The following diagram shows an example where we map a 1920x1200 + * desktop to a 2560x1440 timing with a plane rect in the middle + * of the screen. To map a plane rect from Stream Source to Timing + * Active space, we first multiply stream scaling ratios (i.e 2304/1920 + * horizontal and 1440/1200 vertical) to the plane's x and y, then + * we add stream destination offsets (i.e 128 horizontal, 0 vertical). + * This will give us a plane rect's position in Timing Active. However + * we have to remove the fractional. The rule is that we find left/right + * and top/bottom positions and round the value to the adjacent integer. + * + * Stream Source Space + * ------------ + * __________________________________________________ + * |Stream Source (1920 x 1200) ^ | + * | y | + * | <------- w --------|> | + * | __________________V | + * |<-- x -->|Plane//////////////| ^ | + * | |(pre scale)////////| | | + * | |///////////////////| | | + * | |///////////////////| h | + * | |///////////////////| | | + * | |///////////////////| | | + * | |///////////////////| V | + * | | + * | | + * |__________________________________________________| + * + * + * Timing Active Space + * --------------------------------- + * + * Timing Active (2560 x 1440) + * __________________________________________________ + * |*****| Stteam Destination (2304 x 1440) |*****| + * |*****| |*****| + * |<128>| |*****| + * |*****| __________________ |*****| + * |*****| |Plane/////////////| |*****| + * |*****| |(post scale)//////| |*****| + * |*****| |//////////////////| |*****| + * |*****| |//////////////////| |*****| + * |*****| |//////////////////| |*****| + * |*****| |//////////////////| |*****| + * |*****| |*****| + * |*****| |*****| + * |*****| |*****| + * |*****|______________________________________|*****| + * + * So the resulting formulas are shown below: + * + * recout_x = 128 + round(plane_x * 2304 / 1920) + * recout_w = 128 + round((plane_x + plane_w) * 2304 / 1920) - recout_x + * recout_y = 0 + round(plane_y * 1440 / 1200) + * recout_h = 0 + round((plane_y + plane_h) * 1440 / 1200) - recout_y + * + * NOTE: fixed point division is not error free. To reduce errors + * introduced by fixed point division, we divide only after + * multiplication is complete. + */ + 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 spl_fixed31_32 temp; + + + temp = spl_fixpt_from_fraction(rec_in->x * (long long)stream_dst->width, + stream_src->width); + rec_out.x = stream_dst->x + spl_fixpt_round(temp); + + 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 + spl_fixpt_round(temp) - rec_out.x; + + temp = spl_fixpt_from_fraction(rec_in->y * (long long)stream_dst->height, + stream_src->height); + rec_out.y = stream_dst->y + spl_fixpt_round(temp); + + 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 + spl_fixpt_round(temp) - rec_out.y; + + return rec_out; +} + +static struct spl_rect calculate_mpc_slice_in_timing_active( + struct spl_in *spl_in, + struct spl_rect *plane_clip_rec) +{ + bool use_recout_width_aligned = + spl_in->basic_in.num_h_slices_recout_width_align.use_recout_width_aligned; + int mpc_slice_count = + spl_in->basic_in.num_h_slices_recout_width_align.num_slices_recout_width.mpc_num_h_slices; + int recout_width_align = + spl_in->basic_in.num_h_slices_recout_width_align.num_slices_recout_width.mpc_recout_width_align; + int mpc_slice_idx = spl_in->basic_in.mpc_h_slice_index; + int epimo = mpc_slice_count - plane_clip_rec->width % mpc_slice_count - 1; + struct spl_rect mpc_rec; + + if (use_recout_width_aligned) { + mpc_rec.width = recout_width_align; + if ((mpc_rec.width * (mpc_slice_idx + 1)) > plane_clip_rec->width) { + mpc_rec.width = plane_clip_rec->width % recout_width_align; + mpc_rec.x = plane_clip_rec->x + recout_width_align * mpc_slice_idx; + } else + 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; + + } else { + mpc_rec.width = plane_clip_rec->width / mpc_slice_count; + 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; + } + SPL_ASSERT(mpc_slice_count == 1 || + spl_in->basic_out.view_format != SPL_VIEW_3D_SIDE_BY_SIDE || + mpc_rec.width % 2 == 0); + + /* extra pixels in the division remainder need to go to pipes after + * the extra pixel index minus one(epimo) defined here as: + */ + if (mpc_slice_idx > epimo) { + mpc_rec.x += mpc_slice_idx - epimo - 1; + mpc_rec.width += 1; + } + + if (spl_in->basic_out.view_format == SPL_VIEW_3D_TOP_AND_BOTTOM) { + SPL_ASSERT(mpc_rec.height % 2 == 0); + mpc_rec.height /= 2; + } + return mpc_rec; +} + +static struct spl_rect calculate_odm_slice_in_timing_active(struct spl_in *spl_in) +{ + int odm_slice_count = spl_in->basic_out.odm_combine_factor; + int odm_slice_idx = spl_in->odm_slice_index; + bool is_last_odm_slice = (odm_slice_idx + 1) == odm_slice_count; + int h_active = spl_in->basic_out.output_size.width; + int v_active = spl_in->basic_out.output_size.height; + int odm_slice_width; + struct spl_rect odm_rec; + + if (spl_in->basic_out.odm_combine_factor > 0) { + odm_slice_width = h_active / odm_slice_count; + /* + * deprecated, caller must pass in odm slice rect i.e OPP input + * rect in timing active for the new interface. + */ + if (spl_in->basic_out.use_two_pixels_per_container && (odm_slice_width % 2)) + odm_slice_width++; + + odm_rec.x = odm_slice_width * odm_slice_idx; + odm_rec.width = is_last_odm_slice ? + /* last slice width is the reminder of h_active */ + h_active - odm_slice_width * (odm_slice_count - 1) : + /* odm slice width is the floor of h_active / count */ + odm_slice_width; + odm_rec.y = 0; + odm_rec.height = v_active; + + return odm_rec; + } + + return spl_in->basic_out.odm_slice_rect; +} + +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 + * Source Space. Stream Source is the destination where all planes are + * blended (i.e. positioned, scaled and overlaid). It is a canvas where + * all planes associated with the current stream are drawn together. + * After Stream Source is completed, we will further scale and + * reposition the entire canvas of the stream source to Stream + * Destination in Timing Active Space. This could be due to display + * overscan adjustment where we will need to rescale and reposition all + * the planes so they can fit into a TV with overscan or downscale + * upscale features such as GPU scaling or VSR. + * + * This two step blending is a virtual procedure in software. In + * hardware there is no such thing as Stream Source. all planes are + * blended once in Timing Active Space. Software virtualizes a Stream + * Source space to decouple the math complicity so scaling param + * calculation focuses on one step at a time. + * + * In the following two diagrams, user applied 10% overscan adjustment + * so the Stream Source needs to be scaled down a little before mapping + * to Timing Active Space. As a result the Plane Clip is also scaled + * down by the same ratio, Plane Clip position (i.e. x and y) with + * respect to Stream Source is also scaled down. To map it in Timing + * Active Space additional x and y offsets from Stream Destination are + * added to Plane Clip as well. + * + * Stream Source Space + * ------------ + * __________________________________________________ + * |Stream Source (3840 x 2160) ^ | + * | y | + * | | | + * | __________________V | + * |<-- x -->|Plane Clip/////////| | + * | |(pre scale)////////| | + * | |///////////////////| | + * | |///////////////////| | + * | |///////////////////| | + * | |///////////////////| | + * | |///////////////////| | + * | | + * | | + * |__________________________________________________| + * + * + * Timing Active Space (3840 x 2160) + * --------------------------------- + * + * Timing Active + * __________________________________________________ + * | y_____________________________________________ | + * |x |Stream Destination (3456 x 1944) | | + * | | | | + * | | __________________ | | + * | | |Plane Clip////////| | | + * | | |(post scale)//////| | | + * | | |//////////////////| | | + * | | |//////////////////| | | + * | | |//////////////////| | | + * | | |//////////////////| | | + * | | | | + * | | | | + * | |____________________________________________| | + * |__________________________________________________| + * + * + * In Timing Active Space a plane clip could be further sliced into + * pieces called MPC slices. Each Pipe Context is responsible for + * processing only one MPC slice so the plane processing workload can be + * distributed to multiple DPP Pipes. MPC slices could be blended + * together to a single ODM slice. Each ODM slice is responsible for + * processing a portion of Timing Active divided horizontally so the + * output pixel processing workload can be distributed to multiple OPP + * pipes. All ODM slices are mapped together in ODM block so all MPC + * slices belong to different ODM slices could be pieced together to + * form a single image in Timing Active. MPC slices must belong to + * single ODM slice. If an MPC slice goes across ODM slice boundary, it + * needs to be divided into two MPC slices one for each ODM slice. + * + * In the following diagram the output pixel processing workload is + * divided horizontally into two ODM slices one for each OPP blend tree. + * OPP0 blend tree is responsible for processing left half of Timing + * Active, while OPP2 blend tree is responsible for processing right + * half. + * + * The plane has two MPC slices. However since the right MPC slice goes + * across ODM boundary, two DPP pipes are needed one for each OPP blend + * tree. (i.e. DPP1 for OPP0 blend tree and DPP2 for OPP2 blend tree). + * + * Assuming that we have a Pipe Context associated with OPP0 and DPP1 + * working on processing the plane in the diagram. We want to know the + * width and height of the shaded rectangle and its relative position + * with respect to the ODM slice0. This is called the recout of the pipe + * context. + * + * Planes can be at arbitrary size and position and there could be an + * arbitrary number of MPC and ODM slices. The algorithm needs to take + * all scenarios into account. + * + * Timing Active Space (3840 x 2160) + * --------------------------------- + * + * Timing Active + * __________________________________________________ + * |OPP0(ODM slice0)^ |OPP2(ODM slice1) | + * | y | | + * | | <- w -> | + * | _____V________|____ | + * | |DPP0 ^ |DPP1 |DPP2| | + * |<------ x |-----|->|/////| | | + * | | | |/////| | | + * | | h |/////| | | + * | | | |/////| | | + * | |_____V__|/////|____| | + * | | | + * | | | + * | | | + * |_________________________|________________________| + * + * + */ + struct spl_rect plane_clip; + struct spl_rect mpc_slice_of_plane_clip; + struct spl_rect odm_slice; + struct spl_rect overlapping_area; + + plane_clip = calculate_plane_rec_in_timing_active(spl_in, + &spl_in->basic_in.clip_rect); + /* guard plane clip from drawing beyond stream dst here */ + plane_clip = intersect_rec(&plane_clip, + &spl_in->basic_out.dst_rect); + mpc_slice_of_plane_clip = calculate_mpc_slice_in_timing_active( + spl_in, &plane_clip); + odm_slice = calculate_odm_slice_in_timing_active(spl_in); + overlapping_area = intersect_rec(&mpc_slice_of_plane_clip, &odm_slice); + + if (overlapping_area.height > 0 && + overlapping_area.width > 0) { + /* shift the overlapping area so it is with respect to current + * ODM slice's position + */ + spl_scratch->scl_data.recout = shift_rec( + &overlapping_area, + -odm_slice.x, -odm_slice.y); + spl_scratch->scl_data.recout.height -= + spl_in->debug.visual_confirm_base_offset; + spl_scratch->scl_data.recout.height -= + spl_in->debug.visual_confirm_dpp_offset; + } else + /* if there is no overlap, zero recout */ + 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_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; + const int out_w = spl_in->basic_out.dst_rect.width; + const int out_h = spl_in->basic_out.dst_rect.height; + struct spl_rect surf_src = spl_in->basic_in.src_rect; + + /*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) + spl_swap(surf_src.height, surf_src.width); + + spl_scratch->scl_data.ratios.horz = spl_fixpt_from_fraction( + surf_src.width, + spl_in->basic_in.dst_rect.width); + 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_scratch->scl_data.ratios.horz.value *= 2; + else if (spl_in->basic_out.view_format == SPL_VIEW_3D_TOP_AND_BOTTOM) + spl_scratch->scl_data.ratios.vert.value *= 2; + + 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_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_is_yuv420(spl_in->basic_in.format)) { + spl_scratch->scl_data.ratios.horz_c.value /= 2; + spl_scratch->scl_data.ratios.vert_c.value /= 2; + } + 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_scratch *spl_scratch) +{ + 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) { + 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, + bool *flip_vert_scan_dir, + bool *flip_horz_scan_dir) +{ + *orthogonal_rotation = false; + *flip_vert_scan_dir = false; + *flip_horz_scan_dir = false; + if (rotation == SPL_ROTATION_ANGLE_180) { + *flip_vert_scan_dir = true; + *flip_horz_scan_dir = true; + } else if (rotation == SPL_ROTATION_ANGLE_90) { + *orthogonal_rotation = true; + *flip_horz_scan_dir = true; + } else if (rotation == SPL_ROTATION_ANGLE_270) { + *orthogonal_rotation = true; + *flip_vert_scan_dir = true; + } + + 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. + */ +static void spl_calculate_init_and_vp(bool flip_scan_dir, + int recout_offset_within_recout_full, + int recout_size, + int src_size, + int taps, + struct spl_fixed31_32 ratio, + struct spl_fixed31_32 init_adj, + struct spl_fixed31_32 *init, + int *vp_offset, + int *vp_size) +{ + struct spl_fixed31_32 temp; + int int_part; + + /* + * First of the taps starts sampling pixel number corresponding to recout + * pixel 1. Next recout pixel samples int part of and so on. + * All following calculations are based on this logic. + * + * Init calculated according to formula: + * init = (scaling_ratio + number_of_taps + 1) / 2 + * init_bot = init + scaling_ratio + * to get pixel perfect combine add the fraction from calculating vp offset + */ + temp = spl_fixpt_mul_int(ratio, recout_offset_within_recout_full); + *vp_offset = spl_fixpt_floor(temp); + temp.value &= 0xffffffff; + *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 = 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 = 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 = 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; + + /* We did all the math assuming we are scanning same direction as display does, + * however mirror/rotation changes how vp scans vs how it is offset. If scan direction + * is flipped we simply need to calculate offset from the other side of plane. + * Note that outside of viewport all scaling hardware works in recout space. + */ + if (flip_scan_dir) + *vp_offset = src_size - *vp_offset - *vp_size; +} + +/*Calculate inits and viewport */ +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; + struct spl_rect recout_clip_in_active_timing; + struct spl_rect recout_clip_in_recout_dst; + struct spl_rect overlap_in_active_timing; + struct spl_rect odm_slice = calculate_odm_slice_in_timing_active(spl_in); + int vpc_div = spl_is_subsampled_format(spl_in->basic_in.format) ? 2 : 1; + bool orthogonal_rotation, flip_vert_scan_dir, flip_horz_scan_dir; + 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_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, + &recout_dst_in_active_timing); + if (overlap_in_active_timing.width > 0 && + overlap_in_active_timing.height > 0) + recout_clip_in_recout_dst = shift_rec(&overlap_in_active_timing, + -recout_dst_in_active_timing.x, + -recout_dst_in_active_timing.y); + else + memset(&recout_clip_in_recout_dst, 0, sizeof(struct spl_rect)); + /* + * Work in recout rotation since that requires less transformations + */ + spl_get_vp_scan_direction( + spl_in->basic_in.rotation, + spl_in->basic_in.horizontal_mirror, + &orthogonal_rotation, + &flip_vert_scan_dir, + &flip_horz_scan_dir); + + if (spl_is_subsampled_format(spl_in->basic_in.format)) { + /* this gives the direction of the cositing (negative will move + * left, right otherwise) + */ + int sign = 1; + + switch (spl_in->basic_in.cositing) { + + case CHROMA_COSITING_TOPLEFT: + init_adj_h = spl_fixpt_from_fraction(sign, 4); + init_adj_v = spl_fixpt_from_fraction(sign, 4); + break; + case CHROMA_COSITING_LEFT: + init_adj_h = spl_fixpt_from_fraction(sign, 4); + init_adj_v = spl_fixpt_zero; + break; + case CHROMA_COSITING_NONE: + default: + init_adj_h = spl_fixpt_zero; + init_adj_v = spl_fixpt_zero; + break; + } + } + + if (orthogonal_rotation) { + spl_swap(src.width, src.height); + spl_swap(flip_vert_scan_dir, flip_horz_scan_dir); + spl_swap(init_adj_h, init_adj_v); + } + + spl_calculate_init_and_vp( + flip_horz_scan_dir, + recout_clip_in_recout_dst.x, + spl_scratch->scl_data.recout.width, + src.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_scratch->scl_data.recout.width, + src.width / vpc_div, + spl_scratch->scl_data.taps.h_taps_c, + spl_scratch->scl_data.ratios.horz_c, + init_adj_h, + &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_scratch->scl_data.recout.height, + src.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_scratch->scl_data.recout.height, + src.height / vpc_div, + spl_scratch->scl_data.taps.v_taps_c, + spl_scratch->scl_data.ratios.vert_c, + init_adj_v, + &spl_scratch->scl_data.inits.v_c, + &spl_scratch->scl_data.viewport_c.y, + &spl_scratch->scl_data.viewport_c.height); + if (orthogonal_rotation) { + 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_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) +{ + /* + * Handle side by side and top bottom 3d recout offsets after vp calculation + * since 3d is special and needs to calculate vp as if there is no recout offset + * This may break with rotation, good thing we aren't mixing hw rotation and 3d + */ + if (spl_in->basic_in.mpc_h_slice_index) { + 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) + recout->y += recout->height; + else if (spl_in->basic_out.view_format == SPL_VIEW_3D_SIDE_BY_SIDE) + recout->x += recout->width; + } +} + +static void spl_clamp_viewport(struct spl_rect *viewport) +{ + /* Clamp minimum viewport size */ + if (viewport->height < MIN_VIEWPORT_SIZE) + viewport->height = MIN_VIEWPORT_SIZE; + if (viewport->width < MIN_VIEWPORT_SIZE) + viewport->width = MIN_VIEWPORT_SIZE; +} + +static enum scl_mode spl_get_dscl_mode(const struct spl_in *spl_in, + const struct spl_scaler_data *data, + bool enable_isharp, bool enable_easf) +{ + 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 + && !enable_isharp) + return SCL_MODE_SCALING_444_BYPASS; + + if (!spl_is_subsampled_format(pixel_format)) { + if (spl_is_video_format(pixel_format)) + return SCL_MODE_SCALING_444_YCBCR_ENABLE; + else + return SCL_MODE_SCALING_444_RGB_ENABLE; + } + + /* + * Bypass YUV if Y is 1:1 with no ISHARP + * Do not bypass UV at 1:1 for cositing to be applied + */ + if (!enable_isharp) { + if (data->ratios.horz.value == one && data->ratios.vert.value == one) + return SCL_MODE_SCALING_420_LUMA_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_video_format(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; +} + +/* Check if video is in fullscreen mode */ +static bool spl_is_video_fullscreen(struct spl_in *spl_in) +{ + if (spl_is_video_format(spl_in->basic_in.format) && spl_in->is_fullscreen) + return true; + return false; +} + +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; + bool fullscreen = spl_is_video_fullscreen(spl_in); + + /* 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 RGB and YUV (NV12/P010) + * surfaces based on policy setting + */ + if (!spl_is_video_format(spl_in->basic_in.format) && + (spl_in->sharpen_policy == SHARPEN_YUV)) + return enable_isharp; + else if ((spl_is_video_format(spl_in->basic_in.format) && !fullscreen) && + (spl_in->sharpen_policy == SHARPEN_RGB_FULLSCREEN_YUV)) + return enable_isharp; + else if (!spl_in->is_fullscreen && + spl_in->sharpen_policy == SHARPEN_FULLSCREEN_ALL) + return enable_isharp; + + /* + * 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 number of tap with adaptive scaling off */ +static void spl_get_taps_non_adaptive_scaler( + struct spl_scratch *spl_scratch, const struct spl_taps *in_taps) +{ + 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(2 * spl_fixpt_ceil( + spl_scratch->scl_data.ratios.vert), 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(2 * spl_fixpt_ceil( + spl_scratch->scl_data.ratios.vert_c), 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_scratch->scl_data.taps.h_taps_c = in_taps->h_taps_c; + + if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz)) + spl_scratch->scl_data.taps.h_taps = 1; + if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert)) + 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; + +} + +/* 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_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; + bool is_subsampled = spl_is_subsampled_format(spl_in->basic_in.format); + + if (spl_scratch->scl_data.viewport.width > spl_scratch->scl_data.h_active && + max_downscale_src_width != 0 && + spl_scratch->scl_data.viewport.width > max_downscale_src_width) { + spl_get_taps_non_adaptive_scaler(spl_scratch, in_taps); + *enable_easf_v = false; + *enable_easf_h = false; + *enable_isharp = false; + return false; + } + + /* Disable adaptive scaler and sharpener when integer scaling is enabled */ + if (spl_in->scaling_quality.integer_scaling) { + spl_get_taps_non_adaptive_scaler(spl_scratch, in_taps); + *enable_easf_v = false; + *enable_easf_h = false; + *enable_isharp = false; + return true; + } + + /* 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 (skip_easf) + spl_get_taps_non_adaptive_scaler(spl_scratch, in_taps); + else { + if (spl_is_video_format(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 = 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_is_yuv420(spl_in->basic_in.format)) + lb_config = LB_MEMORY_CONFIG_3; + else + lb_config = LB_MEMORY_CONFIG_0; + // Determine max vtap support by calculating how much line buffer can fit + spl_in->callbacks.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 (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 (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; + + if (max_taps_y < min_taps_y) + return false; + else if (max_taps_c < min_taps_c) + return false; + + 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_video_format(spl_in->basic_in.format)) { + if (spl_scratch->scl_data.taps.h_taps <= 4) { + *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) && + (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 + + /* Sharpener requires scaler to be enabled, including for 1:1 + * Check if ISHARP can be enabled + * If ISHARP is not enabled, set taps to 1 if ratio is 1:1 + * except for chroma taps. Keep previous taps so it can + * handle cositing + */ + + *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) && !is_subsampled) + spl_scratch->scl_data.taps.h_taps_c = 1; + + if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert_c) && !is_subsampled) + 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))) + spl_scratch->scl_data.taps.h_taps = 1; + + if ((!*enable_easf_v) && + (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert))) + spl_scratch->scl_data.taps.v_taps = 1; + + if ((!*enable_easf_h) && !is_subsampled && + (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz_c))) + spl_scratch->scl_data.taps.h_taps_c = 1; + + if ((!*enable_easf_v) && !is_subsampled && + (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) +{ + bool ycbcr = spl_is_video_format(format); + if (ycbcr) { + scl_black_color->offset_rgb_y = BLACK_OFFSET_RGB_Y; + scl_black_color->offset_rgb_cbcr = BLACK_OFFSET_CBCR; + } else { + scl_black_color->offset_rgb_y = 0x0; + scl_black_color->offset_rgb_cbcr = 0x0; + } +} + +static void spl_set_manual_ratio_init_data(struct dscl_prog_data *dscl_prog_data, + const struct spl_scaler_data *scl_data) +{ + struct spl_fixed31_32 bot; + + 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 = + spl_fixpt_u0d19(scl_data->inits.h) << 5; + dscl_prog_data->init.h_filter_init_int = + spl_fixpt_floor(scl_data->inits.h); + dscl_prog_data->init.h_filter_init_frac_c = + spl_fixpt_u0d19(scl_data->inits.h_c) << 5; + dscl_prog_data->init.h_filter_init_int_c = + spl_fixpt_floor(scl_data->inits.h_c); + dscl_prog_data->init.v_filter_init_frac = + spl_fixpt_u0d19(scl_data->inits.v) << 5; + dscl_prog_data->init.v_filter_init_int = + spl_fixpt_floor(scl_data->inits.v); + dscl_prog_data->init.v_filter_init_frac_c = + spl_fixpt_u0d19(scl_data->inits.v_c) << 5; + dscl_prog_data->init.v_filter_init_int_c = + 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, + const struct spl_scaler_data *scl_data) +{ + dscl_prog_data->taps.v_taps = scl_data->taps.v_taps - 1; + dscl_prog_data->taps.h_taps = scl_data->taps.h_taps - 1; + 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; +} + +/* 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_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_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_scratch->scl_data.recout; + // Set values for MPC Size + 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, enable_isharp, + enable_easf); + + // SCL_BLACK_COLOR + spl_set_black_color_data(spl_in->basic_in.format, scl_black_color); + + /* Manually calculate scale ratio and init values */ + spl_set_manual_ratio_init_data(dscl_prog_data, data); + + // Set HTaps/VTaps + spl_set_taps_data(dscl_prog_data, data); + // Set viewport + dscl_prog_data->viewport = spl_scratch->scl_data.viewport; + // Set viewport_c + dscl_prog_data->viewport_c = spl_scratch->scl_data.viewport_c; + // Set filters data + spl_set_filters_data(dscl_prog_data, data, enable_easf_v, enable_easf_h); +} + +/* Calculate C0-C3 coefficients based on HDR_mult */ +static void spl_calculate_c0_c3_hdr(struct dscl_prog_data *dscl_prog_data, uint32_t sdr_white_level_nits) +{ + 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; + uint32_t hdr_multx100_int; + + if ((sdr_white_level_nits >= 80) && (sdr_white_level_nits <= 480)) + hdr_multx100_int = sdr_white_level_nits * 100 / 80; + else + hdr_multx100_int = 100; /* default for 80 nits otherwise */ + + hdr_mult = spl_fixpt_from_fraction((long long)hdr_multx100_int, 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 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 sdr_white_level_nits) +{ + 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 = 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 + /* 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 = + 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 = + 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 = + 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 = + 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 = + 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 = + 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 = + 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 = + 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 = + 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 = + 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 + 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 + dscl_prog_data->easf_v_bf3_pwl_in_set1 = + 0x0B37; // FP0.6.6, BF3 Input value PWL Segment 1 (0.0078125 * 125^3) + dscl_prog_data->easf_v_bf3_pwl_base_set1 = 62; // S0.6, BF3 Base PWL Segment 1 + dscl_prog_data->easf_v_bf3_pwl_slope_set1 = + 0x13B8; // FP1.6.6, BF3 Slope PWL Segment 1 + dscl_prog_data->easf_v_bf3_pwl_in_set2 = + 0x0BB7; // FP0.6.6, BF3 Input value PWL Segment 2 (0.03125 * 125^3) + dscl_prog_data->easf_v_bf3_pwl_base_set2 = 20; // S0.6, BF3 Base PWL Segment 2 + dscl_prog_data->easf_v_bf3_pwl_slope_set2 = + 0x1356; // FP1.6.6, BF3 Slope PWL Segment 2 + dscl_prog_data->easf_v_bf3_pwl_in_set3 = + 0x0BF7; // FP0.6.6, BF3 Input value PWL Segment 3 (0.0625 * 125^3) + dscl_prog_data->easf_v_bf3_pwl_base_set3 = 0; // S0.6, BF3 Base PWL Segment 3 + dscl_prog_data->easf_v_bf3_pwl_slope_set3 = + 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 = 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 = 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 + dscl_prog_data->easf_v_bf3_pwl_in_set1 = + 0x06C0; // FP0.6.6, BF3 Input value PWL Segment 1 (0.0625) + dscl_prog_data->easf_v_bf3_pwl_base_set1 = 63; // S0.6, BF3 Base PWL Segment 1 + dscl_prog_data->easf_v_bf3_pwl_slope_set1 = 0x1896; // FP1.6.6, BF3 Slope PWL Segment 1 + dscl_prog_data->easf_v_bf3_pwl_in_set2 = + 0x0700; // FP0.6.6, BF3 Input value PWL Segment 2 (0.125) + dscl_prog_data->easf_v_bf3_pwl_base_set2 = 20; // S0.6, BF3 Base PWL Segment 2 + dscl_prog_data->easf_v_bf3_pwl_slope_set2 = 0x1810; // FP1.6.6, BF3 Slope PWL Segment 2 + dscl_prog_data->easf_v_bf3_pwl_in_set3 = + 0x0740; // FP0.6.6, BF3 Input value PWL Segment 3 (0.25) + dscl_prog_data->easf_v_bf3_pwl_base_set3 = 0; // S0.6, BF3 Base PWL Segment 3 + dscl_prog_data->easf_v_bf3_pwl_slope_set3 = + 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 = 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 = 0x41; // S0.6, BF3 Base PWL Segment 5 = -63 + } + } else + dscl_prog_data->easf_v_en = false; + + 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 = 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 + /* 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 = + 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 = + 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 = + 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 = + 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 + 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 + dscl_prog_data->easf_h_bf3_pwl_in_set1 = + 0x0B37; // FP0.6.6, BF3 Input value PWL Segment 1 (0.0078125 * 125^3) + dscl_prog_data->easf_h_bf3_pwl_base_set1 = 62; // S0.6, BF3 Base PWL Segment 1 + dscl_prog_data->easf_h_bf3_pwl_slope_set1 = 0x13B8; // FP1.6.6, BF3 Slope PWL Segment 1 + dscl_prog_data->easf_h_bf3_pwl_in_set2 = + 0x0BB7; // FP0.6.6, BF3 Input value PWL Segment 2 (0.03125 * 125^3) + dscl_prog_data->easf_h_bf3_pwl_base_set2 = 20; // S0.6, BF3 Base PWL Segment 2 + dscl_prog_data->easf_h_bf3_pwl_slope_set2 = 0x1356; // FP1.6.6, BF3 Slope PWL Segment 2 + dscl_prog_data->easf_h_bf3_pwl_in_set3 = + 0x0BF7; // FP0.6.6, BF3 Input value PWL Segment 3 (0.0625 * 125^3) + dscl_prog_data->easf_h_bf3_pwl_base_set3 = 0; // S0.6, BF3 Base PWL Segment 3 + 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 = 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 = 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 + dscl_prog_data->easf_h_bf3_pwl_in_set1 = + 0x06C0; // FP0.6.6, BF3 Input value PWL Segment 1 (0.0625) + dscl_prog_data->easf_h_bf3_pwl_base_set1 = 63; // S0.6, BF3 Base PWL Segment 1 + dscl_prog_data->easf_h_bf3_pwl_slope_set1 = 0x1896; // FP1.6.6, BF3 Slope PWL Segment 1 + dscl_prog_data->easf_h_bf3_pwl_in_set2 = + 0x0700; // FP0.6.6, BF3 Input value PWL Segment 2 (0.125) + dscl_prog_data->easf_h_bf3_pwl_base_set2 = 20; // S0.6, BF3 Base PWL Segment 2 + dscl_prog_data->easf_h_bf3_pwl_slope_set2 = 0x1810; // FP1.6.6, BF3 Slope PWL Segment 2 + dscl_prog_data->easf_h_bf3_pwl_in_set3 = + 0x0740; // FP0.6.6, BF3 Input value PWL Segment 3 (0.25) + dscl_prog_data->easf_h_bf3_pwl_base_set3 = 0; // S0.6, BF3 Base PWL Segment 3 + 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 = 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 = 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 + if ((setup == HDR_L) && (spl_is_rgb8(format))) { + /* Calculate C0-C3 coefficients based on HDR multiplier */ + spl_calculate_c0_c3_hdr(dscl_prog_data, sdr_white_level_nits); + } 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 = + 0x3434; // fp1.5.10, C0 coefficient (LN_BT2020: 0.262695312500000) + dscl_prog_data->easf_matrix_c1 = + 0x396D; // fp1.5.10, C1 coefficient (LN_BT2020: 0.678222656250000) + dscl_prog_data->easf_matrix_c2 = + 0x2B97; // fp1.5.10, C2 coefficient (LN_BT2020: 0.059295654296875) + dscl_prog_data->easf_matrix_c3 = + 0x0; // fp1.5.10, C3 coefficient + } + + if (spl_is_subsampled_format(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, + const struct spl_scaler_data *data) +{ + // ISHARP_NOISEDET_MODE + // 0: 3x5 as VxH + // 1: 4x5 as VxH + // 2: + // 3: 5x5 as VxH + 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, struct spl_fixed31_32 ratio, + enum system_setup setup, enum scale_to_sharpness_policy scale_to_sharpness_policy) +{ + /* Turn off sharpener if not required */ + if (!enable_isharp) { + dscl_prog_data->isharp_en = 0; + return; + } + + spl_build_isharp_1dlut_from_reference_curve(ratio, setup, adp_sharpness, + scale_to_sharpness_policy); + memcpy(dscl_prog_data->isharp_delta, spl_get_pregen_filter_isharp_1D_lut(setup), + sizeof(uint32_t) * ISHARP_LUT_TABLE_SIZE); + dscl_prog_data->sharpness_level = adp_sharpness.sharpness_level; + + dscl_prog_data->isharp_en = 1; // ISHARP_EN + // Set ISHARP_NOISEDET_MODE if htaps = 6-tap + 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 + // Program noise detection gain + dscl_prog_data->isharp_noise_det.pwl_start_in = 3; // ISHARP_NOISEDET_PWL_START_IN + 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) /* 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 + + 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 + } + + // 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 */ + dscl_prog_data->isharp_nldelta_sclip.pivot_p = 0; /* ISHARP_NLDELTA_SCLIP_PIVOT_P */ + dscl_prog_data->isharp_nldelta_sclip.slope_p = 0; /* ISHARP_NLDELTA_SCLIP_SLOPE_P */ + dscl_prog_data->isharp_nldelta_sclip.enable_n = 1; /* ISHARP_NLDELTA_SCLIP_EN_N */ + dscl_prog_data->isharp_nldelta_sclip.pivot_n = 71; /* ISHARP_NLDELTA_SCLIP_PIVOT_N */ + dscl_prog_data->isharp_nldelta_sclip.slope_n = 16; /* ISHARP_NLDELTA_SCLIP_SLOPE_N */ + } else { + dscl_prog_data->isharp_nldelta_sclip.enable_p = 1; /* ISHARP_NLDELTA_SCLIP_EN_P */ + dscl_prog_data->isharp_nldelta_sclip.pivot_p = 70; /* ISHARP_NLDELTA_SCLIP_PIVOT_P */ + dscl_prog_data->isharp_nldelta_sclip.slope_p = 24; /* ISHARP_NLDELTA_SCLIP_SLOPE_P */ + dscl_prog_data->isharp_nldelta_sclip.enable_n = 1; /* ISHARP_NLDELTA_SCLIP_EN_N */ + dscl_prog_data->isharp_nldelta_sclip.pivot_n = 70; /* ISHARP_NLDELTA_SCLIP_PIVOT_N */ + dscl_prog_data->isharp_nldelta_sclip.slope_n = 24; /* ISHARP_NLDELTA_SCLIP_SLOPE_N */ + } + + // Set the values as per lookup table + spl_set_blur_scale_data(dscl_prog_data, data); +} + +/* Calculate recout, scaling ratio, and viewport, then get optimal number of taps */ +static bool spl_calculate_number_of_taps(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) +{ + bool res = false; + + 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_scratch, spl_out); + /* depends on pixel format */ + 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_scratch); + + res = spl_get_optimal_number_of_taps( + spl_in->basic_out.max_downscale_src_width, spl_in, + spl_scratch, &spl_in->scaling_quality, enable_easf_v, + enable_easf_h, enable_isharp); + return res; +} + +/* Calculate scaler parameters */ +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; + 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; + + res = spl_calculate_number_of_taps(spl_in, &spl_scratch, spl_out, + &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_scratch); + // Handle 3d recout + spl_handle_3d_recout(spl_in, &spl_scratch.scl_data.recout); + // Clamp + spl_clamp_viewport(&spl_scratch.scl_data.viewport); + + // Save all calculated parameters in dscl_prog_data structure to program hw registers + spl_set_dscl_prog_data(spl_in, &spl_scratch, spl_out, enable_easf_v, enable_easf_h, enable_isharp); + + if (!res) + return res; + + if (spl_in->lls_pref == LLS_PREF_YES) { + if (spl_in->is_hdr_on) + setup = HDR_L; + else + setup = SDR_L; + } else { + if (spl_in->is_hdr_on) + setup = HDR_NL; + else + setup = SDR_NL; + } + + // Set EASF + 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->sdr_white_level_nits); + + // Set iSHARP + 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, isharp_scale_ratio, setup, + spl_in->debug.scale_to_sharpness_policy); + + return res; +} + +/* External interface to get number of taps only */ +bool spl_get_number_of_taps(struct spl_in *spl_in, struct spl_out *spl_out) +{ + bool res = false; + bool enable_easf_v = false; + bool enable_easf_h = false; + bool enable_isharp = false; + struct spl_scratch spl_scratch; + struct dscl_prog_data *dscl_prog_data = spl_out->dscl_prog_data; + const struct spl_scaler_data *data = &spl_scratch.scl_data; + + res = spl_calculate_number_of_taps(spl_in, &spl_scratch, spl_out, + &enable_easf_v, &enable_easf_h, &enable_isharp); + spl_set_taps_data(dscl_prog_data, data); + return res; +} diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.h new file mode 100644 index 000000000000..02a2d6725ed5 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.h @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +// +// Copyright 2024 Advanced Micro Devices, Inc. + +#ifndef __DC_SPL_H__ +#define __DC_SPL_H__ + +#include "dc_spl_types.h" +#define BLACK_OFFSET_RGB_Y 0x0 +#define BLACK_OFFSET_CBCR 0x8000 + +/* SPL interfaces */ + +bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out); + +bool spl_get_number_of_taps(struct spl_in *spl_in, struct spl_out *spl_out); + +#endif /* __DC_SPL_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_filters.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_filters.c new file mode 100644 index 000000000000..99238644e0a1 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/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/sspl/dc_spl_filters.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_filters.h new file mode 100644 index 000000000000..20439cdbdb10 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/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/sspl/dc_spl_isharp_filters.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c new file mode 100644 index 000000000000..e0572252c640 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c @@ -0,0 +1,757 @@ +// SPDX-License-Identifier: MIT +// +// Copyright 2024 Advanced Micro Devices, Inc. + +#include "spl_debug.h" +#include "dc_spl_filters.h" +#include "dc_spl_isharp_filters.h" + +//======================================== +// Delta Gain 1DLUT +// LUT content is packed as 4-bytes into one DWORD/entry +// A_start = 0.000000 +// A_end = 10.000000 +// A_gain = 2.000000 +// B_start = 11.000000 +// B_end = 86.000000 +// C_start = 40.000000 +// C_end = 64.000000 +//======================================== +static const uint32_t filter_isharp_1D_lut_0[ISHARP_LUT_TABLE_SIZE] = { +0x02010000, +0x0A070503, +0x1614100D, +0x1C1B1918, +0x22211F1E, +0x27262423, +0x2A2A2928, +0x2D2D2C2B, +0x302F2F2E, +0x31313030, +0x31313131, +0x31313131, +0x30303031, +0x292D2F2F, +0x191D2125, +0x050A0F14, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +}; +//======================================== +// Delta Gain 1DLUT +// LUT content is packed as 4-bytes into one DWORD/entry +// A_start = 0.000000 +// A_end = 10.000000 +// A_gain = 0.500000 +// B_start = 11.000000 +// B_end = 127.000000 +// C_start = 96.000000 +// C_end = 127.000000 +//======================================== + +static const uint32_t filter_isharp_1D_lut_0p5x[ISHARP_LUT_TABLE_SIZE] = { +0x00000000, +0x02020101, +0x06050403, +0x07070606, +0x09080808, +0x0A0A0A09, +0x0C0B0B0B, +0x0D0D0C0C, +0x0E0E0D0D, +0x0F0F0E0E, +0x100F0F0F, +0x10101010, +0x11111010, +0x11111111, +0x11111111, +0x11111111, +0x11111111, +0x11111111, +0x11111111, +0x10101111, +0x10101010, +0x0F0F0F10, +0x0E0E0F0F, +0x0D0D0E0E, +0x0C0C0D0D, +0x0B0B0B0C, +0x090A0A0A, +0x08080809, +0x06060707, +0x04050506, +0x02030304, +0x00010102, +}; +//======================================== +// Delta Gain 1DLUT +// LUT content is packed as 4-bytes into one DWORD/entry +// A_start = 0.000000 +// A_end = 10.000000 +// A_gain = 1.000000 +// B_start = 11.000000 +// B_end = 127.000000 +// C_start = 96.000000 +// C_end = 127.000000 +//======================================== +static const uint32_t filter_isharp_1D_lut_1p0x[ISHARP_LUT_TABLE_SIZE] = { +0x01000000, +0x05040302, +0x0B0A0806, +0x0E0E0D0C, +0x1211100F, +0x15141312, +0x17171615, +0x1A191918, +0x1C1B1B1A, +0x1E1D1D1C, +0x1F1F1E1E, +0x2020201F, +0x21212121, +0x22222222, +0x23232222, +0x23232323, +0x23232323, +0x22222323, +0x22222222, +0x21212121, +0x1F202020, +0x1E1E1F1F, +0x1C1D1D1E, +0x1A1B1B1C, +0x1819191A, +0x15161717, +0x12131415, +0x0F101112, +0x0C0D0E0E, +0x08090A0B, +0x04050607, +0x00010203, +}; +//======================================== +// Delta Gain 1DLUT +// LUT content is packed as 4-bytes into one DWORD/entry +// A_start = 0.000000 +// A_end = 10.000000 +// A_gain = 1.500000 +// B_start = 11.000000 +// B_end = 127.000000 +// C_start = 96.000000 +// C_end = 127.000000 +//======================================== +static const uint32_t filter_isharp_1D_lut_1p5x[ISHARP_LUT_TABLE_SIZE] = { +0x01010000, +0x07050402, +0x110F0C0A, +0x16141312, +0x1B191817, +0x1F1E1D1C, +0x23222120, +0x26262524, +0x2A292827, +0x2C2C2B2A, +0x2F2E2E2D, +0x3130302F, +0x32323131, +0x33333332, +0x34343433, +0x34343434, +0x34343434, +0x33343434, +0x32333333, +0x31313232, +0x2F303031, +0x2D2E2E2F, +0x2A2B2C2C, +0x2728292A, +0x24252626, +0x20212223, +0x1C1D1E1F, +0x1718191B, +0x12131416, +0x0C0E0F10, +0x0608090B, +0x00020305 +}; +//======================================== +// Delta Gain 1DLUT +// LUT content is packed as 4-bytes into one DWORD/entry +// A_start = 0.000000 +// A_end = 10.000000 +// A_gain = 2.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_2p0x[ISHARP_LUT_TABLE_SIZE] = { +0x02010000, +0x0A070503, +0x1614100D, +0x1D1B1A18, +0x2322201F, +0x29282625, +0x2F2D2C2B, +0x33323130, +0x38373534, +0x3B3A3938, +0x3E3E3D3C, +0x4140403F, +0x43424241, +0x44444443, +0x45454545, +0x46454545, +0x45454546, +0x45454545, +0x43444444, +0x41424243, +0x3F404041, +0x3C3D3E3E, +0x38393A3B, +0x34353738, +0x30313233, +0x2B2C2D2F, +0x25262829, +0x1F202223, +0x181A1B1D, +0x10121416, +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 +//======================================================== +// gen_scaler_coeffs.m +// 15-Dec-2021 +// 6t_64p_LanczosEd_p_1_p_10qb_ +// 6 +// 64 +// LanczosEd +// S1.10 +//======================================================== +static const uint16_t filter_isharp_wide_6tap_64p[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 +}; +// Blur and scale coefficients +//======================================================== +// gen_BlurScale_coeffs.m +// 25-Apr-2022 +// 4 +// 64 +// Blur & Scale LPF +// S1.10 +//======================================================== +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, +0x0000, 0x00D0, 0x0235, 0x00FA, 0x0001, 0x0000, +0x0000, 0x00C9, 0x0234, 0x0101, 0x0002, 0x0000, +0x0000, 0x00C2, 0x0233, 0x0108, 0x0003, 0x0000, +0x0000, 0x00BB, 0x0232, 0x0110, 0x0003, 0x0000, +0x0000, 0x00B5, 0x0230, 0x0117, 0x0004, 0x0000, +0x0000, 0x00AE, 0x022E, 0x011F, 0x0005, 0x0000, +0x0000, 0x00A8, 0x022C, 0x0126, 0x0006, 0x0000, +0x0000, 0x00A2, 0x022A, 0x012D, 0x0007, 0x0000, +0x0000, 0x009C, 0x0228, 0x0134, 0x0008, 0x0000, +0x0000, 0x0096, 0x0225, 0x013C, 0x0009, 0x0000, +0x0000, 0x0090, 0x0222, 0x0143, 0x000B, 0x0000, +0x0000, 0x008A, 0x021F, 0x014B, 0x000C, 0x0000, +0x0000, 0x0085, 0x021C, 0x0151, 0x000E, 0x0000, +0x0000, 0x007F, 0x0218, 0x015A, 0x000F, 0x0000, +0x0000, 0x007A, 0x0215, 0x0160, 0x0011, 0x0000, +0x0000, 0x0074, 0x0211, 0x0168, 0x0013, 0x0000, +0x0000, 0x006F, 0x020D, 0x016F, 0x0015, 0x0000, +0x0000, 0x006A, 0x0209, 0x0176, 0x0017, 0x0000, +0x0000, 0x0065, 0x0204, 0x017E, 0x0019, 0x0000, +0x0000, 0x0060, 0x0200, 0x0185, 0x001B, 0x0000, +0x0000, 0x005C, 0x01FB, 0x018C, 0x001D, 0x0000, +0x0000, 0x0057, 0x01F6, 0x0193, 0x0020, 0x0000, +0x0000, 0x0053, 0x01F1, 0x019A, 0x0022, 0x0000, +0x0000, 0x004E, 0x01EC, 0x01A1, 0x0025, 0x0000, +0x0000, 0x004A, 0x01E6, 0x01A8, 0x0028, 0x0000, +0x0000, 0x0046, 0x01E1, 0x01AF, 0x002A, 0x0000, +0x0000, 0x0042, 0x01DB, 0x01B6, 0x002D, 0x0000, +0x0000, 0x003F, 0x01D5, 0x01BB, 0x0031, 0x0000, +0x0000, 0x003B, 0x01CF, 0x01C2, 0x0034, 0x0000, +0x0000, 0x0037, 0x01C9, 0x01C9, 0x0037, 0x0000 +}; +//======================================================== +// gen_BlurScale_coeffs.m +// 25-Apr-2022 +// 4 +// 64 +// Blur & Scale LPF +// 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, +}; +//======================================================== +// gen_BlurScale_coeffs.m +// 09-Jun-2022 +// 3 +// 64 +// Blur & Scale LPF +// 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, + } + }, +}; + +struct scale_ratio_to_sharpness_level_adj sharpness_level_adj[NUM_SHARPNESS_ADJ_LEVELS] = { + {1125, 1000, 0}, + {11, 10, 1}, + {1075, 1000, 2}, + {105, 100, 3}, + {1025, 1000, 4}, + {1, 1, 5}, +}; + +const uint32_t *spl_get_filter_isharp_1D_lut_0(void) +{ + return filter_isharp_1D_lut_0; +} +const uint32_t *spl_get_filter_isharp_1D_lut_0p5x(void) +{ + return filter_isharp_1D_lut_0p5x; +} +const uint32_t *spl_get_filter_isharp_1D_lut_1p0x(void) +{ + return filter_isharp_1D_lut_1p0x; +} +const uint32_t *spl_get_filter_isharp_1D_lut_1p5x(void) +{ + return filter_isharp_1D_lut_1p5x; +} +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; +} +uint16_t *spl_get_filter_isharp_bs_4tap_in_6_64p(void) +{ + 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_adj(struct spl_fixed31_32 ratio) +{ + int j; + struct spl_fixed31_32 ratio_level; + struct scale_ratio_to_sharpness_level_adj *lookup_ptr; + unsigned int sharpness_level_down_adj; + + /* + * Adjust sharpness level based on current scaling ratio + * + * We have 5 discrete scaling ratios which we will use to adjust the + * sharpness level down by 1 as we pass each ratio. The ratios + * are + * + * 1.125 upscale and higher - no adj + * 1.100 - under 1.125 - adj level down 1 + * 1.075 - under 1.100 - adj level down 2 + * 1.050 - under 1.075 - adj level down 3 + * 1.025 - under 1.050 - adj level down 4 + * 1.000 - under 1.025 - adj level down 5 + * + */ + j = 0; + sharpness_level_down_adj = 0; + lookup_ptr = sharpness_level_adj; + while (j < NUM_SHARPNESS_ADJ_LEVELS) { + ratio_level = spl_fixpt_from_fraction(lookup_ptr->ratio_numer, + lookup_ptr->ratio_denom); + if (ratio.value >= ratio_level.value) { + sharpness_level_down_adj = lookup_ptr->level_down_adj; + break; + } + lookup_ptr++; + j++; + } + return sharpness_level_down_adj; +} + +static unsigned int spl_calculate_sharpness_level(struct spl_fixed31_32 ratio, + int discrete_sharpness_level, enum system_setup setup, + struct spl_sharpness_range sharpness_range, + enum scale_to_sharpness_policy scale_to_sharpness_policy) +{ + unsigned int sharpness_level = 0; + unsigned int sharpness_level_down_adj = 0; + + int min_sharpness, max_sharpness, mid_sharpness; + + /* + * Adjust sharpness level if policy requires we adjust it based on + * scale ratio. Based on scale ratio, we may adjust the sharpness + * level down by a certain number of steps. We will not select + * a sharpness value of 0 so the lowest sharpness level will be + * 0 or 1 depending on what the min_sharpness is + * + * If the policy is no required, this code maybe removed at a later + * date + */ + 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; + if (scale_to_sharpness_policy == SCALE_TO_SHARPNESS_ADJ_ALL) + sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio); + 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; + if (scale_to_sharpness_policy >= SCALE_TO_SHARPNESS_ADJ_YUV) + sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio); + 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; + if (scale_to_sharpness_policy == SCALE_TO_SHARPNESS_ADJ_ALL) + sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio); + break; + } + + if ((min_sharpness == 0) && (sharpness_level_down_adj >= discrete_sharpness_level)) + discrete_sharpness_level = 1; + else if (sharpness_level_down_adj >= discrete_sharpness_level) + discrete_sharpness_level = 0; + else + discrete_sharpness_level -= sharpness_level_down_adj; + + 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, enum scale_to_sharpness_policy scale_to_sharpness_policy) +{ + 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(ratio, + sharpness.sharpness_level, setup, + sharpness.sharpness_range, scale_to_sharpness_policy); + 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/sspl/dc_spl_isharp_filters.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.h new file mode 100644 index 000000000000..89af91e19b6c --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.h @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: MIT +// +// Copyright 2024 Advanced Micro Devices, Inc. + +#ifndef __DC_SPL_ISHARP_FILTERS_H__ +#define __DC_SPL_ISHARP_FILTERS_H__ + +#include "dc_spl_types.h" + +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 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); + +#define NUM_SHARPNESS_ADJ_LEVELS 6 +struct scale_ratio_to_sharpness_level_adj { + unsigned int ratio_numer; + unsigned int ratio_denom; + unsigned int level_down_adj; /* adjust sharpness level down */ +}; + +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, enum scale_to_sharpness_policy scale_to_sharpness_policy); +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/sspl/dc_spl_scl_easf_filters.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.c new file mode 100644 index 000000000000..09bf82f7d468 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/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" + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 3t_64p_LanczosEd_p_0.3_p_10qb_ +// 3 +// 64 +// input/output = 0.300000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 3t_64p_LanczosEd_p_0.4_p_10qb_ +// 3 +// 64 +// input/output = 0.400000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 3t_64p_LanczosEd_p_0.5_p_10qb_ +// 3 +// 64 +// input/output = 0.500000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 3t_64p_LanczosEd_p_0.6_p_10qb_ +// 3 +// 64 +// input/output = 0.600000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 3t_64p_LanczosEd_p_0.7_p_10qb_ +// 3 +// 64 +// input/output = 0.700000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 3t_64p_LanczosEd_p_0.8_p_10qb_ +// 3 +// 64 +// input/output = 0.800000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 3t_64p_LanczosEd_p_0.9_p_10qb_ +// 3 +// 64 +// input/output = 0.900000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 3t_64p_LanczosEd_p_1_p_10qb_ +// 3 +// 64 +// input/output = 1.000000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 4t_64p_LanczosEd_p_0.3_p_10qb_ +// 4 +// 64 +// input/output = 0.300000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 4t_64p_LanczosEd_p_0.4_p_10qb_ +// 4 +// 64 +// input/output = 0.400000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 4t_64p_LanczosEd_p_0.5_p_10qb_ +// 4 +// 64 +// input/output = 0.500000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 4t_64p_LanczosEd_p_0.6_p_10qb_ +// 4 +// 64 +// input/output = 0.600000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 4t_64p_LanczosEd_p_0.7_p_10qb_ +// 4 +// 64 +// input/output = 0.700000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 4t_64p_LanczosEd_p_0.8_p_10qb_ +// 4 +// 64 +// input/output = 0.800000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 4t_64p_LanczosEd_p_0.9_p_10qb_ +// 4 +// 64 +// input/output = 0.900000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 03-Apr-2024 +// 4t_64p_LanczosEd_p_1_p_10qb_ +// 4 +// 64 +// input/output = 1.000000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 02-Apr-2024 +// 6t_64p_LanczosEd_p_0.3_p_10qb_ +// 6 +// 64 +// input/output = 0.300000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 02-Apr-2024 +// 6t_64p_LanczosEd_p_0.4_p_10qb_ +// 6 +// 64 +// input/output = 0.400000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 02-Apr-2024 +// 6t_64p_LanczosEd_p_0.5_p_10qb_ +// 6 +// 64 +// input/output = 0.500000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 02-Apr-2024 +// 6t_64p_LanczosEd_p_0.6_p_10qb_ +// 6 +// 64 +// input/output = 0.600000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 02-Apr-2024 +// 6t_64p_LanczosEd_p_0.7_p_10qb_ +// 6 +// 64 +// input/output = 0.700000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 02-Apr-2024 +// 6t_64p_LanczosEd_p_0.8_p_10qb_ +// 6 +// 64 +// input/output = 0.800000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 02-Apr-2024 +// 6t_64p_LanczosEd_p_0.9_p_10qb_ +// 6 +// 64 +// input/output = 0.900000000000 +// LanczosEd +// 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, +}; + +//======================================================== +// gen_scaler_coeffs_cnf_file.m +// make_test_script.m +// 02-Apr-2024 +// 6t_64p_LanczosEd_p_1_p_10qb_ +// 6 +// 64 +// input/output = 1.000000000000 +// LanczosEd +// 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/sspl/dc_spl_scl_easf_filters.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.h new file mode 100644 index 000000000000..8bb2b8108e38 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/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/sspl/dc_spl_scl_filters.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.c new file mode 100644 index 000000000000..b02c7b0b262b --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.c @@ -0,0 +1,1451 @@ +// SPDX-License-Identifier: MIT +// +// Copyright 2024 Advanced Micro Devices, Inc. + +#include "spl_debug.h" +#include "dc_spl_scl_filters.h" +//========================================= +// = 2 +// = 16 +// = 0.833333 (input/output) +// = 0 +// = ModifiedLanczos +// = s1.10 +// = s1.12 +//========================================= +static const uint16_t filter_2tap_16p[18] = { + 0x1000, 0x0000, + 0x0FF0, 0x0010, + 0x0FB0, 0x0050, + 0x0F34, 0x00CC, + 0x0E68, 0x0198, + 0x0D44, 0x02BC, + 0x0BC4, 0x043C, + 0x09FC, 0x0604, + 0x0800, 0x0800 +}; + +//========================================= +// = 3 +// = 16 +// = 0.83333 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_3tap_16p_upscale[27] = { + 0x0804, 0x07FC, 0x0000, + 0x06AC, 0x0978, 0x3FDC, + 0x055C, 0x0AF0, 0x3FB4, + 0x0420, 0x0C50, 0x3F90, + 0x0300, 0x0D88, 0x3F78, + 0x0200, 0x0E90, 0x3F70, + 0x0128, 0x0F5C, 0x3F7C, + 0x007C, 0x0FD8, 0x3FAC, + 0x0000, 0x1000, 0x0000 +}; + +//========================================= +// = 3 +// = 16 +// = 1.16666 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_3tap_16p_116[27] = { + 0x0804, 0x07FC, 0x0000, + 0x0700, 0x0914, 0x3FEC, + 0x0604, 0x0A1C, 0x3FE0, + 0x050C, 0x0B14, 0x3FE0, + 0x041C, 0x0BF4, 0x3FF0, + 0x0340, 0x0CB0, 0x0010, + 0x0274, 0x0D3C, 0x0050, + 0x01C0, 0x0D94, 0x00AC, + 0x0128, 0x0DB4, 0x0124 +}; + +//========================================= +// = 3 +// = 16 +// = 1.49999 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_3tap_16p_149[27] = { + 0x0804, 0x07FC, 0x0000, + 0x0730, 0x08CC, 0x0004, + 0x0660, 0x098C, 0x0014, + 0x0590, 0x0A3C, 0x0034, + 0x04C4, 0x0AD4, 0x0068, + 0x0400, 0x0B54, 0x00AC, + 0x0348, 0x0BB0, 0x0108, + 0x029C, 0x0BEC, 0x0178, + 0x0200, 0x0C00, 0x0200 +}; + +//========================================= +// = 3 +// = 16 +// = 1.83332 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_3tap_16p_183[27] = { + 0x0804, 0x07FC, 0x0000, + 0x0754, 0x0880, 0x002C, + 0x06A8, 0x08F0, 0x0068, + 0x05FC, 0x0954, 0x00B0, + 0x0550, 0x09AC, 0x0104, + 0x04A8, 0x09F0, 0x0168, + 0x0408, 0x0A20, 0x01D8, + 0x036C, 0x0A40, 0x0254, + 0x02DC, 0x0A48, 0x02DC +}; + +//========================================= +// = 4 +// = 16 +// = 0.83333 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_4tap_16p_upscale[36] = { + 0x0000, 0x1000, 0x0000, 0x0000, + 0x3F74, 0x0FDC, 0x00B4, 0x3FFC, + 0x3F0C, 0x0F70, 0x0194, 0x3FF0, + 0x3ECC, 0x0EC4, 0x0298, 0x3FD8, + 0x3EAC, 0x0DE4, 0x03B8, 0x3FB8, + 0x3EA4, 0x0CD8, 0x04F4, 0x3F90, + 0x3EB8, 0x0BA0, 0x0644, 0x3F64, + 0x3ED8, 0x0A54, 0x07A0, 0x3F34, + 0x3F00, 0x08FC, 0x0900, 0x3F04 +}; + +//========================================= +// = 4 +// = 16 +// = 1.16666 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_4tap_16p_116[36] = { + 0x01A8, 0x0CB4, 0x01A4, 0x0000, + 0x0110, 0x0CB0, 0x0254, 0x3FEC, + 0x0090, 0x0C80, 0x031C, 0x3FD4, + 0x0024, 0x0C2C, 0x03F4, 0x3FBC, + 0x3FD8, 0x0BAC, 0x04DC, 0x3FA0, + 0x3F9C, 0x0B14, 0x05CC, 0x3F84, + 0x3F70, 0x0A60, 0x06C4, 0x3F6C, + 0x3F5C, 0x098C, 0x07BC, 0x3F5C, + 0x3F54, 0x08AC, 0x08AC, 0x3F54 +}; + +//========================================= +// = 4 +// = 16 +// = 1.49999 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_4tap_16p_149[36] = { + 0x02B8, 0x0A90, 0x02B8, 0x0000, + 0x0230, 0x0A90, 0x0350, 0x3FF0, + 0x01B8, 0x0A78, 0x03F0, 0x3FE0, + 0x0148, 0x0A48, 0x049C, 0x3FD4, + 0x00E8, 0x0A00, 0x054C, 0x3FCC, + 0x0098, 0x09A0, 0x0600, 0x3FC8, + 0x0054, 0x0928, 0x06B4, 0x3FD0, + 0x001C, 0x08A4, 0x0760, 0x3FE0, + 0x3FFC, 0x0804, 0x0804, 0x3FFC +}; + +//========================================= +// = 4 +// = 16 +// = 1.83332 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_4tap_16p_183[36] = { + 0x03B0, 0x08A0, 0x03B0, 0x0000, + 0x0348, 0x0898, 0x041C, 0x0004, + 0x02DC, 0x0884, 0x0490, 0x0010, + 0x0278, 0x0864, 0x0500, 0x0024, + 0x021C, 0x0838, 0x0570, 0x003C, + 0x01C8, 0x07FC, 0x05E0, 0x005C, + 0x0178, 0x07B8, 0x064C, 0x0084, + 0x0130, 0x076C, 0x06B0, 0x00B4, + 0x00F0, 0x0714, 0x0710, 0x00EC +}; + +//========================================= +// = 2 +// = 64 +// = 0.833333 (input/output) +// = 0 +// = ModifiedLanczos +// = s1.10 +// = s1.12 +//========================================= +static const uint16_t filter_2tap_64p[66] = { + 0x1000, 0x0000, + 0x1000, 0x0000, + 0x0FFC, 0x0004, + 0x0FF8, 0x0008, + 0x0FF0, 0x0010, + 0x0FE4, 0x001C, + 0x0FD8, 0x0028, + 0x0FC4, 0x003C, + 0x0FB0, 0x0050, + 0x0F98, 0x0068, + 0x0F7C, 0x0084, + 0x0F58, 0x00A8, + 0x0F34, 0x00CC, + 0x0F08, 0x00F8, + 0x0ED8, 0x0128, + 0x0EA4, 0x015C, + 0x0E68, 0x0198, + 0x0E28, 0x01D8, + 0x0DE4, 0x021C, + 0x0D98, 0x0268, + 0x0D44, 0x02BC, + 0x0CEC, 0x0314, + 0x0C90, 0x0370, + 0x0C2C, 0x03D4, + 0x0BC4, 0x043C, + 0x0B58, 0x04A8, + 0x0AE8, 0x0518, + 0x0A74, 0x058C, + 0x09FC, 0x0604, + 0x0980, 0x0680, + 0x0900, 0x0700, + 0x0880, 0x0780, + 0x0800, 0x0800 +}; + +//========================================= +// = 3 +// = 64 +// = 0.83333 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_3tap_64p_upscale[99] = { + 0x0804, 0x07FC, 0x0000, + 0x07A8, 0x0860, 0x3FF8, + 0x0754, 0x08BC, 0x3FF0, + 0x0700, 0x0918, 0x3FE8, + 0x06AC, 0x0978, 0x3FDC, + 0x0654, 0x09D8, 0x3FD4, + 0x0604, 0x0A34, 0x3FC8, + 0x05B0, 0x0A90, 0x3FC0, + 0x055C, 0x0AF0, 0x3FB4, + 0x050C, 0x0B48, 0x3FAC, + 0x04BC, 0x0BA0, 0x3FA4, + 0x0470, 0x0BF4, 0x3F9C, + 0x0420, 0x0C50, 0x3F90, + 0x03D8, 0x0C9C, 0x3F8C, + 0x038C, 0x0CF0, 0x3F84, + 0x0344, 0x0D40, 0x3F7C, + 0x0300, 0x0D88, 0x3F78, + 0x02BC, 0x0DD0, 0x3F74, + 0x027C, 0x0E14, 0x3F70, + 0x023C, 0x0E54, 0x3F70, + 0x0200, 0x0E90, 0x3F70, + 0x01C8, 0x0EC8, 0x3F70, + 0x0190, 0x0EFC, 0x3F74, + 0x015C, 0x0F2C, 0x3F78, + 0x0128, 0x0F5C, 0x3F7C, + 0x00FC, 0x0F7C, 0x3F88, + 0x00CC, 0x0FA4, 0x3F90, + 0x00A4, 0x0FC0, 0x3F9C, + 0x007C, 0x0FD8, 0x3FAC, + 0x0058, 0x0FE8, 0x3FC0, + 0x0038, 0x0FF4, 0x3FD4, + 0x0018, 0x1000, 0x3FE8, + 0x0000, 0x1000, 0x0000 +}; + +//========================================= +// = 3 +// = 64 +// = 1.16666 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_3tap_64p_116[99] = { + 0x0804, 0x07FC, 0x0000, + 0x07C0, 0x0844, 0x3FFC, + 0x0780, 0x0888, 0x3FF8, + 0x0740, 0x08D0, 0x3FF0, + 0x0700, 0x0914, 0x3FEC, + 0x06C0, 0x0958, 0x3FE8, + 0x0684, 0x0998, 0x3FE4, + 0x0644, 0x09DC, 0x3FE0, + 0x0604, 0x0A1C, 0x3FE0, + 0x05C4, 0x0A5C, 0x3FE0, + 0x0588, 0x0A9C, 0x3FDC, + 0x0548, 0x0ADC, 0x3FDC, + 0x050C, 0x0B14, 0x3FE0, + 0x04CC, 0x0B54, 0x3FE0, + 0x0490, 0x0B8C, 0x3FE4, + 0x0458, 0x0BC0, 0x3FE8, + 0x041C, 0x0BF4, 0x3FF0, + 0x03E0, 0x0C28, 0x3FF8, + 0x03A8, 0x0C58, 0x0000, + 0x0374, 0x0C88, 0x0004, + 0x0340, 0x0CB0, 0x0010, + 0x0308, 0x0CD8, 0x0020, + 0x02D8, 0x0CFC, 0x002C, + 0x02A0, 0x0D20, 0x0040, + 0x0274, 0x0D3C, 0x0050, + 0x0244, 0x0D58, 0x0064, + 0x0214, 0x0D70, 0x007C, + 0x01E8, 0x0D84, 0x0094, + 0x01C0, 0x0D94, 0x00AC, + 0x0198, 0x0DA0, 0x00C8, + 0x0170, 0x0DAC, 0x00E4, + 0x014C, 0x0DB0, 0x0104, + 0x0128, 0x0DB4, 0x0124 +}; + +//========================================= +// = 3 +// = 64 +// = 1.49999 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_3tap_64p_149[99] = { + 0x0804, 0x07FC, 0x0000, + 0x07CC, 0x0834, 0x0000, + 0x0798, 0x0868, 0x0000, + 0x0764, 0x089C, 0x0000, + 0x0730, 0x08CC, 0x0004, + 0x0700, 0x08FC, 0x0004, + 0x06CC, 0x092C, 0x0008, + 0x0698, 0x095C, 0x000C, + 0x0660, 0x098C, 0x0014, + 0x062C, 0x09B8, 0x001C, + 0x05FC, 0x09E4, 0x0020, + 0x05C4, 0x0A10, 0x002C, + 0x0590, 0x0A3C, 0x0034, + 0x055C, 0x0A64, 0x0040, + 0x0528, 0x0A8C, 0x004C, + 0x04F8, 0x0AB0, 0x0058, + 0x04C4, 0x0AD4, 0x0068, + 0x0490, 0x0AF8, 0x0078, + 0x0460, 0x0B18, 0x0088, + 0x0430, 0x0B38, 0x0098, + 0x0400, 0x0B54, 0x00AC, + 0x03D0, 0x0B6C, 0x00C4, + 0x03A0, 0x0B88, 0x00D8, + 0x0374, 0x0B9C, 0x00F0, + 0x0348, 0x0BB0, 0x0108, + 0x0318, 0x0BC4, 0x0124, + 0x02EC, 0x0BD4, 0x0140, + 0x02C4, 0x0BE0, 0x015C, + 0x029C, 0x0BEC, 0x0178, + 0x0274, 0x0BF4, 0x0198, + 0x024C, 0x0BFC, 0x01B8, + 0x0228, 0x0BFC, 0x01DC, + 0x0200, 0x0C00, 0x0200 +}; + +//========================================= +// = 3 +// = 64 +// = 1.83332 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_3tap_64p_183[99] = { + 0x0804, 0x07FC, 0x0000, + 0x07D4, 0x0824, 0x0008, + 0x07AC, 0x0840, 0x0014, + 0x0780, 0x0860, 0x0020, + 0x0754, 0x0880, 0x002C, + 0x0728, 0x089C, 0x003C, + 0x0700, 0x08B8, 0x0048, + 0x06D4, 0x08D4, 0x0058, + 0x06A8, 0x08F0, 0x0068, + 0x067C, 0x090C, 0x0078, + 0x0650, 0x0924, 0x008C, + 0x0628, 0x093C, 0x009C, + 0x05FC, 0x0954, 0x00B0, + 0x05D0, 0x096C, 0x00C4, + 0x05A8, 0x0980, 0x00D8, + 0x0578, 0x0998, 0x00F0, + 0x0550, 0x09AC, 0x0104, + 0x0528, 0x09BC, 0x011C, + 0x04FC, 0x09D0, 0x0134, + 0x04D4, 0x09E0, 0x014C, + 0x04A8, 0x09F0, 0x0168, + 0x0480, 0x09FC, 0x0184, + 0x045C, 0x0A08, 0x019C, + 0x0434, 0x0A14, 0x01B8, + 0x0408, 0x0A20, 0x01D8, + 0x03E0, 0x0A2C, 0x01F4, + 0x03B8, 0x0A34, 0x0214, + 0x0394, 0x0A38, 0x0234, + 0x036C, 0x0A40, 0x0254, + 0x0348, 0x0A44, 0x0274, + 0x0324, 0x0A48, 0x0294, + 0x0300, 0x0A48, 0x02B8, + 0x02DC, 0x0A48, 0x02DC +}; + +//========================================= +// = 4 +// = 64 +// = 0.83333 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_4tap_64p_upscale[132] = { + 0x0000, 0x1000, 0x0000, 0x0000, + 0x3FDC, 0x0FFC, 0x0028, 0x0000, + 0x3FB4, 0x0FF8, 0x0054, 0x0000, + 0x3F94, 0x0FE8, 0x0084, 0x0000, + 0x3F74, 0x0FDC, 0x00B4, 0x3FFC, + 0x3F58, 0x0FC4, 0x00E8, 0x3FFC, + 0x3F3C, 0x0FAC, 0x0120, 0x3FF8, + 0x3F24, 0x0F90, 0x0158, 0x3FF4, + 0x3F0C, 0x0F70, 0x0194, 0x3FF0, + 0x3EF8, 0x0F4C, 0x01D0, 0x3FEC, + 0x3EE8, 0x0F20, 0x0210, 0x3FE8, + 0x3ED8, 0x0EF4, 0x0254, 0x3FE0, + 0x3ECC, 0x0EC4, 0x0298, 0x3FD8, + 0x3EC0, 0x0E90, 0x02DC, 0x3FD4, + 0x3EB8, 0x0E58, 0x0324, 0x3FCC, + 0x3EB0, 0x0E20, 0x036C, 0x3FC4, + 0x3EAC, 0x0DE4, 0x03B8, 0x3FB8, + 0x3EA8, 0x0DA4, 0x0404, 0x3FB0, + 0x3EA4, 0x0D60, 0x0454, 0x3FA8, + 0x3EA4, 0x0D1C, 0x04A4, 0x3F9C, + 0x3EA4, 0x0CD8, 0x04F4, 0x3F90, + 0x3EA8, 0x0C88, 0x0548, 0x3F88, + 0x3EAC, 0x0C3C, 0x059C, 0x3F7C, + 0x3EB0, 0x0BF0, 0x05F0, 0x3F70, + 0x3EB8, 0x0BA0, 0x0644, 0x3F64, + 0x3EBC, 0x0B54, 0x0698, 0x3F58, + 0x3EC4, 0x0B00, 0x06F0, 0x3F4C, + 0x3ECC, 0x0AAC, 0x0748, 0x3F40, + 0x3ED8, 0x0A54, 0x07A0, 0x3F34, + 0x3EE0, 0x0A04, 0x07F8, 0x3F24, + 0x3EEC, 0x09AC, 0x0850, 0x3F18, + 0x3EF8, 0x0954, 0x08A8, 0x3F0C, + 0x3F00, 0x08FC, 0x0900, 0x3F04 +}; + +//========================================= +// = 4 +// = 64 +// = 1.16666 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_4tap_64p_116[132] = { + 0x01A8, 0x0CB4, 0x01A4, 0x0000, + 0x017C, 0x0CB8, 0x01D0, 0x3FFC, + 0x0158, 0x0CB8, 0x01F8, 0x3FF8, + 0x0130, 0x0CB4, 0x0228, 0x3FF4, + 0x0110, 0x0CB0, 0x0254, 0x3FEC, + 0x00EC, 0x0CA8, 0x0284, 0x3FE8, + 0x00CC, 0x0C9C, 0x02B4, 0x3FE4, + 0x00AC, 0x0C90, 0x02E8, 0x3FDC, + 0x0090, 0x0C80, 0x031C, 0x3FD4, + 0x0070, 0x0C70, 0x0350, 0x3FD0, + 0x0058, 0x0C5C, 0x0384, 0x3FC8, + 0x003C, 0x0C48, 0x03BC, 0x3FC0, + 0x0024, 0x0C2C, 0x03F4, 0x3FBC, + 0x0010, 0x0C10, 0x042C, 0x3FB4, + 0x3FFC, 0x0BF4, 0x0464, 0x3FAC, + 0x3FE8, 0x0BD4, 0x04A0, 0x3FA4, + 0x3FD8, 0x0BAC, 0x04DC, 0x3FA0, + 0x3FC4, 0x0B8C, 0x0518, 0x3F98, + 0x3FB4, 0x0B68, 0x0554, 0x3F90, + 0x3FA8, 0x0B40, 0x0590, 0x3F88, + 0x3F9C, 0x0B14, 0x05CC, 0x3F84, + 0x3F90, 0x0AEC, 0x0608, 0x3F7C, + 0x3F84, 0x0ABC, 0x0648, 0x3F78, + 0x3F7C, 0x0A90, 0x0684, 0x3F70, + 0x3F70, 0x0A60, 0x06C4, 0x3F6C, + 0x3F6C, 0x0A2C, 0x0700, 0x3F68, + 0x3F64, 0x09F8, 0x0740, 0x3F64, + 0x3F60, 0x09C4, 0x077C, 0x3F60, + 0x3F5C, 0x098C, 0x07BC, 0x3F5C, + 0x3F58, 0x0958, 0x07F8, 0x3F58, + 0x3F58, 0x091C, 0x0834, 0x3F58, + 0x3F54, 0x08E4, 0x0870, 0x3F58, + 0x3F54, 0x08AC, 0x08AC, 0x3F54 +}; + +//========================================= +// = 4 +// = 64 +// = 1.49999 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_4tap_64p_149[132] = { + 0x02B8, 0x0A90, 0x02B8, 0x0000, + 0x0294, 0x0A94, 0x02DC, 0x3FFC, + 0x0274, 0x0A94, 0x0300, 0x3FF8, + 0x0250, 0x0A94, 0x0328, 0x3FF4, + 0x0230, 0x0A90, 0x0350, 0x3FF0, + 0x0214, 0x0A8C, 0x0374, 0x3FEC, + 0x01F0, 0x0A88, 0x03A0, 0x3FE8, + 0x01D4, 0x0A80, 0x03C8, 0x3FE4, + 0x01B8, 0x0A78, 0x03F0, 0x3FE0, + 0x0198, 0x0A70, 0x041C, 0x3FDC, + 0x0180, 0x0A64, 0x0444, 0x3FD8, + 0x0164, 0x0A54, 0x0470, 0x3FD8, + 0x0148, 0x0A48, 0x049C, 0x3FD4, + 0x0130, 0x0A38, 0x04C8, 0x3FD0, + 0x0118, 0x0A24, 0x04F4, 0x3FD0, + 0x0100, 0x0A14, 0x0520, 0x3FCC, + 0x00E8, 0x0A00, 0x054C, 0x3FCC, + 0x00D4, 0x09E8, 0x057C, 0x3FC8, + 0x00C0, 0x09D0, 0x05A8, 0x3FC8, + 0x00AC, 0x09B8, 0x05D4, 0x3FC8, + 0x0098, 0x09A0, 0x0600, 0x3FC8, + 0x0084, 0x0984, 0x0630, 0x3FC8, + 0x0074, 0x0964, 0x065C, 0x3FCC, + 0x0064, 0x0948, 0x0688, 0x3FCC, + 0x0054, 0x0928, 0x06B4, 0x3FD0, + 0x0044, 0x0908, 0x06E0, 0x3FD4, + 0x0038, 0x08E8, 0x070C, 0x3FD4, + 0x002C, 0x08C4, 0x0738, 0x3FD8, + 0x001C, 0x08A4, 0x0760, 0x3FE0, + 0x0014, 0x087C, 0x078C, 0x3FE4, + 0x0008, 0x0858, 0x07B4, 0x3FEC, + 0x0000, 0x0830, 0x07DC, 0x3FF4, + 0x3FFC, 0x0804, 0x0804, 0x3FFC +}; + +//========================================= +// = 4 +// = 64 +// = 1.83332 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_4tap_64p_183[132] = { + 0x03B0, 0x08A0, 0x03B0, 0x0000, + 0x0394, 0x08A0, 0x03CC, 0x0000, + 0x037C, 0x089C, 0x03E8, 0x0000, + 0x0360, 0x089C, 0x0400, 0x0004, + 0x0348, 0x0898, 0x041C, 0x0004, + 0x032C, 0x0894, 0x0438, 0x0008, + 0x0310, 0x0890, 0x0454, 0x000C, + 0x02F8, 0x0888, 0x0474, 0x000C, + 0x02DC, 0x0884, 0x0490, 0x0010, + 0x02C4, 0x087C, 0x04AC, 0x0014, + 0x02AC, 0x0874, 0x04C8, 0x0018, + 0x0290, 0x086C, 0x04E4, 0x0020, + 0x0278, 0x0864, 0x0500, 0x0024, + 0x0264, 0x0858, 0x051C, 0x0028, + 0x024C, 0x084C, 0x0538, 0x0030, + 0x0234, 0x0844, 0x0554, 0x0034, + 0x021C, 0x0838, 0x0570, 0x003C, + 0x0208, 0x0828, 0x058C, 0x0044, + 0x01F0, 0x081C, 0x05A8, 0x004C, + 0x01DC, 0x080C, 0x05C4, 0x0054, + 0x01C8, 0x07FC, 0x05E0, 0x005C, + 0x01B4, 0x07EC, 0x05FC, 0x0064, + 0x019C, 0x07DC, 0x0618, 0x0070, + 0x018C, 0x07CC, 0x0630, 0x0078, + 0x0178, 0x07B8, 0x064C, 0x0084, + 0x0164, 0x07A8, 0x0664, 0x0090, + 0x0150, 0x0794, 0x0680, 0x009C, + 0x0140, 0x0780, 0x0698, 0x00A8, + 0x0130, 0x076C, 0x06B0, 0x00B4, + 0x0120, 0x0758, 0x06C8, 0x00C0, + 0x0110, 0x0740, 0x06E0, 0x00D0, + 0x0100, 0x072C, 0x06F8, 0x00DC, + 0x00F0, 0x0714, 0x0710, 0x00EC +}; + +//========================================= +// = 5 +// = 64 +// = 0.83333 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_5tap_64p_upscale[165] = { + 0x3E40, 0x09C0, 0x09C0, 0x3E40, 0x0000, + 0x3E50, 0x0964, 0x0A18, 0x3E34, 0x0000, + 0x3E5C, 0x0908, 0x0A6C, 0x3E2C, 0x0004, + 0x3E6C, 0x08AC, 0x0AC0, 0x3E20, 0x0008, + 0x3E78, 0x0850, 0x0B14, 0x3E18, 0x000C, + 0x3E88, 0x07F4, 0x0B60, 0x3E14, 0x0010, + 0x3E98, 0x0798, 0x0BB0, 0x3E0C, 0x0014, + 0x3EA8, 0x073C, 0x0C00, 0x3E08, 0x0014, + 0x3EB8, 0x06E4, 0x0C48, 0x3E04, 0x0018, + 0x3ECC, 0x0684, 0x0C90, 0x3E04, 0x001C, + 0x3EDC, 0x062C, 0x0CD4, 0x3E04, 0x0020, + 0x3EEC, 0x05D4, 0x0D1C, 0x3E04, 0x0020, + 0x3EFC, 0x057C, 0x0D5C, 0x3E08, 0x0024, + 0x3F0C, 0x0524, 0x0D98, 0x3E10, 0x0028, + 0x3F20, 0x04CC, 0x0DD8, 0x3E14, 0x0028, + 0x3F30, 0x0478, 0x0E14, 0x3E1C, 0x0028, + 0x3F40, 0x0424, 0x0E48, 0x3E28, 0x002C, + 0x3F50, 0x03D4, 0x0E7C, 0x3E34, 0x002C, + 0x3F60, 0x0384, 0x0EAC, 0x3E44, 0x002C, + 0x3F6C, 0x0338, 0x0EDC, 0x3E54, 0x002C, + 0x3F7C, 0x02E8, 0x0F08, 0x3E68, 0x002C, + 0x3F8C, 0x02A0, 0x0F2C, 0x3E7C, 0x002C, + 0x3F98, 0x0258, 0x0F50, 0x3E94, 0x002C, + 0x3FA4, 0x0210, 0x0F74, 0x3EB0, 0x0028, + 0x3FB0, 0x01CC, 0x0F90, 0x3ECC, 0x0028, + 0x3FC0, 0x018C, 0x0FA8, 0x3EE8, 0x0024, + 0x3FC8, 0x014C, 0x0FC0, 0x3F0C, 0x0020, + 0x3FD4, 0x0110, 0x0FD4, 0x3F2C, 0x001C, + 0x3FE0, 0x00D4, 0x0FE0, 0x3F54, 0x0018, + 0x3FE8, 0x009C, 0x0FF0, 0x3F7C, 0x0010, + 0x3FF0, 0x0064, 0x0FFC, 0x3FA4, 0x000C, + 0x3FFC, 0x0030, 0x0FFC, 0x3FD4, 0x0004, + 0x0000, 0x0000, 0x1000, 0x0000, 0x0000 +}; + +//========================================= +// = 5 +// = 64 +// = 1.16666 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_5tap_64p_116[165] = { + 0x3EDC, 0x0924, 0x0924, 0x3EDC, 0x0000, + 0x3ED8, 0x08EC, 0x095C, 0x3EE0, 0x0000, + 0x3ED4, 0x08B0, 0x0994, 0x3EE8, 0x0000, + 0x3ED0, 0x0878, 0x09C8, 0x3EF0, 0x0000, + 0x3ED0, 0x083C, 0x09FC, 0x3EF8, 0x0000, + 0x3ED0, 0x0800, 0x0A2C, 0x3F04, 0x0000, + 0x3ED0, 0x07C4, 0x0A5C, 0x3F10, 0x0000, + 0x3ED0, 0x0788, 0x0A8C, 0x3F1C, 0x0000, + 0x3ED0, 0x074C, 0x0AC0, 0x3F28, 0x3FFC, + 0x3ED4, 0x0710, 0x0AE8, 0x3F38, 0x3FFC, + 0x3ED8, 0x06D0, 0x0B18, 0x3F48, 0x3FF8, + 0x3EDC, 0x0694, 0x0B3C, 0x3F5C, 0x3FF8, + 0x3EE0, 0x0658, 0x0B68, 0x3F6C, 0x3FF4, + 0x3EE4, 0x061C, 0x0B90, 0x3F80, 0x3FF0, + 0x3EEC, 0x05DC, 0x0BB4, 0x3F98, 0x3FEC, + 0x3EF0, 0x05A0, 0x0BD8, 0x3FB0, 0x3FE8, + 0x3EF8, 0x0564, 0x0BF8, 0x3FC8, 0x3FE4, + 0x3EFC, 0x0528, 0x0C1C, 0x3FE0, 0x3FE0, + 0x3F04, 0x04EC, 0x0C38, 0x3FFC, 0x3FDC, + 0x3F0C, 0x04B4, 0x0C54, 0x0014, 0x3FD8, + 0x3F14, 0x047C, 0x0C70, 0x0030, 0x3FD0, + 0x3F1C, 0x0440, 0x0C88, 0x0050, 0x3FCC, + 0x3F24, 0x0408, 0x0CA0, 0x0070, 0x3FC4, + 0x3F2C, 0x03D0, 0x0CB0, 0x0094, 0x3FC0, + 0x3F34, 0x0398, 0x0CC4, 0x00B8, 0x3FB8, + 0x3F3C, 0x0364, 0x0CD4, 0x00DC, 0x3FB0, + 0x3F48, 0x032C, 0x0CE0, 0x0100, 0x3FAC, + 0x3F50, 0x02F8, 0x0CEC, 0x0128, 0x3FA4, + 0x3F58, 0x02C4, 0x0CF8, 0x0150, 0x3F9C, + 0x3F60, 0x0290, 0x0D00, 0x017C, 0x3F94, + 0x3F68, 0x0260, 0x0D04, 0x01A8, 0x3F8C, + 0x3F74, 0x0230, 0x0D04, 0x01D4, 0x3F84, + 0x3F7C, 0x0200, 0x0D08, 0x0200, 0x3F7C +}; + +//========================================= +// = 5 +// = 64 +// = 1.49999 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_5tap_64p_149[165] = { + 0x3FF4, 0x080C, 0x080C, 0x3FF4, 0x0000, + 0x3FE8, 0x07E8, 0x0830, 0x0000, 0x0000, + 0x3FDC, 0x07C8, 0x0850, 0x0010, 0x3FFC, + 0x3FD0, 0x07A4, 0x0878, 0x001C, 0x3FF8, + 0x3FC4, 0x0780, 0x0898, 0x0030, 0x3FF4, + 0x3FB8, 0x075C, 0x08B8, 0x0040, 0x3FF4, + 0x3FB0, 0x0738, 0x08D8, 0x0050, 0x3FF0, + 0x3FA8, 0x0710, 0x08F8, 0x0064, 0x3FEC, + 0x3FA0, 0x06EC, 0x0914, 0x0078, 0x3FE8, + 0x3F98, 0x06C4, 0x0934, 0x008C, 0x3FE4, + 0x3F90, 0x06A0, 0x094C, 0x00A4, 0x3FE0, + 0x3F8C, 0x0678, 0x0968, 0x00B8, 0x3FDC, + 0x3F84, 0x0650, 0x0984, 0x00D0, 0x3FD8, + 0x3F80, 0x0628, 0x099C, 0x00E8, 0x3FD4, + 0x3F7C, 0x0600, 0x09B8, 0x0100, 0x3FCC, + 0x3F78, 0x05D8, 0x09D0, 0x0118, 0x3FC8, + 0x3F74, 0x05B0, 0x09E4, 0x0134, 0x3FC4, + 0x3F70, 0x0588, 0x09F8, 0x0150, 0x3FC0, + 0x3F70, 0x0560, 0x0A08, 0x016C, 0x3FBC, + 0x3F6C, 0x0538, 0x0A20, 0x0188, 0x3FB4, + 0x3F6C, 0x0510, 0x0A30, 0x01A4, 0x3FB0, + 0x3F6C, 0x04E8, 0x0A3C, 0x01C4, 0x3FAC, + 0x3F6C, 0x04C0, 0x0A48, 0x01E4, 0x3FA8, + 0x3F6C, 0x0498, 0x0A58, 0x0200, 0x3FA4, + 0x3F6C, 0x0470, 0x0A60, 0x0224, 0x3FA0, + 0x3F6C, 0x0448, 0x0A70, 0x0244, 0x3F98, + 0x3F70, 0x0420, 0x0A78, 0x0264, 0x3F94, + 0x3F70, 0x03F8, 0x0A80, 0x0288, 0x3F90, + 0x3F74, 0x03D4, 0x0A84, 0x02A8, 0x3F8C, + 0x3F74, 0x03AC, 0x0A8C, 0x02CC, 0x3F88, + 0x3F78, 0x0384, 0x0A90, 0x02F0, 0x3F84, + 0x3F7C, 0x0360, 0x0A90, 0x0314, 0x3F80, + 0x3F7C, 0x033C, 0x0A90, 0x033C, 0x3F7C +}; + +//========================================= +// = 5 +// = 64 +// = 1.83332 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_5tap_64p_183[165] = { + 0x0168, 0x069C, 0x0698, 0x0164, 0x0000, + 0x0154, 0x068C, 0x06AC, 0x0174, 0x0000, + 0x0144, 0x0674, 0x06C0, 0x0188, 0x0000, + 0x0138, 0x0664, 0x06D0, 0x0198, 0x3FFC, + 0x0128, 0x0654, 0x06E0, 0x01A8, 0x3FFC, + 0x0118, 0x0640, 0x06F0, 0x01BC, 0x3FFC, + 0x010C, 0x0630, 0x0700, 0x01CC, 0x3FF8, + 0x00FC, 0x061C, 0x0710, 0x01E0, 0x3FF8, + 0x00F0, 0x060C, 0x071C, 0x01F0, 0x3FF8, + 0x00E4, 0x05F4, 0x072C, 0x0204, 0x3FF8, + 0x00D8, 0x05E4, 0x0738, 0x0218, 0x3FF4, + 0x00CC, 0x05D0, 0x0744, 0x022C, 0x3FF4, + 0x00C0, 0x05B8, 0x0754, 0x0240, 0x3FF4, + 0x00B4, 0x05A4, 0x0760, 0x0254, 0x3FF4, + 0x00A8, 0x0590, 0x076C, 0x0268, 0x3FF4, + 0x009C, 0x057C, 0x0778, 0x027C, 0x3FF4, + 0x0094, 0x0564, 0x0780, 0x0294, 0x3FF4, + 0x0088, 0x0550, 0x0788, 0x02A8, 0x3FF8, + 0x0080, 0x0538, 0x0794, 0x02BC, 0x3FF8, + 0x0074, 0x0524, 0x079C, 0x02D4, 0x3FF8, + 0x006C, 0x0510, 0x07A4, 0x02E8, 0x3FF8, + 0x0064, 0x04F4, 0x07AC, 0x0300, 0x3FFC, + 0x005C, 0x04E4, 0x07B0, 0x0314, 0x3FFC, + 0x0054, 0x04C8, 0x07B8, 0x032C, 0x0000, + 0x004C, 0x04B4, 0x07C0, 0x0340, 0x0000, + 0x0044, 0x04A0, 0x07C4, 0x0358, 0x0000, + 0x003C, 0x0488, 0x07C8, 0x0370, 0x0004, + 0x0038, 0x0470, 0x07CC, 0x0384, 0x0008, + 0x0030, 0x045C, 0x07D0, 0x039C, 0x0008, + 0x002C, 0x0444, 0x07D0, 0x03B4, 0x000C, + 0x0024, 0x042C, 0x07D4, 0x03CC, 0x0010, + 0x0020, 0x0414, 0x07D4, 0x03E0, 0x0018, + 0x001C, 0x03FC, 0x07D4, 0x03F8, 0x001C +}; + +//========================================= +// = 6 +// = 64 +// = 0.83333 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_6tap_64p_upscale[198] = { + 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, + 0x000C, 0x3FD0, 0x0FFC, 0x0034, 0x3FF4, 0x0000, + 0x0018, 0x3F9C, 0x0FF8, 0x006C, 0x3FE8, 0x0000, + 0x0024, 0x3F6C, 0x0FF0, 0x00A8, 0x3FD8, 0x0000, + 0x002C, 0x3F44, 0x0FE4, 0x00E4, 0x3FC8, 0x0000, + 0x0038, 0x3F18, 0x0FD4, 0x0124, 0x3FB8, 0x0000, + 0x0040, 0x3EF0, 0x0FC0, 0x0164, 0x3FA8, 0x0004, + 0x0048, 0x3EC8, 0x0FAC, 0x01A8, 0x3F98, 0x0004, + 0x0050, 0x3EA8, 0x0F94, 0x01EC, 0x3F84, 0x0004, + 0x0058, 0x3E84, 0x0F74, 0x0234, 0x3F74, 0x0008, + 0x0060, 0x3E68, 0x0F54, 0x027C, 0x3F60, 0x0008, + 0x0064, 0x3E4C, 0x0F30, 0x02C8, 0x3F4C, 0x000C, + 0x006C, 0x3E30, 0x0F04, 0x0314, 0x3F3C, 0x0010, + 0x0070, 0x3E18, 0x0EDC, 0x0360, 0x3F28, 0x0014, + 0x0074, 0x3E04, 0x0EB0, 0x03B0, 0x3F14, 0x0014, + 0x0078, 0x3DF0, 0x0E80, 0x0400, 0x3F00, 0x0018, + 0x0078, 0x3DE0, 0x0E4C, 0x0454, 0x3EEC, 0x001C, + 0x007C, 0x3DD0, 0x0E14, 0x04A8, 0x3ED8, 0x0020, + 0x007C, 0x3DC4, 0x0DDC, 0x04FC, 0x3EC4, 0x0024, + 0x007C, 0x3DBC, 0x0DA0, 0x0550, 0x3EB0, 0x0028, + 0x0080, 0x3DB4, 0x0D5C, 0x05A8, 0x3E9C, 0x002C, + 0x0080, 0x3DAC, 0x0D1C, 0x0600, 0x3E88, 0x0030, + 0x007C, 0x3DA8, 0x0CDC, 0x0658, 0x3E74, 0x0034, + 0x007C, 0x3DA4, 0x0C94, 0x06B0, 0x3E64, 0x0038, + 0x007C, 0x3DA4, 0x0C48, 0x0708, 0x3E50, 0x0040, + 0x0078, 0x3DA4, 0x0C00, 0x0760, 0x3E40, 0x0044, + 0x0078, 0x3DA8, 0x0BB4, 0x07B8, 0x3E2C, 0x0048, + 0x0074, 0x3DAC, 0x0B68, 0x0810, 0x3E1C, 0x004C, + 0x0070, 0x3DB4, 0x0B18, 0x0868, 0x3E0C, 0x0050, + 0x006C, 0x3DBC, 0x0AC4, 0x08C4, 0x3DFC, 0x0054, + 0x0068, 0x3DC4, 0x0A74, 0x0918, 0x3DF0, 0x0058, + 0x0068, 0x3DCC, 0x0A20, 0x0970, 0x3DE0, 0x005C, + 0x0064, 0x3DD4, 0x09C8, 0x09C8, 0x3DD4, 0x0064 +}; + +//========================================= +// = 6 +// = 64 +// = 1.16666 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_6tap_64p_116[198] = { + 0x3F0C, 0x0240, 0x0D68, 0x0240, 0x3F0C, 0x0000, + 0x3F18, 0x0210, 0x0D64, 0x0274, 0x3F00, 0x0000, + 0x3F24, 0x01E0, 0x0D58, 0x02A8, 0x3EF8, 0x0004, + 0x3F2C, 0x01B0, 0x0D58, 0x02DC, 0x3EEC, 0x0004, + 0x3F38, 0x0180, 0x0D50, 0x0310, 0x3EE0, 0x0008, + 0x3F44, 0x0154, 0x0D40, 0x0348, 0x3ED8, 0x0008, + 0x3F50, 0x0128, 0x0D34, 0x037C, 0x3ECC, 0x000C, + 0x3F5C, 0x00FC, 0x0D20, 0x03B4, 0x3EC4, 0x0010, + 0x3F64, 0x00D4, 0x0D14, 0x03EC, 0x3EB8, 0x0010, + 0x3F70, 0x00AC, 0x0CFC, 0x0424, 0x3EB0, 0x0014, + 0x3F78, 0x0084, 0x0CE8, 0x0460, 0x3EA8, 0x0014, + 0x3F84, 0x0060, 0x0CCC, 0x0498, 0x3EA0, 0x0018, + 0x3F90, 0x003C, 0x0CB4, 0x04D0, 0x3E98, 0x0018, + 0x3F98, 0x0018, 0x0C9C, 0x050C, 0x3E90, 0x0018, + 0x3FA0, 0x3FFC, 0x0C78, 0x0548, 0x3E88, 0x001C, + 0x3FAC, 0x3FDC, 0x0C54, 0x0584, 0x3E84, 0x001C, + 0x3FB4, 0x3FBC, 0x0C3C, 0x05BC, 0x3E7C, 0x001C, + 0x3FBC, 0x3FA0, 0x0C14, 0x05F8, 0x3E78, 0x0020, + 0x3FC4, 0x3F84, 0x0BF0, 0x0634, 0x3E74, 0x0020, + 0x3FCC, 0x3F68, 0x0BCC, 0x0670, 0x3E70, 0x0020, + 0x3FD4, 0x3F50, 0x0BA4, 0x06AC, 0x3E6C, 0x0020, + 0x3FDC, 0x3F38, 0x0B78, 0x06E8, 0x3E6C, 0x0020, + 0x3FE0, 0x3F24, 0x0B50, 0x0724, 0x3E68, 0x0020, + 0x3FE8, 0x3F0C, 0x0B24, 0x0760, 0x3E68, 0x0020, + 0x3FF0, 0x3EFC, 0x0AF4, 0x0798, 0x3E68, 0x0020, + 0x3FF4, 0x3EE8, 0x0AC8, 0x07D4, 0x3E68, 0x0020, + 0x3FFC, 0x3ED8, 0x0A94, 0x0810, 0x3E6C, 0x001C, + 0x0000, 0x3EC8, 0x0A64, 0x0848, 0x3E70, 0x001C, + 0x0000, 0x3EB8, 0x0A38, 0x0880, 0x3E74, 0x001C, + 0x0004, 0x3EAC, 0x0A04, 0x08BC, 0x3E78, 0x0018, + 0x0008, 0x3EA4, 0x09D0, 0x08F4, 0x3E7C, 0x0014, + 0x000C, 0x3E98, 0x0998, 0x092C, 0x3E84, 0x0014, + 0x0010, 0x3E90, 0x0964, 0x0960, 0x3E8C, 0x0010 +}; + +//========================================= +// = 6 +// = 64 +// = 1.49999 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_6tap_64p_149[198] = { + 0x3F14, 0x0394, 0x0AB0, 0x0394, 0x3F14, 0x0000, + 0x3F18, 0x036C, 0x0AB0, 0x03B8, 0x3F14, 0x0000, + 0x3F18, 0x0348, 0x0AAC, 0x03E0, 0x3F14, 0x0000, + 0x3F1C, 0x0320, 0x0AAC, 0x0408, 0x3F10, 0x0000, + 0x3F20, 0x02FC, 0x0AA8, 0x042C, 0x3F10, 0x0000, + 0x3F24, 0x02D8, 0x0AA0, 0x0454, 0x3F10, 0x0000, + 0x3F28, 0x02B4, 0x0A98, 0x047C, 0x3F10, 0x0000, + 0x3F28, 0x0290, 0x0A90, 0x04A4, 0x3F14, 0x0000, + 0x3F30, 0x026C, 0x0A84, 0x04CC, 0x3F14, 0x0000, + 0x3F34, 0x024C, 0x0A7C, 0x04F4, 0x3F14, 0x3FFC, + 0x3F38, 0x0228, 0x0A70, 0x051C, 0x3F18, 0x3FFC, + 0x3F3C, 0x0208, 0x0A64, 0x0544, 0x3F1C, 0x3FF8, + 0x3F40, 0x01E8, 0x0A54, 0x056C, 0x3F20, 0x3FF8, + 0x3F44, 0x01C8, 0x0A48, 0x0594, 0x3F24, 0x3FF4, + 0x3F4C, 0x01A8, 0x0A34, 0x05BC, 0x3F28, 0x3FF4, + 0x3F50, 0x0188, 0x0A28, 0x05E4, 0x3F2C, 0x3FF0, + 0x3F54, 0x016C, 0x0A10, 0x060C, 0x3F34, 0x3FF0, + 0x3F5C, 0x014C, 0x09FC, 0x0634, 0x3F3C, 0x3FEC, + 0x3F60, 0x0130, 0x09EC, 0x065C, 0x3F40, 0x3FE8, + 0x3F68, 0x0114, 0x09D0, 0x0684, 0x3F48, 0x3FE8, + 0x3F6C, 0x00F8, 0x09B8, 0x06AC, 0x3F54, 0x3FE4, + 0x3F74, 0x00E0, 0x09A0, 0x06D0, 0x3F5C, 0x3FE0, + 0x3F78, 0x00C4, 0x098C, 0x06F8, 0x3F64, 0x3FDC, + 0x3F7C, 0x00AC, 0x0970, 0x0720, 0x3F70, 0x3FD8, + 0x3F84, 0x0094, 0x0954, 0x0744, 0x3F7C, 0x3FD4, + 0x3F88, 0x007C, 0x093C, 0x0768, 0x3F88, 0x3FD0, + 0x3F90, 0x0064, 0x091C, 0x0790, 0x3F94, 0x3FCC, + 0x3F94, 0x0050, 0x08FC, 0x07B4, 0x3FA4, 0x3FC8, + 0x3F98, 0x003C, 0x08E0, 0x07D8, 0x3FB0, 0x3FC4, + 0x3FA0, 0x0024, 0x08C0, 0x07FC, 0x3FC0, 0x3FC0, + 0x3FA4, 0x0014, 0x08A4, 0x081C, 0x3FD0, 0x3FB8, + 0x3FAC, 0x0000, 0x0880, 0x0840, 0x3FE0, 0x3FB4, + 0x3FB0, 0x3FF0, 0x0860, 0x0860, 0x3FF0, 0x3FB0 +}; + +//========================================= +// = 6 +// = 64 +// = 1.83332 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_6tap_64p_183[198] = { + 0x002C, 0x0420, 0x076C, 0x041C, 0x002C, 0x0000, + 0x0028, 0x040C, 0x0768, 0x0430, 0x0034, 0x0000, + 0x0020, 0x03F8, 0x0768, 0x0448, 0x003C, 0x3FFC, + 0x0018, 0x03E4, 0x0768, 0x045C, 0x0044, 0x3FFC, + 0x0014, 0x03D0, 0x0768, 0x0470, 0x004C, 0x3FF8, + 0x000C, 0x03BC, 0x0764, 0x0484, 0x0058, 0x3FF8, + 0x0008, 0x03A4, 0x0764, 0x049C, 0x0060, 0x3FF4, + 0x0004, 0x0390, 0x0760, 0x04B0, 0x0068, 0x3FF4, + 0x0000, 0x037C, 0x0760, 0x04C4, 0x0070, 0x3FF0, + 0x3FFC, 0x0364, 0x075C, 0x04D8, 0x007C, 0x3FF0, + 0x3FF8, 0x0350, 0x0758, 0x04F0, 0x0084, 0x3FEC, + 0x3FF4, 0x033C, 0x0750, 0x0504, 0x0090, 0x3FEC, + 0x3FF0, 0x0328, 0x074C, 0x0518, 0x009C, 0x3FE8, + 0x3FEC, 0x0314, 0x0744, 0x052C, 0x00A8, 0x3FE8, + 0x3FE8, 0x0304, 0x0740, 0x0540, 0x00B0, 0x3FE4, + 0x3FE4, 0x02EC, 0x073C, 0x0554, 0x00BC, 0x3FE4, + 0x3FE0, 0x02DC, 0x0734, 0x0568, 0x00C8, 0x3FE0, + 0x3FE0, 0x02C4, 0x072C, 0x057C, 0x00D4, 0x3FE0, + 0x3FDC, 0x02B4, 0x0724, 0x058C, 0x00E4, 0x3FDC, + 0x3FDC, 0x02A0, 0x0718, 0x05A0, 0x00F0, 0x3FDC, + 0x3FD8, 0x028C, 0x0714, 0x05B4, 0x00FC, 0x3FD8, + 0x3FD8, 0x0278, 0x0704, 0x05C8, 0x010C, 0x3FD8, + 0x3FD4, 0x0264, 0x0700, 0x05D8, 0x0118, 0x3FD8, + 0x3FD4, 0x0254, 0x06F0, 0x05EC, 0x0128, 0x3FD4, + 0x3FD0, 0x0244, 0x06E8, 0x05FC, 0x0134, 0x3FD4, + 0x3FD0, 0x0230, 0x06DC, 0x060C, 0x0144, 0x3FD4, + 0x3FD0, 0x021C, 0x06D0, 0x0620, 0x0154, 0x3FD0, + 0x3FD0, 0x0208, 0x06C4, 0x0630, 0x0164, 0x3FD0, + 0x3FD0, 0x01F8, 0x06B8, 0x0640, 0x0170, 0x3FD0, + 0x3FCC, 0x01E8, 0x06AC, 0x0650, 0x0180, 0x3FD0, + 0x3FCC, 0x01D8, 0x069C, 0x0660, 0x0190, 0x3FD0, + 0x3FCC, 0x01C4, 0x068C, 0x0670, 0x01A4, 0x3FD0, + 0x3FCC, 0x01B8, 0x0680, 0x067C, 0x01B4, 0x3FCC +}; + +//========================================= +// = 7 +// = 64 +// = 0.83333 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_7tap_64p_upscale[231] = { + 0x00B0, 0x3D98, 0x09BC, 0x09B8, 0x3D94, 0x00B0, 0x0000, + 0x00AC, 0x3DA0, 0x0968, 0x0A10, 0x3D88, 0x00B4, 0x0000, + 0x00A8, 0x3DAC, 0x0914, 0x0A60, 0x3D80, 0x00B8, 0x0000, + 0x00A4, 0x3DB8, 0x08C0, 0x0AB4, 0x3D78, 0x00BC, 0x3FFC, + 0x00A0, 0x3DC8, 0x0868, 0x0B00, 0x3D74, 0x00C0, 0x3FFC, + 0x0098, 0x3DD8, 0x0818, 0x0B54, 0x3D6C, 0x00C0, 0x3FF8, + 0x0094, 0x3DE8, 0x07C0, 0x0B9C, 0x3D6C, 0x00C4, 0x3FF8, + 0x008C, 0x3DFC, 0x0768, 0x0BEC, 0x3D68, 0x00C4, 0x3FF8, + 0x0088, 0x3E0C, 0x0714, 0x0C38, 0x3D68, 0x00C4, 0x3FF4, + 0x0080, 0x3E20, 0x06BC, 0x0C80, 0x3D6C, 0x00C4, 0x3FF4, + 0x0078, 0x3E34, 0x0668, 0x0CC4, 0x3D70, 0x00C4, 0x3FF4, + 0x0074, 0x3E48, 0x0610, 0x0D08, 0x3D78, 0x00C4, 0x3FF0, + 0x006C, 0x3E5C, 0x05BC, 0x0D48, 0x3D80, 0x00C4, 0x3FF0, + 0x0068, 0x3E74, 0x0568, 0x0D84, 0x3D88, 0x00C0, 0x3FF0, + 0x0060, 0x3E88, 0x0514, 0x0DC8, 0x3D94, 0x00BC, 0x3FEC, + 0x0058, 0x3E9C, 0x04C0, 0x0E04, 0x3DA4, 0x00B8, 0x3FEC, + 0x0054, 0x3EB4, 0x046C, 0x0E38, 0x3DB4, 0x00B4, 0x3FEC, + 0x004C, 0x3ECC, 0x0418, 0x0E6C, 0x3DC8, 0x00B0, 0x3FEC, + 0x0044, 0x3EE0, 0x03C8, 0x0EA4, 0x3DDC, 0x00A8, 0x3FEC, + 0x0040, 0x3EF8, 0x0378, 0x0ED0, 0x3DF4, 0x00A0, 0x3FEC, + 0x0038, 0x3F0C, 0x032C, 0x0EFC, 0x3E10, 0x0098, 0x3FEC, + 0x0034, 0x3F24, 0x02DC, 0x0F24, 0x3E2C, 0x0090, 0x3FEC, + 0x002C, 0x3F38, 0x0294, 0x0F4C, 0x3E48, 0x0088, 0x3FEC, + 0x0028, 0x3F50, 0x0248, 0x0F68, 0x3E6C, 0x007C, 0x3FF0, + 0x0020, 0x3F64, 0x0200, 0x0F88, 0x3E90, 0x0074, 0x3FF0, + 0x001C, 0x3F7C, 0x01B8, 0x0FA4, 0x3EB4, 0x0068, 0x3FF0, + 0x0018, 0x3F90, 0x0174, 0x0FBC, 0x3EDC, 0x0058, 0x3FF4, + 0x0014, 0x3FA4, 0x0130, 0x0FD0, 0x3F08, 0x004C, 0x3FF4, + 0x000C, 0x3FB8, 0x00F0, 0x0FE4, 0x3F34, 0x003C, 0x3FF8, + 0x0008, 0x3FCC, 0x00B0, 0x0FF0, 0x3F64, 0x0030, 0x3FF8, + 0x0004, 0x3FDC, 0x0070, 0x0FFC, 0x3F98, 0x0020, 0x3FFC, + 0x0000, 0x3FF0, 0x0038, 0x0FFC, 0x3FCC, 0x0010, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000 +}; + +//========================================= +// = 7 +// = 64 +// = 1.16666 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_7tap_64p_116[231] = { + 0x0020, 0x3E58, 0x0988, 0x0988, 0x3E58, 0x0020, 0x0000, + 0x0024, 0x3E4C, 0x0954, 0x09C0, 0x3E64, 0x0018, 0x0000, + 0x002C, 0x3E44, 0x091C, 0x09F4, 0x3E70, 0x0010, 0x0000, + 0x0030, 0x3E3C, 0x08E8, 0x0A24, 0x3E80, 0x0008, 0x0000, + 0x0034, 0x3E34, 0x08AC, 0x0A5C, 0x3E90, 0x0000, 0x0000, + 0x003C, 0x3E30, 0x0870, 0x0A84, 0x3EA0, 0x3FFC, 0x0004, + 0x0040, 0x3E28, 0x0838, 0x0AB4, 0x3EB4, 0x3FF4, 0x0004, + 0x0044, 0x3E24, 0x07FC, 0x0AE4, 0x3EC8, 0x3FEC, 0x0004, + 0x0048, 0x3E24, 0x07C4, 0x0B08, 0x3EDC, 0x3FE4, 0x0008, + 0x0048, 0x3E20, 0x0788, 0x0B3C, 0x3EF4, 0x3FD8, 0x0008, + 0x004C, 0x3E20, 0x074C, 0x0B60, 0x3F0C, 0x3FD0, 0x000C, + 0x0050, 0x3E20, 0x0710, 0x0B8C, 0x3F24, 0x3FC4, 0x000C, + 0x0050, 0x3E20, 0x06D4, 0x0BB0, 0x3F40, 0x3FBC, 0x0010, + 0x0054, 0x3E24, 0x0698, 0x0BD4, 0x3F5C, 0x3FB0, 0x0010, + 0x0054, 0x3E24, 0x065C, 0x0BFC, 0x3F78, 0x3FA4, 0x0014, + 0x0054, 0x3E28, 0x0624, 0x0C1C, 0x3F98, 0x3F98, 0x0014, + 0x0058, 0x3E2C, 0x05E4, 0x0C3C, 0x3FB8, 0x3F8C, 0x0018, + 0x0058, 0x3E34, 0x05A8, 0x0C58, 0x3FD8, 0x3F80, 0x001C, + 0x0058, 0x3E38, 0x0570, 0x0C78, 0x3FF8, 0x3F74, 0x001C, + 0x0058, 0x3E40, 0x0534, 0x0C94, 0x0018, 0x3F68, 0x0020, + 0x0058, 0x3E48, 0x04F4, 0x0CAC, 0x0040, 0x3F5C, 0x0024, + 0x0058, 0x3E50, 0x04BC, 0x0CC4, 0x0064, 0x3F50, 0x0024, + 0x0054, 0x3E58, 0x0484, 0x0CD8, 0x008C, 0x3F44, 0x0028, + 0x0054, 0x3E60, 0x0448, 0x0CEC, 0x00B4, 0x3F38, 0x002C, + 0x0054, 0x3E68, 0x0410, 0x0CFC, 0x00E0, 0x3F28, 0x0030, + 0x0054, 0x3E74, 0x03D4, 0x0D0C, 0x010C, 0x3F1C, 0x0030, + 0x0050, 0x3E7C, 0x03A0, 0x0D18, 0x0138, 0x3F10, 0x0034, + 0x0050, 0x3E88, 0x0364, 0x0D24, 0x0164, 0x3F04, 0x0038, + 0x004C, 0x3E94, 0x0330, 0x0D30, 0x0194, 0x3EF4, 0x0038, + 0x004C, 0x3EA0, 0x02F8, 0x0D34, 0x01C4, 0x3EE8, 0x003C, + 0x0048, 0x3EAC, 0x02C0, 0x0D3C, 0x01F4, 0x3EDC, 0x0040, + 0x0048, 0x3EB8, 0x0290, 0x0D3C, 0x0224, 0x3ED0, 0x0040, + 0x0044, 0x3EC4, 0x0258, 0x0D40, 0x0258, 0x3EC4, 0x0044 +}; + +//========================================= +// = 7 +// = 64 +// = 1.49999 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_7tap_64p_149[231] = { + 0x3F68, 0x3FEC, 0x08A8, 0x08AC, 0x3FF0, 0x3F68, 0x0000, + 0x3F70, 0x3FDC, 0x0888, 0x08CC, 0x0000, 0x3F60, 0x0000, + 0x3F74, 0x3FC8, 0x0868, 0x08F0, 0x0014, 0x3F58, 0x0000, + 0x3F7C, 0x3FB4, 0x0844, 0x0908, 0x002C, 0x3F54, 0x0004, + 0x3F84, 0x3FA4, 0x0820, 0x0924, 0x0044, 0x3F4C, 0x0004, + 0x3F88, 0x3F90, 0x0800, 0x0944, 0x005C, 0x3F44, 0x0004, + 0x3F90, 0x3F80, 0x07D8, 0x095C, 0x0074, 0x3F40, 0x0008, + 0x3F98, 0x3F70, 0x07B0, 0x097C, 0x008C, 0x3F38, 0x0008, + 0x3F9C, 0x3F60, 0x0790, 0x0994, 0x00A8, 0x3F30, 0x0008, + 0x3FA4, 0x3F54, 0x0764, 0x09B0, 0x00C4, 0x3F28, 0x0008, + 0x3FA8, 0x3F48, 0x0740, 0x09C4, 0x00DC, 0x3F24, 0x000C, + 0x3FB0, 0x3F38, 0x0718, 0x09DC, 0x00FC, 0x3F1C, 0x000C, + 0x3FB4, 0x3F2C, 0x06F0, 0x09F4, 0x0118, 0x3F18, 0x000C, + 0x3FBC, 0x3F24, 0x06C8, 0x0A08, 0x0134, 0x3F10, 0x000C, + 0x3FC0, 0x3F18, 0x06A0, 0x0A1C, 0x0154, 0x3F08, 0x0010, + 0x3FC8, 0x3F10, 0x0678, 0x0A2C, 0x0170, 0x3F04, 0x0010, + 0x3FCC, 0x3F04, 0x0650, 0x0A40, 0x0190, 0x3F00, 0x0010, + 0x3FD0, 0x3EFC, 0x0628, 0x0A54, 0x01B0, 0x3EF8, 0x0010, + 0x3FD4, 0x3EF4, 0x0600, 0x0A64, 0x01D0, 0x3EF4, 0x0010, + 0x3FDC, 0x3EEC, 0x05D8, 0x0A6C, 0x01F4, 0x3EF0, 0x0010, + 0x3FE0, 0x3EE8, 0x05B0, 0x0A7C, 0x0214, 0x3EE8, 0x0010, + 0x3FE4, 0x3EE0, 0x0588, 0x0A88, 0x0238, 0x3EE4, 0x0010, + 0x3FE8, 0x3EDC, 0x055C, 0x0A98, 0x0258, 0x3EE0, 0x0010, + 0x3FEC, 0x3ED8, 0x0534, 0x0AA0, 0x027C, 0x3EDC, 0x0010, + 0x3FF0, 0x3ED4, 0x050C, 0x0AAC, 0x02A0, 0x3ED8, 0x000C, + 0x3FF4, 0x3ED0, 0x04E4, 0x0AB4, 0x02C4, 0x3ED4, 0x000C, + 0x3FF4, 0x3ECC, 0x04C0, 0x0ABC, 0x02E8, 0x3ED0, 0x000C, + 0x3FF8, 0x3ECC, 0x0494, 0x0AC0, 0x030C, 0x3ED0, 0x000C, + 0x3FFC, 0x3EC8, 0x046C, 0x0AC8, 0x0334, 0x3ECC, 0x0008, + 0x0000, 0x3EC8, 0x0444, 0x0AC8, 0x0358, 0x3ECC, 0x0008, + 0x0000, 0x3EC8, 0x041C, 0x0ACC, 0x0380, 0x3EC8, 0x0008, + 0x0000, 0x3EC8, 0x03F4, 0x0AD0, 0x03A8, 0x3EC8, 0x0004, + 0x0004, 0x3EC8, 0x03CC, 0x0AD0, 0x03CC, 0x3EC8, 0x0004 +}; + +//========================================= +// = 7 +// = 64 +// = 1.83332 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_7tap_64p_183[231] = { + 0x3FA4, 0x01E8, 0x0674, 0x0674, 0x01E8, 0x3FA4, 0x0000, + 0x3FA4, 0x01D4, 0x0668, 0x0684, 0x01F8, 0x3FA4, 0x0000, + 0x3FA4, 0x01C4, 0x0658, 0x0690, 0x0208, 0x3FA8, 0x0000, + 0x3FA0, 0x01B4, 0x064C, 0x06A0, 0x021C, 0x3FA8, 0x3FFC, + 0x3FA0, 0x01A4, 0x063C, 0x06AC, 0x022C, 0x3FAC, 0x3FFC, + 0x3FA0, 0x0194, 0x0630, 0x06B4, 0x0240, 0x3FAC, 0x3FFC, + 0x3FA0, 0x0184, 0x0620, 0x06C4, 0x0250, 0x3FB0, 0x3FF8, + 0x3FA0, 0x0174, 0x0614, 0x06CC, 0x0264, 0x3FB0, 0x3FF8, + 0x3FA0, 0x0164, 0x0604, 0x06D8, 0x0278, 0x3FB4, 0x3FF4, + 0x3FA0, 0x0154, 0x05F4, 0x06E4, 0x0288, 0x3FB8, 0x3FF4, + 0x3FA0, 0x0148, 0x05E4, 0x06EC, 0x029C, 0x3FBC, 0x3FF0, + 0x3FA0, 0x0138, 0x05D4, 0x06F4, 0x02B0, 0x3FC0, 0x3FF0, + 0x3FA0, 0x0128, 0x05C4, 0x0704, 0x02C4, 0x3FC0, 0x3FEC, + 0x3FA0, 0x011C, 0x05B4, 0x0708, 0x02D8, 0x3FC4, 0x3FEC, + 0x3FA4, 0x010C, 0x05A4, 0x0714, 0x02E8, 0x3FC8, 0x3FE8, + 0x3FA4, 0x0100, 0x0590, 0x0718, 0x02FC, 0x3FD0, 0x3FE8, + 0x3FA4, 0x00F0, 0x0580, 0x0724, 0x0310, 0x3FD4, 0x3FE4, + 0x3FA4, 0x00E4, 0x056C, 0x072C, 0x0324, 0x3FD8, 0x3FE4, + 0x3FA8, 0x00D8, 0x055C, 0x0730, 0x0338, 0x3FDC, 0x3FE0, + 0x3FA8, 0x00CC, 0x0548, 0x0738, 0x034C, 0x3FE4, 0x3FDC, + 0x3FA8, 0x00BC, 0x0538, 0x0740, 0x0360, 0x3FE8, 0x3FDC, + 0x3FAC, 0x00B0, 0x0528, 0x0744, 0x0374, 0x3FEC, 0x3FD8, + 0x3FAC, 0x00A4, 0x0514, 0x0748, 0x0388, 0x3FF4, 0x3FD8, + 0x3FB0, 0x0098, 0x0500, 0x074C, 0x039C, 0x3FFC, 0x3FD4, + 0x3FB0, 0x0090, 0x04EC, 0x0750, 0x03B0, 0x0000, 0x3FD4, + 0x3FB0, 0x0084, 0x04DC, 0x0758, 0x03C4, 0x0004, 0x3FD0, + 0x3FB4, 0x0078, 0x04CC, 0x0758, 0x03D8, 0x000C, 0x3FCC, + 0x3FB4, 0x006C, 0x04B8, 0x075C, 0x03EC, 0x0014, 0x3FCC, + 0x3FB8, 0x0064, 0x04A0, 0x0760, 0x0400, 0x001C, 0x3FC8, + 0x3FB8, 0x0058, 0x0490, 0x0760, 0x0414, 0x0024, 0x3FC8, + 0x3FBC, 0x0050, 0x047C, 0x0760, 0x0428, 0x002C, 0x3FC4, + 0x3FBC, 0x0048, 0x0464, 0x0764, 0x043C, 0x0034, 0x3FC4, + 0x3FC0, 0x003C, 0x0454, 0x0764, 0x0450, 0x003C, 0x3FC0 +}; + +//========================================= +// = 8 +// = 64 +// = 0.83333 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_8tap_64p_upscale[264] = { + 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3FFC, 0x0014, 0x3FC8, 0x1000, 0x0038, 0x3FEC, 0x0004, 0x0000, + 0x3FF4, 0x0024, 0x3F94, 0x0FFC, 0x0074, 0x3FD8, 0x000C, 0x0000, + 0x3FF0, 0x0038, 0x3F60, 0x0FEC, 0x00B4, 0x3FC4, 0x0014, 0x0000, + 0x3FEC, 0x004C, 0x3F2C, 0x0FE4, 0x00F4, 0x3FAC, 0x0018, 0x0000, + 0x3FE4, 0x005C, 0x3F00, 0x0FD4, 0x0138, 0x3F94, 0x0020, 0x0000, + 0x3FE0, 0x006C, 0x3ED0, 0x0FC4, 0x017C, 0x3F7C, 0x0028, 0x0000, + 0x3FDC, 0x007C, 0x3EA8, 0x0FA4, 0x01C4, 0x3F68, 0x0030, 0x0000, + 0x3FD8, 0x0088, 0x3E80, 0x0F90, 0x020C, 0x3F50, 0x0038, 0x3FFC, + 0x3FD4, 0x0098, 0x3E58, 0x0F70, 0x0258, 0x3F38, 0x0040, 0x3FFC, + 0x3FD0, 0x00A4, 0x3E34, 0x0F54, 0x02A0, 0x3F1C, 0x004C, 0x3FFC, + 0x3FD0, 0x00B0, 0x3E14, 0x0F28, 0x02F0, 0x3F04, 0x0054, 0x3FFC, + 0x3FCC, 0x00BC, 0x3DF4, 0x0F08, 0x033C, 0x3EEC, 0x005C, 0x3FF8, + 0x3FC8, 0x00C8, 0x3DD8, 0x0EDC, 0x038C, 0x3ED4, 0x0064, 0x3FF8, + 0x3FC8, 0x00D0, 0x3DC0, 0x0EAC, 0x03E0, 0x3EBC, 0x006C, 0x3FF4, + 0x3FC4, 0x00D8, 0x3DA8, 0x0E7C, 0x0430, 0x3EA4, 0x0078, 0x3FF4, + 0x3FC4, 0x00E0, 0x3D94, 0x0E48, 0x0484, 0x3E8C, 0x0080, 0x3FF0, + 0x3FC4, 0x00E8, 0x3D80, 0x0E10, 0x04D8, 0x3E74, 0x0088, 0x3FF0, + 0x3FC4, 0x00F0, 0x3D70, 0x0DD8, 0x052C, 0x3E5C, 0x0090, 0x3FEC, + 0x3FC0, 0x00F4, 0x3D60, 0x0DA0, 0x0584, 0x3E44, 0x0098, 0x3FEC, + 0x3FC0, 0x00F8, 0x3D54, 0x0D68, 0x05D8, 0x3E2C, 0x00A0, 0x3FE8, + 0x3FC0, 0x00FC, 0x3D48, 0x0D20, 0x0630, 0x3E18, 0x00AC, 0x3FE8, + 0x3FC0, 0x0100, 0x3D40, 0x0CE0, 0x0688, 0x3E00, 0x00B4, 0x3FE4, + 0x3FC4, 0x0100, 0x3D3C, 0x0C98, 0x06DC, 0x3DEC, 0x00BC, 0x3FE4, + 0x3FC4, 0x0100, 0x3D38, 0x0C58, 0x0734, 0x3DD8, 0x00C0, 0x3FE0, + 0x3FC4, 0x0104, 0x3D38, 0x0C0C, 0x078C, 0x3DC4, 0x00C8, 0x3FDC, + 0x3FC4, 0x0100, 0x3D38, 0x0BC4, 0x07E4, 0x3DB0, 0x00D0, 0x3FDC, + 0x3FC4, 0x0100, 0x3D38, 0x0B78, 0x083C, 0x3DA0, 0x00D8, 0x3FD8, + 0x3FC8, 0x0100, 0x3D3C, 0x0B28, 0x0890, 0x3D90, 0x00DC, 0x3FD8, + 0x3FC8, 0x00FC, 0x3D40, 0x0ADC, 0x08E8, 0x3D80, 0x00E4, 0x3FD4, + 0x3FCC, 0x00FC, 0x3D48, 0x0A84, 0x093C, 0x3D74, 0x00E8, 0x3FD4, + 0x3FCC, 0x00F8, 0x3D50, 0x0A38, 0x0990, 0x3D64, 0x00F0, 0x3FD0, + 0x3FD0, 0x00F4, 0x3D58, 0x09E0, 0x09E4, 0x3D5C, 0x00F4, 0x3FD0 +}; + +//========================================= +// = 8 +// = 64 +// = 1.16666 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_8tap_64p_116[264] = { + 0x0080, 0x3E90, 0x0268, 0x0D14, 0x0264, 0x3E90, 0x0080, 0x0000, + 0x007C, 0x3E9C, 0x0238, 0x0D14, 0x0298, 0x3E84, 0x0080, 0x0000, + 0x0078, 0x3EAC, 0x0200, 0x0D10, 0x02D0, 0x3E78, 0x0084, 0x0000, + 0x0078, 0x3EB8, 0x01D0, 0x0D0C, 0x0304, 0x3E6C, 0x0084, 0x0000, + 0x0074, 0x3EC8, 0x01A0, 0x0D00, 0x033C, 0x3E60, 0x0088, 0x0000, + 0x0070, 0x3ED4, 0x0170, 0x0D00, 0x0374, 0x3E54, 0x0088, 0x3FFC, + 0x006C, 0x3EE4, 0x0140, 0x0CF8, 0x03AC, 0x3E48, 0x0088, 0x3FFC, + 0x006C, 0x3EF0, 0x0114, 0x0CE8, 0x03E4, 0x3E3C, 0x008C, 0x3FFC, + 0x0068, 0x3F00, 0x00E8, 0x0CD8, 0x041C, 0x3E34, 0x008C, 0x3FFC, + 0x0064, 0x3F10, 0x00BC, 0x0CCC, 0x0454, 0x3E28, 0x008C, 0x3FFC, + 0x0060, 0x3F1C, 0x0090, 0x0CBC, 0x0490, 0x3E20, 0x008C, 0x3FFC, + 0x005C, 0x3F2C, 0x0068, 0x0CA4, 0x04CC, 0x3E18, 0x008C, 0x3FFC, + 0x0058, 0x3F38, 0x0040, 0x0C94, 0x0504, 0x3E10, 0x008C, 0x3FFC, + 0x0054, 0x3F48, 0x001C, 0x0C7C, 0x0540, 0x3E08, 0x0088, 0x3FFC, + 0x0050, 0x3F54, 0x3FF8, 0x0C60, 0x057C, 0x3E04, 0x0088, 0x3FFC, + 0x004C, 0x3F64, 0x3FD4, 0x0C44, 0x05B8, 0x3DFC, 0x0088, 0x3FFC, + 0x0048, 0x3F70, 0x3FB4, 0x0C28, 0x05F4, 0x3DF8, 0x0084, 0x3FFC, + 0x0044, 0x3F80, 0x3F90, 0x0C0C, 0x0630, 0x3DF4, 0x0080, 0x3FFC, + 0x0040, 0x3F8C, 0x3F70, 0x0BE8, 0x066C, 0x3DF4, 0x0080, 0x3FFC, + 0x003C, 0x3F9C, 0x3F50, 0x0BC8, 0x06A8, 0x3DF0, 0x007C, 0x3FFC, + 0x0038, 0x3FA8, 0x3F34, 0x0BA0, 0x06E4, 0x3DF0, 0x0078, 0x0000, + 0x0034, 0x3FB4, 0x3F18, 0x0B80, 0x071C, 0x3DF0, 0x0074, 0x0000, + 0x0030, 0x3FC0, 0x3EFC, 0x0B5C, 0x0758, 0x3DF0, 0x0070, 0x0000, + 0x002C, 0x3FCC, 0x3EE4, 0x0B34, 0x0794, 0x3DF4, 0x0068, 0x0000, + 0x002C, 0x3FDC, 0x3ECC, 0x0B08, 0x07CC, 0x3DF4, 0x0064, 0x0000, + 0x0028, 0x3FE4, 0x3EB4, 0x0AE0, 0x0808, 0x3DF8, 0x0060, 0x0000, + 0x0024, 0x3FF0, 0x3EA0, 0x0AB0, 0x0840, 0x3E00, 0x0058, 0x0004, + 0x0020, 0x3FFC, 0x3E90, 0x0A84, 0x0878, 0x3E04, 0x0050, 0x0004, + 0x001C, 0x0004, 0x3E7C, 0x0A54, 0x08B0, 0x3E0C, 0x004C, 0x0008, + 0x0018, 0x000C, 0x3E68, 0x0A28, 0x08E8, 0x3E18, 0x0044, 0x0008, + 0x0018, 0x0018, 0x3E54, 0x09F4, 0x0920, 0x3E20, 0x003C, 0x000C, + 0x0014, 0x0020, 0x3E48, 0x09C0, 0x0954, 0x3E2C, 0x0034, 0x0010, + 0x0010, 0x002C, 0x3E3C, 0x098C, 0x0988, 0x3E38, 0x002C, 0x0010 +}; + +//========================================= +// = 8 +// = 64 +// = 1.49999 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_8tap_64p_149[264] = { + 0x0008, 0x3E8C, 0x03F8, 0x0AE8, 0x03F8, 0x3E8C, 0x0008, 0x0000, + 0x000C, 0x3E8C, 0x03D0, 0x0AE8, 0x0420, 0x3E90, 0x0000, 0x0000, + 0x000C, 0x3E8C, 0x03AC, 0x0AE8, 0x0444, 0x3E90, 0x0000, 0x0000, + 0x0010, 0x3E90, 0x0384, 0x0AE0, 0x046C, 0x3E94, 0x3FFC, 0x0000, + 0x0014, 0x3E90, 0x035C, 0x0ADC, 0x0494, 0x3E94, 0x3FF8, 0x0004, + 0x0018, 0x3E90, 0x0334, 0x0AD8, 0x04BC, 0x3E98, 0x3FF4, 0x0004, + 0x001C, 0x3E94, 0x0310, 0x0AD0, 0x04E4, 0x3E9C, 0x3FEC, 0x0004, + 0x0020, 0x3E98, 0x02E8, 0x0AC4, 0x050C, 0x3EA0, 0x3FE8, 0x0008, + 0x0020, 0x3E98, 0x02C4, 0x0AC0, 0x0534, 0x3EA4, 0x3FE4, 0x0008, + 0x0024, 0x3E9C, 0x02A0, 0x0AB4, 0x055C, 0x3EAC, 0x3FDC, 0x0008, + 0x0024, 0x3EA0, 0x027C, 0x0AA8, 0x0584, 0x3EB0, 0x3FD8, 0x000C, + 0x0028, 0x3EA4, 0x0258, 0x0A9C, 0x05AC, 0x3EB8, 0x3FD0, 0x000C, + 0x0028, 0x3EA8, 0x0234, 0x0A90, 0x05D4, 0x3EC0, 0x3FC8, 0x0010, + 0x002C, 0x3EAC, 0x0210, 0x0A80, 0x05FC, 0x3EC8, 0x3FC4, 0x0010, + 0x002C, 0x3EB4, 0x01F0, 0x0A70, 0x0624, 0x3ED0, 0x3FBC, 0x0010, + 0x002C, 0x3EB8, 0x01CC, 0x0A60, 0x064C, 0x3EDC, 0x3FB4, 0x0014, + 0x0030, 0x3EBC, 0x01A8, 0x0A50, 0x0674, 0x3EE4, 0x3FB0, 0x0014, + 0x0030, 0x3EC4, 0x0188, 0x0A38, 0x069C, 0x3EF0, 0x3FA8, 0x0018, + 0x0030, 0x3ECC, 0x0168, 0x0A28, 0x06C0, 0x3EFC, 0x3FA0, 0x0018, + 0x0030, 0x3ED0, 0x0148, 0x0A14, 0x06E8, 0x3F08, 0x3F98, 0x001C, + 0x0030, 0x3ED8, 0x012C, 0x0A00, 0x070C, 0x3F14, 0x3F90, 0x001C, + 0x0034, 0x3EE0, 0x0108, 0x09E4, 0x0734, 0x3F24, 0x3F8C, 0x001C, + 0x0034, 0x3EE4, 0x00EC, 0x09CC, 0x0758, 0x3F34, 0x3F84, 0x0020, + 0x0034, 0x3EEC, 0x00D0, 0x09B8, 0x077C, 0x3F40, 0x3F7C, 0x0020, + 0x0034, 0x3EF4, 0x00B4, 0x0998, 0x07A4, 0x3F50, 0x3F74, 0x0024, + 0x0030, 0x3EFC, 0x0098, 0x0980, 0x07C8, 0x3F64, 0x3F6C, 0x0024, + 0x0030, 0x3F04, 0x0080, 0x0968, 0x07E8, 0x3F74, 0x3F64, 0x0024, + 0x0030, 0x3F0C, 0x0060, 0x094C, 0x080C, 0x3F88, 0x3F5C, 0x0028, + 0x0030, 0x3F14, 0x0048, 0x0930, 0x0830, 0x3F98, 0x3F54, 0x0028, + 0x0030, 0x3F1C, 0x0030, 0x0914, 0x0850, 0x3FAC, 0x3F4C, 0x0028, + 0x0030, 0x3F24, 0x0018, 0x08F0, 0x0874, 0x3FC0, 0x3F44, 0x002C, + 0x002C, 0x3F2C, 0x0000, 0x08D4, 0x0894, 0x3FD8, 0x3F3C, 0x002C, + 0x002C, 0x3F34, 0x3FEC, 0x08B4, 0x08B4, 0x3FEC, 0x3F34, 0x002C +}; + +//========================================= +// = 8 +// = 64 +// = 1.83332 (input/output) +// = 0 +// = ModifiedLanczos +// = 1.10 +// = 1.12 +//========================================= +static const uint16_t filter_8tap_64p_183[264] = { + 0x3F88, 0x0048, 0x047C, 0x0768, 0x047C, 0x0048, 0x3F88, 0x0000, + 0x3F88, 0x003C, 0x0468, 0x076C, 0x0490, 0x0054, 0x3F84, 0x0000, + 0x3F8C, 0x0034, 0x0454, 0x0768, 0x04A4, 0x005C, 0x3F84, 0x0000, + 0x3F8C, 0x0028, 0x0444, 0x076C, 0x04B4, 0x0068, 0x3F80, 0x0000, + 0x3F90, 0x0020, 0x042C, 0x0768, 0x04C8, 0x0074, 0x3F80, 0x0000, + 0x3F90, 0x0018, 0x041C, 0x0764, 0x04DC, 0x0080, 0x3F7C, 0x0000, + 0x3F94, 0x0010, 0x0408, 0x075C, 0x04F0, 0x008C, 0x3F7C, 0x0000, + 0x3F94, 0x0004, 0x03F8, 0x0760, 0x0500, 0x0098, 0x3F7C, 0x3FFC, + 0x3F98, 0x0000, 0x03E0, 0x075C, 0x0514, 0x00A4, 0x3F78, 0x3FFC, + 0x3F9C, 0x3FF8, 0x03CC, 0x0754, 0x0528, 0x00B0, 0x3F78, 0x3FFC, + 0x3F9C, 0x3FF0, 0x03B8, 0x0754, 0x0538, 0x00BC, 0x3F78, 0x3FFC, + 0x3FA0, 0x3FE8, 0x03A4, 0x0750, 0x054C, 0x00CC, 0x3F74, 0x3FF8, + 0x3FA4, 0x3FE0, 0x0390, 0x074C, 0x055C, 0x00D8, 0x3F74, 0x3FF8, + 0x3FA4, 0x3FDC, 0x037C, 0x0744, 0x0570, 0x00E4, 0x3F74, 0x3FF8, + 0x3FA8, 0x3FD4, 0x0368, 0x0740, 0x0580, 0x00F4, 0x3F74, 0x3FF4, + 0x3FA8, 0x3FCC, 0x0354, 0x073C, 0x0590, 0x0104, 0x3F74, 0x3FF4, + 0x3FAC, 0x3FC8, 0x0340, 0x0730, 0x05A4, 0x0110, 0x3F74, 0x3FF4, + 0x3FB0, 0x3FC0, 0x0330, 0x0728, 0x05B4, 0x0120, 0x3F74, 0x3FF0, + 0x3FB0, 0x3FBC, 0x031C, 0x0724, 0x05C4, 0x0130, 0x3F70, 0x3FF0, + 0x3FB4, 0x3FB4, 0x0308, 0x0720, 0x05D4, 0x013C, 0x3F70, 0x3FF0, + 0x3FB8, 0x3FB0, 0x02F4, 0x0714, 0x05E4, 0x014C, 0x3F74, 0x3FEC, + 0x3FB8, 0x3FAC, 0x02E0, 0x0708, 0x05F8, 0x015C, 0x3F74, 0x3FEC, + 0x3FBC, 0x3FA8, 0x02CC, 0x0704, 0x0604, 0x016C, 0x3F74, 0x3FE8, + 0x3FC0, 0x3FA0, 0x02BC, 0x06F8, 0x0614, 0x017C, 0x3F74, 0x3FE8, + 0x3FC0, 0x3F9C, 0x02A8, 0x06F4, 0x0624, 0x018C, 0x3F74, 0x3FE4, + 0x3FC4, 0x3F98, 0x0294, 0x06E8, 0x0634, 0x019C, 0x3F74, 0x3FE4, + 0x3FC8, 0x3F94, 0x0284, 0x06D8, 0x0644, 0x01AC, 0x3F78, 0x3FE0, + 0x3FC8, 0x3F90, 0x0270, 0x06D4, 0x0650, 0x01BC, 0x3F78, 0x3FE0, + 0x3FCC, 0x3F8C, 0x025C, 0x06C8, 0x0660, 0x01D0, 0x3F78, 0x3FDC, + 0x3FCC, 0x3F8C, 0x024C, 0x06B8, 0x066C, 0x01E0, 0x3F7C, 0x3FDC, + 0x3FD0, 0x3F88, 0x0238, 0x06B0, 0x067C, 0x01F0, 0x3F7C, 0x3FD8, + 0x3FD4, 0x3F84, 0x0228, 0x069C, 0x0688, 0x0204, 0x3F80, 0x3FD8, + 0x3FD4, 0x3F84, 0x0214, 0x0694, 0x0694, 0x0214, 0x3F84, 0x3FD4 +}; + +const uint16_t *spl_get_filter_3tap_16p(struct spl_fixed31_32 ratio) +{ + if (ratio.value < spl_fixpt_one.value) + return filter_3tap_16p_upscale; + else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) + return filter_3tap_16p_116; + 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 spl_fixed31_32 ratio) +{ + if (ratio.value < spl_fixpt_one.value) + return filter_3tap_64p_upscale; + else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) + return filter_3tap_64p_116; + 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 spl_fixed31_32 ratio) +{ + if (ratio.value < spl_fixpt_one.value) + return filter_4tap_16p_upscale; + else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) + return filter_4tap_16p_116; + 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 spl_fixed31_32 ratio) +{ + if (ratio.value < spl_fixpt_one.value) + return filter_4tap_64p_upscale; + else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) + return filter_4tap_64p_116; + 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 spl_fixed31_32 ratio) +{ + if (ratio.value < spl_fixpt_one.value) + return filter_5tap_64p_upscale; + else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) + return filter_5tap_64p_116; + 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 spl_fixed31_32 ratio) +{ + if (ratio.value < spl_fixpt_one.value) + return filter_6tap_64p_upscale; + else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) + return filter_6tap_64p_116; + 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 spl_fixed31_32 ratio) +{ + if (ratio.value < spl_fixpt_one.value) + return filter_7tap_64p_upscale; + else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) + return filter_7tap_64p_116; + 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 spl_fixed31_32 ratio) +{ + if (ratio.value < spl_fixpt_one.value) + return filter_8tap_64p_upscale; + else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) + return filter_8tap_64p_116; + else if (ratio.value < spl_fixpt_from_fraction(5, 3).value) + return filter_8tap_64p_149; + else + return filter_8tap_64p_183; +} + +const uint16_t *spl_get_filter_2tap_16p(void) +{ + return filter_2tap_16p; +} + +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/sspl/dc_spl_scl_filters.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.h new file mode 100644 index 000000000000..48202bc4f81e --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.h @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +// +// Copyright 2024 Advanced Micro Devices, Inc. + +#ifndef __DC_SPL_SCL_FILTERS_H__ +#define __DC_SPL_SCL_FILTERS_H__ + +#include "dc_spl_types.h" + +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_dscl_get_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio); + +#endif /* __DC_SPL_SCL_FILTERS_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h new file mode 100644 index 000000000000..467af9dd90de --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h @@ -0,0 +1,543 @@ +// SPDX-License-Identifier: MIT +// +// Copyright 2024 Advanced Micro Devices, Inc. + +#ifndef __DC_SPL_TYPES_H__ +#define __DC_SPL_TYPES_H__ + +#include "spl_debug.h" +#include "spl_os_types.h" // swap +#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; + uint32_t height; +}; +struct spl_rect { + int x; + int y; + int width; + int height; +}; + +struct spl_ratios { + 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 spl_fixed31_32 h; + struct spl_fixed31_32 h_c; + struct spl_fixed31_32 v; + struct spl_fixed31_32 v_c; +}; + +struct spl_taps { + uint32_t v_taps; + uint32_t h_taps; + uint32_t v_taps_c; + uint32_t h_taps_c; + bool integer_scaling; +}; +enum spl_view_3d { + SPL_VIEW_3D_NONE = 0, + SPL_VIEW_3D_FRAME_SEQUENTIAL, + SPL_VIEW_3D_SIDE_BY_SIDE, + SPL_VIEW_3D_TOP_AND_BOTTOM, + SPL_VIEW_3D_COUNT, + SPL_VIEW_3D_FIRST = SPL_VIEW_3D_FRAME_SEQUENTIAL +}; +/* Pixel format */ +enum spl_pixel_format { + /*graph*/ + SPL_PIXEL_FORMAT_UNINITIALIZED, + SPL_PIXEL_FORMAT_INDEX8, + SPL_PIXEL_FORMAT_RGB565, + SPL_PIXEL_FORMAT_ARGB8888, + SPL_PIXEL_FORMAT_ARGB2101010, + SPL_PIXEL_FORMAT_ARGB2101010_XRBIAS, + SPL_PIXEL_FORMAT_FP16, + /*video*/ + SPL_PIXEL_FORMAT_420BPP8, + SPL_PIXEL_FORMAT_420BPP10, + /*end of pixel format definition*/ + SPL_PIXEL_FORMAT_GRPH_BEGIN = SPL_PIXEL_FORMAT_INDEX8, + SPL_PIXEL_FORMAT_GRPH_END = SPL_PIXEL_FORMAT_FP16, + SPL_PIXEL_FORMAT_SUBSAMPLED_BEGIN = SPL_PIXEL_FORMAT_420BPP8, + SPL_PIXEL_FORMAT_SUBSAMPLED_END = SPL_PIXEL_FORMAT_420BPP10, + SPL_PIXEL_FORMAT_VIDEO_BEGIN = SPL_PIXEL_FORMAT_420BPP8, + SPL_PIXEL_FORMAT_VIDEO_END = SPL_PIXEL_FORMAT_420BPP10, + SPL_PIXEL_FORMAT_INVALID, + 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, + SPL_ROTATION_ANGLE_90, + SPL_ROTATION_ANGLE_180, + SPL_ROTATION_ANGLE_270, + SPL_ROTATION_ANGLE_COUNT +}; +enum spl_color_space { + SPL_COLOR_SPACE_UNKNOWN, + SPL_COLOR_SPACE_SRGB, + SPL_COLOR_SPACE_XR_RGB, + SPL_COLOR_SPACE_SRGB_LIMITED, + SPL_COLOR_SPACE_MSREF_SCRGB, + SPL_COLOR_SPACE_YCBCR601, + SPL_COLOR_SPACE_YCBCR709, + SPL_COLOR_SPACE_XV_YCC_709, + SPL_COLOR_SPACE_XV_YCC_601, + SPL_COLOR_SPACE_YCBCR601_LIMITED, + SPL_COLOR_SPACE_YCBCR709_LIMITED, + SPL_COLOR_SPACE_2020_RGB_FULLRANGE, + SPL_COLOR_SPACE_2020_RGB_LIMITEDRANGE, + SPL_COLOR_SPACE_2020_YCBCR, + SPL_COLOR_SPACE_ADOBERGB, + SPL_COLOR_SPACE_DCIP3, + SPL_COLOR_SPACE_DISPLAYNATIVE, + SPL_COLOR_SPACE_DOLBYVISION, + SPL_COLOR_SPACE_APPCTRL, + SPL_COLOR_SPACE_CUSTOMPOINTS, + 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; + int v_active; + struct spl_taps taps; + struct spl_rect viewport; + struct spl_rect viewport_c; + struct spl_rect recout; + struct spl_ratios ratios; + struct spl_ratios recip_ratios; + struct spl_inits inits; +}; + +enum spl_transfer_func_type { + SPL_TF_TYPE_PREDEFINED, + SPL_TF_TYPE_DISTRIBUTED_POINTS, + SPL_TF_TYPE_BYPASS, + SPL_TF_TYPE_HWPWL +}; + +enum spl_transfer_func_predefined { + SPL_TRANSFER_FUNCTION_SRGB, + SPL_TRANSFER_FUNCTION_BT709, + SPL_TRANSFER_FUNCTION_PQ, + SPL_TRANSFER_FUNCTION_LINEAR, + SPL_TRANSFER_FUNCTION_UNITY, + SPL_TRANSFER_FUNCTION_HLG, + SPL_TRANSFER_FUNCTION_HLG12, + SPL_TRANSFER_FUNCTION_GAMMA22, + SPL_TRANSFER_FUNCTION_GAMMA24, + SPL_TRANSFER_FUNCTION_GAMMA26 +}; + +/*==============================================================*/ +/* Below structs are defined to hold hw register data */ + +// SPL output is used to set below registers + +// MPC_SIZE - set based on scl_data h_active and v_active +struct mpc_size { + uint32_t width; + uint32_t height; +}; +// SCL_MODE - set based on scl_data.ratios and always_scale +enum scl_mode { + SCL_MODE_SCALING_444_BYPASS = 0, + SCL_MODE_SCALING_444_RGB_ENABLE = 1, + SCL_MODE_SCALING_444_YCBCR_ENABLE = 2, + SCL_MODE_SCALING_420_YCBCR_ENABLE = 3, + SCL_MODE_SCALING_420_LUMA_BYPASS = 4, + SCL_MODE_SCALING_420_CHROMA_BYPASS = 5, + SCL_MODE_DSCL_BYPASS = 6 +}; +// SCL_BLACK_COLOR - set based on scl_data.format +struct scl_black_color { + uint32_t offset_rgb_y; + uint32_t offset_rgb_cbcr; +}; +// RATIO - set based on scl_data.ratios +struct ratio { + uint32_t h_scale_ratio; + uint32_t v_scale_ratio; + uint32_t h_scale_ratio_c; + uint32_t v_scale_ratio_c; +}; + +// INIT - set based on scl_data.init +struct init { + // SCL_HORZ_FILTER_INIT + uint32_t h_filter_init_frac; // SCL_H_INIT_FRAC + uint32_t h_filter_init_int; // SCL_H_INIT_INT + // SCL_HORZ_FILTER_INIT_C + uint32_t h_filter_init_frac_c; // SCL_H_INIT_FRAC_C + uint32_t h_filter_init_int_c; // SCL_H_INIT_INT_C + // SCL_VERT_FILTER_INIT + uint32_t v_filter_init_frac; // SCL_V_INIT_FRAC + uint32_t v_filter_init_int; // SCL_V_INIT_INT + // SCL_VERT_FILTER_INIT_C + uint32_t v_filter_init_frac_c; // SCL_V_INIT_FRAC_C + uint32_t v_filter_init_int_c; // SCL_V_INIT_INT_C + // SCL_VERT_FILTER_INIT_BOT + uint32_t v_filter_init_bot_frac; // SCL_V_INIT_FRAC_BOT + uint32_t v_filter_init_bot_int; // SCL_V_INIT_INT_BOT + // SCL_VERT_FILTER_INIT_BOT_C + uint32_t v_filter_init_bot_frac_c; // SCL_V_INIT_FRAC_BOT_C + uint32_t v_filter_init_bot_int_c; // SCL_V_INIT_INT_BOT_C +}; + +// FILTER - calculated based on scl_data ratios and taps + +// iSHARP +struct isharp_noise_det { + uint32_t enable; // ISHARP_NOISEDET_EN + uint32_t mode; // ISHARP_NOISEDET_MODE + uint32_t uthreshold; // ISHARP_NOISEDET_UTHRE + uint32_t dthreshold; // ISHARP_NOISEDET_DTHRE + uint32_t pwl_start_in; // ISHARP_NOISEDET_PWL_START_IN + uint32_t pwl_end_in; // ISHARP_NOISEDET_PWL_END_IN + uint32_t pwl_slope; // ISHARP_NOISEDET_PWL_SLOPE +}; +struct isharp_lba { + uint32_t mode; // ISHARP_LBA_MODE + uint32_t in_seg[6]; + uint32_t base_seg[6]; + uint32_t slope_seg[6]; +}; +struct isharp_fmt { + uint32_t mode; // ISHARP_FMT_MODE + uint32_t norm; // ISHARP_FMT_NORM +}; +struct isharp_nldelta_sclip { + uint32_t enable_p; // ISHARP_NLDELTA_SCLIP_EN_P + uint32_t pivot_p; // ISHARP_NLDELTA_SCLIP_PIVOT_P + uint32_t slope_p; // ISHARP_NLDELTA_SCLIP_SLOPE_P + uint32_t enable_n; // ISHARP_NLDELTA_SCLIP_EN_N + uint32_t pivot_n; // ISHARP_NLDELTA_SCLIP_PIVOT_N + uint32_t slope_n; // ISHARP_NLDELTA_SCLIP_SLOPE_N +}; +enum isharp_en { + ISHARP_DISABLE, + ISHARP_ENABLE +}; +#define ISHARP_LUT_TABLE_SIZE 32 +// Below struct holds values that can be directly used to program +// hardware registers. No conversion/clamping is required +struct dscl_prog_data { + struct spl_rect recout; // RECOUT - set based on scl_data.recout + struct mpc_size mpc_size; + uint32_t dscl_mode; + struct scl_black_color scl_black_color; + struct ratio ratios; + struct init init; + struct spl_taps taps; // TAPS - set based on scl_data.taps + struct spl_rect viewport; + struct spl_rect viewport_c; + // raw filter + const uint16_t *filter_h; + const uint16_t *filter_v; + const uint16_t *filter_h_c; + const uint16_t *filter_v_c; + // EASF registers + uint32_t easf_matrix_mode; + uint32_t easf_ltonl_en; + uint32_t easf_v_en; + uint32_t easf_v_sharp_factor; + uint32_t easf_v_ring; + uint32_t easf_v_bf1_en; + uint32_t easf_v_bf2_mode; + uint32_t easf_v_bf3_mode; + uint32_t easf_v_bf2_flat1_gain; + uint32_t easf_v_bf2_flat2_gain; + uint32_t easf_v_bf2_roc_gain; + uint32_t easf_v_ringest_3tap_dntilt_uptilt; + uint32_t easf_v_ringest_3tap_uptilt_max; + uint32_t easf_v_ringest_3tap_dntilt_slope; + uint32_t easf_v_ringest_3tap_uptilt1_slope; + uint32_t easf_v_ringest_3tap_uptilt2_slope; + uint32_t easf_v_ringest_3tap_uptilt2_offset; + uint32_t easf_v_ringest_eventap_reduceg1; + uint32_t easf_v_ringest_eventap_reduceg2; + uint32_t easf_v_ringest_eventap_gain1; + uint32_t easf_v_ringest_eventap_gain2; + uint32_t easf_v_bf_maxa; + uint32_t easf_v_bf_maxb; + uint32_t easf_v_bf_mina; + uint32_t easf_v_bf_minb; + uint32_t easf_v_bf1_pwl_in_seg0; + uint32_t easf_v_bf1_pwl_base_seg0; + uint32_t easf_v_bf1_pwl_slope_seg0; + uint32_t easf_v_bf1_pwl_in_seg1; + uint32_t easf_v_bf1_pwl_base_seg1; + uint32_t easf_v_bf1_pwl_slope_seg1; + uint32_t easf_v_bf1_pwl_in_seg2; + uint32_t easf_v_bf1_pwl_base_seg2; + uint32_t easf_v_bf1_pwl_slope_seg2; + uint32_t easf_v_bf1_pwl_in_seg3; + uint32_t easf_v_bf1_pwl_base_seg3; + uint32_t easf_v_bf1_pwl_slope_seg3; + uint32_t easf_v_bf1_pwl_in_seg4; + uint32_t easf_v_bf1_pwl_base_seg4; + uint32_t easf_v_bf1_pwl_slope_seg4; + uint32_t easf_v_bf1_pwl_in_seg5; + uint32_t easf_v_bf1_pwl_base_seg5; + uint32_t easf_v_bf1_pwl_slope_seg5; + uint32_t easf_v_bf1_pwl_in_seg6; + uint32_t easf_v_bf1_pwl_base_seg6; + uint32_t easf_v_bf1_pwl_slope_seg6; + uint32_t easf_v_bf1_pwl_in_seg7; + uint32_t easf_v_bf1_pwl_base_seg7; + uint32_t easf_v_bf3_pwl_in_set0; + uint32_t easf_v_bf3_pwl_base_set0; + uint32_t easf_v_bf3_pwl_slope_set0; + uint32_t easf_v_bf3_pwl_in_set1; + uint32_t easf_v_bf3_pwl_base_set1; + uint32_t easf_v_bf3_pwl_slope_set1; + uint32_t easf_v_bf3_pwl_in_set2; + uint32_t easf_v_bf3_pwl_base_set2; + uint32_t easf_v_bf3_pwl_slope_set2; + uint32_t easf_v_bf3_pwl_in_set3; + uint32_t easf_v_bf3_pwl_base_set3; + uint32_t easf_v_bf3_pwl_slope_set3; + uint32_t easf_v_bf3_pwl_in_set4; + uint32_t easf_v_bf3_pwl_base_set4; + uint32_t easf_v_bf3_pwl_slope_set4; + uint32_t easf_v_bf3_pwl_in_set5; + uint32_t easf_v_bf3_pwl_base_set5; + uint32_t easf_h_en; + uint32_t easf_h_sharp_factor; + uint32_t easf_h_ring; + uint32_t easf_h_bf1_en; + uint32_t easf_h_bf2_mode; + uint32_t easf_h_bf3_mode; + uint32_t easf_h_bf2_flat1_gain; + uint32_t easf_h_bf2_flat2_gain; + uint32_t easf_h_bf2_roc_gain; + uint32_t easf_h_ringest_eventap_reduceg1; + uint32_t easf_h_ringest_eventap_reduceg2; + uint32_t easf_h_ringest_eventap_gain1; + uint32_t easf_h_ringest_eventap_gain2; + uint32_t easf_h_bf_maxa; + uint32_t easf_h_bf_maxb; + uint32_t easf_h_bf_mina; + uint32_t easf_h_bf_minb; + uint32_t easf_h_bf1_pwl_in_seg0; + uint32_t easf_h_bf1_pwl_base_seg0; + uint32_t easf_h_bf1_pwl_slope_seg0; + uint32_t easf_h_bf1_pwl_in_seg1; + uint32_t easf_h_bf1_pwl_base_seg1; + uint32_t easf_h_bf1_pwl_slope_seg1; + uint32_t easf_h_bf1_pwl_in_seg2; + uint32_t easf_h_bf1_pwl_base_seg2; + uint32_t easf_h_bf1_pwl_slope_seg2; + uint32_t easf_h_bf1_pwl_in_seg3; + uint32_t easf_h_bf1_pwl_base_seg3; + uint32_t easf_h_bf1_pwl_slope_seg3; + uint32_t easf_h_bf1_pwl_in_seg4; + uint32_t easf_h_bf1_pwl_base_seg4; + uint32_t easf_h_bf1_pwl_slope_seg4; + uint32_t easf_h_bf1_pwl_in_seg5; + uint32_t easf_h_bf1_pwl_base_seg5; + uint32_t easf_h_bf1_pwl_slope_seg5; + uint32_t easf_h_bf1_pwl_in_seg6; + uint32_t easf_h_bf1_pwl_base_seg6; + uint32_t easf_h_bf1_pwl_slope_seg6; + uint32_t easf_h_bf1_pwl_in_seg7; + uint32_t easf_h_bf1_pwl_base_seg7; + uint32_t easf_h_bf3_pwl_in_set0; + uint32_t easf_h_bf3_pwl_base_set0; + uint32_t easf_h_bf3_pwl_slope_set0; + uint32_t easf_h_bf3_pwl_in_set1; + uint32_t easf_h_bf3_pwl_base_set1; + uint32_t easf_h_bf3_pwl_slope_set1; + uint32_t easf_h_bf3_pwl_in_set2; + uint32_t easf_h_bf3_pwl_base_set2; + uint32_t easf_h_bf3_pwl_slope_set2; + uint32_t easf_h_bf3_pwl_in_set3; + uint32_t easf_h_bf3_pwl_base_set3; + uint32_t easf_h_bf3_pwl_slope_set3; + uint32_t easf_h_bf3_pwl_in_set4; + uint32_t easf_h_bf3_pwl_base_set4; + uint32_t easf_h_bf3_pwl_slope_set4; + uint32_t easf_h_bf3_pwl_in_set5; + uint32_t easf_h_bf3_pwl_base_set5; + uint32_t easf_matrix_c0; + uint32_t easf_matrix_c1; + uint32_t easf_matrix_c2; + uint32_t easf_matrix_c3; + // iSharp + uint32_t isharp_en; // ISHARP_EN + struct isharp_noise_det isharp_noise_det; // ISHARP_NOISEDET + uint32_t isharp_nl_en; // ISHARP_NL_EN ? TODO:check this + struct isharp_lba isharp_lba; // ISHARP_LBA + struct isharp_fmt isharp_fmt; // ISHARP_FMT + uint32_t isharp_delta[ISHARP_LUT_TABLE_SIZE]; + struct isharp_nldelta_sclip isharp_nldelta_sclip; // ISHARP_NLDELTA_SCLIP + /* 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 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; +}; + +// end of SPL outputs + +// SPL inputs + +// Basic input information +struct basic_in { + enum spl_pixel_format format; // Pixel Format + enum chroma_cositing cositing; /* Chroma Subsampling Offset */ + struct spl_rect src_rect; // Source rect + struct spl_rect dst_rect; // Destination Rect + struct spl_rect clip_rect; // Clip rect + enum spl_rotation_angle rotation; // Rotation + bool horizontal_mirror; // Horizontal mirror + struct { // previous mpc_combine_h - split count + bool use_recout_width_aligned; + union { + int mpc_num_h_slices; + int mpc_recout_width_align; + } num_slices_recout_width; + } num_h_slices_recout_width_align; + int mpc_h_slice_index; // previous mpc_combine_v - split_idx + // Inputs for adaptive scaler - TODO + enum spl_transfer_func_type tf_type; /* Transfer function type */ + enum spl_transfer_func_predefined tf_predefined_type; /* Transfer function predefined type */ + // enum dc_transfer_func_predefined tf; + enum spl_color_space color_space; // Color Space + unsigned int max_luminance; // Max Luminance TODO: Is determined in dc_hw_sequencer.c is_sdr + bool film_grain_applied; // Film Grain Applied // TODO: To check from where to get this? +}; + +// Basic output information +struct basic_out { + struct spl_size output_size; // Output Size + struct spl_rect dst_rect; // Destination Rect + struct spl_rect src_rect; // Source rect + int odm_combine_factor; // deprecated + struct spl_rect odm_slice_rect; // OPP input rect in timing active + enum spl_view_3d view_format; // TODO: View format Check if it is chroma subsampling + bool always_scale; // Is always scale enabled? Required for getting SCL_MODE + int max_downscale_src_width; // Required to get optimal no of taps + bool alpha_en; + bool use_two_pixels_per_container; +}; +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; + int sharpness_level; + struct spl_sharpness_range sharpness_range; +}; +enum linear_light_scaling { // convert it in translation logic + LLS_PREF_DONT_CARE = 0, + LLS_PREF_YES, + LLS_PREF_NO +}; +enum sharpen_policy { + SHARPEN_ALWAYS = 0, + SHARPEN_YUV = 1, + SHARPEN_RGB_FULLSCREEN_YUV = 2, + SHARPEN_FULLSCREEN_ALL = 3 +}; +enum scale_to_sharpness_policy { + NO_SCALE_TO_SHARPNESS_ADJ = 0, + SCALE_TO_SHARPNESS_ADJ_YUV = 1, + SCALE_TO_SHARPNESS_ADJ_ALL = 2 +}; +struct spl_callbacks { + void (*spl_calc_lb_num_partitions) + (bool alpha_en, + const struct spl_scaler_data *scl_data, + enum lb_memory_config lb_config, + int *num_part_y, + int *num_part_c); +}; + +struct spl_debug { + int visual_confirm_base_offset; + int visual_confirm_dpp_offset; + enum scale_to_sharpness_policy scale_to_sharpness_policy; +}; + +struct spl_in { + struct basic_out basic_out; + struct basic_in basic_in; + // Basic slice information + int odm_slice_index; // ODM Slice Index using get_odm_split_index + struct spl_taps scaling_quality; // Explicit Scaling Quality + struct spl_callbacks callbacks; + // Inputs for isharp and EASF + struct adaptive_sharpness adaptive_sharpness; // Adaptive Sharpness + enum linear_light_scaling lls_pref; // Linear Light Scaling + bool prefer_easf; + bool disable_easf; + struct spl_debug debug; + bool is_fullscreen; + bool is_hdr_on; + int h_active; + int v_active; + int sdr_white_level_nits; + enum sharpen_policy sharpen_policy; +}; +// end of SPL inputs + +#endif /* __DC_SPL_TYPES_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/sspl/spl_custom_float.c b/drivers/gpu/drm/amd/display/dc/sspl/spl_custom_float.c new file mode 100644 index 000000000000..be2f34d034c5 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/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/sspl/spl_custom_float.h b/drivers/gpu/drm/amd/display/dc/sspl/spl_custom_float.h new file mode 100644 index 000000000000..cdc4e107b9de --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/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/sspl/spl_debug.h b/drivers/gpu/drm/amd/display/dc/sspl/spl_debug.h new file mode 100644 index 000000000000..a6f6132df241 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/spl_debug.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright 2024 Advanced Micro Devices, Inc. */ + +#ifndef SPL_DEBUG_H +#define SPL_DEBUG_H + +#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB) +#define SPL_ASSERT_CRITICAL(expr) do { \ + if (WARN_ON(!(expr))) { \ + kgdb_breakpoint(); \ + } \ +} while (0) +#else +#define SPL_ASSERT_CRITICAL(expr) do { \ + if (WARN_ON(!(expr))) { \ + ; \ + } \ +} while (0) +#endif /* CONFIG_HAVE_KGDB || CONFIG_KGDB */ + +#if defined(CONFIG_DEBUG_KERNEL_DC) +#define SPL_ASSERT(expr) SPL_ASSERT_CRITICAL(expr) +#else +#define SPL_ASSERT(expr) WARN_ON(!(expr)) +#endif /* CONFIG_DEBUG_KERNEL_DC */ + +#define SPL_BREAK_TO_DEBUGGER() SPL_ASSERT(0) + +#endif // SPL_DEBUG_H diff --git a/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c new file mode 100644 index 000000000000..131f1e3949d3 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/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 spl_complete_integer_division_u64( + unsigned long long dividend, + unsigned long long divisor, + unsigned long long *remainder) +{ + unsigned long long result; + + SPL_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 = spl_complete_integer_division_u64( + arg1_value, arg2_value, &remainder); + + SPL_ASSERT(res_value <= (unsigned long long)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; + + SPL_ASSERT(res_value <= (unsigned long long)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; + + SPL_ASSERT(res.value <= (long long)LONG_MAX); + + res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART; + + tmp = arg1_int * arg2_fra; + + SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); + + res.value += tmp; + + tmp = arg2_int * arg1_fra; + + SPL_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); + + SPL_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; + + SPL_ASSERT(res.value <= (long long)LONG_MAX); + + res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART; + + tmp = arg_int * arg_fra; + + SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); + + res.value += tmp; + + SPL_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); + + SPL_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 + */ + + SPL_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 spl_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 */ + + SPL_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)); + + SPL_ASSERT(m != 0); + + SPL_ASSERT(spl_fixpt_lt( + spl_fixpt_abs(r), + spl_fixpt_one)); + + if (m > 0) + return spl_fixpt_shl( + spl_fixed31_32_exp_from_taylor_series(r), + (unsigned char)m); + else + return spl_fixpt_div_int( + spl_fixed31_32_exp_from_taylor_series(r), + 1LL << -m); + } else if (arg.value != 0) + return spl_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; + + SPL_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 spl_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 spl_clamp_ux_dy( + long long value, + unsigned int integer_bits, + unsigned int fractional_bits, + unsigned int min_clamp) +{ + unsigned int truncated_val = spl_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 spl_ux_dy(arg.value, 4, 19); +} + +unsigned int spl_fixpt_u3d19(struct spl_fixed31_32 arg) +{ + return spl_ux_dy(arg.value, 3, 19); +} + +unsigned int spl_fixpt_u2d19(struct spl_fixed31_32 arg) +{ + return spl_ux_dy(arg.value, 2, 19); +} + +unsigned int spl_fixpt_u0d19(struct spl_fixed31_32 arg) +{ + return spl_ux_dy(arg.value, 0, 19); +} + +unsigned int spl_fixpt_clamp_u0d14(struct spl_fixed31_32 arg) +{ + return spl_clamp_ux_dy(arg.value, 0, 14, 1); +} + +unsigned int spl_fixpt_clamp_u0d10(struct spl_fixed31_32 arg) +{ + return spl_clamp_ux_dy(arg.value, 0, 10, 1); +} + +int spl_fixpt_s4d19(struct spl_fixed31_32 arg) +{ + if (arg.value < 0) + return -(int)spl_ux_dy(spl_fixpt_abs(arg).value, 4, 19); + else + return spl_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/sspl/spl_fixpt31_32.h b/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.h new file mode 100644 index 000000000000..ed2647f9a099 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.h @@ -0,0 +1,522 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright 2024 Advanced Micro Devices, Inc. */ + +#ifndef __SPL_FIXED31_32_H__ +#define __SPL_FIXED31_32_H__ + +#include "spl_debug.h" +#include "spl_os_types.h" // swap + +#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) +{ + SPL_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; + + SPL_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; + + SPL_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; + + SPL_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; + + SPL_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) { + SPL_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/sspl/spl_os_types.h b/drivers/gpu/drm/amd/display/dc/sspl/spl_os_types.h new file mode 100644 index 000000000000..2e6ba71960ac --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/sspl/spl_os_types.h @@ -0,0 +1,56 @@ +/* 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 "spl_debug.h" + +#include +#include +#include +#include +#include +#include + +/* + * + * general debug capabilities + * + */ + +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_ */ -- cgit v1.2.3 From a77269e33c94f372b141fc9d7e081d5f58a545f6 Mon Sep 17 00:00:00 2001 From: Taimur Hassan Date: Mon, 27 Jan 2025 01:31:18 -0500 Subject: drm/amd/display: 3.2.319 - Move SPL to a new path - Request HW cursor on DCN3.2 with SubVP - Allow reuse of of DCN4x code - Enable odm 4:1 when debug key is set - Fix seamless boot sequence - Support multiple options during psr entry. - Revert "Exit idle optimizations before attempt to access PHY" - Fix out-of-bound accesses - Fixes for mcache programming in DML21 Acked-by: Alex Hung Signed-off-by: Taimur Hassan Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 9ac299fb1034..e5e4cb3d0a0d 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -53,7 +53,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.318" +#define DC_VER "3.2.319" #define MAX_SURFACES 4 #define MAX_PLANES 6 -- cgit v1.2.3 From 3bd202b3c4c7235499060ead7b3a4ffe7008a8aa Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Sun, 2 Feb 2025 21:58:50 +0000 Subject: drm/amd/display: Remove unused mpc1_is_mpcc_idle mpc1_is_mpcc_idle() was added in 2017 by commit feb4a3cd8eb0 ("drm/amd/display: Integrating MPC pseudocode") but never used. Remove it. Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.c | 16 ---------------- drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.h | 4 ---- 2 files changed, 20 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.c index f2f55565e98a..b23c64004dd5 100644 --- a/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.c @@ -142,22 +142,6 @@ struct mpcc *mpc1_get_mpcc_for_dpp(struct mpc_tree *tree, int dpp_id) return NULL; } -bool mpc1_is_mpcc_idle(struct mpc *mpc, int mpcc_id) -{ - struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); - unsigned int top_sel; - unsigned int opp_id; - unsigned int idle; - - REG_GET(MPCC_TOP_SEL[mpcc_id], MPCC_TOP_SEL, &top_sel); - REG_GET(MPCC_OPP_ID[mpcc_id], MPCC_OPP_ID, &opp_id); - REG_GET(MPCC_STATUS[mpcc_id], MPCC_IDLE, &idle); - if (top_sel == 0xf && opp_id == 0xf && idle) - return true; - else - return false; -} - void mpc1_assert_mpcc_idle_before_connect(struct mpc *mpc, int mpcc_id) { struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.h b/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.h index dbfffc6383dc..874e36e39e1b 100644 --- a/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.h +++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.h @@ -173,10 +173,6 @@ void mpc1_update_stereo_mix( struct mpcc_sm_cfg *sm_cfg, int mpcc_id); -bool mpc1_is_mpcc_idle( - struct mpc *mpc, - int mpcc_id); - void mpc1_assert_mpcc_idle_before_connect( struct mpc *mpc, int mpcc_id); -- cgit v1.2.3 From fa88342931bad919a542ae4348bfd4ef0afaf5ca Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Sun, 2 Feb 2025 21:58:52 +0000 Subject: drm/amd/display: Remove unused dc_stream_get_crtc_position The last user of dc_stream_get_crtc_position() was mod_freesync_get_v_position() which is removed in a previous patch in this series. Remove it. Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 27 --------------------------- drivers/gpu/drm/amd/display/dc/dc_stream.h | 12 ------------ 2 files changed, 39 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index a2b0331ef579..e204b69fbc18 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -516,33 +516,6 @@ bool dc_stream_get_last_used_drr_vtotal(struct dc *dc, return status; } -bool dc_stream_get_crtc_position(struct dc *dc, - struct dc_stream_state **streams, int num_streams, - unsigned int *v_pos, unsigned int *nom_v_pos) -{ - /* TODO: Support multiple streams */ - const struct dc_stream_state *stream = streams[0]; - int i; - bool ret = false; - struct crtc_position position; - - dc_exit_ips_for_hw_access(dc); - - for (i = 0; i < MAX_PIPES; i++) { - struct pipe_ctx *pipe = - &dc->current_state->res_ctx.pipe_ctx[i]; - - if (pipe->stream == stream && pipe->stream_res.stream_enc) { - dc->hwss.get_position(&pipe, 1, &position); - - *v_pos = position.vertical_count; - *nom_v_pos = position.nominal_vcount; - ret = true; - } - } - return ret; -} - #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) static inline void dc_stream_forward_dmub_crc_window(struct dc_dmub_srv *dmub_srv, diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 3e303c7808fb..e0bfddaa23e3 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -528,12 +528,6 @@ bool dc_stream_get_last_used_drr_vtotal(struct dc *dc, struct dc_stream_state *stream, uint32_t *refresh_rate); -bool dc_stream_get_crtc_position(struct dc *dc, - struct dc_stream_state **stream, - int num_streams, - unsigned int *v_pos, - unsigned int *nom_v_pos); - #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) bool dc_stream_forward_crc_window(struct dc_stream_state *stream, struct rect *rect, @@ -578,12 +572,6 @@ bool dc_stream_set_gamut_remap(struct dc *dc, bool dc_stream_program_csc_matrix(struct dc *dc, struct dc_stream_state *stream); -bool dc_stream_get_crtc_position(struct dc *dc, - struct dc_stream_state **stream, - int num_streams, - unsigned int *v_pos, - unsigned int *nom_v_pos); - struct pipe_ctx *dc_stream_get_pipe_ctx(struct dc_stream_state *stream); void dc_dmub_update_dirty_rect(struct dc *dc, -- cgit v1.2.3 From 6d04e9785cd153f17a34ecb1d3ac7d848ca4339a Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Sun, 2 Feb 2025 21:58:53 +0000 Subject: drm/amd/display: Remove unused get_clock_requirements_for_state get_clock_requirements_for_state() was added in 2018 by commit 8ab2180f96f5 ("drm/amd/display: Add function to fetch clock requirements") but never used. Remove it. Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 12 ------------ drivers/gpu/drm/amd/display/dc/dc.h | 2 -- 2 files changed, 14 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index e204b69fbc18..c5f1b61ed640 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -5449,18 +5449,6 @@ bool dc_is_dmcu_initialized(struct dc *dc) return false; } -void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info) -{ - info->displayClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz; - info->engineClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_khz; - info->memoryClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dramclk_khz; - info->maxSupportedDppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz; - info->dppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dppclk_khz; - info->socClock = (unsigned int)state->bw_ctx.bw.dcn.clk.socclk_khz; - info->dcfClockDeepSleep = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz; - info->fClock = (unsigned int)state->bw_ctx.bw.dcn.clk.fclk_khz; - info->phyClock = (unsigned int)state->bw_ctx.bw.dcn.clk.phyclk_khz; -} enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping) { if (dc->hwss.set_clock) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index e5e4cb3d0a0d..42ba65e785ca 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1582,8 +1582,6 @@ bool dc_validate_boot_timing(const struct dc *dc, enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state); -void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info); - enum dc_status dc_validate_with_context(struct dc *dc, const struct dc_validation_set set[], int set_count, -- cgit v1.2.3 From 9ab737f3aeea29129903de6ddebf4bbce3ec0644 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Sun, 2 Feb 2025 21:58:54 +0000 Subject: drm/amd/display: Remove unused hubbub1_toggle_watermark_change_req hubbub1_toggle_watermark_change_req() last use was removed in 2017 by commit b8fce2c9d773 ("drm/amd/display: Optimize programming front end") Remove it. Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.c | 18 ------------------ .../gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h | 3 --- 2 files changed, 21 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.c index d738a36f2132..7847c1c4927b 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.c @@ -679,24 +679,6 @@ void hubbub1_update_dchub( dh_data->dchub_info_valid = false; } -void hubbub1_toggle_watermark_change_req(struct hubbub *hubbub) -{ - struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); - - uint32_t watermark_change_req; - - REG_GET(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, - DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, &watermark_change_req); - - if (watermark_change_req) - watermark_change_req = 0; - else - watermark_change_req = 1; - - REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, - DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, watermark_change_req); -} - void hubbub1_soft_reset(struct hubbub *hubbub, bool reset) { struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h index 9fbd45c7dfef..fa5c4c18ed59 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h @@ -489,9 +489,6 @@ void hubbub1_allow_self_refresh_control(struct hubbub *hubbub, bool allow); bool hubbub1_is_allow_self_refresh_enabled(struct hubbub *hubub); -void hubbub1_toggle_watermark_change_req( - struct hubbub *hubbub); - void hubbub1_wm_read_state(struct hubbub *hubbub, struct dcn_hubbub_wm *wm); -- cgit v1.2.3 From 6d4e03d0b1ba9cfc75a600519a15f41c2e7e5a6d Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Sun, 2 Feb 2025 21:58:55 +0000 Subject: drm/amd/display: Remove unused get_max_support_fbc_buffersize get_max_support_fbc_buffersize() is unused since 2021's commit 94f0d0c80cf3 ("drm/amd/display/dc/dce110/dce110_compressor: Remove unused function 'dce110_get_required_compressed_surfacesize") removed it's only caller. Remove it. Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c | 13 ------------- drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.h | 2 -- 2 files changed, 15 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c index d241ee13b293..59a0961b49da 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c @@ -409,19 +409,6 @@ void dce110_compressor_destroy(struct compressor **compressor) *compressor = NULL; } -void get_max_support_fbc_buffersize(unsigned int *max_x, unsigned int *max_y) -{ - *max_x = FBC_MAX_X; - *max_y = FBC_MAX_Y; - - /* if (m_smallLocalFrameBufferMemory == 1) - * { - * *max_x = FBC_MAX_X_SG; - * *max_y = FBC_MAX_Y_SG; - * } - */ -} - static const struct compressor_funcs dce110_compressor_funcs = { .power_up_fbc = dce110_compressor_power_up_fbc, .enable_fbc = dce110_compressor_enable_fbc, diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.h index 26c7335a1cbf..223c57941e92 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.h +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.h @@ -75,7 +75,5 @@ void dce110_compressor_program_lpt_control(struct compressor *cp, bool dce110_compressor_is_lpt_enabled_in_hw(struct compressor *cp); -void get_max_support_fbc_buffersize(unsigned int *max_x, unsigned int *max_y); - #endif -- cgit v1.2.3 From b0fce908cf5db7d624c83f81050211e158febabd Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Sun, 2 Feb 2025 21:58:56 +0000 Subject: drm/amd/display: Remove unused link_enc_cfg_get_link_enc_used_by_stream link_enc_cfg_get_link_enc_used_by_stream() is no longer used after 2021's: commit 6366b00346c0 ("drm/amd/display: Maintain consistent mode of operation during encoder assignment") which introduces and uses the _current version instead. Remove it. Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c | 11 ----------- drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h | 5 ----- 2 files changed, 16 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c index 039b176e086d..08b4258b0e2f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c @@ -559,17 +559,6 @@ struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct dc *dc) return link_enc; } -struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream( - struct dc *dc, - const struct dc_stream_state *stream) -{ - struct link_encoder *link_enc; - - link_enc = link_enc_cfg_get_link_enc_used_by_link(dc, stream->link); - - return link_enc; -} - struct link_encoder *link_enc_cfg_get_link_enc( const struct dc_link *link) { diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h index dc650be3837e..f1afb31ac70b 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h @@ -96,11 +96,6 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_link( /* Return next available DIG link encoder. NULL if none available. */ struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct dc *dc); -/* Return DIG link encoder used by stream. NULL if unused. */ -struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream( - struct dc *dc, - const struct dc_stream_state *stream); - /* Return DIG link encoder. NULL if unused. */ struct link_encoder *link_enc_cfg_get_link_enc(const struct dc_link *link); -- cgit v1.2.3 From 3e7ef261d3866421a71fb6ec9e48bca543a4d339 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Mon, 3 Feb 2025 11:02:03 -0700 Subject: drm/amd/display: Replace pr_info in dc_validate_boot_timing() Use DC_LOG_DEBUG instead of pr_info to match other uses in dc.c. Fixes: 091e301c2b41 ("drm/amd/display: Add debug messages for dc_validate_boot_timing()") Reviewed-by: Mario Limonciello Signed-off-by: Alex Hung Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index c5f1b61ed640..05ad7a9af4ff 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1838,7 +1838,7 @@ bool dc_validate_boot_timing(const struct dc *dc, 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) { - pr_info("boot timing validation failed due to pixels_per_cycle\n"); + DC_LOG_DEBUG("boot timing validation failed due to pixels_per_cycle\n"); return false; } -- cgit v1.2.3 From 59f79d83fcc840e7c639486ec54ed8d68d3c5208 Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Fri, 10 Jan 2025 20:24:08 +0800 Subject: drm/amd/display: Add DCN36 version identifiers Add DCN3.6 asic identifiers. Acked-by: Harry Wentland Reviewed-by: Martin Leung Signed-off-by: Taimur Hassan Signed-off-by: Wayne Lin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_helper.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dc_helper.c b/drivers/gpu/drm/amd/display/dc/dc_helper.c index b402be59b2c8..8f077e15b4f0 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dc_helper.c @@ -741,6 +741,8 @@ char *dce_version_to_string(const int version) return "DCN 3.5"; case DCN_VERSION_3_51: return "DCN 3.5.1"; + case DCN_VERSION_3_6: + return "DCN 3.6"; case DCN_VERSION_4_01: return "DCN 4.0.1"; default: -- cgit v1.2.3 From 02efc0a780442930e6c09ccbd370e9f847401ca0 Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Fri, 10 Jan 2025 20:55:42 +0800 Subject: drm/amd/display: Add DCN36 BIOS command table support Add case for DCN36 in command_table_helper2.c. Acked-by: Harry Wentland Reviewed-by: Martin Leung Signed-off-by: Taimur Hassan Signed-off-by: Wayne Lin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c index 73458e295103..bad4e4711b4f 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c @@ -82,6 +82,7 @@ bool dal_bios_parser_init_cmd_tbl_helper2( case DCN_VERSION_3_21: case DCN_VERSION_3_5: case DCN_VERSION_3_51: + case DCN_VERSION_3_6: case DCN_VERSION_4_01: *h = dal_cmd_tbl_helper_dce112_get_table2(); return true; -- cgit v1.2.3 From 76e3b62db9bf2dbedc5f41070684fdec64cd71a6 Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Fri, 10 Jan 2025 20:27:27 +0800 Subject: drm/amd/display: Add DCN36 IRQ Add IRQ services for DCN36. This allows us to create/init and manage irqs for DCN3 V2: adjust copyright license text Acked-by: Harry Wentland Reviewed-by: Martin Leung Signed-off-by: Taimur Hassan Signed-off-by: Wayne Lin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/irq/Makefile | 9 + .../amd/display/dc/irq/dcn36/irq_service_dcn36.c | 408 +++++++++++++++++++++ .../amd/display/dc/irq/dcn36/irq_service_dcn36.h | 12 + 3 files changed, 429 insertions(+) create mode 100644 drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.c create mode 100644 drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.h (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/irq/Makefile b/drivers/gpu/drm/amd/display/dc/irq/Makefile index 8ac36bdd4e1e..b5e14d792378 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/Makefile +++ b/drivers/gpu/drm/amd/display/dc/irq/Makefile @@ -181,6 +181,15 @@ AMD_DAL_IRQ_DCN351= $(addprefix $(AMDDALPATH)/dc/irq/dcn351/,$(IRQ_DCN351)) AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN351) +############################################################################### +# DCN 36 +############################################################################### +IRQ_DCN36 = irq_service_dcn36.o + +AMD_DAL_IRQ_DCN36= $(addprefix $(AMDDALPATH)/dc/irq/dcn36/,$(IRQ_DCN36)) + +AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN36) + ############################################################################### # DCN 401 ############################################################################### diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.c b/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.c new file mode 100644 index 000000000000..ea958628f8b8 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.c @@ -0,0 +1,408 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright 2025 Advanced Micro Devices, Inc. */ + +#include "dm_services.h" +#include "include/logger_interface.h" +#include "../dce110/irq_service_dce110.h" + +#include "dcn/dcn_3_6_0_offset.h" +#include "dcn/dcn_3_6_0_sh_mask.h" + +#include "irq_service_dcn36.h" + +#include "ivsrcid/dcn/irqsrcs_dcn_1_0.h" + +static enum dc_irq_source to_dal_irq_source_dcn36( + struct irq_service *irq_service, + uint32_t src_id, + uint32_t ext_id) +{ + switch (src_id) { + case DCN_1_0__SRCID__DC_D1_OTG_VSTARTUP: + return DC_IRQ_SOURCE_VBLANK1; + case DCN_1_0__SRCID__DC_D2_OTG_VSTARTUP: + return DC_IRQ_SOURCE_VBLANK2; + case DCN_1_0__SRCID__DC_D3_OTG_VSTARTUP: + return DC_IRQ_SOURCE_VBLANK3; + case DCN_1_0__SRCID__DC_D4_OTG_VSTARTUP: + return DC_IRQ_SOURCE_VBLANK4; + case DCN_1_0__SRCID__DC_D5_OTG_VSTARTUP: + return DC_IRQ_SOURCE_VBLANK5; + case DCN_1_0__SRCID__DC_D6_OTG_VSTARTUP: + return DC_IRQ_SOURCE_VBLANK6; + case DCN_1_0__SRCID__OTG1_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC1_VLINE0; + case DCN_1_0__SRCID__OTG2_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC2_VLINE0; + case DCN_1_0__SRCID__OTG3_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC3_VLINE0; + case DCN_1_0__SRCID__OTG4_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC4_VLINE0; + case DCN_1_0__SRCID__OTG5_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC5_VLINE0; + case DCN_1_0__SRCID__OTG6_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC6_VLINE0; + case DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT: + return DC_IRQ_SOURCE_PFLIP1; + case DCN_1_0__SRCID__HUBP1_FLIP_INTERRUPT: + return DC_IRQ_SOURCE_PFLIP2; + case DCN_1_0__SRCID__HUBP2_FLIP_INTERRUPT: + return DC_IRQ_SOURCE_PFLIP3; + case DCN_1_0__SRCID__HUBP3_FLIP_INTERRUPT: + return DC_IRQ_SOURCE_PFLIP4; + case DCN_1_0__SRCID__HUBP4_FLIP_INTERRUPT: + return DC_IRQ_SOURCE_PFLIP5; + case DCN_1_0__SRCID__HUBP5_FLIP_INTERRUPT: + return DC_IRQ_SOURCE_PFLIP6; + case DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE1; + case DCN_1_0__SRCID__OTG1_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE2; + case DCN_1_0__SRCID__OTG2_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE3; + case DCN_1_0__SRCID__OTG3_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE4; + case DCN_1_0__SRCID__OTG4_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE5; + case DCN_1_0__SRCID__OTG5_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE6; + case DCN_1_0__SRCID__DMCUB_OUTBOX_LOW_PRIORITY_READY_INT: + return DC_IRQ_SOURCE_DMCUB_OUTBOX; + case DCN_1_0__SRCID__DC_HPD1_INT: + /* generic src_id for all HPD and HPDRX interrupts */ + switch (ext_id) { + case DCN_1_0__CTXID__DC_HPD1_INT: + return DC_IRQ_SOURCE_HPD1; + case DCN_1_0__CTXID__DC_HPD2_INT: + return DC_IRQ_SOURCE_HPD2; + case DCN_1_0__CTXID__DC_HPD3_INT: + return DC_IRQ_SOURCE_HPD3; + case DCN_1_0__CTXID__DC_HPD4_INT: + return DC_IRQ_SOURCE_HPD4; + case DCN_1_0__CTXID__DC_HPD5_INT: + return DC_IRQ_SOURCE_HPD5; + case DCN_1_0__CTXID__DC_HPD6_INT: + return DC_IRQ_SOURCE_HPD6; + case DCN_1_0__CTXID__DC_HPD1_RX_INT: + return DC_IRQ_SOURCE_HPD1RX; + case DCN_1_0__CTXID__DC_HPD2_RX_INT: + return DC_IRQ_SOURCE_HPD2RX; + case DCN_1_0__CTXID__DC_HPD3_RX_INT: + return DC_IRQ_SOURCE_HPD3RX; + case DCN_1_0__CTXID__DC_HPD4_RX_INT: + return DC_IRQ_SOURCE_HPD4RX; + case DCN_1_0__CTXID__DC_HPD5_RX_INT: + return DC_IRQ_SOURCE_HPD5RX; + case DCN_1_0__CTXID__DC_HPD6_RX_INT: + return DC_IRQ_SOURCE_HPD6RX; + default: + return DC_IRQ_SOURCE_INVALID; + } + break; + + default: + return DC_IRQ_SOURCE_INVALID; + } +} + +static bool hpd_ack( + struct irq_service *irq_service, + const struct irq_source_info *info) +{ + uint32_t addr = info->status_reg; + uint32_t value = dm_read_reg(irq_service->ctx, addr); + uint32_t current_status = + get_reg_field_value( + value, + HPD0_DC_HPD_INT_STATUS, + DC_HPD_SENSE_DELAYED); + + dal_irq_service_ack_generic(irq_service, info); + + value = dm_read_reg(irq_service->ctx, info->enable_reg); + + set_reg_field_value( + value, + current_status ? 0 : 1, + HPD0_DC_HPD_INT_CONTROL, + DC_HPD_INT_POLARITY); + + dm_write_reg(irq_service->ctx, info->enable_reg, value); + + return true; +} + +static struct irq_source_info_funcs hpd_irq_info_funcs = { + .set = NULL, + .ack = hpd_ack +}; + +static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + +static struct irq_source_info_funcs pflip_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + +static struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + +static struct irq_source_info_funcs vblank_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + +static struct irq_source_info_funcs outbox_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + +static struct irq_source_info_funcs vline0_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + +#undef BASE_INNER +#define BASE_INNER(seg) ctx->dcn_reg_offsets[seg] + +/* compile time expand base address. */ +#define BASE(seg) \ + BASE_INNER(seg) + +#define SRI(reg_name, block, id)\ + BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SRI_DMUB(reg_name)\ + BASE(reg ## reg_name ## _BASE_IDX) + \ + reg ## reg_name + +#define IRQ_REG_ENTRY(base, block, reg_num, reg1, mask1, reg2, mask2)\ + REG_STRUCT[base + reg_num].enable_reg = SRI(reg1, block, reg_num),\ + REG_STRUCT[base + reg_num].enable_mask = \ + block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\ + REG_STRUCT[base + reg_num].enable_value[0] = \ + block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\ + REG_STRUCT[base + reg_num].enable_value[1] = \ + ~block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK, \ + REG_STRUCT[base + reg_num].ack_reg = SRI(reg2, block, reg_num),\ + REG_STRUCT[base + reg_num].ack_mask = \ + block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK,\ + REG_STRUCT[base + reg_num].ack_value = \ + block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK \ + +#define IRQ_REG_ENTRY_DMUB(base, reg1, mask1, reg2, mask2)\ + REG_STRUCT[base].enable_reg = SRI_DMUB(reg1),\ + REG_STRUCT[base].enable_mask = \ + reg1 ## __ ## mask1 ## _MASK,\ + REG_STRUCT[base].enable_value[0] = \ + reg1 ## __ ## mask1 ## _MASK,\ + REG_STRUCT[base].enable_value[1] = \ + ~reg1 ## __ ## mask1 ## _MASK, \ + REG_STRUCT[base].ack_reg = SRI_DMUB(reg2),\ + REG_STRUCT[base].ack_mask = \ + reg2 ## __ ## mask2 ## _MASK,\ + REG_STRUCT[base].ack_value = \ + reg2 ## __ ## mask2 ## _MASK \ + +#define hpd_int_entry(reg_num)\ + IRQ_REG_ENTRY(DC_IRQ_SOURCE_HPD1, HPD, reg_num,\ + DC_HPD_INT_CONTROL, DC_HPD_INT_EN,\ + DC_HPD_INT_CONTROL, DC_HPD_INT_ACK),\ + REG_STRUCT[DC_IRQ_SOURCE_HPD1 + reg_num].funcs = &hpd_irq_info_funcs;\ + REG_STRUCT[DC_IRQ_SOURCE_HPD1 + reg_num].status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num);\ + +#define hpd_rx_int_entry(reg_num)\ + IRQ_REG_ENTRY(DC_IRQ_SOURCE_HPD1RX, HPD, reg_num,\ + DC_HPD_INT_CONTROL, DC_HPD_RX_INT_EN,\ + DC_HPD_INT_CONTROL, DC_HPD_RX_INT_ACK),\ + REG_STRUCT[DC_IRQ_SOURCE_HPD1RX + reg_num].status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num);\ + REG_STRUCT[DC_IRQ_SOURCE_HPD1RX + reg_num].funcs = &hpd_rx_irq_info_funcs;\ + +#define pflip_int_entry(reg_num)\ + IRQ_REG_ENTRY(DC_IRQ_SOURCE_PFLIP1, HUBPREQ, reg_num,\ + DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_INT_MASK,\ + DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_CLEAR),\ + REG_STRUCT[DC_IRQ_SOURCE_PFLIP1 + reg_num].funcs = &pflip_irq_info_funcs\ + +/* vupdate_no_lock_int_entry maps to DC_IRQ_SOURCE_VUPDATEx, to match semantic + * of DCE's DC_IRQ_SOURCE_VUPDATEx. + */ +#define vupdate_no_lock_int_entry(reg_num)\ + IRQ_REG_ENTRY(DC_IRQ_SOURCE_VUPDATE1, OTG, reg_num,\ + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_INT_EN,\ + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR),\ + REG_STRUCT[DC_IRQ_SOURCE_VUPDATE1 + reg_num].funcs = &vupdate_no_lock_irq_info_funcs\ + +#define vblank_int_entry(reg_num)\ + IRQ_REG_ENTRY(DC_IRQ_SOURCE_VBLANK1, OTG, reg_num,\ + OTG_GLOBAL_SYNC_STATUS, VSTARTUP_INT_EN,\ + OTG_GLOBAL_SYNC_STATUS, VSTARTUP_EVENT_CLEAR),\ + REG_STRUCT[DC_IRQ_SOURCE_VBLANK1 + reg_num].funcs = &vblank_irq_info_funcs\ + +#define vline0_int_entry(reg_num)\ + IRQ_REG_ENTRY(DC_IRQ_SOURCE_DC1_VLINE0, OTG, reg_num,\ + OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_INT_ENABLE,\ + OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_CLEAR),\ + REG_STRUCT[DC_IRQ_SOURCE_DC1_VLINE0 + reg_num].funcs = &vline0_irq_info_funcs\ + +#define dmub_outbox_int_entry()\ + IRQ_REG_ENTRY_DMUB(DC_IRQ_SOURCE_DMCUB_OUTBOX, \ + DMCUB_INTERRUPT_ENABLE, DMCUB_OUTBOX1_READY_INT_EN,\ + DMCUB_INTERRUPT_ACK, DMCUB_OUTBOX1_READY_INT_ACK),\ + REG_STRUCT[DC_IRQ_SOURCE_DMCUB_OUTBOX].funcs = &outbox_irq_info_funcs + +#define dummy_irq_entry(irqno) \ + REG_STRUCT[irqno].funcs = &dummy_irq_info_funcs\ + +#define i2c_int_entry(reg_num) \ + dummy_irq_entry(DC_IRQ_SOURCE_I2C_DDC ## reg_num) + +#define dp_sink_int_entry(reg_num) \ + dummy_irq_entry(DC_IRQ_SOURCE_DPSINK ## reg_num) + +#define gpio_pad_int_entry(reg_num) \ + dummy_irq_entry(DC_IRQ_SOURCE_GPIOPAD ## reg_num) + +#define dc_underflow_int_entry(reg_num) \ + dummy_irq_entry(DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW) + +static struct irq_source_info_funcs dummy_irq_info_funcs = { + .set = dal_irq_service_dummy_set, + .ack = dal_irq_service_dummy_ack +}; + +#define dcn36_irq_init_part_1() {\ + dummy_irq_entry(DC_IRQ_SOURCE_INVALID); \ + hpd_int_entry(0); \ + hpd_int_entry(1); \ + hpd_int_entry(2); \ + hpd_int_entry(3); \ + hpd_int_entry(4); \ + hpd_rx_int_entry(0); \ + hpd_rx_int_entry(1); \ + hpd_rx_int_entry(2); \ + hpd_rx_int_entry(3); \ + hpd_rx_int_entry(4); \ + i2c_int_entry(1); \ + i2c_int_entry(2); \ + i2c_int_entry(3); \ + i2c_int_entry(4); \ + i2c_int_entry(5); \ + i2c_int_entry(6); \ + dp_sink_int_entry(1); \ + dp_sink_int_entry(2); \ + dp_sink_int_entry(3); \ + dp_sink_int_entry(4); \ + dp_sink_int_entry(5); \ + dp_sink_int_entry(6); \ + dummy_irq_entry(DC_IRQ_SOURCE_TIMER); \ + pflip_int_entry(0); \ + pflip_int_entry(1); \ + pflip_int_entry(2); \ + pflip_int_entry(3); \ + dummy_irq_entry(DC_IRQ_SOURCE_PFLIP5); \ + dummy_irq_entry(DC_IRQ_SOURCE_PFLIP6); \ + dummy_irq_entry(DC_IRQ_SOURCE_PFLIP_UNDERLAY0); \ + gpio_pad_int_entry(0); \ + gpio_pad_int_entry(1); \ + gpio_pad_int_entry(2); \ + gpio_pad_int_entry(3); \ + gpio_pad_int_entry(4); \ + gpio_pad_int_entry(5); \ + gpio_pad_int_entry(6); \ + gpio_pad_int_entry(7); \ + gpio_pad_int_entry(8); \ + gpio_pad_int_entry(9); \ + gpio_pad_int_entry(10); \ + gpio_pad_int_entry(11); \ + gpio_pad_int_entry(12); \ + gpio_pad_int_entry(13); \ + gpio_pad_int_entry(14); \ + gpio_pad_int_entry(15); \ + gpio_pad_int_entry(16); \ + gpio_pad_int_entry(17); \ + gpio_pad_int_entry(18); \ + gpio_pad_int_entry(19); \ + gpio_pad_int_entry(20); \ + gpio_pad_int_entry(21); \ + gpio_pad_int_entry(22); \ + gpio_pad_int_entry(23); \ + gpio_pad_int_entry(24); \ + gpio_pad_int_entry(25); \ + gpio_pad_int_entry(26); \ + gpio_pad_int_entry(27); \ + gpio_pad_int_entry(28); \ + gpio_pad_int_entry(29); \ + gpio_pad_int_entry(30); \ + dc_underflow_int_entry(1); \ + dc_underflow_int_entry(2); \ + dc_underflow_int_entry(3); \ + dc_underflow_int_entry(4); \ + dc_underflow_int_entry(5); \ + dc_underflow_int_entry(6); \ + dummy_irq_entry(DC_IRQ_SOURCE_DMCU_SCP); \ + dummy_irq_entry(DC_IRQ_SOURCE_VBIOS_SW); \ +} + +#define dcn36_irq_init_part_2() {\ + vupdate_no_lock_int_entry(0); \ + vupdate_no_lock_int_entry(1); \ + vupdate_no_lock_int_entry(2); \ + vupdate_no_lock_int_entry(3); \ + vblank_int_entry(0); \ + vblank_int_entry(1); \ + vblank_int_entry(2); \ + vblank_int_entry(3); \ + vline0_int_entry(0); \ + vline0_int_entry(1); \ + vline0_int_entry(2); \ + vline0_int_entry(3); \ + dummy_irq_entry(DC_IRQ_SOURCE_DC5_VLINE1); \ + dummy_irq_entry(DC_IRQ_SOURCE_DC6_VLINE1); \ + dmub_outbox_int_entry(); \ +} + +#define dcn36_irq_init() {\ + dcn36_irq_init_part_1(); \ + dcn36_irq_init_part_2(); \ +} + +static struct irq_source_info irq_source_info_dcn36[DAL_IRQ_SOURCES_NUMBER] = {0}; + +static struct irq_service_funcs irq_service_funcs_dcn36 = { + .to_dal_irq_source = to_dal_irq_source_dcn36 +}; + +static void dcn36_irq_construct( + struct irq_service *irq_service, + struct irq_service_init_data *init_data) +{ + struct dc_context *ctx = init_data->ctx; + +#define REG_STRUCT irq_source_info_dcn36 + dcn36_irq_init(); + + dal_irq_service_construct(irq_service, init_data); + + irq_service->info = irq_source_info_dcn36; + irq_service->funcs = &irq_service_funcs_dcn36; +} + +struct irq_service *dal_irq_service_dcn36_create( + struct irq_service_init_data *init_data) +{ + struct irq_service *irq_service = kzalloc(sizeof(*irq_service), + GFP_KERNEL); + + if (!irq_service) + return NULL; + + dcn36_irq_construct(irq_service, init_data); + return irq_service; +} diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.h b/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.h new file mode 100644 index 000000000000..21ff95f6562d --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright 2025 Advanced Micro Devices, Inc. */ + +#ifndef __DAL_IRQ_SERVICE_DCN36_H__ +#define __DAL_IRQ_SERVICE_DCN36_H__ + +#include "../irq_service.h" + +struct irq_service *dal_irq_service_dcn36_create( + struct irq_service_init_data *init_data); + +#endif /* __DAL_IRQ_SERVICE_DCN36_H__ */ -- cgit v1.2.3 From 9ae42f6120cade6347336a699d483c246e8fa427 Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Fri, 10 Jan 2025 20:32:48 +0800 Subject: drm/amd/display: Add DCN36 Resource Add resource handling for DCN36. V2: adjust copyright license text V3: remove unnecessary headers Acked-by: Harry Wentland Reviewed-by: Martin Leung Signed-off-by: Taimur Hassan Signed-off-by: Wayne Lin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/resource/Makefile | 8 + .../amd/display/dc/resource/dcn36/dcn36_resource.c | 2171 ++++++++++++++++++++ .../amd/display/dc/resource/dcn36/dcn36_resource.h | 73 + 3 files changed, 2252 insertions(+) create mode 100644 drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c create mode 100644 drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.h (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/resource/Makefile b/drivers/gpu/drm/amd/display/dc/resource/Makefile index 09320344d8e9..b8cddef6b3d2 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/Makefile +++ b/drivers/gpu/drm/amd/display/dc/resource/Makefile @@ -198,6 +198,14 @@ AMD_DISPLAY_FILES += $(AMD_DAL_RESOURCE_DCN351) ############################################################################### +RESOURCE_DCN36 = dcn36_resource.o + +AMD_DAL_RESOURCE_DCN36 = $(addprefix $(AMDDALPATH)/dc/resource/dcn36/,$(RESOURCE_DCN36)) + +AMD_DISPLAY_FILES += $(AMD_DAL_RESOURCE_DCN36) + +############################################################################### + 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/dcn36/dcn36_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c new file mode 100644 index 000000000000..b6468573dc33 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c @@ -0,0 +1,2171 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright 2025 Advanced Micro Devices, Inc. */ + +#include "dm_services.h" +#include "dc.h" + +#include "dcn31/dcn31_init.h" +#include "dcn35/dcn35_init.h" +#include "dcn36/dcn36_resource.h" + +#include "resource.h" +#include "include/irq_service_interface.h" +#include "dcn36_resource.h" +#include "dml2/dml2_wrapper.h" + +#include "dcn20/dcn20_resource.h" +#include "dcn30/dcn30_resource.h" +#include "dcn31/dcn31_resource.h" +#include "dcn32/dcn32_resource.h" +#include "dcn35/dcn35_resource.h" + +#include "dcn10/dcn10_ipp.h" +#include "dcn30/dcn30_hubbub.h" +#include "dcn31/dcn31_hubbub.h" +#include "dcn35/dcn35_hubbub.h" +#include "dcn32/dcn32_mpc.h" +#include "dcn35/dcn35_hubp.h" +#include "irq/dcn36/irq_service_dcn36.h" +#include "dcn35/dcn35_dpp.h" +#include "dcn35/dcn35_optc.h" +#include "dcn20/dcn20_hwseq.h" +#include "dcn30/dcn30_hwseq.h" +#include "dce110/dce110_hwseq.h" +#include "dcn35/dcn35_opp.h" +#include "dcn35/dcn35_dsc.h" +#include "dcn30/dcn30_vpg.h" +#include "dcn30/dcn30_afmt.h" +#include "dcn31/dcn31_dio_link_encoder.h" +#include "dcn35/dcn35_dio_stream_encoder.h" +#include "dcn31/dcn31_hpo_dp_stream_encoder.h" +#include "dcn31/dcn31_hpo_dp_link_encoder.h" +#include "dcn32/dcn32_hpo_dp_link_encoder.h" +#include "link.h" +#include "dcn31/dcn31_apg.h" +#include "dcn32/dcn32_dio_link_encoder.h" +#include "dcn31/dcn31_vpg.h" +#include "dcn31/dcn31_afmt.h" +#include "dce/dce_clock_source.h" +#include "dce/dce_audio.h" +#include "dce/dce_hwseq.h" +#include "clk_mgr.h" +#include "virtual/virtual_stream_encoder.h" +#include "dce110/dce110_resource.h" +#include "dml/display_mode_vba.h" +#include "dcn35/dcn35_dccg.h" +#include "dcn35/dcn35_pg_cntl.h" +#include "dcn10/dcn10_resource.h" +#include "dcn31/dcn31_panel_cntl.h" +#include "dcn35/dcn35_hwseq.h" +#include "dcn35/dcn35_dio_link_encoder.h" +#include "dml/dcn31/dcn31_fpu.h" /*todo*/ +#include "dml/dcn35/dcn35_fpu.h" +#include "dcn35/dcn35_dwb.h" +#include "dcn35/dcn35_mmhubbub.h" + +#include "dcn/dcn_3_6_0_offset.h" +#include "dcn/dcn_3_6_0_sh_mask.h" + +#define regBIF_BX2_BIOS_SCRATCH_2 0x2ffc004e +#define regBIF_BX2_BIOS_SCRATCH_2_BASE_IDX 5 + +#define regBIF_BX2_BIOS_SCRATCH_3 0x2ffc004f +#define regBIF_BX2_BIOS_SCRATCH_3_BASE_IDX 5 + +#define regBIF_BX2_BIOS_SCRATCH_6 0x2ffc0052 +#define regBIF_BX2_BIOS_SCRATCH_6_BASE_IDX 5 + +#define DSCC0_DSCC_CONFIG0__ICH_RESET_AT_END_OF_LINE__SHIFT 0x0 +#define DSCC0_DSCC_CONFIG0__ICH_RESET_AT_END_OF_LINE_MASK 0x0000000FL + +#include "reg_helper.h" +#include "dce/dmub_abm.h" +#include "dce/dmub_psr.h" +#include "dce/dmub_replay.h" +#include "dce/dce_aux.h" +#include "dce/dce_i2c.h" +#include "dml/dcn31/display_mode_vba_31.h" /*temp*/ +#include "vm_helper.h" +#include "dcn20/dcn20_vmid.h" + +#include "dc_state_priv.h" + +#include "link_enc_cfg.h" +#define DC_LOGGER_INIT(logger) + +enum dcn36_clk_src_array_id { + DCN36_CLK_SRC_PLL0, + DCN36_CLK_SRC_PLL1, + DCN36_CLK_SRC_PLL2, + DCN36_CLK_SRC_PLL3, + DCN36_CLK_SRC_PLL4, + DCN36_CLK_SRC_TOTAL +}; + +/* begin ********************* + * macros to expend register list macro defined in HW object header file + */ + +/* DCN */ +/* TODO awful hack. fixup dcn20_dwb.h */ +#undef BASE_INNER +#define BASE_INNER(seg) ctx->dcn_reg_offsets[seg] + +#define BASE(seg) BASE_INNER(seg) + +#define SR(reg_name)\ + REG_STRUCT.reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ + reg ## reg_name + +#define SR_ARR(reg_name, id) \ + REG_STRUCT[id].reg_name = BASE(reg##reg_name##_BASE_IDX) + reg##reg_name + +#define SR_ARR_INIT(reg_name, id, value) \ + REG_STRUCT[id].reg_name = value + +#define SRI(reg_name, block, id)\ + REG_STRUCT.reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SRI_ARR(reg_name, block, id)\ + REG_STRUCT[id].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SR_ARR_I2C(reg_name, id) \ + REG_STRUCT[id-1].reg_name = BASE(reg##reg_name##_BASE_IDX) + reg##reg_name + +#define SRI_ARR_I2C(reg_name, block, id)\ + REG_STRUCT[id-1].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SRI_ARR_ALPHABET(reg_name, block, index, id)\ + REG_STRUCT[index].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SRI2(reg_name, block, id)\ + .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ + reg ## reg_name + +#define SRI2_ARR(reg_name, block, id)\ + REG_STRUCT[id].reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ + reg ## reg_name + +#define SRIR(var_name, reg_name, block, id)\ + .var_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SRII(reg_name, block, id)\ + REG_STRUCT.reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SRII_ARR_2(reg_name, block, id, inst)\ + REG_STRUCT[inst].reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SRII_MPC_RMU(reg_name, block, id)\ + .RMU##_##reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SRII_DWB(reg_name, temp_name, block, id)\ + REG_STRUCT.reg_name[id] = BASE(reg ## block ## id ## _ ## temp_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## temp_name + +#define SF_DWB2(reg_name, block, id, field_name, post_fix) \ + .field_name = reg_name ## __ ## field_name ## post_fix + +#define DCCG_SRII(reg_name, block, id)\ + REG_STRUCT.block ## _ ## reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define VUPDATE_SRII(reg_name, block, id)\ + REG_STRUCT.reg_name[id] = BASE(reg ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ + reg ## reg_name ## _ ## block ## id + +/* NBIO */ +#define NBIO_BASE_INNER(seg) ctx->nbio_reg_offsets[seg] + +#define NBIO_BASE(seg) \ + NBIO_BASE_INNER(seg) + +#define NBIO_SR(reg_name)\ + REG_STRUCT.reg_name = NBIO_BASE(regBIF_BX2_ ## reg_name ## _BASE_IDX) + \ + regBIF_BX2_ ## reg_name + +#define NBIO_SR_ARR(reg_name, id)\ + REG_STRUCT[id].reg_name = NBIO_BASE(regBIF_BX2_ ## reg_name ## _BASE_IDX) + \ + regBIF_BX2_ ## reg_name + +#define bios_regs_init() \ + ( \ + NBIO_SR(BIOS_SCRATCH_3),\ + NBIO_SR(BIOS_SCRATCH_6)\ + ) + +static struct bios_registers bios_regs; + +#define clk_src_regs_init(index, pllid)\ + CS_COMMON_REG_LIST_DCN3_0_RI(index, pllid) + +static struct dce110_clk_src_regs clk_src_regs[5]; + +static const struct dce110_clk_src_shift cs_shift = { + CS_COMMON_MASK_SH_LIST_DCN3_1_4(__SHIFT) +}; + +static const struct dce110_clk_src_mask cs_mask = { + CS_COMMON_MASK_SH_LIST_DCN3_1_4(_MASK) +}; + +#define abm_regs_init(id)\ + ABM_DCN32_REG_LIST_RI(id) + +static struct dce_abm_registers abm_regs[4]; + +static const struct dce_abm_shift abm_shift = { + ABM_MASK_SH_LIST_DCN35(__SHIFT) +}; + +static const struct dce_abm_mask abm_mask = { + ABM_MASK_SH_LIST_DCN35(_MASK) +}; + +#define audio_regs_init(id)\ + AUD_COMMON_REG_LIST_RI(id) + +static struct dce_audio_registers audio_regs[7]; + + +#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\ + SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\ + SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\ + AUD_COMMON_MASK_SH_LIST_BASE(mask_sh) + +static const struct dce_audio_shift audio_shift = { + DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT) +}; + +static const struct dce_audio_mask audio_mask = { + DCE120_AUD_COMMON_MASK_SH_LIST(_MASK) +}; + +#define vpg_regs_init(id)\ + VPG_DCN31_REG_LIST_RI(id) + +static struct dcn31_vpg_registers vpg_regs[10]; + +static const struct dcn31_vpg_shift vpg_shift = { + DCN31_VPG_MASK_SH_LIST(__SHIFT) +}; + +static const struct dcn31_vpg_mask vpg_mask = { + DCN31_VPG_MASK_SH_LIST(_MASK) +}; + +#define afmt_regs_init(id)\ + AFMT_DCN31_REG_LIST_RI(id) + +static struct dcn31_afmt_registers afmt_regs[6]; + +static const struct dcn31_afmt_shift afmt_shift = { + DCN31_AFMT_MASK_SH_LIST(__SHIFT) +}; + +static const struct dcn31_afmt_mask afmt_mask = { + DCN31_AFMT_MASK_SH_LIST(_MASK) +}; + +#define apg_regs_init(id)\ + APG_DCN31_REG_LIST_RI(id) + +static struct dcn31_apg_registers apg_regs[4]; + +static const struct dcn31_apg_shift apg_shift = { + DCN31_APG_MASK_SH_LIST(__SHIFT) +}; + +static const struct dcn31_apg_mask apg_mask = { + DCN31_APG_MASK_SH_LIST(_MASK) +}; + +#define stream_enc_regs_init(id)\ + SE_DCN35_REG_LIST_RI(id) + +static struct dcn10_stream_enc_registers stream_enc_regs[5]; + +static const struct dcn10_stream_encoder_shift se_shift = { + SE_COMMON_MASK_SH_LIST_DCN35(__SHIFT) +}; + +static const struct dcn10_stream_encoder_mask se_mask = { + SE_COMMON_MASK_SH_LIST_DCN35(_MASK) +}; + +#define aux_regs_init(id)\ + DCN2_AUX_REG_LIST_RI(id) + +static struct dcn10_link_enc_aux_registers link_enc_aux_regs[5]; + +#define hpd_regs_init(id)\ + HPD_REG_LIST_RI(id) + +static struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[5]; + + +static const struct dce110_aux_registers_shift aux_shift = { + DCN_AUX_MASK_SH_LIST(__SHIFT) +}; + +static const struct dce110_aux_registers_mask aux_mask = { + DCN_AUX_MASK_SH_LIST(_MASK) +}; + +#define link_regs_init(id, phyid)\ + ( \ + LE_DCN35_REG_LIST_RI(id), \ + UNIPHY_DCN2_REG_LIST_RI(id, phyid)\ + ) + +static struct dcn10_link_enc_registers link_enc_regs[5]; + +static const struct dcn10_link_enc_shift le_shift = { + LINK_ENCODER_MASK_SH_LIST_DCN35(__SHIFT), \ + //DPCS_DCN31_MASK_SH_LIST(__SHIFT) +}; + +static const struct dcn10_link_enc_mask le_mask = { + LINK_ENCODER_MASK_SH_LIST_DCN35(_MASK), \ + //DPCS_DCN31_MASK_SH_LIST(_MASK) +}; + +#define hpo_dp_stream_encoder_reg_init(id)\ + DCN3_1_HPO_DP_STREAM_ENC_REG_LIST_RI(id) + +static struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs[4]; + +static const struct dcn31_hpo_dp_stream_encoder_shift hpo_dp_se_shift = { + DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(__SHIFT) +}; + +static const struct dcn31_hpo_dp_stream_encoder_mask hpo_dp_se_mask = { + DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(_MASK) +}; + +#define hpo_dp_link_encoder_reg_init(id)\ + DCN3_1_HPO_DP_LINK_ENC_REG_LIST_RI(id) + +static struct dcn31_hpo_dp_link_encoder_registers hpo_dp_link_enc_regs[2]; + +static const struct dcn31_hpo_dp_link_encoder_shift hpo_dp_le_shift = { + DCN3_1_HPO_DP_LINK_ENC_COMMON_MASK_SH_LIST(__SHIFT) +}; + +static const struct dcn31_hpo_dp_link_encoder_mask hpo_dp_le_mask = { + DCN3_1_HPO_DP_LINK_ENC_COMMON_MASK_SH_LIST(_MASK) +}; + +#define dpp_regs_init(id)\ + DPP_REG_LIST_DCN35_RI(id) + +static struct dcn3_dpp_registers dpp_regs[4]; + +static const struct dcn35_dpp_shift tf_shift = { + DPP_REG_LIST_SH_MASK_DCN35(__SHIFT) +}; + +static const struct dcn35_dpp_mask tf_mask = { + DPP_REG_LIST_SH_MASK_DCN35(_MASK) +}; + +#define opp_regs_init(id)\ + OPP_REG_LIST_DCN35_RI(id) + +static struct dcn35_opp_registers opp_regs[4]; + +static const struct dcn35_opp_shift opp_shift = { + OPP_MASK_SH_LIST_DCN35(__SHIFT) +}; + +static const struct dcn35_opp_mask opp_mask = { + OPP_MASK_SH_LIST_DCN35(_MASK) +}; + +#define aux_engine_regs_init(id)\ + ( \ + AUX_COMMON_REG_LIST0_RI(id), \ + SR_ARR_INIT(AUXN_IMPCAL, id, 0), \ + SR_ARR_INIT(AUXP_IMPCAL, id, 0), \ + SR_ARR_INIT(AUX_RESET_MASK, id, DP_AUX0_AUX_CONTROL__AUX_RESET_MASK) \ + ) + +static struct dce110_aux_registers aux_engine_regs[5]; + +#define dwbc_regs_dcn3_init(id)\ + DWBC_COMMON_REG_LIST_DCN30_RI(id) + +static struct dcn30_dwbc_registers dwbc35_regs[1]; + +static const struct dcn35_dwbc_shift dwbc35_shift = { + DWBC_COMMON_MASK_SH_LIST_DCN35(__SHIFT) +}; + +static const struct dcn35_dwbc_mask dwbc35_mask = { + DWBC_COMMON_MASK_SH_LIST_DCN35(_MASK) +}; + +#define mcif_wb_regs_dcn3_init(id)\ + MCIF_WB_COMMON_REG_LIST_DCN3_5_RI(id) + +static struct dcn35_mmhubbub_registers mcif_wb35_regs[1]; + +static const struct dcn35_mmhubbub_shift mcif_wb35_shift = { + MCIF_WB_COMMON_MASK_SH_LIST_DCN3_5(__SHIFT) +}; + +static const struct dcn35_mmhubbub_mask mcif_wb35_mask = { + MCIF_WB_COMMON_MASK_SH_LIST_DCN3_5(_MASK) +}; + +#define dsc_regsDCN35_init(id)\ + DSC_REG_LIST_DCN20_RI(id) + +static struct dcn20_dsc_registers dsc_regs[4]; + +static const struct dcn35_dsc_shift dsc_shift = { + DSC_REG_LIST_SH_MASK_DCN35(__SHIFT) +}; + +static const struct dcn35_dsc_mask dsc_mask = { + DSC_REG_LIST_SH_MASK_DCN35(_MASK) +}; + +static struct dcn30_mpc_registers mpc_regs; + +#define dcn_mpc_regs_init() \ + MPC_REG_LIST_DCN3_2_RI(0),\ + MPC_REG_LIST_DCN3_2_RI(1),\ + MPC_REG_LIST_DCN3_2_RI(2),\ + MPC_REG_LIST_DCN3_2_RI(3),\ + MPC_OUT_MUX_REG_LIST_DCN3_0_RI(0),\ + MPC_OUT_MUX_REG_LIST_DCN3_0_RI(1),\ + MPC_OUT_MUX_REG_LIST_DCN3_0_RI(2),\ + MPC_OUT_MUX_REG_LIST_DCN3_0_RI(3),\ + MPC_DWB_MUX_REG_LIST_DCN3_0_RI(0) + +static const struct dcn30_mpc_shift mpc_shift = { + MPC_COMMON_MASK_SH_LIST_DCN32(__SHIFT) +}; + +static const struct dcn30_mpc_mask mpc_mask = { + MPC_COMMON_MASK_SH_LIST_DCN32(_MASK) +}; + +#define optc_regs_init(id)\ + OPTC_COMMON_REG_LIST_DCN3_5_RI(id) + +static struct dcn_optc_registers optc_regs[4]; + +static const struct dcn_optc_shift optc_shift = { + OPTC_COMMON_MASK_SH_LIST_DCN3_5(__SHIFT) +}; + +static const struct dcn_optc_mask optc_mask = { + OPTC_COMMON_MASK_SH_LIST_DCN3_5(_MASK) +}; + +#define hubp_regs_init(id)\ + HUBP_REG_LIST_DCN30_RI(id) + +static struct dcn_hubp2_registers hubp_regs[4]; + + +static const struct dcn35_hubp2_shift hubp_shift = { + HUBP_MASK_SH_LIST_DCN35(__SHIFT) +}; + +static const struct dcn35_hubp2_mask hubp_mask = { + HUBP_MASK_SH_LIST_DCN35(_MASK) +}; + +static struct dcn_hubbub_registers hubbub_reg; + +#define hubbub_reg_init()\ + HUBBUB_REG_LIST_DCN35(0) + +static const struct dcn_hubbub_shift hubbub_shift = { + HUBBUB_MASK_SH_LIST_DCN35(__SHIFT) +}; + +static const struct dcn_hubbub_mask hubbub_mask = { + HUBBUB_MASK_SH_LIST_DCN35(_MASK) +}; + +static struct dccg_registers dccg_regs; + +#define dccg_regs_init()\ + DCCG_REG_LIST_DCN35() + +static const struct dccg_shift dccg_shift = { + DCCG_MASK_SH_LIST_DCN35(__SHIFT) +}; + +static const struct dccg_mask dccg_mask = { + DCCG_MASK_SH_LIST_DCN35(_MASK) +}; + +static struct pg_cntl_registers pg_cntl_regs; + +#define pg_cntl_dcn35_regs_init() \ + PG_CNTL_REG_LIST_DCN35() + +static const struct pg_cntl_shift pg_cntl_shift = { + PG_CNTL_MASK_SH_LIST_DCN35(__SHIFT) +}; + +static const struct pg_cntl_mask pg_cntl_mask = { + PG_CNTL_MASK_SH_LIST_DCN35(_MASK) +}; + +#define SRII2(reg_name_pre, reg_name_post, id)\ + .reg_name_pre ## _ ## reg_name_post[id] = BASE(reg ## reg_name_pre \ + ## id ## _ ## reg_name_post ## _BASE_IDX) + \ + reg ## reg_name_pre ## id ## _ ## reg_name_post + +static struct dce_hwseq_registers hwseq_reg; + +#define hwseq_reg_init()\ + HWSEQ_DCN36_REG_LIST() + +#define HWSEQ_DCN36_MASK_SH_LIST(mask_sh)\ + HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ + HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ + HWS_SF(, DCHUBBUB_ARB_HOSTVM_CNTL, DISABLE_HOSTVM_FORCE_ALLOW_PSTATE, mask_sh), \ + HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN22_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN22_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN23_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN23_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN24_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN24_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN25_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN25_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN19_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN22_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN23_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN24_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN25_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ + HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \ + HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_G_GATE_DIS, mask_sh), \ + HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \ + HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \ + HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh), \ + HWS_SF(, HPO_TOP_HW_CONTROL, HPO_IO_EN, mask_sh),\ + HWS_SF(, DMU_CLK_CNTL, DISPCLK_R_DMU_GATE_DIS, mask_sh),\ + HWS_SF(, DMU_CLK_CNTL, DISPCLK_G_RBBMIF_GATE_DIS, mask_sh),\ + HWS_SF(, DMU_CLK_CNTL, RBBMIF_FGCG_REP_DIS, mask_sh),\ + HWS_SF(, DMU_CLK_CNTL, DPREFCLK_ALLOW_DS_CLKSTOP, mask_sh),\ + HWS_SF(, DMU_CLK_CNTL, DISPCLK_ALLOW_DS_CLKSTOP, mask_sh),\ + HWS_SF(, DMU_CLK_CNTL, DPPCLK_ALLOW_DS_CLKSTOP, mask_sh),\ + HWS_SF(, DMU_CLK_CNTL, DTBCLK_ALLOW_DS_CLKSTOP, mask_sh),\ + HWS_SF(, DMU_CLK_CNTL, DCFCLK_ALLOW_DS_CLKSTOP, mask_sh),\ + HWS_SF(, DMU_CLK_CNTL, DPIACLK_ALLOW_DS_CLKSTOP, mask_sh),\ + HWS_SF(, DMU_CLK_CNTL, LONO_FGCG_REP_DIS, mask_sh),\ + HWS_SF(, DMU_CLK_CNTL, LONO_DISPCLK_GATE_DISABLE, mask_sh),\ + HWS_SF(, DMU_CLK_CNTL, LONO_SOCCLK_GATE_DISABLE, mask_sh),\ + HWS_SF(, DMU_CLK_CNTL, LONO_DMCUBCLK_GATE_DISABLE, mask_sh),\ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKA_FE_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKB_FE_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKC_FE_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKD_FE_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKE_FE_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, HDMICHARCLK0_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKA_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKB_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKC_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKD_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKE_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, PHYASYMCLK_ROOT_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, PHYBSYMCLK_ROOT_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, PHYCSYMCLK_ROOT_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, PHYDSYMCLK_ROOT_GATE_DISABLE, mask_sh), \ + HWS_SF(, DCCG_GATE_DISABLE_CNTL2, PHYESYMCLK_ROOT_GATE_DISABLE, mask_sh),\ + HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, mask_sh),\ + HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DTBCLK_P1_GATE_DISABLE, mask_sh),\ + HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DTBCLK_P2_GATE_DISABLE, mask_sh),\ + HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DTBCLK_P3_GATE_DISABLE, mask_sh),\ + HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK0_GATE_DISABLE, mask_sh),\ + HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK1_GATE_DISABLE, mask_sh),\ + HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK2_GATE_DISABLE, mask_sh),\ + HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK3_GATE_DISABLE, mask_sh),\ + HWS_SF(, DCCG_GATE_DISABLE_CNTL4, DPIASYMCLK0_GATE_DISABLE, mask_sh),\ + HWS_SF(, DCCG_GATE_DISABLE_CNTL4, DPIASYMCLK1_GATE_DISABLE, mask_sh),\ + HWS_SF(, DCCG_GATE_DISABLE_CNTL4, DPIASYMCLK2_GATE_DISABLE, mask_sh),\ + HWS_SF(, DCCG_GATE_DISABLE_CNTL4, DPIASYMCLK3_GATE_DISABLE, mask_sh) + +static const struct dce_hwseq_shift hwseq_shift = { + HWSEQ_DCN36_MASK_SH_LIST(__SHIFT) +}; + +static const struct dce_hwseq_mask hwseq_mask = { + HWSEQ_DCN36_MASK_SH_LIST(_MASK) +}; + +#define vmid_regs_init(id)\ + DCN20_VMID_REG_LIST_RI(id) + +static struct dcn_vmid_registers vmid_regs[16]; + +static const struct dcn20_vmid_shift vmid_shifts = { + DCN20_VMID_MASK_SH_LIST(__SHIFT) +}; + +static const struct dcn20_vmid_mask vmid_masks = { + DCN20_VMID_MASK_SH_LIST(_MASK) +}; + +static const struct resource_caps res_cap_dcn36 = { + .num_timing_generator = 4, + .num_opp = 4, + .num_video_plane = 4, + .num_audio = 5, + .num_stream_encoder = 5, + .num_dig_link_enc = 5, + .num_hpo_dp_stream_encoder = 4, + .num_hpo_dp_link_encoder = 2, + .num_pll = 4,/*1 c10 edp, 3xc20 combo PHY*/ + .num_dwb = 1, + .num_ddc = 5, + .num_vmid = 16, + .num_mpc_3dlut = 2, + .num_dsc = 4, +}; + +static const struct dc_plane_cap plane_cap = { + .type = DC_PLANE_TYPE_DCN_UNIVERSAL, + .per_pixel_alpha = true, + + .pixel_format_support = { + .argb8888 = true, + .nv12 = true, + .fp16 = true, + .p010 = true, + .ayuv = false, + }, + + .max_upscale_factor = { + .argb8888 = 16000, + .nv12 = 16000, + .fp16 = 16000 + }, + + // 6:1 downscaling ratio: 1000/6 = 166.666 + .max_downscale_factor = { + .argb8888 = 250, + .nv12 = 167, + .fp16 = 167 + }, + 64, + 64 +}; + +static const struct dc_debug_options debug_defaults_drv = { + .disable_dmcu = true, + .force_abm_enable = false, + .clock_trace = true, + .disable_pplib_clock_request = false, + .pipe_split_policy = MPC_SPLIT_AVOID, + .force_single_disp_pipe_split = false, + .disable_dcc = DCC_ENABLE, + .disable_dpp_power_gate = true, + .disable_hubp_power_gate = true, + .disable_optc_power_gate = true, /*should the same as above two*/ + .disable_hpo_power_gate = true, /*dmubfw force domain25 on*/ + .disable_clock_gate = false, + .disable_dsc_power_gate = true, + .vsr_support = true, + .performance_trace = false, + .max_downscale_src_width = 4096,/*upto true 4k*/ + .disable_pplib_wm_range = false, + .scl_reset_length10 = true, + .sanity_checks = false, + .underflow_assert_delay_us = 0xFFFFFFFF, + .dwb_fi_phase = -1, // -1 = disable, + .dmub_command_table = true, + .pstate_enabled = true, + .use_max_lb = true, + .enable_mem_low_power = { + .bits = { + .vga = false, + .i2c = true, + .dmcu = false, // This is previously known to cause hang on S3 cycles if enabled + .dscl = true, + .cm = true, + .mpc = true, + .optc = true, + .vpg = true, + .afmt = true, + } + }, + .root_clock_optimization = { + .bits = { + .dpp = true, + .dsc = true,/*dscclk and dsc pg*/ + .hdmistream = true, + .hdmichar = true, + .dpstream = true, + .symclk32_se = true, + .symclk32_le = true, + .symclk_fe = true, + .physymclk = false, + .dpiasymclk = true, + } + }, + .seamless_boot_odm_combine = DML_FAIL_SOURCE_PIXEL_FORMAT, + .enable_z9_disable_interface = true, /* Allow support for the PMFW interface for disable Z9*/ + .minimum_z8_residency_time = 1, /* Always allow when other conditions are met */ + .using_dml2 = true, + .support_eDP1_5 = true, + .enable_hpo_pg_support = false, + .enable_legacy_fast_update = true, + .enable_single_display_2to1_odm_policy = true, + .disable_idle_power_optimizations = false, + .dmcub_emulation = false, + .disable_boot_optimizations = false, + .disable_unbounded_requesting = false, + .disable_mem_low_power = false, + //must match enable_single_display_2to1_odm_policy to support dynamic ODM transitions + .enable_double_buffered_dsc_pg_support = true, + .enable_dp_dig_pixel_rate_div_policy = 1, + .disable_z10 = false, + .ignore_pg = true, + .psp_disabled_wa = true, + .ips2_eval_delay_us = 2000, + .ips2_entry_delay_us = 800, + .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 = { + .psr = { + .disable_psr = false, + .disallow_psrsu = false, + .disallow_replay = false, + }, + .ilr = { + .optimize_edp_link_rate = true, + }, +}; + +static void dcn35_dpp_destroy(struct dpp **dpp) +{ + kfree(TO_DCN20_DPP(*dpp)); + *dpp = NULL; +} + +static struct dpp *dcn35_dpp_create(struct dc_context *ctx, uint32_t inst) +{ + struct dcn3_dpp *dpp = kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + bool success = (dpp != NULL); + + if (!success) + return NULL; + +#undef REG_STRUCT +#define REG_STRUCT dpp_regs + dpp_regs_init(0), + dpp_regs_init(1), + dpp_regs_init(2), + dpp_regs_init(3); + + success = dpp35_construct(dpp, ctx, inst, &dpp_regs[inst], &tf_shift, + &tf_mask); + if (success) { + dpp35_set_fgcg( + dpp, + ctx->dc->debug.enable_fine_grain_clock_gating.bits.dpp); + return &dpp->base; + } + + BREAK_TO_DEBUGGER(); + kfree(dpp); + return NULL; +} + +static struct output_pixel_processor *dcn35_opp_create( + struct dc_context *ctx, uint32_t inst) +{ + struct dcn20_opp *opp = + kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + + if (!opp) { + BREAK_TO_DEBUGGER(); + return NULL; + } + +#undef REG_STRUCT +#define REG_STRUCT opp_regs + opp_regs_init(0), + opp_regs_init(1), + opp_regs_init(2), + opp_regs_init(3); + + dcn35_opp_construct(opp, ctx, inst, + &opp_regs[inst], &opp_shift, &opp_mask); + + dcn35_opp_set_fgcg(opp, ctx->dc->debug.enable_fine_grain_clock_gating.bits.opp); + + return &opp->base; +} + +static struct dce_aux *dcn31_aux_engine_create( + struct dc_context *ctx, + uint32_t inst) +{ + struct aux_engine_dce110 *aux_engine = + kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + + if (!aux_engine) + return NULL; + +#undef REG_STRUCT +#define REG_STRUCT aux_engine_regs + aux_engine_regs_init(0), + aux_engine_regs_init(1), + aux_engine_regs_init(2), + aux_engine_regs_init(3), + aux_engine_regs_init(4); + + dce110_aux_engine_construct(aux_engine, ctx, inst, + SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, + &aux_engine_regs[inst], + &aux_mask, + &aux_shift, + ctx->dc->caps.extended_aux_timeout_support); + + return &aux_engine->base; +} + +#define i2c_inst_regs_init(id)\ + I2C_HW_ENGINE_COMMON_REG_LIST_DCN30_RI(id) + +static struct dce_i2c_registers i2c_hw_regs[5]; + +static const struct dce_i2c_shift i2c_shifts = { + I2C_COMMON_MASK_SH_LIST_DCN35(__SHIFT) +}; + +static const struct dce_i2c_mask i2c_masks = { + I2C_COMMON_MASK_SH_LIST_DCN35(_MASK) +}; + +/* ========================================================== */ + +/* + * DPIA index | Preferred Encoder | Host Router + * 0 | C | 0 + * 1 | First Available | 0 + * 2 | D | 1 + * 3 | First Available | 1 + */ +/* ========================================================== */ +static const enum engine_id dpia_to_preferred_enc_id_table[] = { + ENGINE_ID_DIGC, + ENGINE_ID_DIGC, + ENGINE_ID_DIGD, + ENGINE_ID_DIGD +}; + +static enum engine_id dcn36_get_preferred_eng_id_dpia(unsigned int dpia_index) +{ + return dpia_to_preferred_enc_id_table[dpia_index]; +} + +static struct dce_i2c_hw *dcn31_i2c_hw_create( + struct dc_context *ctx, + uint32_t inst) +{ + struct dce_i2c_hw *dce_i2c_hw = + kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + + if (!dce_i2c_hw) + return NULL; + +#undef REG_STRUCT +#define REG_STRUCT i2c_hw_regs + i2c_inst_regs_init(1), + i2c_inst_regs_init(2), + i2c_inst_regs_init(3), + i2c_inst_regs_init(4), + i2c_inst_regs_init(5); + + dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst, + &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks); + + return dce_i2c_hw; +} +static struct mpc *dcn35_mpc_create( + struct dc_context *ctx, + int num_mpcc, + int num_rmu) +{ + struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), GFP_KERNEL); + + if (!mpc30) + return NULL; + +#undef REG_STRUCT +#define REG_STRUCT mpc_regs + dcn_mpc_regs_init(); + + dcn32_mpc_construct(mpc30, ctx, + &mpc_regs, + &mpc_shift, + &mpc_mask, + num_mpcc, + num_rmu); + + return &mpc30->base; +} + +static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx) +{ + int i; + + struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), + GFP_KERNEL); + + if (!hubbub3) + return NULL; + +#undef REG_STRUCT +#define REG_STRUCT hubbub_reg + hubbub_reg_init(); + +#undef REG_STRUCT +#define REG_STRUCT vmid_regs + vmid_regs_init(0), + vmid_regs_init(1), + vmid_regs_init(2), + vmid_regs_init(3), + vmid_regs_init(4), + vmid_regs_init(5), + vmid_regs_init(6), + vmid_regs_init(7), + vmid_regs_init(8), + vmid_regs_init(9), + vmid_regs_init(10), + vmid_regs_init(11), + vmid_regs_init(12), + vmid_regs_init(13), + vmid_regs_init(14), + vmid_regs_init(15); + + hubbub35_construct(hubbub3, ctx, + &hubbub_reg, + &hubbub_shift, + &hubbub_mask, + 384,/*ctx->dc->dml.ip.det_buffer_size_kbytes,*/ + 8, /*ctx->dc->dml.ip.pixel_chunk_size_kbytes,*/ + 1792 /*ctx->dc->dml.ip.config_return_buffer_size_in_kbytes*/); + + + for (i = 0; i < res_cap_dcn36.num_vmid; i++) { + struct dcn20_vmid *vmid = &hubbub3->vmid[i]; + + vmid->ctx = ctx; + + vmid->regs = &vmid_regs[i]; + vmid->shifts = &vmid_shifts; + vmid->masks = &vmid_masks; + } + + return &hubbub3->base; +} + +static struct timing_generator *dcn35_timing_generator_create( + struct dc_context *ctx, + uint32_t instance) +{ + struct optc *tgn10 = + kzalloc(sizeof(struct optc), GFP_KERNEL); + + if (!tgn10) + return NULL; + +#undef REG_STRUCT +#define REG_STRUCT optc_regs + optc_regs_init(0), + optc_regs_init(1), + optc_regs_init(2), + optc_regs_init(3); + + tgn10->base.inst = instance; + tgn10->base.ctx = ctx; + + tgn10->tg_regs = &optc_regs[instance]; + tgn10->tg_shift = &optc_shift; + tgn10->tg_mask = &optc_mask; + + dcn35_timing_generator_init(tgn10); + + return &tgn10->base; +} + +static const struct encoder_feature_support link_enc_feature = { + .max_hdmi_deep_color = COLOR_DEPTH_121212, + .max_hdmi_pixel_clock = 600000, + .hdmi_ycbcr420_supported = true, + .dp_ycbcr420_supported = true, + .fec_supported = true, + .flags.bits.IS_HBR2_CAPABLE = true, + .flags.bits.IS_HBR3_CAPABLE = true, + .flags.bits.IS_TPS3_CAPABLE = true, + .flags.bits.IS_TPS4_CAPABLE = true +}; + +static struct link_encoder *dcn35_link_encoder_create( + struct dc_context *ctx, + const struct encoder_init_data *enc_init_data) +{ + struct dcn20_link_encoder *enc20 = + kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + + if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) + return NULL; + +#undef REG_STRUCT +#define REG_STRUCT link_enc_aux_regs + aux_regs_init(0), + aux_regs_init(1), + aux_regs_init(2), + aux_regs_init(3), + aux_regs_init(4); + +#undef REG_STRUCT +#define REG_STRUCT link_enc_hpd_regs + hpd_regs_init(0), + hpd_regs_init(1), + hpd_regs_init(2), + hpd_regs_init(3), + hpd_regs_init(4); + +#undef REG_STRUCT +#define REG_STRUCT link_enc_regs + link_regs_init(0, A), + link_regs_init(1, B), + link_regs_init(2, C), + link_regs_init(3, D), + link_regs_init(4, E); + + dcn35_link_encoder_construct(enc20, + enc_init_data, + &link_enc_feature, + &link_enc_regs[enc_init_data->transmitter], + &link_enc_aux_regs[enc_init_data->channel - 1], + &link_enc_hpd_regs[enc_init_data->hpd_source], + &le_shift, + &le_mask); + + return &enc20->enc10.base; +} + +/* Create a minimal link encoder object not associated with a particular + * physical connector. + * resource_funcs.link_enc_create_minimal + */ +static struct link_encoder *dcn31_link_enc_create_minimal( + struct dc_context *ctx, enum engine_id eng_id) +{ + struct dcn20_link_encoder *enc20; + + if ((eng_id - ENGINE_ID_DIGA) > ctx->dc->res_pool->res_cap->num_dig_link_enc) + return NULL; + + enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + if (!enc20) + return NULL; + + dcn31_link_encoder_construct_minimal( + enc20, + ctx, + &link_enc_feature, + &link_enc_regs[eng_id - ENGINE_ID_DIGA], + eng_id); + + return &enc20->enc10.base; +} + +static struct panel_cntl *dcn31_panel_cntl_create(const struct panel_cntl_init_data *init_data) +{ + struct dcn31_panel_cntl *panel_cntl = + kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL); + + if (!panel_cntl) + return NULL; + + dcn31_panel_cntl_construct(panel_cntl, init_data); + + return &panel_cntl->base; +} + +static void read_dce_straps( + struct dc_context *ctx, + struct resource_straps *straps) +{ + generic_reg_get(ctx, regDC_PINSTRAPS + BASE(regDC_PINSTRAPS_BASE_IDX), + FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio); + +} + +static struct audio *dcn31_create_audio( + struct dc_context *ctx, unsigned int inst) +{ + +#undef REG_STRUCT +#define REG_STRUCT audio_regs + audio_regs_init(0), + audio_regs_init(1), + audio_regs_init(2), + audio_regs_init(3), + audio_regs_init(4); + audio_regs_init(5); + audio_regs_init(6); + + return dce_audio_create(ctx, inst, + &audio_regs[inst], &audio_shift, &audio_mask); +} + +static struct vpg *dcn31_vpg_create( + struct dc_context *ctx, + uint32_t inst) +{ + struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL); + + if (!vpg31) + return NULL; + +#undef REG_STRUCT +#define REG_STRUCT vpg_regs + vpg_regs_init(0), + vpg_regs_init(1), + vpg_regs_init(2), + vpg_regs_init(3), + vpg_regs_init(4), + vpg_regs_init(5), + vpg_regs_init(6), + vpg_regs_init(7), + vpg_regs_init(8), + vpg_regs_init(9); + + vpg31_construct(vpg31, ctx, inst, + &vpg_regs[inst], + &vpg_shift, + &vpg_mask); + + return &vpg31->base; +} + +static struct afmt *dcn31_afmt_create( + struct dc_context *ctx, + uint32_t inst) +{ + struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL); + + if (!afmt31) + return NULL; + +#undef REG_STRUCT +#define REG_STRUCT afmt_regs + afmt_regs_init(0), + afmt_regs_init(1), + afmt_regs_init(2), + afmt_regs_init(3), + afmt_regs_init(4), + afmt_regs_init(5); + + afmt31_construct(afmt31, ctx, inst, + &afmt_regs[inst], + &afmt_shift, + &afmt_mask); + + // Light sleep by default, no need to power down here + + return &afmt31->base; +} + +static struct apg *dcn31_apg_create( + struct dc_context *ctx, + uint32_t inst) +{ + struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL); + + if (!apg31) + return NULL; + +#undef REG_STRUCT +#define REG_STRUCT apg_regs + apg_regs_init(0), + apg_regs_init(1), + apg_regs_init(2), + apg_regs_init(3); + + apg31_construct(apg31, ctx, inst, + &apg_regs[inst], + &apg_shift, + &apg_mask); + + return &apg31->base; +} + +static struct stream_encoder *dcn35_stream_encoder_create( + enum engine_id eng_id, + struct dc_context *ctx) +{ + struct dcn10_stream_encoder *enc1; + struct vpg *vpg; + struct afmt *afmt; + int vpg_inst; + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ + if (eng_id <= ENGINE_ID_DIGF) { + vpg_inst = eng_id; + afmt_inst = eng_id; + } else + return NULL; + + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + afmt = dcn31_afmt_create(ctx, afmt_inst); + + if (!enc1 || !vpg || !afmt) { + kfree(enc1); + kfree(vpg); + kfree(afmt); + return NULL; + } + +#undef REG_STRUCT +#define REG_STRUCT stream_enc_regs + stream_enc_regs_init(0), + stream_enc_regs_init(1), + stream_enc_regs_init(2), + stream_enc_regs_init(3), + stream_enc_regs_init(4); + + dcn35_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, + eng_id, vpg, afmt, + &stream_enc_regs[eng_id], + &se_shift, &se_mask); + + return &enc1->base; +} + +static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create( + enum engine_id eng_id, + struct dc_context *ctx) +{ + struct dcn31_hpo_dp_stream_encoder *hpo_dp_enc31; + struct vpg *vpg; + struct apg *apg; + uint32_t hpo_dp_inst; + uint32_t vpg_inst; + uint32_t apg_inst; + + ASSERT((eng_id >= ENGINE_ID_HPO_DP_0) && (eng_id <= ENGINE_ID_HPO_DP_3)); + hpo_dp_inst = eng_id - ENGINE_ID_HPO_DP_0; + + /* Mapping of VPG register blocks to HPO DP block instance: + * VPG[6] -> HPO_DP[0] + * VPG[7] -> HPO_DP[1] + * VPG[8] -> HPO_DP[2] + * VPG[9] -> HPO_DP[3] + */ + vpg_inst = hpo_dp_inst + 6; + + /* Mapping of APG register blocks to HPO DP block instance: + * APG[0] -> HPO_DP[0] + * APG[1] -> HPO_DP[1] + * APG[2] -> HPO_DP[2] + * APG[3] -> HPO_DP[3] + */ + apg_inst = hpo_dp_inst; + + /* allocate HPO stream encoder and create VPG sub-block */ + hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + apg = dcn31_apg_create(ctx, apg_inst); + + if (!hpo_dp_enc31 || !vpg || !apg) { + kfree(hpo_dp_enc31); + kfree(vpg); + kfree(apg); + return NULL; + } + +#undef REG_STRUCT +#define REG_STRUCT hpo_dp_stream_enc_regs + hpo_dp_stream_encoder_reg_init(0), + hpo_dp_stream_encoder_reg_init(1), + hpo_dp_stream_encoder_reg_init(2), + hpo_dp_stream_encoder_reg_init(3); + + dcn31_hpo_dp_stream_encoder_construct(hpo_dp_enc31, ctx, ctx->dc_bios, + hpo_dp_inst, eng_id, vpg, apg, + &hpo_dp_stream_enc_regs[hpo_dp_inst], + &hpo_dp_se_shift, &hpo_dp_se_mask); + + return &hpo_dp_enc31->base; +} + +static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( + uint8_t inst, + struct dc_context *ctx) +{ + struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31; + + /* allocate HPO link encoder */ + hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); + if (!hpo_dp_enc31) + return NULL; /* out of memory */ + +#undef REG_STRUCT +#define REG_STRUCT hpo_dp_link_enc_regs + hpo_dp_link_encoder_reg_init(0), + hpo_dp_link_encoder_reg_init(1); + + hpo_dp_link_encoder31_construct(hpo_dp_enc31, ctx, inst, + &hpo_dp_link_enc_regs[inst], + &hpo_dp_le_shift, &hpo_dp_le_mask); + + return &hpo_dp_enc31->base; +} + +static struct dce_hwseq *dcn36_hwseq_create( + struct dc_context *ctx) +{ + struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + +#undef REG_STRUCT +#define REG_STRUCT hwseq_reg + hwseq_reg_init(); + + if (hws) { + hws->ctx = ctx; + hws->regs = &hwseq_reg; + hws->shifts = &hwseq_shift; + hws->masks = &hwseq_mask; + } + return hws; +} +static const struct resource_create_funcs res_create_funcs = { + .read_dce_straps = read_dce_straps, + .create_audio = dcn31_create_audio, + .create_stream_encoder = dcn35_stream_encoder_create, + .create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create, + .create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create, + .create_hwseq = dcn36_hwseq_create, +}; + +static void dcn36_resource_destruct(struct dcn36_resource_pool *pool) +{ + unsigned int i; + + for (i = 0; i < pool->base.stream_enc_count; i++) { + if (pool->base.stream_enc[i] != NULL) { + if (pool->base.stream_enc[i]->vpg != NULL) { + kfree(DCN30_VPG_FROM_VPG(pool->base.stream_enc[i]->vpg)); + pool->base.stream_enc[i]->vpg = NULL; + } + if (pool->base.stream_enc[i]->afmt != NULL) { + kfree(DCN30_AFMT_FROM_AFMT(pool->base.stream_enc[i]->afmt)); + pool->base.stream_enc[i]->afmt = NULL; + } + kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i])); + pool->base.stream_enc[i] = NULL; + } + } + + for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) { + if (pool->base.hpo_dp_stream_enc[i] != NULL) { + if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) { + kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_dp_stream_enc[i]->vpg)); + pool->base.hpo_dp_stream_enc[i]->vpg = NULL; + } + if (pool->base.hpo_dp_stream_enc[i]->apg != NULL) { + kfree(DCN31_APG_FROM_APG(pool->base.hpo_dp_stream_enc[i]->apg)); + pool->base.hpo_dp_stream_enc[i]->apg = NULL; + } + kfree(DCN3_1_HPO_DP_STREAM_ENC_FROM_HPO_STREAM_ENC(pool->base.hpo_dp_stream_enc[i])); + pool->base.hpo_dp_stream_enc[i] = NULL; + } + } + + for (i = 0; i < pool->base.hpo_dp_link_enc_count; i++) { + if (pool->base.hpo_dp_link_enc[i] != NULL) { + kfree(DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(pool->base.hpo_dp_link_enc[i])); + pool->base.hpo_dp_link_enc[i] = NULL; + } + } + + for (i = 0; i < pool->base.res_cap->num_dsc; i++) { + if (pool->base.dscs[i] != NULL) + dcn20_dsc_destroy(&pool->base.dscs[i]); + } + + if (pool->base.mpc != NULL) { + kfree(TO_DCN20_MPC(pool->base.mpc)); + pool->base.mpc = NULL; + } + if (pool->base.hubbub != NULL) { + kfree(pool->base.hubbub); + pool->base.hubbub = NULL; + } + for (i = 0; i < pool->base.pipe_count; i++) { + if (pool->base.dpps[i] != NULL) + dcn35_dpp_destroy(&pool->base.dpps[i]); + + if (pool->base.ipps[i] != NULL) + pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]); + + if (pool->base.hubps[i] != NULL) { + kfree(TO_DCN20_HUBP(pool->base.hubps[i])); + pool->base.hubps[i] = NULL; + } + + if (pool->base.irqs != NULL) { + dal_irq_service_destroy(&pool->base.irqs); + } + } + + for (i = 0; i < pool->base.res_cap->num_ddc; i++) { + if (pool->base.engines[i] != NULL) + dce110_engine_destroy(&pool->base.engines[i]); + if (pool->base.hw_i2cs[i] != NULL) { + kfree(pool->base.hw_i2cs[i]); + pool->base.hw_i2cs[i] = NULL; + } + if (pool->base.sw_i2cs[i] != NULL) { + kfree(pool->base.sw_i2cs[i]); + pool->base.sw_i2cs[i] = NULL; + } + } + + for (i = 0; i < pool->base.res_cap->num_opp; i++) { + if (pool->base.opps[i] != NULL) + pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]); + } + + for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) { + if (pool->base.timing_generators[i] != NULL) { + kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i])); + pool->base.timing_generators[i] = NULL; + } + } + + for (i = 0; i < pool->base.res_cap->num_dwb; i++) { + if (pool->base.dwbc[i] != NULL) { + kfree(TO_DCN30_DWBC(pool->base.dwbc[i])); + pool->base.dwbc[i] = NULL; + } + if (pool->base.mcif_wb[i] != NULL) { + kfree(TO_DCN30_MMHUBBUB(pool->base.mcif_wb[i])); + pool->base.mcif_wb[i] = NULL; + } + } + + for (i = 0; i < pool->base.audio_count; i++) { + if (pool->base.audios[i]) + dce_aud_destroy(&pool->base.audios[i]); + } + + for (i = 0; i < pool->base.clk_src_count; i++) { + if (pool->base.clock_sources[i] != NULL) { + dcn20_clock_source_destroy(&pool->base.clock_sources[i]); + pool->base.clock_sources[i] = NULL; + } + } + + for (i = 0; i < pool->base.res_cap->num_mpc_3dlut; i++) { + if (pool->base.mpc_lut[i] != NULL) { + dc_3dlut_func_release(pool->base.mpc_lut[i]); + pool->base.mpc_lut[i] = NULL; + } + if (pool->base.mpc_shaper[i] != NULL) { + dc_transfer_func_release(pool->base.mpc_shaper[i]); + pool->base.mpc_shaper[i] = NULL; + } + } + + if (pool->base.dp_clock_source != NULL) { + dcn20_clock_source_destroy(&pool->base.dp_clock_source); + pool->base.dp_clock_source = NULL; + } + + for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) { + if (pool->base.multiple_abms[i] != NULL) + dce_abm_destroy(&pool->base.multiple_abms[i]); + } + + if (pool->base.psr != NULL) + dmub_psr_destroy(&pool->base.psr); + + if (pool->base.replay != NULL) + dmub_replay_destroy(&pool->base.replay); + + if (pool->base.pg_cntl != NULL) + dcn_pg_cntl_destroy(&pool->base.pg_cntl); + + if (pool->base.dccg != NULL) + dcn_dccg_destroy(&pool->base.dccg); +} + +static struct hubp *dcn35_hubp_create( + struct dc_context *ctx, + uint32_t inst) +{ + struct dcn20_hubp *hubp2 = + kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + + if (!hubp2) + return NULL; + +#undef REG_STRUCT +#define REG_STRUCT hubp_regs + hubp_regs_init(0), + hubp_regs_init(1), + hubp_regs_init(2), + hubp_regs_init(3); + + if (hubp35_construct(hubp2, ctx, inst, + &hubp_regs[inst], &hubp_shift, &hubp_mask)) + return &hubp2->base; + + BREAK_TO_DEBUGGER(); + kfree(hubp2); + return NULL; +} + +static void dcn35_dwbc_init(struct dcn30_dwbc *dwbc30, struct dc_context *ctx) +{ + dcn35_dwbc_set_fgcg( + dwbc30, ctx->dc->debug.enable_fine_grain_clock_gating.bits.dwb); +} + +static bool dcn35_dwbc_create(struct dc_context *ctx, struct resource_pool *pool) +{ + int i; + uint32_t pipe_count = pool->res_cap->num_dwb; + + for (i = 0; i < pipe_count; i++) { + struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), + GFP_KERNEL); + + if (!dwbc30) { + dm_error("DC: failed to create dwbc30!\n"); + return false; + } + +#undef REG_STRUCT +#define REG_STRUCT dwbc35_regs + dwbc_regs_dcn3_init(0); + + dcn35_dwbc_construct(dwbc30, ctx, + &dwbc35_regs[i], + &dwbc35_shift, + &dwbc35_mask, + i); + + pool->dwbc[i] = &dwbc30->base; + + dcn35_dwbc_init(dwbc30, ctx); + } + return true; +} + +static void dcn35_mmhubbub_init(struct dcn30_mmhubbub *mcif_wb30, + struct dc_context *ctx) +{ + dcn35_mmhubbub_set_fgcg( + mcif_wb30, + ctx->dc->debug.enable_fine_grain_clock_gating.bits.mmhubbub); +} + +static bool dcn35_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool) +{ + int i; + uint32_t pipe_count = pool->res_cap->num_dwb; + + for (i = 0; i < pipe_count; i++) { + struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), + GFP_KERNEL); + + if (!mcif_wb30) { + dm_error("DC: failed to create mcif_wb30!\n"); + return false; + } + +#undef REG_STRUCT +#define REG_STRUCT mcif_wb35_regs + mcif_wb_regs_dcn3_init(0); + + dcn35_mmhubbub_construct(mcif_wb30, ctx, + &mcif_wb35_regs[i], + &mcif_wb35_shift, + &mcif_wb35_mask, + i); + + dcn35_mmhubbub_init(mcif_wb30, ctx); + + pool->mcif_wb[i] = &mcif_wb30->base; + } + return true; +} + +static struct display_stream_compressor *dcn35_dsc_create( + struct dc_context *ctx, uint32_t inst) +{ + struct dcn20_dsc *dsc = + kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + + if (!dsc) { + BREAK_TO_DEBUGGER(); + return NULL; + } + +#undef REG_STRUCT +#define REG_STRUCT dsc_regs + dsc_regsDCN35_init(0), + dsc_regsDCN35_init(1), + dsc_regsDCN35_init(2), + dsc_regsDCN35_init(3); + + dsc35_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask); + dsc35_set_fgcg(dsc, + ctx->dc->debug.enable_fine_grain_clock_gating.bits.dsc); + return &dsc->base; +} + +static void dcn36_destroy_resource_pool(struct resource_pool **pool) +{ + struct dcn36_resource_pool *dcn36_pool = TO_DCN36_RES_POOL(*pool); + + dcn36_resource_destruct(dcn36_pool); + kfree(dcn36_pool); + *pool = NULL; +} + +static struct clock_source *dcn35_clock_source_create( + struct dc_context *ctx, + struct dc_bios *bios, + enum clock_source_id id, + const struct dce110_clk_src_regs *regs, + bool dp_clk_src) +{ + struct dce110_clk_src *clk_src = + kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + + if (!clk_src) + return NULL; + + if (dcn31_clk_src_construct(clk_src, ctx, bios, id, + regs, &cs_shift, &cs_mask)) { + clk_src->base.dp_clk_src = dp_clk_src; + return &clk_src->base; + } + + kfree(clk_src); + BREAK_TO_DEBUGGER(); + return NULL; +} + +static struct dc_cap_funcs cap_funcs = { + .get_dcc_compression_cap = dcn20_get_dcc_compression_cap +}; + +static void dcn35_get_panel_config_defaults(struct dc_panel_config *panel_config) +{ + *panel_config = panel_config_defaults; +} + + +static bool dcn35_validate_bandwidth(struct dc *dc, + struct dc_state *context, + bool fast_validate) +{ + bool out = false; + + out = dml2_validate(dc, context, + context->power_source == DC_POWER_SOURCE_DC ? context->bw_ctx.dml2_dc_power_source : context->bw_ctx.dml2, + fast_validate); + + if (fast_validate) + return out; + + DC_FP_START(); + dcn35_decide_zstate_support(dc, context); + DC_FP_END(); + + return out; +} + + +static struct resource_funcs dcn36_res_pool_funcs = { + .destroy = dcn36_destroy_resource_pool, + .link_enc_create = dcn35_link_encoder_create, + .link_enc_create_minimal = dcn31_link_enc_create_minimal, + .link_encs_assign = link_enc_cfg_link_encs_assign, + .link_enc_unassign = link_enc_cfg_link_enc_unassign, + .panel_cntl_create = dcn31_panel_cntl_create, + .validate_bandwidth = dcn35_validate_bandwidth, + .calculate_wm_and_dlg = NULL, + .update_soc_for_wm_a = dcn31_update_soc_for_wm_a, + .populate_dml_pipes = dcn35_populate_dml_pipes_from_context_fpu, + .acquire_free_pipe_as_secondary_dpp_pipe = dcn20_acquire_free_pipe_for_layer, + .release_pipe = dcn20_release_pipe, + .add_stream_to_ctx = dcn30_add_stream_to_ctx, + .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource, + .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, + .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context, + .set_mcif_arb_params = dcn30_set_mcif_arb_params, + .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link, + .acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut, + .release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut, + .update_bw_bounding_box = dcn35_update_bw_bounding_box_fpu, + .patch_unknown_plane_state = dcn20_patch_unknown_plane_state, + .get_panel_config_defaults = dcn35_get_panel_config_defaults, + .get_preferred_eng_id_dpia = dcn36_get_preferred_eng_id_dpia, + .get_vstartup_for_pipe = dcn10_get_vstartup_for_pipe +}; + +static bool dcn36_resource_construct( + uint8_t num_virtual_links, + struct dc *dc, + struct dcn36_resource_pool *pool) +{ + int i; + struct dc_context *ctx = dc->ctx; + struct irq_service_init_data init_data; + +#undef REG_STRUCT +#define REG_STRUCT bios_regs + bios_regs_init(); + +#undef REG_STRUCT +#define REG_STRUCT clk_src_regs + clk_src_regs_init(0, A), + clk_src_regs_init(1, B), + clk_src_regs_init(2, C), + clk_src_regs_init(3, D), + clk_src_regs_init(4, E); + +#undef REG_STRUCT +#define REG_STRUCT abm_regs + abm_regs_init(0), + abm_regs_init(1), + abm_regs_init(2), + abm_regs_init(3); + +#undef REG_STRUCT +#define REG_STRUCT dccg_regs + dccg_regs_init(); + + ctx->dc_bios->regs = &bios_regs; + + pool->base.res_cap = &res_cap_dcn36; + + pool->base.funcs = &dcn36_res_pool_funcs; + + /************************************************* + * Resource + asic cap harcoding * + *************************************************/ + pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; + pool->base.pipe_count = pool->base.res_cap->num_timing_generator; + pool->base.mpcc_count = pool->base.res_cap->num_timing_generator; + dc->caps.max_downscale_ratio = 600; + dc->caps.i2c_speed_in_khz = 100; + dc->caps.i2c_speed_in_khz_hdcp = 100; + dc->caps.max_cursor_size = 256; + dc->caps.min_horizontal_blanking_period = 80; + dc->caps.dmdata_alloc_size = 2048; + dc->caps.max_slave_planes = 3; + dc->caps.max_slave_yuv_planes = 3; + dc->caps.max_slave_rgb_planes = 3; + dc->caps.post_blend_color_processing = true; + dc->caps.force_dp_tps4_for_cp2520 = true; + if (dc->config.forceHBR2CP2520) + dc->caps.force_dp_tps4_for_cp2520 = false; + dc->caps.dp_hpo = true; + dc->caps.dp_hdmi21_pcon_support = true; + + dc->caps.edp_dsc_support = true; + dc->caps.extended_aux_timeout_support = true; + dc->caps.dmcub_support = true; + dc->caps.is_apu = true; + dc->caps.seamless_odm = true; + + dc->caps.zstate_support = true; + dc->caps.ips_support = true; + dc->caps.max_v_total = (1 << 15) - 1; + dc->caps.vtotal_limited_by_fp2 = true; + + /* Color pipeline capabilities */ + dc->caps.color.dpp.dcn_arch = 1; + dc->caps.color.dpp.input_lut_shared = 0; + dc->caps.color.dpp.icsc = 1; + dc->caps.color.dpp.dgam_ram = 0; // must use gamma_corr + dc->caps.color.dpp.dgam_rom_caps.srgb = 1; + dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1; + dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 1; + dc->caps.color.dpp.dgam_rom_caps.pq = 1; + dc->caps.color.dpp.dgam_rom_caps.hlg = 1; + dc->caps.color.dpp.post_csc = 1; + dc->caps.color.dpp.gamma_corr = 1; + dc->caps.color.dpp.dgam_rom_for_yuv = 0; + + dc->caps.color.dpp.hw_3d_lut = 1; + dc->caps.color.dpp.ogam_ram = 0; // no OGAM in DPP since DCN1 + // no OGAM ROM on DCN301 + dc->caps.color.dpp.ogam_rom_caps.srgb = 0; + dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0; + dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0; + dc->caps.color.dpp.ogam_rom_caps.pq = 0; + dc->caps.color.dpp.ogam_rom_caps.hlg = 0; + dc->caps.color.dpp.ocsc = 0; + + dc->caps.color.mpc.gamut_remap = 1; + dc->caps.color.mpc.num_3dluts = pool->base.res_cap->num_mpc_3dlut; //2 + dc->caps.color.mpc.ogam_ram = 1; + dc->caps.color.mpc.ogam_rom_caps.srgb = 0; + dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0; + dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0; + dc->caps.color.mpc.ogam_rom_caps.pq = 0; + dc->caps.color.mpc.ogam_rom_caps.hlg = 0; + dc->caps.color.mpc.ocsc = 1; + + /* max_disp_clock_khz_at_vmin is slightly lower than the STA value in order + * to provide some margin. + * It's expected for furture ASIC to have equal or higher value, in order to + * have determinstic power improvement from generate to genration. + * (i.e., we should not expect new ASIC generation with lower vmin rate) + */ + dc->caps.max_disp_clock_khz_at_vmin = 650000; + + /* Sequential ONO is based on ASIC. */ + if (dc->ctx->asic_id.hw_internal_rev > 0x10) + dc->caps.sequential_ono = true; + + /* 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) { + enum bp_result bp_query_result; + uint8_t is_vbios_lttpr_enable = 0; + + bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable); + dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable; + } + + /* interop bit is implicit */ + { + dc->caps.vbios_lttpr_aware = true; + } + } + + if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) + dc->debug = debug_defaults_drv; + + /*HW default is to have all the FGCG enabled, SW no need to program them*/ + dc->debug.enable_fine_grain_clock_gating.u32All = 0xFFFF; + // Init the vm_helper + if (dc->vm_helper) + vm_helper_init(dc->vm_helper, 16); + + /************************************************* + * Create resources * + *************************************************/ + + /* Clock Sources for Pixel Clock*/ + pool->base.clock_sources[DCN36_CLK_SRC_PLL0] = + dcn35_clock_source_create(ctx, ctx->dc_bios, + CLOCK_SOURCE_COMBO_PHY_PLL0, + &clk_src_regs[0], false); + pool->base.clock_sources[DCN36_CLK_SRC_PLL1] = + dcn35_clock_source_create(ctx, ctx->dc_bios, + CLOCK_SOURCE_COMBO_PHY_PLL1, + &clk_src_regs[1], false); + pool->base.clock_sources[DCN36_CLK_SRC_PLL2] = + dcn35_clock_source_create(ctx, ctx->dc_bios, + CLOCK_SOURCE_COMBO_PHY_PLL2, + &clk_src_regs[2], false); + pool->base.clock_sources[DCN36_CLK_SRC_PLL3] = + dcn35_clock_source_create(ctx, ctx->dc_bios, + CLOCK_SOURCE_COMBO_PHY_PLL3, + &clk_src_regs[3], false); + pool->base.clock_sources[DCN36_CLK_SRC_PLL4] = + dcn35_clock_source_create(ctx, ctx->dc_bios, + CLOCK_SOURCE_COMBO_PHY_PLL4, + &clk_src_regs[4], false); + + pool->base.clk_src_count = DCN36_CLK_SRC_TOTAL; + + /* todo: not reuse phy_pll registers */ + pool->base.dp_clock_source = + dcn35_clock_source_create(ctx, ctx->dc_bios, + CLOCK_SOURCE_ID_DP_DTO, + &clk_src_regs[0], true); + + for (i = 0; i < pool->base.clk_src_count; i++) { + if (pool->base.clock_sources[i] == NULL) { + dm_error("DC: failed to create clock sources!\n"); + BREAK_TO_DEBUGGER(); + goto create_fail; + } + } + /*temp till dml2 fully work without dml1*/ + dml_init_instance(&dc->dml, &dcn3_5_soc, &dcn3_5_ip, DML_PROJECT_DCN31); + + /* TODO: DCCG */ + pool->base.dccg = dccg35_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask); + if (pool->base.dccg == NULL) { + dm_error("DC: failed to create dccg!\n"); + BREAK_TO_DEBUGGER(); + goto create_fail; + } + +#undef REG_STRUCT +#define REG_STRUCT pg_cntl_regs + pg_cntl_dcn35_regs_init(); + + pool->base.pg_cntl = pg_cntl35_create(ctx, &pg_cntl_regs, &pg_cntl_shift, &pg_cntl_mask); + if (pool->base.pg_cntl == NULL) { + dm_error("DC: failed to create power gate control!\n"); + BREAK_TO_DEBUGGER(); + goto create_fail; + } + + /* TODO: IRQ */ + init_data.ctx = dc->ctx; + pool->base.irqs = dal_irq_service_dcn36_create(&init_data); + if (!pool->base.irqs) + goto create_fail; + + /* HUBBUB */ + pool->base.hubbub = dcn35_hubbub_create(ctx); + if (pool->base.hubbub == NULL) { + BREAK_TO_DEBUGGER(); + dm_error("DC: failed to create hubbub!\n"); + goto create_fail; + } + + /* HUBPs, DPPs, OPPs and TGs */ + for (i = 0; i < pool->base.pipe_count; i++) { + pool->base.hubps[i] = dcn35_hubp_create(ctx, i); + if (pool->base.hubps[i] == NULL) { + BREAK_TO_DEBUGGER(); + dm_error( + "DC: failed to create hubps!\n"); + goto create_fail; + } + + pool->base.dpps[i] = dcn35_dpp_create(ctx, i); + if (pool->base.dpps[i] == NULL) { + BREAK_TO_DEBUGGER(); + dm_error( + "DC: failed to create dpps!\n"); + goto create_fail; + } + } + + for (i = 0; i < pool->base.res_cap->num_opp; i++) { + pool->base.opps[i] = dcn35_opp_create(ctx, i); + if (pool->base.opps[i] == NULL) { + BREAK_TO_DEBUGGER(); + dm_error( + "DC: failed to create output pixel processor!\n"); + goto create_fail; + } + } + + for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) { + pool->base.timing_generators[i] = dcn35_timing_generator_create( + ctx, i); + if (pool->base.timing_generators[i] == NULL) { + BREAK_TO_DEBUGGER(); + dm_error("DC: failed to create tg!\n"); + goto create_fail; + } + } + pool->base.timing_generator_count = i; + + /* PSR */ + pool->base.psr = dmub_psr_create(ctx); + if (pool->base.psr == NULL) { + dm_error("DC: failed to create psr obj!\n"); + BREAK_TO_DEBUGGER(); + goto create_fail; + } + + /* Replay */ + pool->base.replay = dmub_replay_create(ctx); + if (pool->base.replay == NULL) { + dm_error("DC: failed to create replay obj!\n"); + BREAK_TO_DEBUGGER(); + goto create_fail; + } + + /* ABM */ + for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) { + pool->base.multiple_abms[i] = dmub_abm_create(ctx, + &abm_regs[i], + &abm_shift, + &abm_mask); + if (pool->base.multiple_abms[i] == NULL) { + dm_error("DC: failed to create abm for pipe %d!\n", i); + BREAK_TO_DEBUGGER(); + goto create_fail; + } + } + + /* MPC and DSC */ + pool->base.mpc = dcn35_mpc_create(ctx, pool->base.mpcc_count, pool->base.res_cap->num_mpc_3dlut); + if (pool->base.mpc == NULL) { + BREAK_TO_DEBUGGER(); + dm_error("DC: failed to create mpc!\n"); + goto create_fail; + } + + for (i = 0; i < pool->base.res_cap->num_dsc; i++) { + pool->base.dscs[i] = dcn35_dsc_create(ctx, i); + if (pool->base.dscs[i] == NULL) { + BREAK_TO_DEBUGGER(); + dm_error("DC: failed to create display stream compressor %d!\n", i); + goto create_fail; + } + } + + /* DWB and MMHUBBUB */ + if (!dcn35_dwbc_create(ctx, &pool->base)) { + BREAK_TO_DEBUGGER(); + dm_error("DC: failed to create dwbc!\n"); + goto create_fail; + } + + if (!dcn35_mmhubbub_create(ctx, &pool->base)) { + BREAK_TO_DEBUGGER(); + dm_error("DC: failed to create mcif_wb!\n"); + goto create_fail; + } + + /* AUX and I2C */ + for (i = 0; i < pool->base.res_cap->num_ddc; i++) { + pool->base.engines[i] = dcn31_aux_engine_create(ctx, i); + if (pool->base.engines[i] == NULL) { + BREAK_TO_DEBUGGER(); + dm_error( + "DC:failed to create aux engine!!\n"); + goto create_fail; + } + pool->base.hw_i2cs[i] = dcn31_i2c_hw_create(ctx, i); + if (pool->base.hw_i2cs[i] == NULL) { + BREAK_TO_DEBUGGER(); + dm_error( + "DC:failed to create hw i2c!!\n"); + goto create_fail; + } + pool->base.sw_i2cs[i] = NULL; + } + + /* DCN3.5 has 6 DPIA */ + pool->base.usb4_dpia_count = 4; + if (dc->debug.dpia_debug.bits.disable_dpia) + pool->base.usb4_dpia_count = 0; + + /* Audio, Stream Encoders including HPO and virtual, MPC 3D LUTs */ + if (!resource_construct(num_virtual_links, dc, &pool->base, + &res_create_funcs)) + goto create_fail; + + /* HW Sequencer and Plane caps */ + dcn35_hw_sequencer_construct(dc); + + dc->caps.max_planes = pool->base.pipe_count; + + for (i = 0; i < dc->caps.max_planes; ++i) + dc->caps.planes[i] = plane_cap; + + dc->cap_funcs = cap_funcs; + + dc->dcn_ip->max_num_dpp = pool->base.pipe_count; + + dc->dml2_options.dcn_pipe_count = pool->base.pipe_count; + dc->dml2_options.use_native_pstate_optimization = true; + dc->dml2_options.use_native_soc_bb_construction = true; + dc->dml2_options.minimize_dispclk_using_odm = false; + if (dc->config.EnableMinDispClkODM) + dc->dml2_options.minimize_dispclk_using_odm = true; + dc->dml2_options.enable_windowed_mpo_odm = dc->config.enable_windowed_mpo_odm; + + 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; + + dc->dml2_options.max_segments_per_hubp = 24; + dc->dml2_options.det_segment_size = DCN3_2_DET_SEG_SIZE;/*todo*/ + dc->dml2_options.override_det_buffer_size_kbytes = true; + + if (dc->config.sdpif_request_limit_words_per_umc == 0) + dc->config.sdpif_request_limit_words_per_umc = 16;/*todo*/ + + return true; + +create_fail: + + dcn36_resource_destruct(pool); + + return false; +} + +struct resource_pool *dcn36_create_resource_pool( + const struct dc_init_data *init_data, + struct dc *dc) +{ + struct dcn36_resource_pool *pool = + kzalloc(sizeof(struct dcn36_resource_pool), GFP_KERNEL); + + if (!pool) + return NULL; + + if (dcn36_resource_construct(init_data->num_virtual_links, dc, pool)) + return &pool->base; + + BREAK_TO_DEBUGGER(); + kfree(pool); + return NULL; +} diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.h b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.h new file mode 100644 index 000000000000..5490c9975e23 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright 2025 Advanced Micro Devices, Inc. */ + +#ifndef _DCN36_RESOURCE_H_ +#define _DCN36_RESOURCE_H_ + +#include "core_types.h" + +extern struct _vcs_dpi_ip_params_st dcn3_6_ip; +extern struct _vcs_dpi_soc_bounding_box_st dcn3_6_soc; + +#define TO_DCN36_RES_POOL(pool)\ + container_of(pool, struct dcn36_resource_pool, base) + +struct dcn36_resource_pool { + struct resource_pool base; +}; + +struct resource_pool *dcn36_create_resource_pool( + const struct dc_init_data *init_data, + struct dc *dc); + +#define HWSEQ_DCN36_REG_LIST()\ + SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \ + SR(DCHUBBUB_ARB_HOSTVM_CNTL), \ + SR(DIO_MEM_PWR_CTRL), \ + SR(ODM_MEM_PWR_CTRL3), \ + SR(MMHUBBUB_MEM_PWR_CNTL), \ + SR(DCCG_GATE_DISABLE_CNTL), \ + SR(DCCG_GATE_DISABLE_CNTL2), \ + SR(DCCG_GATE_DISABLE_CNTL4), \ + SR(DCCG_GATE_DISABLE_CNTL5), \ + SR(DCFCLK_CNTL),\ + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \ + SRII(PIXEL_RATE_CNTL, OTG, 0), \ + SRII(PIXEL_RATE_CNTL, OTG, 1),\ + SRII(PIXEL_RATE_CNTL, OTG, 2),\ + SRII(PIXEL_RATE_CNTL, OTG, 3),\ + SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 0),\ + SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 1),\ + SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 2),\ + SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 3),\ + SR(MICROSECOND_TIME_BASE_DIV), \ + SR(MILLISECOND_TIME_BASE_DIV), \ + SR(DISPCLK_FREQ_CHANGE_CNTL), \ + SR(RBBMIF_TIMEOUT_DIS), \ + SR(RBBMIF_TIMEOUT_DIS_2), \ + SR(DCHUBBUB_CRC_CTRL), \ + SR(DPP_TOP0_DPP_CRC_CTRL), \ + SR(MPC_CRC_CTRL), \ + SR(DOMAIN0_PG_CONFIG), \ + SR(DOMAIN1_PG_CONFIG), \ + SR(DOMAIN2_PG_CONFIG), \ + SR(DOMAIN3_PG_CONFIG), \ + SR(DOMAIN16_PG_CONFIG), \ + SR(DOMAIN17_PG_CONFIG), \ + SR(DOMAIN18_PG_CONFIG), \ + SR(DOMAIN19_PG_CONFIG), \ + SR(DOMAIN0_PG_STATUS), \ + SR(DOMAIN1_PG_STATUS), \ + SR(DOMAIN2_PG_STATUS), \ + SR(DOMAIN3_PG_STATUS), \ + SR(DOMAIN16_PG_STATUS), \ + SR(DOMAIN17_PG_STATUS), \ + SR(DOMAIN18_PG_STATUS), \ + SR(DOMAIN19_PG_STATUS), \ + SR(DC_IP_REQUEST_CNTL), \ + SR(AZALIA_AUDIO_DTO), \ + SR(AZALIA_CONTROLLER_CLOCK_GATING), \ + SR(HPO_TOP_HW_CONTROL),\ + SR(DMU_CLK_CNTL) + +#endif /* _DCN36_RESOURCE_H_ */ -- cgit v1.2.3 From 4bcba9844b7cfdfc3dc72568f8683b435a2bb3e2 Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Fri, 10 Jan 2025 20:37:14 +0800 Subject: drm/amd/display: Add DCN36 GPIO Add DCN36 support in GPIO. Acked-by: Harry Wentland Reviewed-by: Martin Leung Signed-off-by: Taimur Hassan Signed-off-by: Wayne Lin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c | 1 + drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c index 9a0952f9004f..8bc67ca42197 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c @@ -112,6 +112,7 @@ bool dal_hw_factory_init( case DCN_VERSION_3_21: case DCN_VERSION_3_5: case DCN_VERSION_3_51: + case DCN_VERSION_3_6: dal_hw_factory_dcn32_init(factory); return true; case DCN_VERSION_4_01: diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c index 9832247ee739..cb79a2832287 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c @@ -113,6 +113,7 @@ bool dal_hw_translate_init( case DCN_VERSION_3_21: case DCN_VERSION_3_5: case DCN_VERSION_3_51: + case DCN_VERSION_3_6: dal_hw_translate_dcn32_init(translate); return true; case DCN_VERSION_4_01: -- cgit v1.2.3 From 8cb06693bcd2596ba7e60681d3b8c7b98157a180 Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Fri, 10 Jan 2025 20:41:03 +0800 Subject: drm/amd/display: Add DCN36 DML2 support Enable DML2 for DCN36. Acked-by: Harry Wentland Reviewed-by: Martin Leung Signed-off-by: Taimur Hassan Signed-off-by: Wayne Lin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h | 1 + drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c | 1 + drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c | 3 +++ drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c | 4 ++++ 4 files changed, 9 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h index dd3f43181a6e..0670e4dc4fd9 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h +++ b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h @@ -38,6 +38,7 @@ enum dml_project_id { dml_project_dcn35 = 3, dml_project_dcn351 = 4, dml_project_dcn401 = 5, + dml_project_dcn36 = 6, }; enum dml_prefetch_modes { dml_prefetch_support_uclk_fclk_and_stutter_if_possible = 0, diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c index c4c52173ef22..ef693f608d59 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c @@ -301,6 +301,7 @@ void build_unoptimized_policy_settings(enum dml_project_id project, struct dml_m policy->AssumeModeSupportAtMaxPwrStateEvenDRAMClockChangeNotSupported = true; // TOREVIEW: What does this mean? policy->AssumeModeSupportAtMaxPwrStateEvenFClockChangeNotSupported = true; // TOREVIEW: What does this mean? if (project == dml_project_dcn35 || + project == dml_project_dcn36 || project == dml_project_dcn351) { policy->DCCProgrammingAssumesScanDirectionUnknownFinal = false; policy->EnhancedPrefetchScheduleAccelerationFinal = 0; 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 b8a34abaf519..f829d5ac7c8e 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 @@ -107,6 +107,7 @@ void dml2_init_ip_params(struct dml2_context *dml2, const struct dc *in_dc, stru case dml_project_dcn35: case dml_project_dcn351: + case dml_project_dcn36: out->rob_buffer_size_kbytes = 64; out->config_return_buffer_size_in_kbytes = 1792; out->compressed_buffer_segment_size_in_kbytes = 64; @@ -292,6 +293,7 @@ void dml2_init_socbb_params(struct dml2_context *dml2, const struct dc *in_dc, s case dml_project_dcn35: case dml_project_dcn351: + case dml_project_dcn36: out->num_chans = 4; out->round_trip_ping_latency_dcfclk_cycles = 106; out->smn_latency_us = 2; @@ -506,6 +508,7 @@ void dml2_init_soc_states(struct dml2_context *dml2, const struct dc *in_dc, p->dcfclk_stas_mhz[3] = 1324; p->dcfclk_stas_mhz[4] = p->in_states->state_array[1].dcfclk_mhz; } else if (dml2->v20.dml_core_ctx.project != dml_project_dcn35 && + dml2->v20.dml_core_ctx.project != dml_project_dcn36 && dml2->v20.dml_core_ctx.project != dml_project_dcn351) { p->dcfclk_stas_mhz[0] = 300; p->dcfclk_stas_mhz[1] = 615; 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 556a780466ce..45584e2f5dfe 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c @@ -72,6 +72,7 @@ static void map_hw_resources(struct dml2_context *dml2, in_out_display_cfg->hw.NumberOfDSCSlices[i] = mode_support_info->NumberOfDSCSlices[i]; in_out_display_cfg->hw.DLGRefClkFreqMHz = 24; if (dml2->v20.dml_core_ctx.project != dml_project_dcn35 && + dml2->v20.dml_core_ctx.project != dml_project_dcn36 && dml2->v20.dml_core_ctx.project != dml_project_dcn351) { /*dGPU default as 50Mhz*/ in_out_display_cfg->hw.DLGRefClkFreqMHz = 50; @@ -762,6 +763,9 @@ static void dml2_init(const struct dc *in_dc, const struct dml2_configuration_op case DCN_VERSION_3_51: (*dml2)->v20.dml_core_ctx.project = dml_project_dcn351; break; + case DCN_VERSION_3_6: + (*dml2)->v20.dml_core_ctx.project = dml_project_dcn36; + break; case DCN_VERSION_3_2: (*dml2)->v20.dml_core_ctx.project = dml_project_dcn32; break; -- cgit v1.2.3 From 23577b3a154ba0fd529d784c681c435b734d13a6 Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Fri, 10 Jan 2025 21:13:40 +0800 Subject: drm/amd/display: Support DCN36 DSC Add case on clean_up_dsc_blocks() to support DCN36 as well. Acked-by: Harry Wentland Reviewed-by: Martin Leung Signed-off-by: Taimur Hassan Signed-off-by: Wayne Lin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/display/dc') 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 e033e6476fe5..7572448e5b9f 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 @@ -1835,6 +1835,7 @@ static void clean_up_dsc_blocks(struct dc *dc) int i; if (dc->ctx->dce_version != DCN_VERSION_3_5 && + dc->ctx->dce_version != DCN_VERSION_3_6 && dc->ctx->dce_version != DCN_VERSION_3_51) return; -- cgit v1.2.3 From 4bc8f12db282e0b686a308e0d908262b6a6580e1 Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Fri, 10 Jan 2025 21:19:52 +0800 Subject: drm/amd/display: Add DCN36 CORE Add DCN36 support in dc_resource.c. Acked-by: Harry Wentland Reviewed-by: Martin Leung Signed-off-by: Taimur Hassan Signed-off-by: Wayne Lin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') 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 f59722e17abd..bf14fa1e3771 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -76,6 +76,7 @@ #include "dcn321/dcn321_resource.h" #include "dcn35/dcn35_resource.h" #include "dcn351/dcn351_resource.h" +#include "dcn36/dcn36_resource.h" #include "dcn401/dcn401_resource.h" #if defined(CONFIG_DRM_AMD_DC_FP) #include "dc_spl_translate.h" @@ -204,6 +205,8 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) dc_version = DCN_VERSION_3_5; if (ASICREV_IS_GC_11_0_4(asic_id.hw_internal_rev)) dc_version = DCN_VERSION_3_51; + if (ASICREV_IS_DCN36(asic_id.hw_internal_rev)) + dc_version = DCN_VERSION_3_6; break; case AMDGPU_FAMILY_GC_12_0_0: if (ASICREV_IS_GC_12_0_1_A0(asic_id.hw_internal_rev) || @@ -320,6 +323,9 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc, case DCN_VERSION_3_51: res_pool = dcn351_create_resource_pool(init_data, dc); break; + case DCN_VERSION_3_6: + res_pool = dcn36_create_resource_pool(init_data, dc); + break; case DCN_VERSION_4_01: res_pool = dcn401_create_resource_pool(init_data, dc); break; -- cgit v1.2.3 From 14d7ca5273fe7634f9c50dcc5bf2f2943e8bb0a4 Mon Sep 17 00:00:00 2001 From: Zaeem Mohamed Date: Fri, 6 Sep 2024 12:36:04 -0400 Subject: drm/amd/display: Expose 3 secondary planes for supported ASICs [why] For enabling 4-plane MPO, we need dc to expose 4 planes for DCN35 and beyond, as well as DCN21 [how] Set dc_caps.max_slave_*planes to 3 for appropriate ASICs Reviewed-by: Sun peng Li Signed-off-by: Zaeem Mohamed Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c | 6 +++--- drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 6 +++--- drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 6 +++--- drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 2615c36d5ffe..4bd5c2278596 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 @@ -1413,9 +1413,9 @@ static bool dcn21_resource_construct( dc->caps.min_horizontal_blanking_period = 80; dc->caps.dmdata_alloc_size = 2048; - dc->caps.max_slave_planes = 1; - dc->caps.max_slave_yuv_planes = 1; - dc->caps.max_slave_rgb_planes = 1; + dc->caps.max_slave_planes = 3; + dc->caps.max_slave_yuv_planes = 3; + dc->caps.max_slave_rgb_planes = 3; dc->caps.post_blend_color_processing = true; dc->caps.force_dp_tps4_for_cp2520 = true; dc->caps.extended_aux_timeout_support = true; 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 8ee3d99ea2aa..6d163dcecde6 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 @@ -1839,9 +1839,9 @@ static bool dcn35_resource_construct( dc->caps.max_cursor_size = 256; dc->caps.min_horizontal_blanking_period = 80; dc->caps.dmdata_alloc_size = 2048; - dc->caps.max_slave_planes = 2; - dc->caps.max_slave_yuv_planes = 2; - dc->caps.max_slave_rgb_planes = 2; + dc->caps.max_slave_planes = 3; + dc->caps.max_slave_yuv_planes = 3; + dc->caps.max_slave_rgb_planes = 3; dc->caps.post_blend_color_processing = true; dc->caps.force_dp_tps4_for_cp2520 = true; if (dc->config.forceHBR2CP2520) diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c index 14f7c3acdc96..4a03df5d760f 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c @@ -1811,9 +1811,9 @@ static bool dcn351_resource_construct( dc->caps.max_cursor_size = 256; dc->caps.min_horizontal_blanking_period = 80; dc->caps.dmdata_alloc_size = 2048; - dc->caps.max_slave_planes = 2; - dc->caps.max_slave_yuv_planes = 2; - dc->caps.max_slave_rgb_planes = 2; + dc->caps.max_slave_planes = 3; + dc->caps.max_slave_yuv_planes = 3; + dc->caps.max_slave_rgb_planes = 3; dc->caps.post_blend_color_processing = true; dc->caps.force_dp_tps4_for_cp2520 = true; if (dc->config.forceHBR2CP2520) 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 5cb0e0191a16..6ab194a86cb9 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 @@ -1872,9 +1872,9 @@ static bool dcn401_resource_construct( dc->caps.subvp_vertical_int_margin_us = 30; dc->caps.subvp_drr_vblank_start_margin_us = 100; // 100us margin - dc->caps.max_slave_planes = 2; - dc->caps.max_slave_yuv_planes = 2; - dc->caps.max_slave_rgb_planes = 2; + dc->caps.max_slave_planes = 3; + dc->caps.max_slave_yuv_planes = 3; + dc->caps.max_slave_rgb_planes = 3; dc->caps.post_blend_color_processing = true; dc->caps.force_dp_tps4_for_cp2520 = true; dc->caps.dp_hpo = true; -- cgit v1.2.3 From fed4c27537893fd0b57975d05163dfe36edb257c Mon Sep 17 00:00:00 2001 From: Zaeem Mohamed Date: Fri, 27 Sep 2024 10:15:49 -0400 Subject: drm/amd/display: docstring definitions MAX_SURFACES and MAX_PLANES MAX_SURFACES and MAX_PLANES now have docstrings that better show the difference between the two. Reviewed-by: Sun peng Li Signed-off-by: Zaeem Mohamed Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 42ba65e785ca..e1f4f643c364 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -55,7 +55,13 @@ struct dmub_notification; #define DC_VER "3.2.319" +/** + * MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC + */ #define MAX_SURFACES 4 +/** + * MAX_PLANES - representative of the upper bound of planes that are supported by the HW + */ #define MAX_PLANES 6 #define MAX_STREAMS 6 #define MIN_VIEWPORT_SIZE 12 -- cgit v1.2.3 From e8bffa52e0253cfd689813a620e64521256bc712 Mon Sep 17 00:00:00 2001 From: Ilya Bakoulin Date: Tue, 28 Jan 2025 13:14:54 -0500 Subject: drm/amd/display: Don't try AUX transactions on disconnected link [Why] Setting link DPMS off in response to HPD disconnect creates AUX transactions on a link that is supposed to be disconnected. This can cause issues in some cases when the sink re-asserts HPD and expects source to re-enable the link. [How] Avoid AUX transactions on disconnected link. Reviewed-by: Wenjing Liu Signed-off-by: Ilya Bakoulin Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c index 2c73ac87cd66..c27ffec5d84f 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c @@ -75,7 +75,8 @@ void dp_disable_link_phy(struct dc_link *link, struct dc *dc = link->ctx->dc; if (!link->wa_flags.dp_keep_receiver_powered && - !link->skip_implict_edp_power_control) + !link->skip_implict_edp_power_control && + link->type != dc_connection_none) dpcd_write_rx_power_ctrl(link, false); dc->hwss.disable_link_output(link, link_res, signal); @@ -163,8 +164,9 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource } else { if (link->fec_state == dc_link_fec_ready) { fec_config = 0; - core_link_write_dpcd(link, DP_FEC_CONFIGURATION, - &fec_config, sizeof(fec_config)); + if (link->type != dc_connection_none) + core_link_write_dpcd(link, DP_FEC_CONFIGURATION, + &fec_config, sizeof(fec_config)); link_enc->funcs->fec_set_ready(link_enc, false); link->fec_state = dc_link_fec_not_ready; -- cgit v1.2.3 From 1b30456150e57a79e300b82eb2efac40c25a162e Mon Sep 17 00:00:00 2001 From: Austin Zheng Date: Tue, 21 Jan 2025 17:10:27 -0500 Subject: drm/amd/display: DML21 Reintegration For various fixes to mcache_row_bytes calculation. Reviewed-by: Alvin Lee Signed-off-by: Austin Zheng Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/dc/dml2/dml21/inc/dml_top_types.h | 5 - .../dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c | 22 +- .../dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.h | 3 - .../dml21/src/dml2_core/dml2_core_dcn4_calcs.c | 94 +- .../dc/dml2/dml21/src/dml2_core/dml2_core_shared.c | 12413 ------------------- .../dml21/src/dml2_core/dml2_core_shared_types.h | 9 +- .../dc/dml2/dml21/src/dml2_core/dml2_core_utils.c | 3 +- .../dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c | 6 +- .../dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.h | 2 - .../dc/dml2/dml21/src/dml2_mcg/dml2_mcg_factory.c | 2 +- .../dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c | 5 +- .../dml2/dml21/src/dml2_top/dml2_top_interfaces.c | 1 - .../display/dc/dml2/dml21/src/dml2_top/dml_top.c | 354 - .../amd/display/dc/dml2/dml21/src/inc/dml2_debug.c | 5 - .../amd/display/dc/dml2/dml21/src/inc/dml2_debug.h | 6 +- .../dml21/src/inc/dml2_internal_shared_types.h | 6 - 16 files changed, 83 insertions(+), 12853 deletions(-) delete mode 100644 drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c delete mode 100644 drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c (limited to 'drivers/gpu/drm/amd/display/dc') 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 0ab19cf4d242..19bce4084382 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 @@ -14,11 +14,6 @@ struct dml2_instance; -enum dml2_status { - dml2_success = 0, - dml2_error_generic = 1 -}; - enum dml2_project_id { dml2_project_invalid = 0, dml2_project_dcn4x_stage1 = 1, 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 ec0beb139200..3664980d1574 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 @@ -44,7 +44,7 @@ struct dml2_core_ip_params core_dcn4_ip_caps_base = { .dppclk_delay_scl_lb_only = 16, .dppclk_delay_cnvc_formatter = 28, .dppclk_delay_cnvc_cursor = 6, - .cursor_buffer_size = 24, + .cursor_buffer_size = 42, .cursor_chunk_size = 2, .dispclk_delay_subtotal = 125, .max_inter_dcn_tile_repeaters = 8, @@ -327,11 +327,11 @@ static void pack_mode_programming_params_with_implicit_subvp(struct dml2_core_in dml2_core_calcs_get_mall_allocation(&core->clean_me_up.mode_lib, &programming->plane_programming[plane_index].surface_size_mall_bytes, dml_internal_pipe_index); memcpy(&programming->plane_programming[plane_index].mcache_allocation, - &display_cfg->stage2.mcache_allocations[plane_index], - sizeof(struct dml2_mcache_surface_allocation)); + &display_cfg->stage2.mcache_allocations[plane_index], + sizeof(struct dml2_mcache_surface_allocation)); total_main_mcaches_required += programming->plane_programming[plane_index].mcache_allocation.num_mcaches_plane0 + - programming->plane_programming[plane_index].mcache_allocation.num_mcaches_plane1 - - (programming->plane_programming[plane_index].mcache_allocation.last_slice_sharing.plane0_plane1 ? 1 : 0); + programming->plane_programming[plane_index].mcache_allocation.num_mcaches_plane1 - + (programming->plane_programming[plane_index].mcache_allocation.last_slice_sharing.plane0_plane1 ? 1 : 0); for (pipe_offset = 0; pipe_offset < programming->plane_programming[plane_index].num_dpps_required; pipe_offset++) { // Assign storage for this pipe's register values @@ -374,17 +374,17 @@ static void pack_mode_programming_params_with_implicit_subvp(struct dml2_core_in /* generate mcache allocation, phantoms use identical mcache configuration, but in the MALL set and unique mcache ID's beginning after all main ID's */ memcpy(&programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation, - &programming->plane_programming[main_plane_index].mcache_allocation, - sizeof(struct dml2_mcache_surface_allocation)); + &programming->plane_programming[main_plane_index].mcache_allocation, + sizeof(struct dml2_mcache_surface_allocation)); for (mcache_index = 0; mcache_index < programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.num_mcaches_plane0; mcache_index++) { programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane0[mcache_index] += total_main_mcaches_required; programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_mall_plane0[mcache_index] = - programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane0[mcache_index]; + programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane0[mcache_index]; } for (mcache_index = 0; mcache_index < programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.num_mcaches_plane1; mcache_index++) { programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane1[mcache_index] += total_main_mcaches_required; programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_mall_plane1[mcache_index] = - programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane1[mcache_index]; + programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane1[mcache_index]; } for (pipe_offset = 0; pipe_offset < programming->plane_programming[main_plane_index].num_dpps_required; pipe_offset++) { @@ -597,8 +597,8 @@ bool core_dcn4_mode_programming(struct dml2_core_mode_programming_in_out *in_out 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); memcpy(&in_out->programming->plane_programming[plane_index].mcache_allocation, - &in_out->display_cfg->stage2.mcache_allocations[plane_index], - sizeof(struct dml2_mcache_surface_allocation)); + &in_out->display_cfg->stage2.mcache_allocations[plane_index], + sizeof(struct dml2_mcache_surface_allocation)); for (pipe_offset = 0; pipe_offset < in_out->programming->plane_programming[plane_index].num_dpps_required; pipe_offset++) { in_out->programming->plane_programming[plane_index].plane_descriptor = &in_out->programming->display_config.plane_descriptors[plane_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 e62b2d3eeee6..a68bb001a346 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 @@ -9,7 +9,4 @@ bool core_dcn4_mode_support(struct dml2_core_mode_support_in_out *in_out); bool core_dcn4_mode_programming(struct dml2_core_mode_programming_in_out *in_out); bool core_dcn4_populate_informative(struct dml2_core_populate_informative_in_out *in_out); bool core_dcn4_calculate_mcache_allocation(struct dml2_calculate_mcache_allocation_in_out *in_out); - -bool core_dcn4_unit_test(void); - #endif 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 47872c6f657e..87e53f59cb9f 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 @@ -2352,6 +2352,7 @@ static void calculate_mcache_row_bytes( if (p->full_vp_height == 0 && p->full_vp_width == 0) { *p->num_mcaches = 0; *p->mcache_row_bytes = 0; + *p->mcache_row_bytes_per_channel = 0; } else { blk_bytes = dml_get_tile_block_size_bytes(p->tiling_mode); @@ -2420,15 +2421,18 @@ static void calculate_mcache_row_bytes( // If this mcache_row_bytes for the full viewport of the surface is less than or equal to mcache_bytes, // then one mcache can be used for this request stream. If not, it is useful to know the width of the viewport that can be supported in the mcache_bytes. - if (p->gpuvm_enable || !p->surf_vert) { - *p->mcache_row_bytes = mvmpg_per_row_ub * meta_per_mvmpg_per_channel_ub; + if (p->gpuvm_enable || p->surf_vert) { + *p->mcache_row_bytes_per_channel = mvmpg_per_row_ub * meta_per_mvmpg_per_channel_ub; + *p->mcache_row_bytes = *p->mcache_row_bytes_per_channel * p->num_chans; } else { // horizontal and gpuvm disable *p->mcache_row_bytes = *p->meta_row_width_ub * p->blk_height * p->bytes_per_pixel / 256; - *p->mcache_row_bytes = (unsigned int)math_ceil2((double)*p->mcache_row_bytes / p->num_chans, p->mcache_line_size_bytes); + if (p->mcache_line_size_bytes != 0) + *p->mcache_row_bytes_per_channel = (unsigned int)math_ceil2((double)*p->mcache_row_bytes / p->num_chans, p->mcache_line_size_bytes); } *p->dcc_dram_bw_pref_overhead_factor = 1 + math_max2(1.0 / 256.0, *p->mcache_row_bytes / p->full_swath_bytes); // dcc_dr_oh_pref - *p->num_mcaches = (unsigned int)math_ceil2((double)*p->mcache_row_bytes / p->mcache_size_bytes, 1); + if (p->mcache_size_bytes != 0) + *p->num_mcaches = (unsigned int)math_ceil2((double)*p->mcache_row_bytes_per_channel / p->mcache_size_bytes, 1); mvmpg_per_mcache = p->mcache_size_bytes / meta_per_mvmpg_per_channel_ub; *p->mvmpg_per_mcache_lb = (unsigned int)math_floor2(mvmpg_per_mcache, 1); @@ -2449,6 +2453,7 @@ static void calculate_mcache_row_bytes( #ifdef __DML_VBA_DEBUG__ dml2_printf("DML::%s: mcache_row_bytes = %u\n", __func__, *p->mcache_row_bytes); + dml2_printf("DML::%s: mcache_row_bytes_per_channel = %u\n", __func__, *p->mcache_row_bytes_per_channel); dml2_printf("DML::%s: num_mcaches = %u\n", __func__, *p->num_mcaches); #endif DML2_ASSERT(*p->num_mcaches > 0); @@ -2465,11 +2470,13 @@ static void calculate_mcache_setting( *p->num_mcaches_l = 0; *p->mcache_row_bytes_l = 0; + *p->mcache_row_bytes_per_channel_l = 0; *p->dcc_dram_bw_nom_overhead_factor_l = 1.0; *p->dcc_dram_bw_pref_overhead_factor_l = 1.0; *p->num_mcaches_c = 0; *p->mcache_row_bytes_c = 0; + *p->mcache_row_bytes_per_channel_c = 0; *p->dcc_dram_bw_nom_overhead_factor_c = 1.0; *p->dcc_dram_bw_pref_overhead_factor_c = 1.0; @@ -2505,6 +2512,7 @@ static void calculate_mcache_setting( // output l->l_p.num_mcaches = p->num_mcaches_l; l->l_p.mcache_row_bytes = p->mcache_row_bytes_l; + l->l_p.mcache_row_bytes_per_channel = p->mcache_row_bytes_per_channel_l; l->l_p.dcc_dram_bw_nom_overhead_factor = p->dcc_dram_bw_nom_overhead_factor_l; l->l_p.dcc_dram_bw_pref_overhead_factor = p->dcc_dram_bw_pref_overhead_factor_l; l->l_p.mvmpg_width = &l->mvmpg_width_l; @@ -2514,7 +2522,7 @@ static void calculate_mcache_setting( l->l_p.mvmpg_per_mcache_lb = &l->mvmpg_per_mcache_lb_l; calculate_mcache_row_bytes(scratch, &l->l_p); - dml2_assert(*p->num_mcaches_l > 0); + DML2_ASSERT(*p->num_mcaches_l > 0); if (l->is_dual_plane) { l->c_p.num_chans = p->num_chans; @@ -2540,6 +2548,7 @@ static void calculate_mcache_setting( // output l->c_p.num_mcaches = p->num_mcaches_c; l->c_p.mcache_row_bytes = p->mcache_row_bytes_c; + l->c_p.mcache_row_bytes_per_channel = p->mcache_row_bytes_per_channel_c; l->c_p.dcc_dram_bw_nom_overhead_factor = p->dcc_dram_bw_nom_overhead_factor_c; l->c_p.dcc_dram_bw_pref_overhead_factor = p->dcc_dram_bw_pref_overhead_factor_c; l->c_p.mvmpg_width = &l->mvmpg_width_c; @@ -2549,12 +2558,12 @@ static void calculate_mcache_setting( l->c_p.mvmpg_per_mcache_lb = &l->mvmpg_per_mcache_lb_c; calculate_mcache_row_bytes(scratch, &l->c_p); - dml2_assert(*p->num_mcaches_c > 0); + DML2_ASSERT(*p->num_mcaches_c > 0); } // Sharing for iMALL access - l->mcache_remainder_l = *p->mcache_row_bytes_l % p->mcache_size_bytes; - l->mcache_remainder_c = *p->mcache_row_bytes_c % p->mcache_size_bytes; + l->mcache_remainder_l = *p->mcache_row_bytes_per_channel_l % p->mcache_size_bytes; + l->mcache_remainder_c = *p->mcache_row_bytes_per_channel_c % p->mcache_size_bytes; l->mvmpg_access_width_l = p->surf_vert ? l->mvmpg_height_l : l->mvmpg_width_l; l->mvmpg_access_width_c = p->surf_vert ? l->mvmpg_height_c : l->mvmpg_width_c; @@ -2577,11 +2586,14 @@ static void calculate_mcache_setting( if (l->is_dual_plane) { 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)) { - l->lc_comb_last_mcache_size = (unsigned int)((l->mcache_remainder_l * (*p->mall_comb_mcache_l ? 2 : 1) * l->luma_time_factor) + - (l->mcache_remainder_c * (*p->mall_comb_mcache_c ? 2 : 1))); + /* if either remainder is 0, then mcache sharing is not needed or not possible due to full utilization */ + if (l->mcache_remainder_l && l->mcache_remainder_c) { + if (!p->imall_enable || (*p->mall_comb_mcache_l == *p->mall_comb_mcache_c)) { + l->lc_comb_last_mcache_size = (unsigned int)((l->mcache_remainder_l * (*p->mall_comb_mcache_l ? 2 : 1) * l->luma_time_factor) + + (l->mcache_remainder_c * (*p->mall_comb_mcache_c ? 2 : 1))); + } + *p->lc_comb_mcache = (l->lc_comb_last_mcache_size <= p->mcache_size_bytes) && (*p->mall_comb_mcache_l == *p->mall_comb_mcache_c); } - *p->lc_comb_mcache = (l->lc_comb_last_mcache_size <= p->mcache_size_bytes) && (*p->mall_comb_mcache_l == *p->mall_comb_mcache_c); } #ifdef __DML_VBA_DEBUG__ @@ -2637,9 +2649,6 @@ static void calculate_mcache_setting( // Luma/Chroma combine in the last mcache // In the case of Luma/Chroma combine-mCache (with lc_comb_mcache==1), all mCaches except the last segment are filled as much as possible, when stay aligned to mvmpg boundary if (*p->lc_comb_mcache && l->is_dual_plane) { - /* if luma and chroma planes share an mcache, increase total chroma mcache count */ - *p->num_mcaches_c = *p->num_mcaches_c + 1; - for (n = 0; n < *p->num_mcaches_l - 1; n++) p->mcache_offsets_l[n] = (n + 1) * l->mvmpg_per_mcache_lb_l * l->mvmpg_access_width_l; p->mcache_offsets_l[*p->num_mcaches_l - 1] = l->full_vp_access_width_l; @@ -3400,7 +3409,7 @@ static void calculate_cursor_req_attributes( } else { if (cursor_width > 0) { dml2_printf("DML::%s: Invalid cursor_bpp = %d\n", __func__, cursor_bpp); - dml2_assert(0); + DML2_ASSERT(0); } } @@ -3443,7 +3452,7 @@ static void calculate_cursor_urgent_burst_factor( CursorBufferSizeInTime = LinesInCursorBuffer * LineTime; if (CursorBufferSizeInTime - UrgentLatency <= 0) { *NotEnoughUrgentLatencyHiding = 1; - *UrgentBurstFactorCursor = 0; + *UrgentBurstFactorCursor = 1; } else { *NotEnoughUrgentLatencyHiding = 0; *UrgentBurstFactorCursor = CursorBufferSizeInTime / (CursorBufferSizeInTime - UrgentLatency); @@ -3506,7 +3515,7 @@ static void CalculateUrgentBurstFactor( DETBufferSizeInTimeLuma = math_floor2(LinesInDETLuma, SwathHeightY) * LineTime / VRatio; if (DETBufferSizeInTimeLuma - UrgentLatency <= 0) { *NotEnoughUrgentLatencyHiding = 1; - *UrgentBurstFactorLuma = 0; + *UrgentBurstFactorLuma = 1; } else { *UrgentBurstFactorLuma = DETBufferSizeInTimeLuma / (DETBufferSizeInTimeLuma - UrgentLatency); } @@ -3517,7 +3526,7 @@ static void CalculateUrgentBurstFactor( DETBufferSizeInTimeChroma = math_floor2(LinesInDETChroma, SwathHeightC) * LineTime / VRatioC; if (DETBufferSizeInTimeChroma - UrgentLatency <= 0) { *NotEnoughUrgentLatencyHiding = 1; - *UrgentBurstFactorChroma = 0; + *UrgentBurstFactorChroma = 1; } else { *UrgentBurstFactorChroma = DETBufferSizeInTimeChroma / (DETBufferSizeInTimeChroma - UrgentLatency); } @@ -5391,7 +5400,7 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch } /* oto prefetch bw should be always be less than total vactive bw */ - DML2_ASSERT(s->prefetch_bw_oto < s->per_pipe_vactive_sw_bw * p->myPipe->DPPPerSurface); + //DML2_ASSERT(s->prefetch_bw_oto < s->per_pipe_vactive_sw_bw * p->myPipe->DPPPerSurface); s->prefetch_bw_oto = math_max2(s->per_pipe_vactive_sw_bw, s->prefetch_bw_oto) * p->mall_prefetch_sdp_overhead_factor; @@ -5801,7 +5810,7 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch dml2_printf("DML::%s: cursor_prefetch_bytes = %d\n", __func__, s->cursor_prefetch_bytes); dml2_printf("DML::%s: prefetch_cursor_bw = %f\n", __func__, *p->prefetch_cursor_bw); #endif - dml2_assert(*p->dst_y_prefetch < 64); + DML2_ASSERT(*p->dst_y_prefetch < 64); unsigned int min_lsw_required = (unsigned int)math_max2(2, p->tdlut_drain_time / s->LineTime); if (s->LinesToRequestPrefetchPixelData >= min_lsw_required && s->prefetch_bw_equ > 0) { @@ -5994,7 +6003,7 @@ static unsigned int find_max_impact_plane(unsigned int this_plane_idx, unsigned } } if (max_idx <= 0) { - dml2_assert(max_idx >= 0); + DML2_ASSERT(max_idx >= 0); max_idx = this_plane_idx; } @@ -6341,7 +6350,7 @@ static void calculate_peak_bandwidth_required( dml2_printf("DML::%s: urg_bandwidth_required_qual[%s][%s]=%f\n", __func__, dml2_core_internal_soc_state_type_str(m), dml2_core_internal_bw_type_str(n), p->urg_bandwidth_required[m][n]); dml2_printf("DML::%s: non_urg_bandwidth_required%s[%s][%s]=%f\n", __func__, (p->inc_flip_bw ? "_flip" : ""), dml2_core_internal_soc_state_type_str(m), dml2_core_internal_bw_type_str(n), p->non_urg_bandwidth_required[m][n]); #endif - dml2_assert(p->urg_bandwidth_required[m][n] >= p->non_urg_bandwidth_required[m][n]); + DML2_ASSERT(p->urg_bandwidth_required[m][n] >= p->non_urg_bandwidth_required[m][n]); } } } @@ -6473,7 +6482,7 @@ static void calculate_immediate_flip_bandwidth_support( dml2_printf("DML::%s: urg_bandwidth_required_flip = %f\n", __func__, urg_bandwidth_required_flip[eval_state][n]); dml2_printf("DML::%s: flip_bandwidth_support_ok = %d\n", __func__, *flip_bandwidth_support_ok); #endif - dml2_assert(urg_bandwidth_required_flip[eval_state][n] >= non_urg_bandwidth_required_flip[eval_state][n]); + DML2_ASSERT(urg_bandwidth_required_flip[eval_state][n] >= non_urg_bandwidth_required_flip[eval_state][n]); } *frac_urg_bandwidth_flip = (frac_urg_bw_flip_sdp > frac_urg_bw_flip_dram) ? frac_urg_bw_flip_sdp : frac_urg_bw_flip_dram; @@ -6587,7 +6596,7 @@ static void CalculateFlipSchedule( #ifdef __DML_VBA_DEBUG__ dml2_printf("DML::%s: min_row_time = %f\n", __func__, l->min_row_time); #endif - dml2_assert(l->min_row_time > 0); + DML2_ASSERT(l->min_row_time > 0); if (use_lb_flip_bw) { // For mode check, calculation the flip bw requirement with worst case flip time @@ -7163,7 +7172,8 @@ static unsigned int get_active_min_uclk_dpm_index(unsigned long uclk_freq_khz, c } } - dml2_assert(clk_entry_found); + if (!clk_entry_found) + 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); @@ -8772,11 +8782,13 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out calculate_mcache_setting_params->num_mcaches_l = &mode_lib->ms.num_mcaches_l[k]; calculate_mcache_setting_params->mcache_row_bytes_l = &mode_lib->ms.mcache_row_bytes_l[k]; + calculate_mcache_setting_params->mcache_row_bytes_per_channel_l = &mode_lib->ms.mcache_row_bytes_per_channel_l[k]; calculate_mcache_setting_params->mcache_offsets_l = mode_lib->ms.mcache_offsets_l[k]; calculate_mcache_setting_params->mcache_shift_granularity_l = &mode_lib->ms.mcache_shift_granularity_l[k]; calculate_mcache_setting_params->num_mcaches_c = &mode_lib->ms.num_mcaches_c[k]; calculate_mcache_setting_params->mcache_row_bytes_c = &mode_lib->ms.mcache_row_bytes_c[k]; + calculate_mcache_setting_params->mcache_row_bytes_per_channel_c = &mode_lib->ms.mcache_row_bytes_per_channel_c[k]; calculate_mcache_setting_params->mcache_offsets_c = mode_lib->ms.mcache_offsets_c[k]; calculate_mcache_setting_params->mcache_shift_granularity_c = &mode_lib->ms.mcache_shift_granularity_c[k]; @@ -10430,13 +10442,13 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex for (k = 0; k < s->num_active_planes; ++k) { unsigned int stream_index = display_cfg->plane_descriptors[k].stream_index; - dml2_assert(cfg_support_info->stream_support_info[stream_index].odms_used <= 4); - dml2_assert(cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 4 || + DML2_ASSERT(cfg_support_info->stream_support_info[stream_index].odms_used <= 4); + DML2_ASSERT(cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 4 || cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 2 || cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 1); if (cfg_support_info->stream_support_info[stream_index].odms_used > 1) - dml2_assert(cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 1); + DML2_ASSERT(cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 1); switch (cfg_support_info->stream_support_info[stream_index].odms_used) { case (4): @@ -10462,7 +10474,7 @@ 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.dcn4x.dppclk_khz / 1000.0; - dml2_assert(mode_lib->mp.Dppclk[k] > 0); + DML2_ASSERT(mode_lib->mp.Dppclk[k] > 0); } for (k = 0; k < s->num_active_planes; ++k) { @@ -10474,14 +10486,14 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex 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); - dml2_assert(mode_lib->mp.dram_bw_mbps > 0); - dml2_assert(mode_lib->mp.uclk_freq_mhz > 0); - dml2_assert(mode_lib->mp.GlobalDPPCLK > 0); - dml2_assert(mode_lib->mp.Dispclk > 0); - dml2_assert(mode_lib->mp.DCFCLKDeepSleep > 0); - dml2_assert(s->SOCCLK > 0); + DML2_ASSERT(mode_lib->mp.Dcfclk > 0); + DML2_ASSERT(mode_lib->mp.FabricClock > 0); + DML2_ASSERT(mode_lib->mp.dram_bw_mbps > 0); + DML2_ASSERT(mode_lib->mp.uclk_freq_mhz > 0); + DML2_ASSERT(mode_lib->mp.GlobalDPPCLK > 0); + DML2_ASSERT(mode_lib->mp.Dispclk > 0); + DML2_ASSERT(mode_lib->mp.DCFCLKDeepSleep > 0); + DML2_ASSERT(s->SOCCLK > 0); #ifdef __DML_VBA_DEBUG__ dml2_printf("DML::%s: num_active_planes = %u\n", __func__, s->num_active_planes); @@ -10869,11 +10881,13 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex calculate_mcache_setting_params->num_mcaches_l = &mode_lib->mp.num_mcaches_l[k]; calculate_mcache_setting_params->mcache_row_bytes_l = &mode_lib->mp.mcache_row_bytes_l[k]; + calculate_mcache_setting_params->mcache_row_bytes_per_channel_l = &mode_lib->mp.mcache_row_bytes_per_channel_l[k]; calculate_mcache_setting_params->mcache_offsets_l = mode_lib->mp.mcache_offsets_l[k]; calculate_mcache_setting_params->mcache_shift_granularity_l = &mode_lib->mp.mcache_shift_granularity_l[k]; calculate_mcache_setting_params->num_mcaches_c = &mode_lib->mp.num_mcaches_c[k]; calculate_mcache_setting_params->mcache_row_bytes_c = &mode_lib->mp.mcache_row_bytes_c[k]; + calculate_mcache_setting_params->mcache_row_bytes_per_channel_c = &mode_lib->mp.mcache_row_bytes_per_channel_c[k]; calculate_mcache_setting_params->mcache_offsets_c = mode_lib->mp.mcache_offsets_c[k]; calculate_mcache_setting_params->mcache_shift_granularity_c = &mode_lib->mp.mcache_shift_granularity_c[k]; @@ -11585,7 +11599,6 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex calculate_peak_bandwidth_params->surface_read_bandwidth_c = mode_lib->mp.vactive_sw_bw_c; calculate_peak_bandwidth_params->prefetch_bandwidth_l = mode_lib->mp.RequiredPrefetchPixelDataBWLuma; calculate_peak_bandwidth_params->prefetch_bandwidth_c = mode_lib->mp.RequiredPrefetchPixelDataBWChroma; - calculate_peak_bandwidth_params->prefetch_bandwidth_oto = s->dummy_single_array[k]; calculate_peak_bandwidth_params->excess_vactive_fill_bw_l = mode_lib->mp.excess_vactive_fill_bw_l; calculate_peak_bandwidth_params->excess_vactive_fill_bw_c = mode_lib->mp.excess_vactive_fill_bw_c; calculate_peak_bandwidth_params->cursor_bw = mode_lib->mp.cursor_bw; @@ -11593,6 +11606,7 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex calculate_peak_bandwidth_params->meta_row_bw = mode_lib->mp.meta_row_bw; calculate_peak_bandwidth_params->prefetch_cursor_bw = mode_lib->mp.prefetch_cursor_bw; calculate_peak_bandwidth_params->prefetch_vmrow_bw = mode_lib->mp.prefetch_vmrow_bw; + calculate_peak_bandwidth_params->prefetch_bandwidth_oto = s->dummy_single_array[0]; calculate_peak_bandwidth_params->flip_bw = mode_lib->mp.final_flip_bw; calculate_peak_bandwidth_params->urgent_burst_factor_l = mode_lib->mp.UrgentBurstFactorLuma; calculate_peak_bandwidth_params->urgent_burst_factor_c = mode_lib->mp.UrgentBurstFactorChroma; @@ -12398,7 +12412,7 @@ static void rq_dlg_get_dlg_reg( dml2_printf("DML_DLG::%s: Calculation for pipe_idx=%d\n", __func__, pipe_idx); l->plane_idx = dml_get_plane_idx(mode_lib, pipe_idx); - dml2_assert(l->plane_idx < DML2_MAX_PLANES); + DML2_ASSERT(l->plane_idx < DML2_MAX_PLANES); l->source_format = dml2_444_8; l->odm_mode = dml2_odm_mode_bypass; 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 deleted file mode 100644 index 8f3c1c0b1cc1..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c +++ /dev/null @@ -1,12413 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright 2024 Advanced Micro Devices, Inc. - - -#include "dml2_internal_shared_types.h" -#include "dml2_core_shared.h" -#include "dml2_debug.h" -#include "lib_float_math.h" - -double dml2_core_shared_div_rem(double dividend, unsigned int divisor, unsigned int *remainder) -{ - *remainder = ((dividend / divisor) - (int)(dividend / divisor) > 0); - return dividend / divisor; - -} - -/* - * START OF STATIC HELPERS - * These static methods are baseline implemenations from DCN4. These should NEVER - * be modified when developing new DCNs. New DCN code should replace the static helpers - * using the function pointer pattern. - */ - -static void dml2_print_dml_mode_support_info(const struct dml2_core_internal_mode_support_info *support, bool fail_only); -static void get_stream_output_bpp(double *out_bpp, const struct dml2_display_cfg *display_cfg); -static unsigned int dml_round_to_multiple(unsigned int num, unsigned int multiple, bool up); -static unsigned int dml_get_num_active_pipes(int unsigned num_planes, const struct core_display_cfg_support_info *cfg_support_info); -static void dml_calc_pipe_plane_mapping(const struct core_display_cfg_support_info *cfg_support_info, unsigned int *pipe_plane); -static bool dml_is_phantom_pipe(const struct dml2_plane_parameters *plane_cfg); -static bool dml_get_is_phantom_pipe(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, unsigned int pipe_idx); -static void CalculateMaxDETAndMinCompressedBufferSize(unsigned int ConfigReturnBufferSizeInKByte, - unsigned int ConfigReturnBufferSegmentSizeInKByte, - unsigned int ROBBufferSizeInKByte, - unsigned int MaxNumDPP, - unsigned int nomDETInKByteOverrideEnable, // VBA_DELTA, allow DV to override default DET size - unsigned int nomDETInKByteOverrideValue, // VBA_DELTA - bool is_mrq_present, - - // Output - unsigned int *MaxTotalDETInKByte, - unsigned int *nomDETInKByte, - unsigned int *MinCompressedBufferSizeInKByte); - static void PixelClockAdjustmentForProgressiveToInterlaceUnit(const struct dml2_display_cfg *display_cfg, bool ptoi_supported, double *PixelClockBackEnd); -static unsigned int dml_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode); -static bool dml_is_vertical_rotation(enum dml2_rotation_angle Scan); -static int unsigned dml_get_gfx_version(enum dml2_swizzle_mode sw_mode); -static void CalculateBytePerPixelAndBlockSizes(enum dml2_source_format_class SourcePixelFormat, - enum dml2_swizzle_mode SurfaceTiling, - unsigned int pitch_y, - unsigned int pitch_c, - - // Output - unsigned int *BytePerPixelY, - unsigned int *BytePerPixelC, - double *BytePerPixelDETY, - double *BytePerPixelDETC, - unsigned int *BlockHeight256BytesY, - unsigned int *BlockHeight256BytesC, - unsigned int *BlockWidth256BytesY, - unsigned int *BlockWidth256BytesC, - unsigned int *MacroTileHeightY, - unsigned int *MacroTileHeightC, - unsigned int *MacroTileWidthY, - unsigned int *MacroTileWidthC, - bool *surf_linear128_l, - bool *surf_linear128_c); -static void CalculateSinglePipeDPPCLKAndSCLThroughput( - double HRatio, - double HRatioChroma, - double VRatio, - double VRatioChroma, - double MaxDCHUBToPSCLThroughput, - double MaxPSCLToLBThroughput, - double PixelClock, - enum dml2_source_format_class SourcePixelFormat, - unsigned int HTaps, - unsigned int HTapsChroma, - unsigned int VTaps, - unsigned int VTapsChroma, - - // Output - double *PSCL_THROUGHPUT, - double *PSCL_THROUGHPUT_CHROMA, - double *DPPCLKUsingSingleDPP); -static void CalculateSwathWidth( - const struct dml2_display_cfg *display_cfg, - bool ForceSingleDPP, - unsigned int NumberOfActiveSurfaces, - enum dml2_odm_mode ODMMode[], - unsigned int BytePerPixY[], - unsigned int BytePerPixC[], - unsigned int Read256BytesBlockHeightY[], - unsigned int Read256BytesBlockHeightC[], - unsigned int Read256BytesBlockWidthY[], - unsigned int Read256BytesBlockWidthC[], - bool surf_linear128_l[], - bool surf_linear128_c[], - unsigned int DPPPerSurface[], - - // Output - unsigned int req_per_swath_ub_l[], - unsigned int req_per_swath_ub_c[], - unsigned int SwathWidthSingleDPPY[], - unsigned int SwathWidthSingleDPPC[], - unsigned int SwathWidthY[], // per-pipe - unsigned int SwathWidthC[], // per-pipe - unsigned int MaximumSwathHeightY[], - unsigned int MaximumSwathHeightC[], - unsigned int swath_width_luma_ub[], // per-pipe - unsigned int swath_width_chroma_ub[]); // per-pipe -static bool UnboundedRequest(bool unb_req_force_en, bool unb_req_force_val, unsigned int TotalNumberOfActiveDPP, bool NoChromaOrLinear); -static void CalculateDETBufferSize(struct dml2_core_shared_calculate_det_buffer_size_params *p); -static double CalculateRequiredDispclk(enum dml2_odm_mode ODMMode, double PixelClock); -static double TruncToValidBPP( - struct dml2_core_shared_TruncToValidBPP_locals *l, - double LinkBitRate, - unsigned int Lanes, - unsigned int HTotal, - unsigned int HActive, - double PixelClock, - double DesiredBPP, - bool DSCEnable, - enum dml2_output_encoder_class Output, - enum dml2_output_format_class Format, - unsigned int DSCInputBitPerComponent, - unsigned int DSCSlices, - unsigned int AudioRate, - unsigned int AudioLayout, - enum dml2_odm_mode ODMModeNoDSC, - enum dml2_odm_mode ODMModeDSC, - - // Output - unsigned int *RequiredSlots); -static unsigned int dscceComputeDelay( - unsigned int bpc, - double BPP, - unsigned int sliceWidth, - unsigned int numSlices, - enum dml2_output_format_class pixelFormat, - enum dml2_output_encoder_class Output); -static unsigned int dscComputeDelay(enum dml2_output_format_class pixelFormat, enum dml2_output_encoder_class Output); -static unsigned int CalculateHostVMDynamicLevels(bool GPUVMEnable, bool HostVMEnable, unsigned int HostVMMinPageSize, unsigned int HostVMMaxNonCachedPageTableLevels); -static unsigned int CalculateVMAndRowBytes(struct dml2_core_shared_calculate_vm_and_row_bytes_params *p); -static unsigned int CalculatePrefetchSourceLines( - double VRatio, - unsigned int VTaps, - bool Interlace, - bool ProgressiveToInterlaceUnitInOPP, - unsigned int SwathHeight, - enum dml2_rotation_angle RotationAngle, - bool mirrored, - bool ViewportStationary, - unsigned int SwathWidth, - unsigned int ViewportHeight, - unsigned int ViewportXStart, - unsigned int ViewportYStart, - - // Output - unsigned int *VInitPreFill, - unsigned int *MaxNumSwath); -static void CalculateRowBandwidth( - bool GPUVMEnable, - bool use_one_row_for_frame, - enum dml2_source_format_class SourcePixelFormat, - double VRatio, - double VRatioChroma, - bool DCCEnable, - double LineTime, - unsigned int PixelPTEBytesPerRowLuma, - unsigned int PixelPTEBytesPerRowChroma, - unsigned int dpte_row_height_luma, - unsigned int dpte_row_height_chroma, - - bool mrq_present, - unsigned int meta_row_bytes_per_row_ub_l, - unsigned int meta_row_bytes_per_row_ub_c, - unsigned int meta_row_height_luma, - unsigned int meta_row_height_chroma, - - // Output - double *dpte_row_bw, - double *meta_row_bw); -static void CalculateMALLUseForStaticScreen( - const struct dml2_display_cfg *display_cfg, - unsigned int NumberOfActiveSurfaces, - unsigned int MALLAllocatedForDCN, - unsigned int SurfaceSizeInMALL[], - bool one_row_per_frame_fits_in_buffer[], - - // Output - bool is_using_mall_for_ss[]); -static void CalculateDCCConfiguration( - bool DCCEnabled, - bool DCCProgrammingAssumesScanDirectionUnknown, - enum dml2_source_format_class SourcePixelFormat, - unsigned int SurfaceWidthLuma, - unsigned int SurfaceWidthChroma, - unsigned int SurfaceHeightLuma, - unsigned int SurfaceHeightChroma, - unsigned int nomDETInKByte, - unsigned int RequestHeight256ByteLuma, - unsigned int RequestHeight256ByteChroma, - enum dml2_swizzle_mode TilingFormat, - unsigned int BytePerPixelY, - unsigned int BytePerPixelC, - double BytePerPixelDETY, - double BytePerPixelDETC, - enum dml2_rotation_angle RotationAngle, - - // Output - enum dml2_core_internal_request_type *RequestLuma, - enum dml2_core_internal_request_type *RequestChroma, - unsigned int *MaxUncompressedBlockLuma, - unsigned int *MaxUncompressedBlockChroma, - unsigned int *MaxCompressedBlockLuma, - unsigned int *MaxCompressedBlockChroma, - unsigned int *IndependentBlockLuma, - unsigned int *IndependentBlockChroma); -static void calculate_mcache_row_bytes(struct dml2_core_internal_scratch *scratch, struct dml2_core_calcs_calculate_mcache_row_bytes_params *p); -static void calculate_mcache_setting(struct dml2_core_internal_scratch *scratch, struct dml2_core_calcs_calculate_mcache_setting_params *p); -static void calculate_mall_bw_overhead_factor( - double mall_prefetch_sdp_overhead_factor[], - double mall_prefetch_dram_overhead_factor[], - - // input - const struct dml2_display_cfg *display_cfg, - unsigned int num_active_planes); -static double dml_get_return_bandwidth_available( - const struct dml2_soc_bb *soc, - enum dml2_core_internal_soc_state_type state_type, - enum dml2_core_internal_bw_type bw_type, - bool is_avg_bw, - bool is_hvm_en, - bool is_hvm_only, - double dcflk_mhz, - double fclk_mhz, - double dram_bw_mbps); -static void calculate_bandwidth_available( - double avg_bandwidth_available_min[dml2_core_internal_soc_state_max], - double avg_bandwidth_available[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_bandwidth_available_min[dml2_core_internal_soc_state_max], // min between SDP and DRAM - double urg_bandwidth_available[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_bandwidth_available_vm_only[dml2_core_internal_soc_state_max], - double urg_bandwidth_available_pixel_and_vm[dml2_core_internal_soc_state_max], - - const struct dml2_soc_bb *soc, - bool HostVMEnable, - double dcfclk_mhz, - double fclk_mhz, - double dram_bw_mbps); -static void calculate_avg_bandwidth_required( - double avg_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - - // input - const struct dml2_display_cfg *display_cfg, - unsigned int num_active_planes, - double ReadBandwidthLuma[], - double ReadBandwidthChroma[], - double cursor_bw[], - double dcc_dram_bw_nom_overhead_factor_p0[], - double dcc_dram_bw_nom_overhead_factor_p1[], - double mall_prefetch_dram_overhead_factor[], - double mall_prefetch_sdp_overhead_factor[]); -static void CalculateVMRowAndSwath(struct dml2_core_internal_scratch *scratch, struct dml2_core_calcs_CalculateVMRowAndSwath_params *p); -static double CalculateUrgentLatency( - double UrgentLatencyPixelDataOnly, - double UrgentLatencyPixelMixedWithVMData, - double UrgentLatencyVMDataOnly, - bool DoUrgentLatencyAdjustment, - double UrgentLatencyAdjustmentFabricClockComponent, - double UrgentLatencyAdjustmentFabricClockReference, - double FabricClock, - double uclk_freq_mhz, - enum dml2_qos_param_type qos_type, - unsigned int urgent_ramp_uclk_cycles, - unsigned int df_qos_response_time_fclk_cycles, - unsigned int max_round_trip_to_furthest_cs_fclk_cycles, - unsigned int mall_overhead_fclk_cycles, - double umc_urgent_ramp_latency_margin, - double fabric_max_transport_latency_margin); -static double CalculateTripToMemory( - double UrgLatency, - double FabricClock, - double uclk_freq_mhz, - enum dml2_qos_param_type qos_type, - unsigned int trip_to_memory_uclk_cycles, - unsigned int max_round_trip_to_furthest_cs_fclk_cycles, - unsigned int mall_overhead_fclk_cycles, - double umc_max_latency_margin, - double fabric_max_transport_latency_margin); -static double CalculateMetaTripToMemory( - double UrgLatency, - double FabricClock, - double uclk_freq_mhz, - enum dml2_qos_param_type qos_type, - unsigned int meta_trip_to_memory_uclk_cycles, - unsigned int meta_trip_to_memory_fclk_cycles, - double umc_max_latency_margin, - double fabric_max_transport_latency_margin); -static void calculate_cursor_req_attributes( - unsigned int cursor_width, - unsigned int cursor_bpp, - - // output - unsigned int *cursor_lines_per_chunk, - unsigned int *cursor_bytes_per_line, - unsigned int *cursor_bytes_per_chunk, - unsigned int *cursor_bytes); -static void calculate_cursor_urgent_burst_factor( - unsigned int CursorBufferSize, - unsigned int CursorWidth, - unsigned int cursor_bytes_per_chunk, - unsigned int cursor_lines_per_chunk, - double LineTime, - double UrgentLatency, - - double *UrgentBurstFactorCursor, - bool *NotEnoughUrgentLatencyHiding); -static void CalculateUrgentBurstFactor( - const struct dml2_plane_parameters *plane_cfg, - unsigned int swath_width_luma_ub, - unsigned int swath_width_chroma_ub, - unsigned int SwathHeightY, - unsigned int SwathHeightC, - double LineTime, - double UrgentLatency, - double VRatio, - double VRatioC, - double BytePerPixelInDETY, - double BytePerPixelInDETC, - unsigned int DETBufferSizeY, - unsigned int DETBufferSizeC, - // Output - double *UrgentBurstFactorLuma, - double *UrgentBurstFactorChroma, - bool *NotEnoughUrgentLatencyHiding); -static void CalculateDCFCLKDeepSleep( - const struct dml2_display_cfg *display_cfg, - unsigned int NumberOfActiveSurfaces, - unsigned int BytePerPixelY[], - unsigned int BytePerPixelC[], - unsigned int SwathWidthY[], - unsigned int SwathWidthC[], - unsigned int DPPPerSurface[], - double PSCL_THROUGHPUT[], - double PSCL_THROUGHPUT_CHROMA[], - double Dppclk[], - double ReadBandwidthLuma[], - double ReadBandwidthChroma[], - unsigned int ReturnBusWidth, - - // Output - double *DCFClkDeepSleep); -static double CalculateWriteBackDelay( - enum dml2_source_format_class WritebackPixelFormat, - double WritebackHRatio, - double WritebackVRatio, - unsigned int WritebackVTaps, - unsigned int WritebackDestinationWidth, - unsigned int WritebackDestinationHeight, - unsigned int WritebackSourceHeight, - unsigned int HTotal); -static unsigned int CalculateMaxVStartup( - bool ptoi_supported, - unsigned int vblank_nom_default_us, - const struct dml2_timing_cfg *timing, - double write_back_delay_us); -static void CalculateSwathAndDETConfiguration(struct dml2_core_internal_scratch *scratch, struct dml2_core_calcs_CalculateSwathAndDETConfiguration_params *p); -static void CalculateODMMode( - unsigned int MaximumPixelsPerLinePerDSCUnit, - unsigned int HActive, - enum dml2_output_encoder_class Output, - enum dml2_odm_mode ODMUse, - double MaxDispclk, - bool DSCEnable, - unsigned int TotalNumberOfActiveDPP, - unsigned int MaxNumDPP, - double PixelClock, - - // Output - bool *TotalAvailablePipesSupport, - unsigned int *NumberOfDPP, - enum dml2_odm_mode *ODMMode, - double *RequiredDISPCLKPerSurface); -static void CalculateOutputLink( - struct dml2_core_internal_scratch *s, - double PHYCLK, - double PHYCLKD18, - double PHYCLKD32, - double Downspreading, - bool IsMainSurfaceUsingTheIndicatedTiming, - enum dml2_output_encoder_class Output, - enum dml2_output_format_class OutputFormat, - unsigned int HTotal, - unsigned int HActive, - double PixelClockBackEnd, - double ForcedOutputLinkBPP, - unsigned int DSCInputBitPerComponent, - unsigned int NumberOfDSCSlices, - double AudioSampleRate, - unsigned int AudioSampleLayout, - enum dml2_odm_mode ODMModeNoDSC, - enum dml2_odm_mode ODMModeDSC, - enum dml2_dsc_enable_option DSCEnable, - unsigned int OutputLinkDPLanes, - enum dml2_output_link_dp_rate OutputLinkDPRate, - - // Output - bool *RequiresDSC, - bool *RequiresFEC, - double *OutBpp, - enum dml2_core_internal_output_type *OutputType, - enum dml2_core_internal_output_type_rate *OutputRate, - unsigned int *RequiredSlots); -static double CalculateWriteBackDISPCLK( - enum dml2_source_format_class WritebackPixelFormat, - double PixelClock, - double WritebackHRatio, - double WritebackVRatio, - unsigned int WritebackHTaps, - unsigned int WritebackVTaps, - unsigned int WritebackSourceWidth, - unsigned int WritebackDestinationWidth, - unsigned int HTotal, - unsigned int WritebackLineBufferSize); -static double RequiredDTBCLK( - bool DSCEnable, - double PixelClock, - enum dml2_output_format_class OutputFormat, - double OutputBpp, - unsigned int DSCSlices, - unsigned int HTotal, - unsigned int HActive, - unsigned int AudioRate, - unsigned int AudioLayout); -static unsigned int DSCDelayRequirement( - bool DSCEnabled, - enum dml2_odm_mode ODMMode, - unsigned int DSCInputBitPerComponent, - double OutputBpp, - unsigned int HActive, - unsigned int HTotal, - unsigned int NumberOfDSCSlices, - enum dml2_output_format_class OutputFormat, - enum dml2_output_encoder_class Output, - double PixelClock, - double PixelClockBackEnd); -static void CalculateSurfaceSizeInMall( - const struct dml2_display_cfg *display_cfg, - unsigned int NumberOfActiveSurfaces, - unsigned int MALLAllocatedForDCN, - unsigned int BytesPerPixelY[], - unsigned int BytesPerPixelC[], - unsigned int Read256BytesBlockWidthY[], - unsigned int Read256BytesBlockWidthC[], - unsigned int Read256BytesBlockHeightY[], - unsigned int Read256BytesBlockHeightC[], - unsigned int ReadBlockWidthY[], - unsigned int ReadBlockWidthC[], - unsigned int ReadBlockHeightY[], - unsigned int ReadBlockHeightC[], - - // Output - unsigned int SurfaceSizeInMALL[], - bool *ExceededMALLSize); -static void calculate_tdlut_setting(struct dml2_core_internal_scratch *scratch, struct dml2_core_calcs_calculate_tdlut_setting_params *p); -static void CalculateTarb( - const struct dml2_display_cfg *display_cfg, - unsigned int PixelChunkSizeInKByte, - unsigned int NumberOfActiveSurfaces, - unsigned int NumberOfDPP[], - unsigned int dpte_group_bytes[], - unsigned int tdlut_bytes_per_group[], - double HostVMInefficiencyFactor, - double HostVMInefficiencyFactorPrefetch, - unsigned int HostVMMinPageSize, - double ReturnBW, - - unsigned int MetaChunkSize, - - // output - double *Tarb, - double *Tarb_prefetch); -static double CalculateTWait(long reserved_vblank_time_ns, double UrgentLatency, double Ttrip); -static void CalculateVUpdateAndDynamicMetadataParameters( - unsigned int MaxInterDCNTileRepeaters, - double Dppclk, - double Dispclk, - double DCFClkDeepSleep, - double PixelClock, - unsigned int HTotal, - unsigned int VBlank, - unsigned int DynamicMetadataTransmittedBytes, - unsigned int DynamicMetadataLinesBeforeActiveRequired, - unsigned int InterlaceEnable, - bool ProgressiveToInterlaceUnitInOPP, - - // Output - double *TSetup, - double *Tdmbf, - double *Tdmec, - double *Tdmsks, - unsigned int *VUpdateOffsetPix, - unsigned int *VUpdateWidthPix, - unsigned int *VReadyOffsetPix); -static double get_urgent_bandwidth_required( - struct dml2_core_shared_get_urgent_bandwidth_required_locals *l, - const struct dml2_display_cfg *display_cfg, - enum dml2_core_internal_soc_state_type state_type, - enum dml2_core_internal_bw_type bw_type, - bool inc_flip_bw, // including flip bw - unsigned int NumberOfActiveSurfaces, - unsigned int NumberOfDPP[], - double dcc_dram_bw_nom_overhead_factor_p0[], - double dcc_dram_bw_nom_overhead_factor_p1[], - double dcc_dram_bw_pref_overhead_factor_p0[], - double dcc_dram_bw_pref_overhead_factor_p1[], - double mall_prefetch_sdp_overhead_factor[], - double mall_prefetch_dram_overhead_factor[], - double ReadBandwidthLuma[], - double ReadBandwidthChroma[], - double PrefetchBandwidthLuma[], - double PrefetchBandwidthChroma[], - double cursor_bw[], - double dpte_row_bw[], - double meta_row_bw[], - double prefetch_cursor_bw[], - double prefetch_vmrow_bw[], - double flip_bw[], - double UrgentBurstFactorLuma[], - double UrgentBurstFactorChroma[], - double UrgentBurstFactorCursor[], - double UrgentBurstFactorLumaPre[], - double UrgentBurstFactorChromaPre[], - double UrgentBurstFactorCursorPre[]); -static void CalculateExtraLatency( - const struct dml2_display_cfg *display_cfg, - unsigned int ROBBufferSizeInKByte, - unsigned int RoundTripPingLatencyCycles, - unsigned int ReorderingBytes, - double DCFCLK, - double FabricClock, - unsigned int PixelChunkSizeInKByte, - double ReturnBW, - unsigned int NumberOfActiveSurfaces, - unsigned int NumberOfDPP[], - unsigned int dpte_group_bytes[], - unsigned int tdlut_bytes_per_group[], - double HostVMInefficiencyFactor, - double HostVMInefficiencyFactorPrefetch, - unsigned int HostVMMinPageSize, - enum dml2_qos_param_type qos_type, - bool max_oustanding_when_urgent_expected, - unsigned int max_outstanding_requests, - unsigned int request_size_bytes_luma[], - unsigned int request_size_bytes_chroma[], - unsigned int MetaChunkSize, - unsigned int dchub_arb_to_ret_delay, - double Ttrip, - unsigned int hostvm_mode, - - // output - double *ExtraLatency, // Tex - double *ExtraLatency_sr, // Tex_sr - double *ExtraLatencyPrefetch); -static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch, struct dml2_core_calcs_CalculatePrefetchSchedule_params *p); -static void calculate_peak_bandwidth_required( - struct dml2_core_internal_scratch *s, - - // output - double urg_vactive_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double non_urg_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - - // input - const struct dml2_display_cfg *display_cfg, - unsigned int inc_flip_bw, - unsigned int NumberOfActiveSurfaces, - unsigned int NumberOfDPP[], - double dcc_dram_bw_nom_overhead_factor_p0[], - double dcc_dram_bw_nom_overhead_factor_p1[], - double dcc_dram_bw_pref_overhead_factor_p0[], - double dcc_dram_bw_pref_overhead_factor_p1[], - double mall_prefetch_sdp_overhead_factor[], - double mall_prefetch_dram_overhead_factor[], - double ReadBandwidthLuma[], - double ReadBandwidthChroma[], - double PrefetchBandwidthLuma[], - double PrefetchBandwidthChroma[], - double cursor_bw[], - double dpte_row_bw[], - double meta_row_bw[], - double prefetch_cursor_bw[], - double prefetch_vmrow_bw[], - double flip_bw[], - double UrgentBurstFactorLuma[], - double UrgentBurstFactorChroma[], - double UrgentBurstFactorCursor[], - double UrgentBurstFactorLumaPre[], - double UrgentBurstFactorChromaPre[], - double UrgentBurstFactorCursorPre[]); -static void check_urgent_bandwidth_support( - double *frac_urg_bandwidth_nom, - double *frac_urg_bandwidth_mall, - bool *vactive_bandwidth_support_ok, // vactive ok - bool *bandwidth_support_ok, // max of vm, prefetch, vactive all ok - - unsigned int mall_allocated_for_dcn_mbytes, - double non_urg_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_vactive_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_bandwidth_available[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max]); -static double get_bandwidth_available_for_immediate_flip( - enum dml2_core_internal_soc_state_type eval_state, - double urg_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], // no flip - double urg_bandwidth_available[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max]); -static void calculate_immediate_flip_bandwidth_support( - // Output - double *frac_urg_bandwidth_flip, - bool *flip_bandwidth_support_ok, - - // Input - enum dml2_core_internal_soc_state_type eval_state, - double urg_bandwidth_required_flip[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double non_urg_bandwidth_required_flip[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_bandwidth_available[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max]); -static void CalculateFlipSchedule( - struct dml2_core_internal_scratch *s, - bool iflip_enable, - bool use_lb_flip_bw, - double HostVMInefficiencyFactor, - double Tvm_trips_flip, - double Tr0_trips_flip, - double Tvm_trips_flip_rounded, - double Tr0_trips_flip_rounded, - bool GPUVMEnable, - double vm_bytes, // vm_bytes - double DPTEBytesPerRow, // dpte_row_bytes - double BandwidthAvailableForImmediateFlip, - unsigned int TotImmediateFlipBytes, - enum dml2_source_format_class SourcePixelFormat, - double LineTime, - double VRatio, - double VRatioChroma, - double Tno_bw_flip, - unsigned int dpte_row_height, - unsigned int dpte_row_height_chroma, - bool use_one_row_for_frame_flip, - unsigned int max_flip_time_us, - unsigned int per_pipe_flip_bytes, - unsigned int meta_row_bytes, - unsigned int meta_row_height, - unsigned int meta_row_height_chroma, - bool dcc_mrq_enable, - - // Output - double *dst_y_per_vm_flip, - double *dst_y_per_row_flip, - double *final_flip_bw, - bool *ImmediateFlipSupportedForPipe); -static void CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport( - struct dml2_core_internal_scratch *scratch, - struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params *p); -static double uclk_khz_to_dram_bw_mbps(unsigned long uclk_khz, const struct dml2_dram_params *dram_config); -static double dram_bw_kbps_to_uclk_mhz(unsigned long long bw_kbps, const struct dml2_dram_params *dram_config); -static unsigned int get_qos_param_index(unsigned long uclk_freq_khz, const struct dml2_dcn4_uclk_dpm_dependent_qos_params *per_uclk_dpm_params); -static unsigned int get_active_min_uclk_dpm_index(unsigned long uclk_freq_khz, const struct dml2_soc_state_table *clk_table); -static unsigned int get_pipe_flip_bytes( - double hostvm_inefficiency_factor, - unsigned int vm_bytes, - unsigned int dpte_row_bytes, - unsigned int meta_row_bytes); -static void calculate_hostvm_inefficiency_factor( - double *HostVMInefficiencyFactor, - double *HostVMInefficiencyFactorPrefetch, - - bool gpuvm_enable, - bool hostvm_enable, - unsigned int remote_iommu_outstanding_translations, - unsigned int max_outstanding_reqs, - double urg_bandwidth_avail_active_pixel_and_vm, - double urg_bandwidth_avail_active_vm_only); -static void CalculatePixelDeliveryTimes( - const struct dml2_display_cfg *display_cfg, - const struct core_display_cfg_support_info *cfg_support_info, - unsigned int NumberOfActiveSurfaces, - double VRatioPrefetchY[], - double VRatioPrefetchC[], - unsigned int swath_width_luma_ub[], - unsigned int swath_width_chroma_ub[], - double PSCL_THROUGHPUT[], - double PSCL_THROUGHPUT_CHROMA[], - double Dppclk[], - unsigned int BytePerPixelC[], - unsigned int req_per_swath_ub_l[], - unsigned int req_per_swath_ub_c[], - - // Output - double DisplayPipeLineDeliveryTimeLuma[], - double DisplayPipeLineDeliveryTimeChroma[], - double DisplayPipeLineDeliveryTimeLumaPrefetch[], - double DisplayPipeLineDeliveryTimeChromaPrefetch[], - double DisplayPipeRequestDeliveryTimeLuma[], - double DisplayPipeRequestDeliveryTimeChroma[], - double DisplayPipeRequestDeliveryTimeLumaPrefetch[], - double DisplayPipeRequestDeliveryTimeChromaPrefetch[]); -static void CalculateMetaAndPTETimes(struct dml2_core_shared_CalculateMetaAndPTETimes_params *p); -static void CalculateVMGroupAndRequestTimes( - const struct dml2_display_cfg *display_cfg, - unsigned int NumberOfActiveSurfaces, - unsigned int BytePerPixelC[], - double dst_y_per_vm_vblank[], - double dst_y_per_vm_flip[], - unsigned int dpte_row_width_luma_ub[], - unsigned int dpte_row_width_chroma_ub[], - unsigned int vm_group_bytes[], - unsigned int dpde0_bytes_per_frame_ub_l[], - unsigned int dpde0_bytes_per_frame_ub_c[], - unsigned int tdlut_pte_bytes_per_frame[], - unsigned int meta_pte_bytes_per_frame_ub_l[], - unsigned int meta_pte_bytes_per_frame_ub_c[], - bool mrq_present, - - // Output - double TimePerVMGroupVBlank[], - double TimePerVMGroupFlip[], - double TimePerVMRequestVBlank[], - double TimePerVMRequestFlip[]); -static void CalculateStutterEfficiency(struct dml2_core_internal_scratch *scratch, struct dml2_core_calcs_CalculateStutterEfficiency_params *p); -static bool dml_is_dual_plane(enum dml2_source_format_class source_format); -static unsigned int dml_get_plane_idx(const struct dml2_core_internal_display_mode_lib *mode_lib, unsigned int pipe_idx); -static void rq_dlg_get_wm_regs(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_dchub_watermark_regs *wm_regs); -static unsigned int log_and_substract_if_non_zero(unsigned int a, unsigned int subtrahend); -static void rq_dlg_get_rq_reg(struct dml2_display_rq_regs *rq_regs, - const struct dml2_display_cfg *display_cfg, - const struct dml2_core_internal_display_mode_lib *mode_lib, - unsigned int pipe_idx); -static void rq_dlg_get_dlg_reg(struct dml2_core_internal_scratch *s, - struct dml2_display_dlg_regs *disp_dlg_regs, - struct dml2_display_ttu_regs *disp_ttu_regs, - const struct dml2_display_cfg *display_cfg, - const struct dml2_core_internal_display_mode_lib *mode_lib, - const unsigned int pipe_idx); -static void rq_dlg_get_arb_params(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_display_arb_regs *arb_param); - -/* - * END OF STATIC HELPERS - */ - -bool dml2_core_shared_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; - const struct dml2_display_cfg *display_cfg = in_out_params->in_display_cfg; - const struct dml2_mcg_min_clock_table *min_clk_table = in_out_params->min_clk_table; - - struct dml2_core_calcs_mode_support_locals *s = &mode_lib->scratch.dml_core_mode_support_locals; - struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params *CalculateWatermarks_params = &mode_lib->scratch.CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params; - struct dml2_core_calcs_CalculateVMRowAndSwath_params *CalculateVMRowAndSwath_params = &mode_lib->scratch.CalculateVMRowAndSwath_params; - struct dml2_core_calcs_CalculateSwathAndDETConfiguration_params *CalculateSwathAndDETConfiguration_params = &mode_lib->scratch.CalculateSwathAndDETConfiguration_params; - struct dml2_core_calcs_CalculatePrefetchSchedule_params *CalculatePrefetchSchedule_params = &mode_lib->scratch.CalculatePrefetchSchedule_params; - struct dml2_core_calcs_calculate_tdlut_setting_params *calculate_tdlut_setting_params = &mode_lib->scratch.calculate_tdlut_setting_params; - struct dml2_core_calcs_calculate_mcache_setting_params *calculate_mcache_setting_params = &mode_lib->scratch.calculate_mcache_setting_params; - unsigned int k, m, n; - - memset(&mode_lib->ms, 0, sizeof(struct dml2_core_internal_mode_support)); - - mode_lib->ms.num_active_planes = display_cfg->num_planes; - get_stream_output_bpp(s->OutputBpp, display_cfg); - - mode_lib->ms.state_idx = in_out_params->min_clk_index; - mode_lib->ms.SOCCLK = ((double)mode_lib->soc.clk_table.socclk.clk_values_khz[0] / 1000); - mode_lib->ms.DCFCLK = ((double)min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].min_dcfclk_khz / 1000); - mode_lib->ms.FabricClock = ((double)min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].min_fclk_khz / 1000); - mode_lib->ms.MaxDCFCLK = (double)min_clk_table->max_clocks_khz.dcfclk / 1000; - mode_lib->ms.MaxFabricClock = (double)min_clk_table->max_clocks_khz.fclk / 1000; - mode_lib->ms.max_dispclk_freq_mhz = (double)min_clk_table->max_clocks_khz.dispclk / 1000; - mode_lib->ms.max_dscclk_freq_mhz = (double)min_clk_table->max_clocks_khz.dscclk / 1000; - 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.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__) - dml2_printf("DML::%s: --- START --- \n", __func__); - dml2_printf("DML::%s: num_active_planes = %u\n", __func__, mode_lib->ms.num_active_planes); - dml2_printf("DML::%s: min_clk_index = %0d\n", __func__, in_out_params->min_clk_index); - dml2_printf("DML::%s: qos_param_index = %0d\n", __func__, mode_lib->ms.qos_param_index); - dml2_printf("DML::%s: SOCCLK = %f\n", __func__, mode_lib->ms.SOCCLK); - dml2_printf("DML::%s: dram_bw_mbps = %f\n", __func__, mode_lib->ms.dram_bw_mbps); - dml2_printf("DML::%s: uclk_freq_mhz = %f\n", __func__, mode_lib->ms.uclk_freq_mhz); - dml2_printf("DML::%s: DCFCLK = %f\n", __func__, mode_lib->ms.DCFCLK); - dml2_printf("DML::%s: FabricClock = %f\n", __func__, mode_lib->ms.FabricClock); - dml2_printf("DML::%s: MaxDCFCLK = %f\n", __func__, mode_lib->ms.MaxDCFCLK); - dml2_printf("DML::%s: max_dispclk_freq_mhz = %f\n", __func__, mode_lib->ms.max_dispclk_freq_mhz); - 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); - - for (k = 0; k < mode_lib->ms.num_active_planes; k++) - dml2_printf("DML::%s: plane_%d: reserved_vblank_time_ns = %u\n", __func__, k, display_cfg->plane_descriptors[k].overrides.reserved_vblank_time_ns); - - // dml2_printf_dml_policy(&mode_lib->ms.policy); - // dml2_printf_dml_display_cfg_timing(&display_cfg->timing, mode_lib->ms.num_active_planes); - // dml2_printf_dml_display_cfg_plane(&display_cfg->plane, mode_lib->ms.num_active_planes); - // dml2_printf_dml_display_cfg_surface(&display_cfg->surface, mode_lib->ms.num_active_planes); - // dml2_printf_dml_display_cfg_output(&display_cfg->output, mode_lib->ms.num_active_planes); -#endif - - CalculateMaxDETAndMinCompressedBufferSize( - mode_lib->ip.config_return_buffer_size_in_kbytes, - mode_lib->ip.config_return_buffer_segment_size_in_kbytes, - mode_lib->ip.rob_buffer_size_kbytes, - mode_lib->ip.max_num_dpp, - display_cfg->overrides.hw.force_nom_det_size_kbytes.enable, - display_cfg->overrides.hw.force_nom_det_size_kbytes.value, - mode_lib->ip.dcn_mrq_present, - - /* Output */ - &mode_lib->ms.MaxTotalDETInKByte, - &mode_lib->ms.NomDETInKByte, - &mode_lib->ms.MinCompressedBufferSizeInKByte); - - PixelClockAdjustmentForProgressiveToInterlaceUnit(display_cfg, mode_lib->ip.ptoi_supported, s->PixelClockBackEnd); - - /*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/ - - /*Scale Ratio, taps Support Check*/ - mode_lib->ms.support.ScaleRatioAndTapsSupport = true; - // Many core tests are still setting scaling parameters "incorrectly" - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - if (display_cfg->plane_descriptors[k].composition.scaler_info.enabled == false - && (dml2_core_shared_is_420(display_cfg->plane_descriptors[k].pixel_format) - || display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio != 1.0 - || display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_taps != 1.0 - || display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio != 1.0 - || display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps != 1.0)) { - mode_lib->ms.support.ScaleRatioAndTapsSupport = false; - } else if (display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps < 1.0 || display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps > 8.0 - || display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_taps < 1.0 || display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_taps > 8.0 - || (display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_taps > 1.0 && (display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_taps % 2) == 1) - || display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio > mode_lib->ip.max_hscl_ratio - || display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio > mode_lib->ip.max_vscl_ratio - || display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio > display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_taps - || display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio > display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps - || (dml2_core_shared_is_420(display_cfg->plane_descriptors[k].pixel_format) - && (display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps < 1 || display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps > 8 || - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_taps < 1 || display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_taps > 8 || - (display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_taps > 1 && display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_taps % 2 == 1) || - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio > mode_lib->ip.max_hscl_ratio || - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio > mode_lib->ip.max_vscl_ratio || - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio > display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_taps || - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio > display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps))) { - mode_lib->ms.support.ScaleRatioAndTapsSupport = false; - } - } - - /*Source Format, Pixel Format and Scan Support Check*/ - mode_lib->ms.support.SourceFormatPixelAndScanSupport = true; - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - if (display_cfg->plane_descriptors[k].surface.tiling == dml2_sw_linear && dml_is_vertical_rotation(display_cfg->plane_descriptors[k].composition.rotation_angle)) { - mode_lib->ms.support.SourceFormatPixelAndScanSupport = false; - } - } - - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - CalculateBytePerPixelAndBlockSizes( - display_cfg->plane_descriptors[k].pixel_format, - display_cfg->plane_descriptors[k].surface.tiling, - display_cfg->plane_descriptors[k].surface.plane0.pitch, - display_cfg->plane_descriptors[k].surface.plane1.pitch, - - /* Output */ - &mode_lib->ms.BytePerPixelY[k], - &mode_lib->ms.BytePerPixelC[k], - &mode_lib->ms.BytePerPixelInDETY[k], - &mode_lib->ms.BytePerPixelInDETC[k], - &mode_lib->ms.Read256BlockHeightY[k], - &mode_lib->ms.Read256BlockHeightC[k], - &mode_lib->ms.Read256BlockWidthY[k], - &mode_lib->ms.Read256BlockWidthC[k], - &mode_lib->ms.MacroTileHeightY[k], - &mode_lib->ms.MacroTileHeightC[k], - &mode_lib->ms.MacroTileWidthY[k], - &mode_lib->ms.MacroTileWidthC[k], - &mode_lib->ms.surf_linear128_l[k], - &mode_lib->ms.surf_linear128_c[k]); - } - - /*Bandwidth Support Check*/ - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - if (!dml_is_vertical_rotation(display_cfg->plane_descriptors[k].composition.rotation_angle)) { - mode_lib->ms.SwathWidthYSingleDPP[k] = display_cfg->plane_descriptors[k].composition.viewport.plane0.width; - mode_lib->ms.SwathWidthCSingleDPP[k] = display_cfg->plane_descriptors[k].composition.viewport.plane1.width; - } else { - mode_lib->ms.SwathWidthYSingleDPP[k] = display_cfg->plane_descriptors[k].composition.viewport.plane0.height; - mode_lib->ms.SwathWidthCSingleDPP[k] = display_cfg->plane_descriptors[k].composition.viewport.plane1.height; - } - } - - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - mode_lib->ms.SurfaceReadBandwidthLuma[k] = mode_lib->ms.SwathWidthYSingleDPP[k] * math_ceil2(mode_lib->ms.BytePerPixelY[k], 1.0) / (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)) * display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio; - mode_lib->ms.SurfaceReadBandwidthChroma[k] = mode_lib->ms.SwathWidthCSingleDPP[k] * math_ceil2(mode_lib->ms.BytePerPixelC[k], 2.0) / (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)) * display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio; - - mode_lib->ms.cursor_bw[k] = display_cfg->plane_descriptors[k].cursor.num_cursors * display_cfg->plane_descriptors[k].cursor.cursor_width * - display_cfg->plane_descriptors[k].cursor.cursor_bpp / 8.0 / (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)); - -#ifdef __DML_VBA_DEBUG__ - double old_ReadBandwidthLuma = mode_lib->ms.SwathWidthYSingleDPP[k] * math_ceil2(mode_lib->ms.BytePerPixelInDETY[k], 1.0) / (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)) * display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio; - double old_ReadBandwidthChroma = mode_lib->ms.SwathWidthYSingleDPP[k] / 2 * math_ceil2(mode_lib->ms.BytePerPixelInDETC[k], 2.0) / (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)) * display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio / 2.0; - dml2_printf("DML::%s: k=%u, old_ReadBandwidthLuma = %f\n", __func__, k, old_ReadBandwidthLuma); - dml2_printf("DML::%s: k=%u, old_ReadBandwidthChroma = %f\n", __func__, k, old_ReadBandwidthChroma); - dml2_printf("DML::%s: k=%u, ReadBandwidthLuma = %f\n", __func__, k, mode_lib->ms.SurfaceReadBandwidthLuma[k]); - dml2_printf("DML::%s: k=%u, ReadBandwidthChroma = %f\n", __func__, k, mode_lib->ms.SurfaceReadBandwidthChroma[k]); -#endif - } - - // Writeback bandwidth - 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 && display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.pixel_format == dml2_444_64) { - mode_lib->ms.WriteBandwidth[k] = 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].writeback.scaling_info.input_height - * 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)) * 8.0; - } else if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.enable == true) { - mode_lib->ms.WriteBandwidth[k] = 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].writeback.scaling_info.input_height - * 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)) * 4.0; - } else { - mode_lib->ms.WriteBandwidth[k] = 0.0; - } - } - - /*Writeback Latency support check*/ - 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.support.WritebackLatencySupport = false; - } - } - - /* Writeback Mode Support Check */ - s->TotalNumberOfActiveWriteback = 0; - for (k = 0; k <= (unsigned int)mode_lib->ms.num_active_planes - 1; k++) { - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.enable == true - && (display_cfg->plane_descriptors[k].stream_index == k)) { - s->TotalNumberOfActiveWriteback = s->TotalNumberOfActiveWriteback + 1; - } - } - - mode_lib->ms.support.EnoughWritebackUnits = 1; - if (s->TotalNumberOfActiveWriteback > (unsigned int)mode_lib->ip.max_num_wb) { - mode_lib->ms.support.EnoughWritebackUnits = false; - } - - /* Writeback Scale Ratio and Taps Support Check */ - mode_lib->ms.support.WritebackScaleRatioAndTapsSupport = 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) { - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.h_ratio > mode_lib->ip.writeback_max_hscl_ratio - || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.v_ratio > mode_lib->ip.writeback_max_vscl_ratio - || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.h_ratio < mode_lib->ip.writeback_min_hscl_ratio - || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.v_ratio < mode_lib->ip.writeback_min_vscl_ratio - || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.h_taps > (unsigned int) mode_lib->ip.writeback_max_hscl_taps - || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.v_taps > (unsigned int) mode_lib->ip.writeback_max_vscl_taps - || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.h_ratio > (unsigned int)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_ratio > (unsigned int)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.h_taps > 2.0 && ((display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.h_taps % 2) == 1))) { - mode_lib->ms.support.WritebackScaleRatioAndTapsSupport = false; - } - if (2.0 * 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.v_taps - 1) * 57 > mode_lib->ip.writeback_line_buffer_buffer_size) { - mode_lib->ms.support.WritebackScaleRatioAndTapsSupport = false; - } - } - } - - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - CalculateSinglePipeDPPCLKAndSCLThroughput( - display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio, - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio, - display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio, - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio, - mode_lib->ip.max_dchub_pscl_bw_pix_per_clk, - mode_lib->ip.max_pscl_lb_bw_pix_per_clk, - ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000), - display_cfg->plane_descriptors[k].pixel_format, - display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_taps, - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_taps, - display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps, - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps, - /* Output */ - &mode_lib->ms.PSCL_FACTOR[k], - &mode_lib->ms.PSCL_FACTOR_CHROMA[k], - &mode_lib->ms.MinDPPCLKUsingSingleDPP[k]); - } - - // Max Viewport Size support - for (k = 0; k < mode_lib->ms.num_active_planes; k++) { - if (display_cfg->plane_descriptors[k].surface.tiling == dml2_sw_linear) { - s->MaximumSwathWidthSupportLuma = 15360; - } else if (!dml_is_vertical_rotation(display_cfg->plane_descriptors[k].composition.rotation_angle) && mode_lib->ms.BytePerPixelC[k] > 0 && display_cfg->plane_descriptors[k].pixel_format != dml2_rgbe_alpha) { // horz video - s->MaximumSwathWidthSupportLuma = 7680 + 16; - } else if (dml_is_vertical_rotation(display_cfg->plane_descriptors[k].composition.rotation_angle) && mode_lib->ms.BytePerPixelC[k] > 0 && display_cfg->plane_descriptors[k].pixel_format != dml2_rgbe_alpha) { // vert video - s->MaximumSwathWidthSupportLuma = 4320 + 16; - } else if (display_cfg->plane_descriptors[k].pixel_format == dml2_rgbe_alpha) { // rgbe + alpha - s->MaximumSwathWidthSupportLuma = 5120 + 16; - } else if (dml_is_vertical_rotation(display_cfg->plane_descriptors[k].composition.rotation_angle) && mode_lib->ms.BytePerPixelY[k] == 8 && display_cfg->plane_descriptors[k].surface.dcc.enable == true) { // vert 64bpp - s->MaximumSwathWidthSupportLuma = 3072 + 16; - } else { - s->MaximumSwathWidthSupportLuma = 6144 + 16; - } - - if (dml2_core_shared_is_420(display_cfg->plane_descriptors[k].pixel_format)) { - s->MaximumSwathWidthSupportChroma = (unsigned int)(s->MaximumSwathWidthSupportLuma / 2.0); - } else { - s->MaximumSwathWidthSupportChroma = s->MaximumSwathWidthSupportLuma; - } - mode_lib->ms.MaximumSwathWidthInLineBufferLuma = mode_lib->ip.line_buffer_size_bits * math_max2(display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio, 1.0) / 57 /*FIXME_STAGE2 was: LBBitPerPixel*/ / - (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 = mode_lib->ip.line_buffer_size_bits * math_max2(display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio, 1.0) / 57 /*FIXME_STAGE2 was: LBBitPerPixel*/ / - (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)); - } - mode_lib->ms.MaximumSwathWidthLuma[k] = math_min2(s->MaximumSwathWidthSupportLuma, mode_lib->ms.MaximumSwathWidthInLineBufferLuma); - mode_lib->ms.MaximumSwathWidthChroma[k] = math_min2(s->MaximumSwathWidthSupportChroma, mode_lib->ms.MaximumSwathWidthInLineBufferChroma); - } - - /* 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) { - mode_lib->ms.support.CursorSupport = false; - } - } - } - - /* Valid Pitch Check */ - mode_lib->ms.support.PitchSupport = true; - for (k = 0; k < mode_lib->ms.num_active_planes; k++) { - - // data pitch - unsigned int alignment_l = mode_lib->ms.MacroTileWidthY[k]; - - if (mode_lib->ms.surf_linear128_l[k]) - alignment_l = alignment_l / 2; - - mode_lib->ms.support.AlignedYPitch[k] = (unsigned int)math_ceil2(math_max2(display_cfg->plane_descriptors[k].surface.plane0.pitch, display_cfg->plane_descriptors[k].surface.plane0.width), alignment_l); - if (dml2_core_shared_is_420(display_cfg->plane_descriptors[k].pixel_format) || display_cfg->plane_descriptors[k].pixel_format == dml2_rgbe_alpha) { - unsigned int alignment_c = mode_lib->ms.MacroTileWidthC[k]; - - if (mode_lib->ms.surf_linear128_c[k]) - alignment_c = alignment_c / 2; - mode_lib->ms.support.AlignedCPitch[k] = (unsigned int)math_ceil2(math_max2(display_cfg->plane_descriptors[k].surface.plane1.pitch, display_cfg->plane_descriptors[k].surface.plane1.width), alignment_c); - } else { - mode_lib->ms.support.AlignedCPitch[k] = display_cfg->plane_descriptors[k].surface.plane1.pitch; - } - - if (mode_lib->ms.support.AlignedYPitch[k] > display_cfg->plane_descriptors[k].surface.plane0.pitch || - mode_lib->ms.support.AlignedCPitch[k] > display_cfg->plane_descriptors[k].surface.plane1.pitch) { - mode_lib->ms.support.PitchSupport = false; -#if defined(__DML_VBA_DEBUG__) - dml2_printf("DML::%s: k=%u AlignedYPitch = %d\n", __func__, k, mode_lib->ms.support.AlignedYPitch[k]); - dml2_printf("DML::%s: k=%u PitchY = %d\n", __func__, k, display_cfg->plane_descriptors[k].surface.plane0.pitch); - dml2_printf("DML::%s: k=%u AlignedCPitch = %d\n", __func__, k, mode_lib->ms.support.AlignedCPitch[k]); - dml2_printf("DML::%s: k=%u PitchC = %d\n", __func__, k, display_cfg->plane_descriptors[k].surface.plane1.pitch); - dml2_printf("DML::%s: k=%u PitchSupport = %d\n", __func__, k, mode_lib->ms.support.PitchSupport); -#endif - } - - // meta pitch - if (mode_lib->ip.dcn_mrq_present && display_cfg->plane_descriptors[k].surface.dcc.enable) { - mode_lib->ms.support.AlignedDCCMetaPitchY[k] = (unsigned int)math_ceil2(math_max2(display_cfg->plane_descriptors[k].surface.dcc.plane0.pitch, - display_cfg->plane_descriptors[k].surface.plane0.width), 64.0 * mode_lib->ms.Read256BlockWidthY[k]); - - if (mode_lib->ms.support.AlignedDCCMetaPitchY[k] > display_cfg->plane_descriptors[k].surface.dcc.plane0.pitch) - mode_lib->ms.support.PitchSupport = false; - - if (dml2_core_shared_is_420(display_cfg->plane_descriptors[k].pixel_format) || display_cfg->plane_descriptors[k].pixel_format == dml2_rgbe_alpha) { - mode_lib->ms.support.AlignedDCCMetaPitchC[k] = (unsigned int)math_ceil2(math_max2(display_cfg->plane_descriptors[k].surface.dcc.plane1.pitch, - display_cfg->plane_descriptors[k].surface.plane1.width), 64.0 * mode_lib->ms.Read256BlockWidthC[k]); - - if (mode_lib->ms.support.AlignedDCCMetaPitchC[k] > display_cfg->plane_descriptors[k].surface.dcc.plane1.pitch) - mode_lib->ms.support.PitchSupport = false; - } - } else { - mode_lib->ms.support.AlignedDCCMetaPitchY[k] = 0; - mode_lib->ms.support.AlignedDCCMetaPitchC[k] = 0; - } - } - - 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) { - 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); - dml2_printf("DML::%s: k=%u SurfaceWidthY = %d\n", __func__, k, display_cfg->plane_descriptors[k].surface.plane0.width); - dml2_printf("DML::%s: k=%u ViewportHeight = %d\n", __func__, k, display_cfg->plane_descriptors[k].composition.viewport.plane0.height); - 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 (dml2_core_shared_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; - } - } - } - } - } - - CalculateSwathAndDETConfiguration_params->display_cfg = display_cfg; - CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSizeInKByte = mode_lib->ip.config_return_buffer_size_in_kbytes; - CalculateSwathAndDETConfiguration_params->MaxTotalDETInKByte = mode_lib->ms.MaxTotalDETInKByte; - CalculateSwathAndDETConfiguration_params->MinCompressedBufferSizeInKByte = mode_lib->ms.MinCompressedBufferSizeInKByte; - CalculateSwathAndDETConfiguration_params->rob_buffer_size_kbytes = mode_lib->ip.rob_buffer_size_kbytes; - CalculateSwathAndDETConfiguration_params->pixel_chunk_size_kbytes = mode_lib->ip.pixel_chunk_size_kbytes; - CalculateSwathAndDETConfiguration_params->rob_buffer_size_kbytes = mode_lib->ip.rob_buffer_size_kbytes; - CalculateSwathAndDETConfiguration_params->pixel_chunk_size_kbytes = mode_lib->ip.pixel_chunk_size_kbytes; - CalculateSwathAndDETConfiguration_params->ForceSingleDPP = 1; - CalculateSwathAndDETConfiguration_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes; - CalculateSwathAndDETConfiguration_params->nomDETInKByte = mode_lib->ms.NomDETInKByte; - CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSegmentSizeInkByte = mode_lib->ip.config_return_buffer_segment_size_in_kbytes; - CalculateSwathAndDETConfiguration_params->CompressedBufferSegmentSizeInkByte = mode_lib->ip.compressed_buffer_segment_size_in_kbytes; - CalculateSwathAndDETConfiguration_params->ReadBandwidthLuma = mode_lib->ms.SurfaceReadBandwidthLuma; - CalculateSwathAndDETConfiguration_params->ReadBandwidthChroma = mode_lib->ms.SurfaceReadBandwidthChroma; - CalculateSwathAndDETConfiguration_params->MaximumSwathWidthLuma = mode_lib->ms.MaximumSwathWidthLuma; - CalculateSwathAndDETConfiguration_params->MaximumSwathWidthChroma = mode_lib->ms.MaximumSwathWidthChroma; - CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightY = mode_lib->ms.Read256BlockHeightY; - CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightC = mode_lib->ms.Read256BlockHeightC; - CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthY = mode_lib->ms.Read256BlockWidthY; - CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthC = mode_lib->ms.Read256BlockWidthC; - CalculateSwathAndDETConfiguration_params->surf_linear128_l = mode_lib->ms.surf_linear128_l; - CalculateSwathAndDETConfiguration_params->surf_linear128_c = mode_lib->ms.surf_linear128_c; - CalculateSwathAndDETConfiguration_params->ODMMode = s->dummy_odm_mode; - CalculateSwathAndDETConfiguration_params->BytePerPixY = mode_lib->ms.BytePerPixelY; - CalculateSwathAndDETConfiguration_params->BytePerPixC = mode_lib->ms.BytePerPixelC; - CalculateSwathAndDETConfiguration_params->BytePerPixDETY = mode_lib->ms.BytePerPixelInDETY; - CalculateSwathAndDETConfiguration_params->BytePerPixDETC = mode_lib->ms.BytePerPixelInDETC; - CalculateSwathAndDETConfiguration_params->DPPPerSurface = s->dummy_integer_array[2]; - CalculateSwathAndDETConfiguration_params->mrq_present = mode_lib->ip.dcn_mrq_present; - - // output - CalculateSwathAndDETConfiguration_params->req_per_swath_ub_l = s->dummy_integer_array[0]; - CalculateSwathAndDETConfiguration_params->req_per_swath_ub_c = s->dummy_integer_array[1]; - CalculateSwathAndDETConfiguration_params->swath_width_luma_ub = s->dummy_integer_array[3]; - CalculateSwathAndDETConfiguration_params->swath_width_chroma_ub = s->dummy_integer_array[4]; - CalculateSwathAndDETConfiguration_params->SwathWidth = s->dummy_integer_array[5]; - CalculateSwathAndDETConfiguration_params->SwathWidthChroma = s->dummy_integer_array[6]; - CalculateSwathAndDETConfiguration_params->SwathHeightY = s->dummy_integer_array[7]; - CalculateSwathAndDETConfiguration_params->SwathHeightC = s->dummy_integer_array[8]; - CalculateSwathAndDETConfiguration_params->request_size_bytes_luma = s->dummy_integer_array[26]; - CalculateSwathAndDETConfiguration_params->request_size_bytes_chroma = s->dummy_integer_array[27]; - CalculateSwathAndDETConfiguration_params->DETBufferSizeInKByte = s->dummy_integer_array[9]; - CalculateSwathAndDETConfiguration_params->DETBufferSizeY = s->dummy_integer_array[10]; - CalculateSwathAndDETConfiguration_params->DETBufferSizeC = s->dummy_integer_array[11]; - CalculateSwathAndDETConfiguration_params->full_swath_bytes_l = s->full_swath_bytes_l; - CalculateSwathAndDETConfiguration_params->full_swath_bytes_c = s->full_swath_bytes_c; - CalculateSwathAndDETConfiguration_params->UnboundedRequestEnabled = &s->dummy_boolean[0]; - CalculateSwathAndDETConfiguration_params->compbuf_reserved_space_64b = &s->dummy_integer[1]; - CalculateSwathAndDETConfiguration_params->hw_debug5 = &s->dummy_boolean[2]; - CalculateSwathAndDETConfiguration_params->CompressedBufferSizeInkByte = &s->dummy_integer[0]; - CalculateSwathAndDETConfiguration_params->ViewportSizeSupportPerSurface = mode_lib->ms.SingleDPPViewportSizeSupportPerSurface; - CalculateSwathAndDETConfiguration_params->ViewportSizeSupport = &s->dummy_boolean[1]; - CalculateSwathAndDETConfiguration_params->funcs = &mode_lib->funcs; - - // This calls is just to find out if there is enough DET space to support full vp in 1 pipe. - CalculateSwathAndDETConfiguration(&mode_lib->scratch, CalculateSwathAndDETConfiguration_params); - - { - mode_lib->ms.TotalNumberOfActiveDPP = 0; - mode_lib->ms.support.TotalAvailablePipesSupport = true; - - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - CalculateODMMode( - mode_lib->ip.maximum_pixels_per_line_per_dsc_unit, - 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].output.output_encoder, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].overrides.odm_mode, - mode_lib->ms.max_dispclk_freq_mhz, - false, // DSCEnable - mode_lib->ms.TotalNumberOfActiveDPP, - mode_lib->ip.max_num_dpp, - ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000), - - /* Output */ - &s->TotalAvailablePipesSupportNoDSC, - &s->NumberOfDPPNoDSC, - &s->ODMModeNoDSC, - &s->RequiredDISPCLKPerSurfaceNoDSC); - - CalculateODMMode( - mode_lib->ip.maximum_pixels_per_line_per_dsc_unit, - 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].output.output_encoder, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].overrides.odm_mode, - mode_lib->ms.max_dispclk_freq_mhz, - true, // DSCEnable - mode_lib->ms.TotalNumberOfActiveDPP, - mode_lib->ip.max_num_dpp, - ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000), - - /* Output */ - &s->TotalAvailablePipesSupportDSC, - &s->NumberOfDPPDSC, - &s->ODMModeDSC, - &s->RequiredDISPCLKPerSurfaceDSC); - - /*Number Of DSC Slices*/ - if (display_cfg->plane_descriptors[k].stream_index == k) { - if (s->PixelClockBackEnd[k] > 4800) { - mode_lib->ms.support.NumberOfDSCSlices[k] = (unsigned int)(math_ceil2(s->PixelClockBackEnd[k] / 600, 4)); - } else if (s->PixelClockBackEnd[k] > 2400) { - mode_lib->ms.support.NumberOfDSCSlices[k] = 8; - } else if (s->PixelClockBackEnd[k] > 1200) { - mode_lib->ms.support.NumberOfDSCSlices[k] = 4; - } else if (s->PixelClockBackEnd[k] > 340) { - mode_lib->ms.support.NumberOfDSCSlices[k] = 2; - } else { - mode_lib->ms.support.NumberOfDSCSlices[k] = 1; - } - } else { - mode_lib->ms.support.NumberOfDSCSlices[k] = 0; - } - - if (s->ODMModeDSC == dml2_odm_mode_combine_2to1) - mode_lib->ms.support.NumberOfDSCSlices[k] = 2 * (unsigned int)math_ceil2(mode_lib->ms.support.NumberOfDSCSlices[k] / 2.0, 1.0); - else if (s->ODMModeDSC == dml2_odm_mode_combine_3to1) - mode_lib->ms.support.NumberOfDSCSlices[k] = 12; - else if (s->ODMModeDSC == dml2_odm_mode_combine_4to1) - mode_lib->ms.support.NumberOfDSCSlices[k] = 4 * (unsigned int)math_ceil2(mode_lib->ms.support.NumberOfDSCSlices[k] / 4.0, 1.0); - - CalculateOutputLink( - &mode_lib->scratch, - ((double)mode_lib->soc.clk_table.phyclk.clk_values_khz[0] / 1000), - ((double)mode_lib->soc.clk_table.phyclk_d18.clk_values_khz[0] / 1000), - ((double)mode_lib->soc.clk_table.phyclk_d32.clk_values_khz[0] / 1000), - mode_lib->soc.phy_downspread_percent, - (display_cfg->plane_descriptors[k].stream_index == k), - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_active, - s->PixelClockBackEnd[k], - s->OutputBpp[k], - mode_lib->ip.maximum_dsc_bits_per_component, - mode_lib->ms.support.NumberOfDSCSlices[k], - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.audio_sample_rate, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.audio_sample_layout, - s->ODMModeNoDSC, - s->ODMModeDSC, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.dsc.enable, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_dp_lane_count, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_dp_link_rate, - - /* Output */ - &mode_lib->ms.RequiresDSC[k], - &mode_lib->ms.RequiresFEC[k], - &mode_lib->ms.OutputBpp[k], - &mode_lib->ms.OutputType[k], // VBA_DELTA, VBA uses a string to represent type and rate, but DML uses enum, don't want to rely on strng - &mode_lib->ms.OutputRate[k], - &mode_lib->ms.RequiredSlots[k]); - - if (mode_lib->ms.RequiresDSC[k] == false) { - mode_lib->ms.ODMMode[k] = s->ODMModeNoDSC; - mode_lib->ms.RequiredDISPCLKPerSurface[k] = s->RequiredDISPCLKPerSurfaceNoDSC; - if (!s->TotalAvailablePipesSupportNoDSC) - mode_lib->ms.support.TotalAvailablePipesSupport = false; - mode_lib->ms.TotalNumberOfActiveDPP = mode_lib->ms.TotalNumberOfActiveDPP + s->NumberOfDPPNoDSC; - } else { - mode_lib->ms.ODMMode[k] = s->ODMModeDSC; - mode_lib->ms.RequiredDISPCLKPerSurface[k] = s->RequiredDISPCLKPerSurfaceDSC; - if (!s->TotalAvailablePipesSupportDSC) - mode_lib->ms.support.TotalAvailablePipesSupport = false; - mode_lib->ms.TotalNumberOfActiveDPP = mode_lib->ms.TotalNumberOfActiveDPP + s->NumberOfDPPDSC; - } - dml2_printf("DML::%s: k=%d RequiresDSC = %d\n", __func__, k, mode_lib->ms.RequiresDSC[k]); - dml2_printf("DML::%s: k=%d ODMMode = %d\n", __func__, k, mode_lib->ms.ODMMode[k]); - } - - // FIXME_DCN4 - add odm vs mpc use check - - // FIXME_DCN4 - add imall cap check - mode_lib->ms.support.incorrect_imall_usage = 0; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - if (mode_lib->ip.imall_supported && display_cfg->plane_descriptors[k].overrides.legacy_svp_config == dml2_svp_mode_override_imall) - mode_lib->ms.support.incorrect_imall_usage = 1; - } - - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - mode_lib->ms.MPCCombine[k] = false; - mode_lib->ms.NoOfDPP[k] = 1; - - if (mode_lib->ms.ODMMode[k] == dml2_odm_mode_combine_4to1) { - mode_lib->ms.MPCCombine[k] = false; - mode_lib->ms.NoOfDPP[k] = 4; - } else if (mode_lib->ms.ODMMode[k] == dml2_odm_mode_combine_3to1) { - mode_lib->ms.MPCCombine[k] = false; - mode_lib->ms.NoOfDPP[k] = 3; - } else if (mode_lib->ms.ODMMode[k] == dml2_odm_mode_combine_2to1) { - mode_lib->ms.MPCCombine[k] = false; - mode_lib->ms.NoOfDPP[k] = 2; - } else if (display_cfg->plane_descriptors[k].overrides.mpcc_combine_factor == 2) { - mode_lib->ms.MPCCombine[k] = true; - mode_lib->ms.NoOfDPP[k] = 2; - mode_lib->ms.TotalNumberOfActiveDPP++; - } else if (display_cfg->plane_descriptors[k].overrides.mpcc_combine_factor == 1) { - mode_lib->ms.MPCCombine[k] = false; - mode_lib->ms.NoOfDPP[k] = 1; - if (!mode_lib->ms.SingleDPPViewportSizeSupportPerSurface[k]) { - dml2_printf("ERROR: DML::%s: MPCC is override to disable but viewport is too large to be supported with single pipe!\n", __func__); - } - } else { - if ((mode_lib->ms.MinDPPCLKUsingSingleDPP[k] > mode_lib->ms.max_dppclk_freq_mhz) || !mode_lib->ms.SingleDPPViewportSizeSupportPerSurface[k]) { - mode_lib->ms.MPCCombine[k] = true; - mode_lib->ms.NoOfDPP[k] = 2; - mode_lib->ms.TotalNumberOfActiveDPP++; - } - } -#if defined(__DML_VBA_DEBUG__) - dml2_printf("DML::%s: k=%d, NoOfDPP = %d\n", __func__, k, mode_lib->ms.NoOfDPP[k]); -#endif - } - - if (mode_lib->ms.TotalNumberOfActiveDPP > (unsigned int)mode_lib->ip.max_num_dpp) - mode_lib->ms.support.TotalAvailablePipesSupport = false; - - - mode_lib->ms.TotalNumberOfSingleDPPSurfaces = 0; - for (k = 0; k < (unsigned int)mode_lib->ms.num_active_planes; ++k) { - if (mode_lib->ms.NoOfDPP[k] == 1) - mode_lib->ms.TotalNumberOfSingleDPPSurfaces = mode_lib->ms.TotalNumberOfSingleDPPSurfaces + 1; - } - - //DISPCLK/DPPCLK - mode_lib->ms.WritebackRequiredDISPCLK = 0; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.enable) { - mode_lib->ms.WritebackRequiredDISPCLK = math_max2(mode_lib->ms.WritebackRequiredDISPCLK, - CalculateWriteBackDISPCLK(display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.pixel_format, - ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000), - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.h_ratio, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.v_ratio, - 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].timing.h_total, - mode_lib->ip.writeback_line_buffer_buffer_size)); - } - } - - mode_lib->ms.RequiredDISPCLK = mode_lib->ms.WritebackRequiredDISPCLK; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - mode_lib->ms.RequiredDISPCLK = math_max2(mode_lib->ms.RequiredDISPCLK, mode_lib->ms.RequiredDISPCLKPerSurface[k]); - } - - mode_lib->ms.GlobalDPPCLK = 0; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - mode_lib->ms.RequiredDPPCLK[k] = mode_lib->ms.MinDPPCLKUsingSingleDPP[k] / mode_lib->ms.NoOfDPP[k]; - mode_lib->ms.GlobalDPPCLK = math_max2(mode_lib->ms.GlobalDPPCLK, mode_lib->ms.RequiredDPPCLK[k]); - } - - mode_lib->ms.support.DISPCLK_DPPCLK_Support = !((mode_lib->ms.RequiredDISPCLK > mode_lib->ms.max_dispclk_freq_mhz) || (mode_lib->ms.GlobalDPPCLK > mode_lib->ms.max_dppclk_freq_mhz)); - } - - /* Total Available OTG, HDMIFRL, DP Support Check */ - s->TotalNumberOfActiveOTG = 0; - s->TotalNumberOfActiveHDMIFRL = 0; - s->TotalNumberOfActiveDP2p0 = 0; - s->TotalNumberOfActiveDP2p0Outputs = 0; - - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - if (display_cfg->plane_descriptors[k].stream_index == k) { - s->TotalNumberOfActiveOTG = s->TotalNumberOfActiveOTG + 1; - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_hdmifrl) - s->TotalNumberOfActiveHDMIFRL = s->TotalNumberOfActiveHDMIFRL + 1; - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_dp2p0) { - s->TotalNumberOfActiveDP2p0 = s->TotalNumberOfActiveDP2p0 + 1; - // FIXME_STAGE2: SW not using backend related stuff, need mapping for mst setup - //if (display_cfg->output.OutputMultistreamId[k] == k || display_cfg->output.OutputMultistreamEn[k] == false) { - s->TotalNumberOfActiveDP2p0Outputs = s->TotalNumberOfActiveDP2p0Outputs + 1; - //} - } - } - } - - mode_lib->ms.support.NumberOfOTGSupport = (s->TotalNumberOfActiveOTG <= (unsigned int)mode_lib->ip.max_num_otg); - mode_lib->ms.support.NumberOfHDMIFRLSupport = (s->TotalNumberOfActiveHDMIFRL <= (unsigned int)mode_lib->ip.max_num_hdmi_frl_outputs); - mode_lib->ms.support.NumberOfDP2p0Support = (s->TotalNumberOfActiveDP2p0 <= (unsigned int)mode_lib->ip.max_num_dp2p0_streams && s->TotalNumberOfActiveDP2p0Outputs <= (unsigned int)mode_lib->ip.max_num_dp2p0_outputs); - - mode_lib->ms.support.ExceededMultistreamSlots = false; - mode_lib->ms.support.LinkCapacitySupport = true; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_disabled == false && - display_cfg->plane_descriptors[k].stream_index == k && (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_dp || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_dp2p0 || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_edp || - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_hdmi || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_hdmifrl) && mode_lib->ms.OutputBpp[k] == 0) { - mode_lib->ms.support.LinkCapacitySupport = false; - } - } - - mode_lib->ms.support.P2IWith420 = false; - mode_lib->ms.support.DSCOnlyIfNecessaryWithBPP = false; - mode_lib->ms.support.DSC422NativeNotSupported = false; - mode_lib->ms.support.LinkRateDoesNotMatchDPVersion = false; - mode_lib->ms.support.LinkRateForMultistreamNotIndicated = false; - mode_lib->ms.support.BPPForMultistreamNotIndicated = false; - mode_lib->ms.support.MultistreamWithHDMIOreDP = false; - mode_lib->ms.support.MSOOrODMSplitWithNonDPLink = false; - mode_lib->ms.support.NotEnoughLanesForMSO = false; - - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - if (display_cfg->plane_descriptors[k].stream_index == k && (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_dp || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_dp2p0 || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_edp || - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_hdmi || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_hdmifrl)) { - 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; - - if (((display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_dp_link_rate == dml2_dp_rate_hbr || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_dp_link_rate == dml2_dp_rate_hbr2 || - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_dp_link_rate == dml2_dp_rate_hbr3) && - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder != dml2_dp && display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder != dml2_edp) || - ((display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_dp_link_rate == dml2_dp_rate_uhbr10 || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_dp_link_rate == dml2_dp_rate_uhbr13p5 || - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_dp_link_rate == dml2_dp_rate_uhbr20) && - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder != dml2_dp2p0)) - mode_lib->ms.support.LinkRateDoesNotMatchDPVersion = true; - - // FIXME_STAGE2 - //if (display_cfg->output.OutputMultistreamEn[k] == 1) { - // if (display_cfg->output.OutputMultistreamId[k] == k && display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_dp_link_rate == dml2_dp_rate_na) - // mode_lib->ms.support.LinkRateForMultistreamNotIndicated = true; - // if (display_cfg->output.OutputMultistreamId[k] == k && s->OutputBpp[k] == 0) - // mode_lib->ms.support.BPPForMultistreamNotIndicated = true; - // for (n = 0; n < mode_lib->ms.num_active_planes; ++n) { - // if (display_cfg->output.OutputMultistreamId[k] == n && s->OutputBpp[k] == 0) - // mode_lib->ms.support.BPPForMultistreamNotIndicated = true; - // } - //} - - if ((display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_edp || - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_hdmi || - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_hdmifrl)) { - // FIXME_STAGE2 - //if (display_cfg->output.OutputMultistreamEn[k] == 1 && display_cfg->output.OutputMultistreamId[k] == k) - // mode_lib->ms.support.MultistreamWithHDMIOreDP = true; - //for (n = 0; n < mode_lib->ms.num_active_planes; ++n) { - // if (display_cfg->output.OutputMultistreamEn[k] == 1 && display_cfg->output.OutputMultistreamId[k] == n) - // mode_lib->ms.support.MultistreamWithHDMIOreDP = true; - //} - } - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder != dml2_dp && (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].overrides.odm_mode == dml2_odm_mode_split_1to2 || - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].overrides.odm_mode == dml2_odm_mode_mso_1to2 || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].overrides.odm_mode == dml2_odm_mode_mso_1to4)) - mode_lib->ms.support.MSOOrODMSplitWithNonDPLink = true; - - if ((display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].overrides.odm_mode == dml2_odm_mode_mso_1to2 && display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_dp_lane_count < 2) || - (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].overrides.odm_mode == dml2_odm_mode_mso_1to4 && display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_dp_lane_count < 4)) - mode_lib->ms.support.NotEnoughLanesForMSO = true; - } - } - - mode_lib->ms.support.DTBCLKRequiredMoreThanSupported = false; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - if (display_cfg->plane_descriptors[k].stream_index == k && - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_hdmifrl && - RequiredDTBCLK( - mode_lib->ms.RequiresDSC[k], - s->PixelClockBackEnd[k], - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format, - mode_lib->ms.OutputBpp[k], - mode_lib->ms.support.NumberOfDSCSlices[k], - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total, - 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].output.audio_sample_rate, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.audio_sample_layout) > ((double)mode_lib->soc.clk_table.dtbclk.clk_values_khz[0] / 1000)) { - mode_lib->ms.support.DTBCLKRequiredMoreThanSupported = true; - } - } - - mode_lib->ms.support.DSCCLKRequiredMoreThanSupported = false; - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - if (display_cfg->plane_descriptors[k].stream_index == k) { - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_dp || - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_dp2p0 || - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_edp || - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_hdmifrl) { - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format == dml2_420) { - s->DSCFormatFactor = 2; - } else if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format == dml2_444) { - s->DSCFormatFactor = 1; - } else if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format == dml2_n422 || display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_hdmifrl) { - s->DSCFormatFactor = 2; - } else { - s->DSCFormatFactor = 1; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, RequiresDSC = %u\n", __func__, k, mode_lib->ms.RequiresDSC[k]); -#endif - if (mode_lib->ms.RequiresDSC[k] == true) { - s->PixelClockBackEndFactor = 3.0; - - if (mode_lib->ms.ODMMode[k] == dml2_odm_mode_combine_4to1) - s->PixelClockBackEndFactor = 12.0; - else if (mode_lib->ms.ODMMode[k] == dml2_odm_mode_combine_3to1) - s->PixelClockBackEndFactor = 9.0; - else if (mode_lib->ms.ODMMode[k] == dml2_odm_mode_combine_2to1) - s->PixelClockBackEndFactor = 6.0; - - mode_lib->ms.required_dscclk_freq_mhz[k] = s->PixelClockBackEnd[k] / s->PixelClockBackEndFactor / (double)s->DSCFormatFactor; - if (mode_lib->ms.required_dscclk_freq_mhz[k] > mode_lib->ms.max_dscclk_freq_mhz) { - mode_lib->ms.support.DSCCLKRequiredMoreThanSupported = true; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, PixelClockBackEnd = %f\n", __func__, k, s->PixelClockBackEnd[k]); - dml2_printf("DML::%s: k=%u, required_dscclk_freq_mhz = %f\n", __func__, k, mode_lib->ms.required_dscclk_freq_mhz[k]); - dml2_printf("DML::%s: k=%u, DSCFormatFactor = %u\n", __func__, k, s->DSCFormatFactor); - dml2_printf("DML::%s: k=%u, DSCCLKRequiredMoreThanSupported = %u\n", __func__, k, mode_lib->ms.support.DSCCLKRequiredMoreThanSupported); -#endif - } - } - } - } - - /* Check DSC Unit and Slices Support */ - mode_lib->ms.support.NotEnoughDSCSlices = false; - s->TotalDSCUnitsRequired = 0; - mode_lib->ms.support.PixelsPerLinePerDSCUnitSupport = true; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - if (mode_lib->ms.RequiresDSC[k] == true) { - s->NumDSCUnitRequired = 1; - - if (mode_lib->ms.ODMMode[k] == dml2_odm_mode_combine_4to1) - s->NumDSCUnitRequired = 4; - else if (mode_lib->ms.ODMMode[k] == dml2_odm_mode_combine_3to1) - s->NumDSCUnitRequired = 3; - else if (mode_lib->ms.ODMMode[k] == dml2_odm_mode_combine_2to1) - s->NumDSCUnitRequired = 2; - - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_active > s->NumDSCUnitRequired * (unsigned int)mode_lib->ip.maximum_pixels_per_line_per_dsc_unit) - mode_lib->ms.support.PixelsPerLinePerDSCUnitSupport = false; - s->TotalDSCUnitsRequired = s->TotalDSCUnitsRequired + s->NumDSCUnitRequired; - if (mode_lib->ms.support.NumberOfDSCSlices[k] > 4 * s->NumDSCUnitRequired) - mode_lib->ms.support.NotEnoughDSCSlices = true; - } - } - - mode_lib->ms.support.NotEnoughDSCUnits = false; - if (s->TotalDSCUnitsRequired > (unsigned int)mode_lib->ip.num_dsc) { - mode_lib->ms.support.NotEnoughDSCUnits = true; - } - - /*DSC Delay per state*/ - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - 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], - 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], - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder, - ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000), - s->PixelClockBackEnd[k]); - } - - for (k = 0; k < mode_lib->ms.num_active_planes; k++) { - for (m = 0; m < mode_lib->ms.num_active_planes; m++) { - if (display_cfg->plane_descriptors[k].stream_index == m && mode_lib->ms.RequiresDSC[m] == true) { - mode_lib->ms.DSCDelay[k] = mode_lib->ms.DSCDelay[m]; - } - } - } - - // Figure out the swath and DET configuration after the num dpp per plane is figured out - CalculateSwathAndDETConfiguration_params->ForceSingleDPP = false; - CalculateSwathAndDETConfiguration_params->ODMMode = mode_lib->ms.ODMMode; - CalculateSwathAndDETConfiguration_params->DPPPerSurface = mode_lib->ms.NoOfDPP; - - // output - CalculateSwathAndDETConfiguration_params->req_per_swath_ub_l = s->dummy_integer_array[0]; - CalculateSwathAndDETConfiguration_params->req_per_swath_ub_c = s->dummy_integer_array[1]; - CalculateSwathAndDETConfiguration_params->swath_width_luma_ub = mode_lib->ms.swath_width_luma_ub; - CalculateSwathAndDETConfiguration_params->swath_width_chroma_ub = mode_lib->ms.swath_width_chroma_ub; - CalculateSwathAndDETConfiguration_params->SwathWidth = mode_lib->ms.SwathWidthY; - CalculateSwathAndDETConfiguration_params->SwathWidthChroma = mode_lib->ms.SwathWidthC; - CalculateSwathAndDETConfiguration_params->SwathHeightY = mode_lib->ms.SwathHeightY; - CalculateSwathAndDETConfiguration_params->SwathHeightC = mode_lib->ms.SwathHeightC; - CalculateSwathAndDETConfiguration_params->request_size_bytes_luma = mode_lib->ms.support.request_size_bytes_luma; - CalculateSwathAndDETConfiguration_params->request_size_bytes_chroma = mode_lib->ms.support.request_size_bytes_chroma; - CalculateSwathAndDETConfiguration_params->DETBufferSizeInKByte = mode_lib->ms.DETBufferSizeInKByte; // FIXME: This is per pipe but the pipes in plane will use that - CalculateSwathAndDETConfiguration_params->DETBufferSizeY = mode_lib->ms.DETBufferSizeY; - CalculateSwathAndDETConfiguration_params->DETBufferSizeC = mode_lib->ms.DETBufferSizeC; - CalculateSwathAndDETConfiguration_params->UnboundedRequestEnabled = &mode_lib->ms.UnboundedRequestEnabled; - CalculateSwathAndDETConfiguration_params->compbuf_reserved_space_64b = s->dummy_integer_array[3]; - CalculateSwathAndDETConfiguration_params->hw_debug5 = s->dummy_boolean_array[1]; - CalculateSwathAndDETConfiguration_params->CompressedBufferSizeInkByte = &mode_lib->ms.CompressedBufferSizeInkByte; - CalculateSwathAndDETConfiguration_params->ViewportSizeSupportPerSurface = s->dummy_boolean_array[0]; - CalculateSwathAndDETConfiguration_params->ViewportSizeSupport = &mode_lib->ms.support.ViewportSizeSupport; - CalculateSwathAndDETConfiguration_params->funcs = &mode_lib->funcs; - - CalculateSwathAndDETConfiguration(&mode_lib->scratch, CalculateSwathAndDETConfiguration_params); - - if (mode_lib->soc.mall_allocated_for_dcn_mbytes == 0) { - for (k = 0; k < mode_lib->ms.num_active_planes; k++) - mode_lib->ms.SurfaceSizeInMALL[k] = 0; - mode_lib->ms.support.ExceededMALLSize = 0; - } else { - CalculateSurfaceSizeInMall( - display_cfg, - mode_lib->ms.num_active_planes, - mode_lib->soc.mall_allocated_for_dcn_mbytes, - - mode_lib->ms.BytePerPixelY, - mode_lib->ms.BytePerPixelC, - mode_lib->ms.Read256BlockWidthY, - mode_lib->ms.Read256BlockWidthC, - mode_lib->ms.Read256BlockHeightY, - mode_lib->ms.Read256BlockHeightC, - mode_lib->ms.MacroTileWidthY, - mode_lib->ms.MacroTileWidthC, - mode_lib->ms.MacroTileHeightY, - mode_lib->ms.MacroTileHeightC, - - /* Output */ - mode_lib->ms.SurfaceSizeInMALL, - &mode_lib->ms.support.ExceededMALLSize); - } - - mode_lib->ms.TotalNumberOfDCCActiveDPP = 0; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - if (display_cfg->plane_descriptors[k].surface.dcc.enable == true) { - mode_lib->ms.TotalNumberOfDCCActiveDPP = mode_lib->ms.TotalNumberOfDCCActiveDPP + mode_lib->ms.NoOfDPP[k]; - } - } - - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - s->SurfParameters[k].PixelClock = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000); - s->SurfParameters[k].DPPPerSurface = mode_lib->ms.NoOfDPP[k]; - s->SurfParameters[k].RotationAngle = display_cfg->plane_descriptors[k].composition.rotation_angle; - s->SurfParameters[k].ViewportHeight = display_cfg->plane_descriptors[k].composition.viewport.plane0.height; - s->SurfParameters[k].ViewportHeightC = display_cfg->plane_descriptors[k].composition.viewport.plane1.height; - s->SurfParameters[k].BlockWidth256BytesY = mode_lib->ms.Read256BlockWidthY[k]; - s->SurfParameters[k].BlockHeight256BytesY = mode_lib->ms.Read256BlockHeightY[k]; - s->SurfParameters[k].BlockWidth256BytesC = mode_lib->ms.Read256BlockWidthC[k]; - s->SurfParameters[k].BlockHeight256BytesC = mode_lib->ms.Read256BlockHeightC[k]; - s->SurfParameters[k].BlockWidthY = mode_lib->ms.MacroTileWidthY[k]; - s->SurfParameters[k].BlockHeightY = mode_lib->ms.MacroTileHeightY[k]; - s->SurfParameters[k].BlockWidthC = mode_lib->ms.MacroTileWidthC[k]; - s->SurfParameters[k].BlockHeightC = mode_lib->ms.MacroTileHeightC[k]; - s->SurfParameters[k].InterlaceEnable = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced; - s->SurfParameters[k].HTotal = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total; - s->SurfParameters[k].DCCEnable = display_cfg->plane_descriptors[k].surface.dcc.enable; - s->SurfParameters[k].SourcePixelFormat = display_cfg->plane_descriptors[k].pixel_format; - s->SurfParameters[k].SurfaceTiling = display_cfg->plane_descriptors[k].surface.tiling; - s->SurfParameters[k].BytePerPixelY = mode_lib->ms.BytePerPixelY[k]; - s->SurfParameters[k].BytePerPixelC = mode_lib->ms.BytePerPixelC[k]; - s->SurfParameters[k].ProgressiveToInterlaceUnitInOPP = mode_lib->ip.ptoi_supported; - s->SurfParameters[k].VRatio = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio; - s->SurfParameters[k].VRatioChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio; - s->SurfParameters[k].VTaps = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps; - s->SurfParameters[k].VTapsChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps; - s->SurfParameters[k].PitchY = display_cfg->plane_descriptors[k].surface.plane0.pitch; - s->SurfParameters[k].PitchC = display_cfg->plane_descriptors[k].surface.plane1.pitch; - s->SurfParameters[k].ViewportStationary = display_cfg->plane_descriptors[k].composition.viewport.stationary; - s->SurfParameters[k].ViewportXStart = display_cfg->plane_descriptors[k].composition.viewport.plane0.x_start; - s->SurfParameters[k].ViewportYStart = display_cfg->plane_descriptors[k].composition.viewport.plane0.y_start; - s->SurfParameters[k].ViewportXStartC = display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start; - s->SurfParameters[k].ViewportYStartC = display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start; - s->SurfParameters[k].FORCE_ONE_ROW_FOR_FRAME = display_cfg->plane_descriptors[k].overrides.hw.force_one_row_for_frame; - s->SurfParameters[k].SwathHeightY = mode_lib->ms.SwathHeightY[k]; - s->SurfParameters[k].SwathHeightC = mode_lib->ms.SwathHeightC[k]; - - s->SurfParameters[k].DCCMetaPitchY = display_cfg->plane_descriptors[k].surface.dcc.plane0.pitch; - s->SurfParameters[k].DCCMetaPitchC = display_cfg->plane_descriptors[k].surface.dcc.plane1.pitch; - } - - CalculateVMRowAndSwath_params->display_cfg = display_cfg; - CalculateVMRowAndSwath_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes; - CalculateVMRowAndSwath_params->myPipe = s->SurfParameters; - CalculateVMRowAndSwath_params->SurfaceSizeInMALL = mode_lib->ms.SurfaceSizeInMALL; - CalculateVMRowAndSwath_params->PTEBufferSizeInRequestsLuma = mode_lib->ip.dpte_buffer_size_in_pte_reqs_luma; - CalculateVMRowAndSwath_params->PTEBufferSizeInRequestsChroma = mode_lib->ip.dpte_buffer_size_in_pte_reqs_chroma; - CalculateVMRowAndSwath_params->MALLAllocatedForDCN = mode_lib->soc.mall_allocated_for_dcn_mbytes; - CalculateVMRowAndSwath_params->SwathWidthY = mode_lib->ms.SwathWidthY; - CalculateVMRowAndSwath_params->SwathWidthC = mode_lib->ms.SwathWidthC; - CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->soc.hostvm_min_page_size_kbytes; - CalculateVMRowAndSwath_params->DCCMetaBufferSizeBytes = mode_lib->ip.dcc_meta_buffer_size_bytes; - CalculateVMRowAndSwath_params->mrq_present = mode_lib->ip.dcn_mrq_present; - - // output - CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = mode_lib->ms.PTEBufferSizeNotExceeded; - CalculateVMRowAndSwath_params->dpte_row_width_luma_ub = s->dummy_integer_array[12]; - CalculateVMRowAndSwath_params->dpte_row_width_chroma_ub = s->dummy_integer_array[13]; - CalculateVMRowAndSwath_params->dpte_row_height_luma = mode_lib->ms.dpte_row_height; - CalculateVMRowAndSwath_params->dpte_row_height_chroma = mode_lib->ms.dpte_row_height_chroma; - CalculateVMRowAndSwath_params->dpte_row_height_linear_luma = s->dummy_integer_array[14]; // VBA_DELTA - CalculateVMRowAndSwath_params->dpte_row_height_linear_chroma = s->dummy_integer_array[15]; // VBA_DELTA - CalculateVMRowAndSwath_params->vm_group_bytes = s->dummy_integer_array[16]; - CalculateVMRowAndSwath_params->dpte_group_bytes = mode_lib->ms.dpte_group_bytes; - CalculateVMRowAndSwath_params->PixelPTEReqWidthY = s->dummy_integer_array[17]; - CalculateVMRowAndSwath_params->PixelPTEReqHeightY = s->dummy_integer_array[18]; - CalculateVMRowAndSwath_params->PTERequestSizeY = s->dummy_integer_array[19]; - CalculateVMRowAndSwath_params->PixelPTEReqWidthC = s->dummy_integer_array[20]; - CalculateVMRowAndSwath_params->PixelPTEReqHeightC = s->dummy_integer_array[21]; - CalculateVMRowAndSwath_params->PTERequestSizeC = s->dummy_integer_array[22]; - CalculateVMRowAndSwath_params->vmpg_width_y = s->vmpg_width_y; - CalculateVMRowAndSwath_params->vmpg_height_y = s->vmpg_height_y; - CalculateVMRowAndSwath_params->vmpg_width_c = s->vmpg_width_c; - CalculateVMRowAndSwath_params->vmpg_height_c = s->vmpg_height_c; - CalculateVMRowAndSwath_params->dpde0_bytes_per_frame_ub_l = s->dummy_integer_array[23]; - CalculateVMRowAndSwath_params->dpde0_bytes_per_frame_ub_c = s->dummy_integer_array[24]; - CalculateVMRowAndSwath_params->PrefetchSourceLinesY = mode_lib->ms.PrefetchLinesY; - CalculateVMRowAndSwath_params->PrefetchSourceLinesC = mode_lib->ms.PrefetchLinesC; - CalculateVMRowAndSwath_params->VInitPreFillY = mode_lib->ms.PrefillY; - CalculateVMRowAndSwath_params->VInitPreFillC = mode_lib->ms.PrefillC; - CalculateVMRowAndSwath_params->MaxNumSwathY = mode_lib->ms.MaxNumSwathY; - CalculateVMRowAndSwath_params->MaxNumSwathC = mode_lib->ms.MaxNumSwathC; - CalculateVMRowAndSwath_params->dpte_row_bw = mode_lib->ms.dpte_row_bw; - CalculateVMRowAndSwath_params->PixelPTEBytesPerRow = mode_lib->ms.DPTEBytesPerRow; - CalculateVMRowAndSwath_params->vm_bytes = mode_lib->ms.vm_bytes; - CalculateVMRowAndSwath_params->use_one_row_for_frame = mode_lib->ms.use_one_row_for_frame; - CalculateVMRowAndSwath_params->use_one_row_for_frame_flip = mode_lib->ms.use_one_row_for_frame_flip; - CalculateVMRowAndSwath_params->is_using_mall_for_ss = s->dummy_boolean_array[0]; - CalculateVMRowAndSwath_params->PTE_BUFFER_MODE = s->dummy_boolean_array[1]; - CalculateVMRowAndSwath_params->BIGK_FRAGMENT_SIZE = s->dummy_integer_array[25]; - CalculateVMRowAndSwath_params->DCCMetaBufferSizeNotExceeded = mode_lib->ms.DCCMetaBufferSizeNotExceeded; - CalculateVMRowAndSwath_params->meta_row_bw = mode_lib->ms.meta_row_bw; - CalculateVMRowAndSwath_params->meta_row_bytes = mode_lib->ms.meta_row_bytes; - CalculateVMRowAndSwath_params->meta_req_width_luma = s->dummy_integer_array[26]; - CalculateVMRowAndSwath_params->meta_req_height_luma = s->dummy_integer_array[27]; - CalculateVMRowAndSwath_params->meta_row_width_luma = s->dummy_integer_array[28]; - CalculateVMRowAndSwath_params->meta_row_height_luma = s->meta_row_height_luma; - CalculateVMRowAndSwath_params->meta_pte_bytes_per_frame_ub_l = s->dummy_integer_array[29]; - CalculateVMRowAndSwath_params->meta_req_width_chroma = s->dummy_integer_array[30]; - CalculateVMRowAndSwath_params->meta_req_height_chroma = s->dummy_integer_array[31]; - CalculateVMRowAndSwath_params->meta_row_width_chroma = s->dummy_integer_array[32]; - CalculateVMRowAndSwath_params->meta_row_height_chroma = s->meta_row_height_chroma; - CalculateVMRowAndSwath_params->meta_pte_bytes_per_frame_ub_c = s->dummy_integer_array[33]; - - CalculateVMRowAndSwath(&mode_lib->scratch, CalculateVMRowAndSwath_params); - - mode_lib->ms.support.PTEBufferSizeNotExceeded = true; - mode_lib->ms.support.DCCMetaBufferSizeNotExceeded = true; - - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - if (mode_lib->ms.PTEBufferSizeNotExceeded[k] == false) - mode_lib->ms.support.PTEBufferSizeNotExceeded = false; - - if (mode_lib->ms.DCCMetaBufferSizeNotExceeded[k] == false) - mode_lib->ms.support.DCCMetaBufferSizeNotExceeded = false; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, PTEBufferSizeNotExceeded = %u\n", __func__, k, mode_lib->ms.PTEBufferSizeNotExceeded[k]); - dml2_printf("DML::%s: k=%u, DCCMetaBufferSizeNotExceeded = %u\n", __func__, k, mode_lib->ms.DCCMetaBufferSizeNotExceeded[k]); -#endif - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: PTEBufferSizeNotExceeded = %u\n", __func__, mode_lib->ms.support.PTEBufferSizeNotExceeded); - dml2_printf("DML::%s: DCCMetaBufferSizeNotExceeded = %u\n", __func__, mode_lib->ms.support.DCCMetaBufferSizeNotExceeded); -#endif - - mode_lib->ms.UrgLatency = CalculateUrgentLatency( - 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.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.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.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); - 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]); - - bool cursor_not_enough_urgent_latency_hiding = 0; - 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); - mode_lib->ms.UrgentBurstFactorCursorPre[k] = mode_lib->ms.UrgentBurstFactorCursor[k]; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%d, Calling CalculateUrgentBurstFactor\n", __func__, k); - dml2_printf("DML::%s: k=%d, VRatio=%f\n", __func__, k, display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio); - dml2_printf("DML::%s: k=%d, VRatioChroma=%f\n", __func__, k, display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio); -#endif - - CalculateUrgentBurstFactor( - &display_cfg->plane_descriptors[k], - mode_lib->ms.swath_width_luma_ub[k], - mode_lib->ms.swath_width_chroma_ub[k], - mode_lib->ms.SwathHeightY[k], - mode_lib->ms.SwathHeightC[k], - line_time_us, - mode_lib->ms.UrgLatency, - display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio, - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio, - mode_lib->ms.BytePerPixelInDETY[k], - mode_lib->ms.BytePerPixelInDETC[k], - mode_lib->ms.DETBufferSizeY[k], - mode_lib->ms.DETBufferSizeC[k], - - // Output - &mode_lib->ms.UrgentBurstFactorLuma[k], - &mode_lib->ms.UrgentBurstFactorChroma[k], - &mode_lib->ms.NotEnoughUrgentLatencyHiding[k]); - - mode_lib->ms.NotEnoughUrgentLatencyHiding[k] = mode_lib->ms.NotEnoughUrgentLatencyHiding[k] || cursor_not_enough_urgent_latency_hiding; - } - - CalculateDCFCLKDeepSleep( - display_cfg, - mode_lib->ms.num_active_planes, - mode_lib->ms.BytePerPixelY, - mode_lib->ms.BytePerPixelC, - mode_lib->ms.SwathWidthY, - mode_lib->ms.SwathWidthC, - mode_lib->ms.NoOfDPP, - mode_lib->ms.PSCL_FACTOR, - mode_lib->ms.PSCL_FACTOR_CHROMA, - mode_lib->ms.RequiredDPPCLK, - mode_lib->ms.SurfaceReadBandwidthLuma, - mode_lib->ms.SurfaceReadBandwidthChroma, - mode_lib->soc.return_bus_width_bytes, - - /* Output */ - &mode_lib->ms.dcfclk_deepsleep); - - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - if (display_cfg->plane_descriptors[k].stream_index == k) { - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.enable == true) { - mode_lib->ms.WritebackDelayTime[k] = mode_lib->soc.qos_parameters.writeback.base_latency_us + CalculateWriteBackDelay( - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.pixel_format, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.h_ratio, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.v_ratio, - 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.output_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.input_height, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total) / mode_lib->ms.RequiredDISPCLK; - } else { - mode_lib->ms.WritebackDelayTime[k] = 0.0; - } - for (m = 0; m <= mode_lib->ms.num_active_planes - 1; m++) { - if (display_cfg->plane_descriptors[m].stream_index == k && display_cfg->stream_descriptors[display_cfg->plane_descriptors[m].stream_index].writeback.enable == true) { - mode_lib->ms.WritebackDelayTime[k] = math_max2(mode_lib->ms.WritebackDelayTime[k], - mode_lib->soc.qos_parameters.writeback.base_latency_us + CalculateWriteBackDelay( - display_cfg->stream_descriptors[display_cfg->plane_descriptors[m].stream_index].writeback.pixel_format, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[m].stream_index].writeback.scaling_info.h_ratio, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[m].stream_index].writeback.scaling_info.v_ratio, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[m].stream_index].writeback.scaling_info.v_taps, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[m].stream_index].writeback.scaling_info.output_width, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[m].stream_index].writeback.scaling_info.output_height, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[m].stream_index].writeback.scaling_info.input_height, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[m].stream_index].timing.h_total) / mode_lib->ms.RequiredDISPCLK); - } - } - } - } - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - for (m = 0; m <= mode_lib->ms.num_active_planes - 1; m++) { - if (display_cfg->plane_descriptors[k].stream_index == m) { - mode_lib->ms.WritebackDelayTime[k] = mode_lib->ms.WritebackDelayTime[m]; - } - } - } - - // MaximumVStartup is actually Tvstartup_min in DCN4 programming guide - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - bool isInterlaceTiming = (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced && !mode_lib->ip.ptoi_supported); - s->MaximumVStartup[k] = CalculateMaxVStartup( - mode_lib->ip.ptoi_supported, - mode_lib->ip.vblank_nom_default_us, - &display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing, - mode_lib->ms.WritebackDelayTime[k]); - mode_lib->ms.MaxVStartupLines[k] = (isInterlaceTiming ? (2 * s->MaximumVStartup[k]) : s->MaximumVStartup[k]); - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, MaximumVStartup = %u\n", __func__, k, s->MaximumVStartup[k]); -#endif - - /* Immediate Flip and MALL parameters */ - s->ImmediateFlipRequired = false; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - s->ImmediateFlipRequired = s->ImmediateFlipRequired || display_cfg->plane_descriptors[k].immediate_flip; - } - - mode_lib->ms.support.ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe = false; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - mode_lib->ms.support.ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe = - mode_lib->ms.support.ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe || - ((display_cfg->hostvm_enable == true || display_cfg->plane_descriptors[k].immediate_flip == true) && - (display_cfg->plane_descriptors[k].overrides.uclk_pstate_change_strategy == dml2_uclk_pstate_change_strategy_force_mall_full_frame || dml_is_phantom_pipe(&display_cfg->plane_descriptors[k]))); - } - - mode_lib->ms.support.InvalidCombinationOfMALLUseForPStateAndStaticScreen = false; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - mode_lib->ms.support.InvalidCombinationOfMALLUseForPStateAndStaticScreen = mode_lib->ms.support.InvalidCombinationOfMALLUseForPStateAndStaticScreen || - ((display_cfg->plane_descriptors[k].overrides.refresh_from_mall == dml2_refresh_from_mall_mode_override_force_enable || display_cfg->plane_descriptors[k].overrides.refresh_from_mall == dml2_refresh_from_mall_mode_override_auto) && (dml_is_phantom_pipe(&display_cfg->plane_descriptors[k]))) || - ((display_cfg->plane_descriptors[k].overrides.refresh_from_mall == dml2_refresh_from_mall_mode_override_force_disable || display_cfg->plane_descriptors[k].overrides.refresh_from_mall == dml2_refresh_from_mall_mode_override_auto) && (display_cfg->plane_descriptors[k].overrides.uclk_pstate_change_strategy == dml2_uclk_pstate_change_strategy_force_mall_full_frame)); - } - - s->FullFrameMALLPStateMethod = false; - s->SubViewportMALLPStateMethod = false; - s->PhantomPipeMALLPStateMethod = false; - s->SubViewportMALLRefreshGreaterThan120Hz = false; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - if (display_cfg->plane_descriptors[k].overrides.uclk_pstate_change_strategy == dml2_uclk_pstate_change_strategy_force_mall_full_frame) - s->FullFrameMALLPStateMethod = true; - if (display_cfg->plane_descriptors[k].overrides.legacy_svp_config == dml2_svp_mode_override_main_pipe) { - s->SubViewportMALLPStateMethod = true; - if (!display_cfg->overrides.enable_subvp_implicit_pmo) { - // For dv, small frame tests will have very high refresh rate - unsigned long long refresh_rate = (unsigned long long) ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz * 1000 / - (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.v_total); - if (refresh_rate > 120) - s->SubViewportMALLRefreshGreaterThan120Hz = true; - } - } - if (dml_is_phantom_pipe(&display_cfg->plane_descriptors[k])) - s->PhantomPipeMALLPStateMethod = true; - } - mode_lib->ms.support.InvalidCombinationOfMALLUseForPState = (s->SubViewportMALLPStateMethod != s->PhantomPipeMALLPStateMethod) || - (s->SubViewportMALLPStateMethod && s->FullFrameMALLPStateMethod) || s->SubViewportMALLRefreshGreaterThan120Hz; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: SubViewportMALLPStateMethod = %u\n", __func__, s->SubViewportMALLPStateMethod); - dml2_printf("DML::%s: PhantomPipeMALLPStateMethod = %u\n", __func__, s->PhantomPipeMALLPStateMethod); - dml2_printf("DML::%s: FullFrameMALLPStateMethod = %u\n", __func__, s->FullFrameMALLPStateMethod); - dml2_printf("DML::%s: SubViewportMALLRefreshGreaterThan120Hz = %u\n", __func__, s->SubViewportMALLRefreshGreaterThan120Hz); - dml2_printf("DML::%s: InvalidCombinationOfMALLUseForPState = %u\n", __func__, mode_lib->ms.support.InvalidCombinationOfMALLUseForPState); - dml2_printf("DML::%s: in_out_params->min_clk_index = %u\n", __func__, in_out_params->min_clk_index); - dml2_printf("DML::%s: mode_lib->ms.DCFCLK = %f\n", __func__, mode_lib->ms.DCFCLK); - dml2_printf("DML::%s: mode_lib->ms.FabricClock = %f\n", __func__, mode_lib->ms.FabricClock); - dml2_printf("DML::%s: mode_lib->ms.uclk_freq_mhz = %f\n", __func__, mode_lib->ms.uclk_freq_mhz); - dml2_printf("DML::%s: max_urgent_latency_us = %f\n", __func__, mode_lib->ms.support.max_urgent_latency_us); - dml2_printf("DML::%s: urgent latency tolerance = %f\n", __func__, ((mode_lib->ip.rob_buffer_size_kbytes - mode_lib->ip.pixel_chunk_size_kbytes) * 1024 / (mode_lib->ms.DCFCLK * mode_lib->soc.return_bus_width_bytes))); -#endif - - mode_lib->ms.support.OutstandingRequestsSupport = true; - mode_lib->ms.support.OutstandingRequestsUrgencyAvoidance = true; - - mode_lib->ms.support.avg_urgent_latency_us - = (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.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_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)); - - if (outstanding_latency_us < mode_lib->ms.support.avg_urgent_latency_us) { - mode_lib->ms.support.OutstandingRequestsSupport = false; - } - - if (outstanding_latency_us < mode_lib->ms.support.avg_non_urgent_latency_us) { - mode_lib->ms.support.OutstandingRequestsUrgencyAvoidance = false; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: avg_urgent_latency_us = %f\n", __func__, mode_lib->ms.support.avg_urgent_latency_us); - dml2_printf("DML::%s: avg_non_urgent_latency_us = %f\n", __func__, mode_lib->ms.support.avg_non_urgent_latency_us); - dml2_printf("DML::%s: k=%d, request_size_bytes_luma = %d\n", __func__, k, mode_lib->ms.support.request_size_bytes_luma[k]); - dml2_printf("DML::%s: k=%d, outstanding_latency_us = %f (luma)\n", __func__, k, outstanding_latency_us); -#endif - } - - 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)); - - if (outstanding_latency_us < mode_lib->ms.support.avg_urgent_latency_us) { - mode_lib->ms.support.OutstandingRequestsSupport = false; - } - - if (outstanding_latency_us < mode_lib->ms.support.avg_non_urgent_latency_us) { - mode_lib->ms.support.OutstandingRequestsUrgencyAvoidance = false; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%d, request_size_bytes_chroma = %d\n", __func__, k, mode_lib->ms.support.request_size_bytes_chroma[k]); - dml2_printf("DML::%s: k=%d, outstanding_latency_us = %f (chroma)\n", __func__, k, outstanding_latency_us); -#endif - } - } - - memset(calculate_mcache_setting_params, 0, sizeof(struct dml2_core_calcs_calculate_mcache_setting_params)); - if (mode_lib->soc.mall_allocated_for_dcn_mbytes == 0 || mode_lib->ip.dcn_mrq_present) { - for (k = 0; k < mode_lib->ms.num_active_planes; k++) { - mode_lib->ms.mall_prefetch_sdp_overhead_factor[k] = 1.0; - mode_lib->ms.mall_prefetch_dram_overhead_factor[k] = 1.0; - mode_lib->ms.dcc_dram_bw_nom_overhead_factor_p0[k] = 1.0; - mode_lib->ms.dcc_dram_bw_pref_overhead_factor_p0[k] = 1.0; - mode_lib->ms.dcc_dram_bw_nom_overhead_factor_p1[k] = 1.0; - mode_lib->ms.dcc_dram_bw_pref_overhead_factor_p1[k] = 1.0; - } - } else { - for (k = 0; k < mode_lib->ms.num_active_planes; k++) { - calculate_mcache_setting_params->dcc_enable = display_cfg->plane_descriptors[k].surface.dcc.enable; - calculate_mcache_setting_params->num_chans = mode_lib->soc.clk_table.dram_config.channel_count; - calculate_mcache_setting_params->mem_word_bytes = mode_lib->soc.mem_word_bytes; - calculate_mcache_setting_params->mcache_size_bytes = mode_lib->soc.mcache_size_bytes; - calculate_mcache_setting_params->mcache_line_size_bytes = mode_lib->soc.mcache_line_size_bytes; - calculate_mcache_setting_params->gpuvm_enable = display_cfg->gpuvm_enable; - calculate_mcache_setting_params->gpuvm_page_size_kbytes = display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes; - - calculate_mcache_setting_params->source_format = display_cfg->plane_descriptors[k].pixel_format; - calculate_mcache_setting_params->surf_vert = dml_is_vertical_rotation(display_cfg->plane_descriptors[k].composition.rotation_angle); - calculate_mcache_setting_params->vp_stationary = display_cfg->plane_descriptors[k].composition.viewport.stationary; - calculate_mcache_setting_params->tiling_mode = display_cfg->plane_descriptors[k].surface.tiling; - calculate_mcache_setting_params->imall_enable = mode_lib->ip.imall_supported && display_cfg->plane_descriptors[k].overrides.legacy_svp_config == dml2_svp_mode_override_imall; - - calculate_mcache_setting_params->vp_start_x_l = display_cfg->plane_descriptors[k].composition.viewport.plane0.x_start; - calculate_mcache_setting_params->vp_start_y_l = display_cfg->plane_descriptors[k].composition.viewport.plane0.y_start; - calculate_mcache_setting_params->full_vp_width_l = display_cfg->plane_descriptors[k].composition.viewport.plane0.width; - calculate_mcache_setting_params->full_vp_height_l = display_cfg->plane_descriptors[k].composition.viewport.plane0.height; - calculate_mcache_setting_params->blk_width_l = mode_lib->ms.MacroTileWidthY[k]; - calculate_mcache_setting_params->blk_height_l = mode_lib->ms.MacroTileHeightY[k]; - calculate_mcache_setting_params->vmpg_width_l = s->vmpg_width_y[k]; - calculate_mcache_setting_params->vmpg_height_l = s->vmpg_height_y[k]; - calculate_mcache_setting_params->full_swath_bytes_l = s->full_swath_bytes_l[k]; - calculate_mcache_setting_params->bytes_per_pixel_l = mode_lib->ms.BytePerPixelY[k]; - - calculate_mcache_setting_params->vp_start_x_c = display_cfg->plane_descriptors[k].composition.viewport.plane1.x_start; - calculate_mcache_setting_params->vp_start_y_c = display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start; - calculate_mcache_setting_params->full_vp_width_c = display_cfg->plane_descriptors[k].composition.viewport.plane1.width; - calculate_mcache_setting_params->full_vp_height_c = display_cfg->plane_descriptors[k].composition.viewport.plane1.height; - calculate_mcache_setting_params->blk_width_c = mode_lib->ms.MacroTileWidthC[k]; - calculate_mcache_setting_params->blk_height_c = mode_lib->ms.MacroTileHeightC[k]; - calculate_mcache_setting_params->vmpg_width_c = s->vmpg_width_c[k]; - calculate_mcache_setting_params->vmpg_height_c = s->vmpg_height_c[k]; - calculate_mcache_setting_params->full_swath_bytes_c = s->full_swath_bytes_c[k]; - calculate_mcache_setting_params->bytes_per_pixel_c = mode_lib->ms.BytePerPixelC[k]; - - // output - calculate_mcache_setting_params->dcc_dram_bw_nom_overhead_factor_l = &mode_lib->ms.dcc_dram_bw_nom_overhead_factor_p0[k]; - calculate_mcache_setting_params->dcc_dram_bw_pref_overhead_factor_l = &mode_lib->ms.dcc_dram_bw_pref_overhead_factor_p0[k]; - calculate_mcache_setting_params->dcc_dram_bw_nom_overhead_factor_c = &mode_lib->ms.dcc_dram_bw_nom_overhead_factor_p1[k]; - calculate_mcache_setting_params->dcc_dram_bw_pref_overhead_factor_c = &mode_lib->ms.dcc_dram_bw_pref_overhead_factor_p1[k]; - - calculate_mcache_setting_params->num_mcaches_l = &mode_lib->ms.num_mcaches_l[k]; - calculate_mcache_setting_params->mcache_row_bytes_l = &mode_lib->ms.mcache_row_bytes_l[k]; - calculate_mcache_setting_params->mcache_offsets_l = mode_lib->ms.mcache_offsets_l[k]; - calculate_mcache_setting_params->mcache_shift_granularity_l = &mode_lib->ms.mcache_shift_granularity_l[k]; - - calculate_mcache_setting_params->num_mcaches_c = &mode_lib->ms.num_mcaches_c[k]; - calculate_mcache_setting_params->mcache_row_bytes_c = &mode_lib->ms.mcache_row_bytes_c[k]; - calculate_mcache_setting_params->mcache_offsets_c = mode_lib->ms.mcache_offsets_c[k]; - calculate_mcache_setting_params->mcache_shift_granularity_c = &mode_lib->ms.mcache_shift_granularity_c[k]; - - calculate_mcache_setting_params->mall_comb_mcache_l = &mode_lib->ms.mall_comb_mcache_l[k]; - calculate_mcache_setting_params->mall_comb_mcache_c = &mode_lib->ms.mall_comb_mcache_c[k]; - calculate_mcache_setting_params->lc_comb_mcache = &mode_lib->ms.lc_comb_mcache[k]; - - calculate_mcache_setting(&mode_lib->scratch, calculate_mcache_setting_params); - } - - calculate_mall_bw_overhead_factor( - mode_lib->ms.mall_prefetch_sdp_overhead_factor, - mode_lib->ms.mall_prefetch_dram_overhead_factor, - - // input - display_cfg, - mode_lib->ms.num_active_planes); - } - - // Calculate all the bandwidth available - // Need anothe bw for latency evaluation - calculate_bandwidth_available( - mode_lib->ms.support.avg_bandwidth_available_min, // not used - mode_lib->ms.support.avg_bandwidth_available, // not used - mode_lib->ms.support.urg_bandwidth_available_min_latency, - mode_lib->ms.support.urg_bandwidth_available, // not used - mode_lib->ms.support.urg_bandwidth_available_vm_only, // not used - mode_lib->ms.support.urg_bandwidth_available_pixel_and_vm, // not used - - &mode_lib->soc, - display_cfg->hostvm_enable, - mode_lib->ms.DCFCLK, - mode_lib->ms.FabricClock, - mode_lib->ms.dram_bw_mbps); - - calculate_bandwidth_available( - mode_lib->ms.support.avg_bandwidth_available_min, - mode_lib->ms.support.avg_bandwidth_available, - mode_lib->ms.support.urg_bandwidth_available_min, - mode_lib->ms.support.urg_bandwidth_available, - mode_lib->ms.support.urg_bandwidth_available_vm_only, - mode_lib->ms.support.urg_bandwidth_available_pixel_and_vm, - - &mode_lib->soc, - display_cfg->hostvm_enable, - mode_lib->ms.MaxDCFCLK, - mode_lib->ms.MaxFabricClock, - mode_lib->ms.dram_bw_mbps); - - - // Average BW support check - calculate_avg_bandwidth_required( - mode_lib->ms.support.avg_bandwidth_required, - // input - display_cfg, - mode_lib->ms.num_active_planes, - mode_lib->ms.SurfaceReadBandwidthLuma, - mode_lib->ms.SurfaceReadBandwidthChroma, - mode_lib->ms.cursor_bw, - mode_lib->ms.dcc_dram_bw_nom_overhead_factor_p0, - mode_lib->ms.dcc_dram_bw_nom_overhead_factor_p1, - mode_lib->ms.mall_prefetch_dram_overhead_factor, - mode_lib->ms.mall_prefetch_sdp_overhead_factor); - - for (m = 0; m < dml2_core_internal_bw_max; m++) { // check sdp and dram - mode_lib->ms.support.avg_bandwidth_support_ok[dml2_core_internal_soc_state_sys_idle][m] = 1; - mode_lib->ms.support.avg_bandwidth_support_ok[dml2_core_internal_soc_state_sys_active][m] = (mode_lib->ms.support.avg_bandwidth_required[dml2_core_internal_soc_state_sys_active][m] <= mode_lib->ms.support.avg_bandwidth_available[dml2_core_internal_soc_state_sys_active][m]); - mode_lib->ms.support.avg_bandwidth_support_ok[dml2_core_internal_soc_state_svp_prefetch][m] = (mode_lib->ms.support.avg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][m] <= mode_lib->ms.support.avg_bandwidth_available[dml2_core_internal_soc_state_svp_prefetch][m]); - } - - mode_lib->ms.support.AvgBandwidthSupport = true; - mode_lib->ms.support.EnoughUrgentLatencyHidingSupport = true; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - if (mode_lib->ms.NotEnoughUrgentLatencyHiding[k]) { - mode_lib->ms.support.EnoughUrgentLatencyHidingSupport = false; - dml2_printf("DML::%s: k=%u NotEnoughUrgentLatencyHiding set\n", __func__, k); - - } - } - for (m = 0; m < dml2_core_internal_soc_state_max; m++) { - for (n = 0; n < dml2_core_internal_bw_max; n++) { // check sdp and dram - if (!mode_lib->ms.support.avg_bandwidth_support_ok[m][n] && (m == dml2_core_internal_soc_state_sys_active || mode_lib->soc.mall_allocated_for_dcn_mbytes > 0)) { - mode_lib->ms.support.AvgBandwidthSupport = false; -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: avg_bandwidth_support_ok[%s][%s] not ok\n", __func__, dml2_core_internal_soc_state_type_str(m), dml2_core_internal_bw_type_str(n)); -#endif - } - } - } - - /* Prefetch Check */ - { - mode_lib->ms.TimeCalc = 24 / mode_lib->ms.dcfclk_deepsleep; - - - calculate_hostvm_inefficiency_factor( - &s->HostVMInefficiencyFactor, - &s->HostVMInefficiencyFactorPrefetch, - - display_cfg->gpuvm_enable, - display_cfg->hostvm_enable, - mode_lib->ip.remote_iommu_outstanding_translations, - mode_lib->soc.max_outstanding_reqs, - mode_lib->ms.support.urg_bandwidth_available_pixel_and_vm[dml2_core_internal_soc_state_sys_active], - mode_lib->ms.support.urg_bandwidth_available_vm_only[dml2_core_internal_soc_state_sys_active]); - - mode_lib->ms.Total3dlutActive = 0; - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - if (display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut) - mode_lib->ms.Total3dlutActive = mode_lib->ms.Total3dlutActive + 1; - - // Calculate tdlut schedule related terms - calculate_tdlut_setting_params->dispclk_mhz = mode_lib->ms.RequiredDISPCLK; - calculate_tdlut_setting_params->setup_for_tdlut = display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut; - calculate_tdlut_setting_params->tdlut_width_mode = display_cfg->plane_descriptors[k].tdlut.tdlut_width_mode; - calculate_tdlut_setting_params->tdlut_addressing_mode = display_cfg->plane_descriptors[k].tdlut.tdlut_addressing_mode; - calculate_tdlut_setting_params->cursor_buffer_size = mode_lib->ip.cursor_buffer_size; - calculate_tdlut_setting_params->gpuvm_enable = display_cfg->gpuvm_enable; - calculate_tdlut_setting_params->gpuvm_page_size_kbytes = display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes; - calculate_tdlut_setting_params->tdlut_mpc_width_flag = display_cfg->plane_descriptors[k].tdlut.tdlut_mpc_width_flag; - calculate_tdlut_setting_params->is_gfx11 = dml_get_gfx_version(display_cfg->plane_descriptors[k].surface.tiling); - - // output - calculate_tdlut_setting_params->tdlut_pte_bytes_per_frame = &s->tdlut_pte_bytes_per_frame[k]; - calculate_tdlut_setting_params->tdlut_bytes_per_frame = &s->tdlut_bytes_per_frame[k]; - calculate_tdlut_setting_params->tdlut_groups_per_2row_ub = &s->tdlut_groups_per_2row_ub[k]; - calculate_tdlut_setting_params->tdlut_opt_time = &s->tdlut_opt_time[k]; - calculate_tdlut_setting_params->tdlut_drain_time = &s->tdlut_drain_time[k]; - calculate_tdlut_setting_params->tdlut_bytes_per_group = &s->tdlut_bytes_per_group[k]; - - calculate_tdlut_setting(&mode_lib->scratch, calculate_tdlut_setting_params); - } - - 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, - mode_lib->soc.qos_parameters.qos_params.dcn32x.loaded_round_trip_latency_fclk_cycles, - s->ReorderingBytes, - mode_lib->ms.DCFCLK, - mode_lib->ms.FabricClock, - mode_lib->ip.pixel_chunk_size_kbytes, - min_return_bw_for_latency, - mode_lib->ms.num_active_planes, - mode_lib->ms.NoOfDPP, - mode_lib->ms.dpte_group_bytes, - s->tdlut_bytes_per_group, - s->HostVMInefficiencyFactor, - s->HostVMInefficiencyFactorPrefetch, - mode_lib->soc.hostvm_min_page_size_kbytes, - mode_lib->soc.qos_parameters.qos_type, - !(display_cfg->overrides.max_outstanding_when_urgent_expected_disable), - mode_lib->soc.max_outstanding_reqs, - mode_lib->ms.support.request_size_bytes_luma, - mode_lib->ms.support.request_size_bytes_chroma, - mode_lib->ip.meta_chunk_size_kbytes, - mode_lib->ip.dchub_arb_to_ret_delay, - mode_lib->ms.TripToMemory, - mode_lib->ip.hostvm_mode, - - // output - &mode_lib->ms.ExtraLatency, - &mode_lib->ms.ExtraLatency_sr, - &mode_lib->ms.ExtraLatencyPrefetch); - - { - mode_lib->ms.support.PrefetchSupported = true; - for (k = 0; k < mode_lib->ms.num_active_planes; k++) { - - mode_lib->ms.TWait[k] = CalculateTWait( - display_cfg->plane_descriptors[k].overrides.reserved_vblank_time_ns, - mode_lib->ms.UrgLatency, - mode_lib->ms.TripToMemory); - - struct dml2_core_internal_DmlPipe *myPipe = &s->myPipe; - myPipe->Dppclk = mode_lib->ms.RequiredDPPCLK[k]; - myPipe->Dispclk = mode_lib->ms.RequiredDISPCLK; - myPipe->PixelClock = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000); - myPipe->DCFClkDeepSleep = mode_lib->ms.dcfclk_deepsleep; - myPipe->DPPPerSurface = mode_lib->ms.NoOfDPP[k]; - myPipe->ScalerEnabled = display_cfg->plane_descriptors[k].composition.scaler_info.enabled; - myPipe->VRatio = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio; - myPipe->VRatioChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio; - myPipe->VTaps = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps; - myPipe->VTapsChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps; - myPipe->RotationAngle = display_cfg->plane_descriptors[k].composition.rotation_angle; - myPipe->mirrored = display_cfg->plane_descriptors[k].composition.mirrored; - myPipe->BlockWidth256BytesY = mode_lib->ms.Read256BlockWidthY[k]; - myPipe->BlockHeight256BytesY = mode_lib->ms.Read256BlockHeightY[k]; - myPipe->BlockWidth256BytesC = mode_lib->ms.Read256BlockWidthC[k]; - myPipe->BlockHeight256BytesC = mode_lib->ms.Read256BlockHeightC[k]; - myPipe->InterlaceEnable = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced; - myPipe->NumberOfCursors = display_cfg->plane_descriptors[k].cursor.num_cursors; - myPipe->VBlank = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active; - myPipe->HTotal = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total; - myPipe->HActive = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_active; - myPipe->DCCEnable = display_cfg->plane_descriptors[k].surface.dcc.enable; - myPipe->ODMMode = mode_lib->ms.ODMMode[k]; - myPipe->SourcePixelFormat = display_cfg->plane_descriptors[k].pixel_format; - myPipe->BytePerPixelY = mode_lib->ms.BytePerPixelY[k]; - myPipe->BytePerPixelC = mode_lib->ms.BytePerPixelC[k]; - myPipe->ProgressiveToInterlaceUnitInOPP = mode_lib->ip.ptoi_supported; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: Calling CalculatePrefetchSchedule for k=%u\n", __func__, k); - dml2_printf("DML::%s: MaximumVStartup = %u\n", __func__, s->MaximumVStartup[k]); -#endif - CalculatePrefetchSchedule_params->display_cfg = display_cfg; - CalculatePrefetchSchedule_params->HostVMInefficiencyFactor = s->HostVMInefficiencyFactorPrefetch; - CalculatePrefetchSchedule_params->myPipe = myPipe; - CalculatePrefetchSchedule_params->DSCDelay = mode_lib->ms.DSCDelay[k]; - CalculatePrefetchSchedule_params->DPPCLKDelaySubtotalPlusCNVCFormater = mode_lib->ip.dppclk_delay_subtotal + mode_lib->ip.dppclk_delay_cnvc_formatter; - CalculatePrefetchSchedule_params->DPPCLKDelaySCL = mode_lib->ip.dppclk_delay_scl; - CalculatePrefetchSchedule_params->DPPCLKDelaySCLLBOnly = mode_lib->ip.dppclk_delay_scl_lb_only; - CalculatePrefetchSchedule_params->DPPCLKDelayCNVCCursor = mode_lib->ip.dppclk_delay_cnvc_cursor; - CalculatePrefetchSchedule_params->DISPCLKDelaySubtotal = mode_lib->ip.dispclk_delay_subtotal; - CalculatePrefetchSchedule_params->DPP_RECOUT_WIDTH = (unsigned int)(mode_lib->ms.SwathWidthY[k] / display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio); - 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; - CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = display_cfg->plane_descriptors[k].dynamic_meta_data.lines_before_active_required; - CalculatePrefetchSchedule_params->DynamicMetadataTransmittedBytes = display_cfg->plane_descriptors[k].dynamic_meta_data.transmitted_bytes; - CalculatePrefetchSchedule_params->UrgentLatency = mode_lib->ms.UrgLatency; - CalculatePrefetchSchedule_params->ExtraLatencyPrefetch = mode_lib->ms.ExtraLatencyPrefetch; - CalculatePrefetchSchedule_params->TCalc = mode_lib->ms.TimeCalc; - CalculatePrefetchSchedule_params->vm_bytes = mode_lib->ms.vm_bytes[k]; - CalculatePrefetchSchedule_params->PixelPTEBytesPerRow = mode_lib->ms.DPTEBytesPerRow[k]; - CalculatePrefetchSchedule_params->PrefetchSourceLinesY = mode_lib->ms.PrefetchLinesY[k]; - CalculatePrefetchSchedule_params->VInitPreFillY = mode_lib->ms.PrefillY[k]; - CalculatePrefetchSchedule_params->MaxNumSwathY = mode_lib->ms.MaxNumSwathY[k]; - CalculatePrefetchSchedule_params->PrefetchSourceLinesC = mode_lib->ms.PrefetchLinesC[k]; - CalculatePrefetchSchedule_params->VInitPreFillC = mode_lib->ms.PrefillC[k]; - CalculatePrefetchSchedule_params->MaxNumSwathC = mode_lib->ms.MaxNumSwathC[k]; - CalculatePrefetchSchedule_params->swath_width_luma_ub = mode_lib->ms.swath_width_luma_ub[k]; - CalculatePrefetchSchedule_params->swath_width_chroma_ub = mode_lib->ms.swath_width_chroma_ub[k]; - CalculatePrefetchSchedule_params->SwathHeightY = mode_lib->ms.SwathHeightY[k]; - CalculatePrefetchSchedule_params->SwathHeightC = mode_lib->ms.SwathHeightC[k]; - CalculatePrefetchSchedule_params->TWait = mode_lib->ms.TWait[k]; - CalculatePrefetchSchedule_params->Ttrip = mode_lib->ms.TripToMemory; - CalculatePrefetchSchedule_params->setup_for_tdlut = display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut; - CalculatePrefetchSchedule_params->tdlut_pte_bytes_per_frame = s->tdlut_pte_bytes_per_frame[k]; - CalculatePrefetchSchedule_params->tdlut_bytes_per_frame = s->tdlut_bytes_per_frame[k]; - CalculatePrefetchSchedule_params->tdlut_opt_time = s->tdlut_opt_time[k]; - CalculatePrefetchSchedule_params->tdlut_drain_time = s->tdlut_drain_time[k]; - CalculatePrefetchSchedule_params->num_cursors = (display_cfg->plane_descriptors[k].cursor.cursor_width > 0); - CalculatePrefetchSchedule_params->cursor_bytes_per_chunk = s->cursor_bytes_per_chunk[k]; - CalculatePrefetchSchedule_params->cursor_bytes_per_line = s->cursor_bytes_per_line[k]; - CalculatePrefetchSchedule_params->dcc_enable = display_cfg->plane_descriptors[k].surface.dcc.enable; - CalculatePrefetchSchedule_params->mrq_present = mode_lib->ip.dcn_mrq_present; - CalculatePrefetchSchedule_params->meta_row_bytes = mode_lib->ms.meta_row_bytes[k]; - CalculatePrefetchSchedule_params->mall_prefetch_sdp_overhead_factor = mode_lib->ms.mall_prefetch_sdp_overhead_factor[k]; - - // output - CalculatePrefetchSchedule_params->DSTXAfterScaler = &s->DSTXAfterScaler[k]; - CalculatePrefetchSchedule_params->DSTYAfterScaler = &s->DSTYAfterScaler[k]; - CalculatePrefetchSchedule_params->dst_y_prefetch = &mode_lib->ms.dst_y_prefetch[k]; - CalculatePrefetchSchedule_params->dst_y_per_vm_vblank = &mode_lib->ms.LinesForVM[k]; - CalculatePrefetchSchedule_params->dst_y_per_row_vblank = &mode_lib->ms.LinesForDPTERow[k]; - CalculatePrefetchSchedule_params->VRatioPrefetchY = &mode_lib->ms.VRatioPreY[k]; - CalculatePrefetchSchedule_params->VRatioPrefetchC = &mode_lib->ms.VRatioPreC[k]; - CalculatePrefetchSchedule_params->RequiredPrefetchPixelDataBWLuma = &mode_lib->ms.RequiredPrefetchPixelDataBWLuma[k]; // prefetch_sw_bw_l - CalculatePrefetchSchedule_params->RequiredPrefetchPixelDataBWChroma = &mode_lib->ms.RequiredPrefetchPixelDataBWChroma[k]; // prefetch_sw_bw_c - CalculatePrefetchSchedule_params->NotEnoughTimeForDynamicMetadata = &mode_lib->ms.NoTimeForDynamicMetadata[k]; - CalculatePrefetchSchedule_params->Tno_bw = &mode_lib->ms.Tno_bw[k]; - CalculatePrefetchSchedule_params->Tno_bw_flip = &mode_lib->ms.Tno_bw_flip[k]; - CalculatePrefetchSchedule_params->prefetch_vmrow_bw = &mode_lib->ms.prefetch_vmrow_bw[k]; - CalculatePrefetchSchedule_params->Tdmdl_vm = &s->dummy_single[0]; - CalculatePrefetchSchedule_params->Tdmdl = &s->dummy_single[1]; - CalculatePrefetchSchedule_params->TSetup = &s->dummy_single[2]; - CalculatePrefetchSchedule_params->Tvm_trips = &s->Tvm_trips[k]; - CalculatePrefetchSchedule_params->Tr0_trips = &s->Tr0_trips[k]; - CalculatePrefetchSchedule_params->Tvm_trips_flip = &s->Tvm_trips_flip[k]; - CalculatePrefetchSchedule_params->Tr0_trips_flip = &s->Tr0_trips_flip[k]; - CalculatePrefetchSchedule_params->Tvm_trips_flip_rounded = &s->Tvm_trips_flip_rounded[k]; - CalculatePrefetchSchedule_params->Tr0_trips_flip_rounded = &s->Tr0_trips_flip_rounded[k]; - CalculatePrefetchSchedule_params->VUpdateOffsetPix = &s->dummy_integer[0]; - CalculatePrefetchSchedule_params->VUpdateWidthPix = &s->dummy_integer[1]; - CalculatePrefetchSchedule_params->VReadyOffsetPix = &s->dummy_integer[2]; - CalculatePrefetchSchedule_params->prefetch_cursor_bw = &mode_lib->ms.prefetch_cursor_bw[k]; - - mode_lib->ms.NoTimeForPrefetch[k] = CalculatePrefetchSchedule(&mode_lib->scratch, CalculatePrefetchSchedule_params); - - mode_lib->ms.support.PrefetchSupported &= !mode_lib->ms.NoTimeForPrefetch[k]; - dml2_printf("DML::%s: k=%d, dst_y_per_vm_vblank = %f\n", __func__, k, *CalculatePrefetchSchedule_params->dst_y_per_vm_vblank); - dml2_printf("DML::%s: k=%d, dst_y_per_row_vblank = %f\n", __func__, k, *CalculatePrefetchSchedule_params->dst_y_per_row_vblank); - } // for k num_planes - - for (k = 0; k < mode_lib->ms.num_active_planes; k++) { - if (mode_lib->ms.dst_y_prefetch[k] < 2.0 - || mode_lib->ms.LinesForVM[k] >= 32.0 - || mode_lib->ms.LinesForDPTERow[k] >= 16.0 - || mode_lib->ms.NoTimeForPrefetch[k] == true - || s->DSTYAfterScaler[k] > 8) { - mode_lib->ms.support.PrefetchSupported = false; - 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]); - } - } - - mode_lib->ms.support.DynamicMetadataSupported = true; - for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { - if (mode_lib->ms.NoTimeForDynamicMetadata[k] == true) { - mode_lib->ms.support.DynamicMetadataSupported = false; - } - } - - 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__) { - mode_lib->ms.support.VRatioInPrefetchSupported = false; - 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++) { - // Calculate Urgent burst factor for prefetch -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%d, Calling CalculateUrgentBurstFactor (for prefetch)\n", __func__, k); - dml2_printf("DML::%s: k=%d, VRatioPreY=%f\n", __func__, k, mode_lib->ms.VRatioPreY[k]); - dml2_printf("DML::%s: k=%d, VRatioPreC=%f\n", __func__, k, mode_lib->ms.VRatioPreC[k]); -#endif - double 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); - CalculateUrgentBurstFactor( - &display_cfg->plane_descriptors[k], - mode_lib->ms.swath_width_luma_ub[k], - mode_lib->ms.swath_width_chroma_ub[k], - mode_lib->ms.SwathHeightY[k], - mode_lib->ms.SwathHeightC[k], - line_time_us, - mode_lib->ms.UrgLatency, - mode_lib->ms.VRatioPreY[k], - mode_lib->ms.VRatioPreC[k], - mode_lib->ms.BytePerPixelInDETY[k], - mode_lib->ms.BytePerPixelInDETC[k], - mode_lib->ms.DETBufferSizeY[k], - mode_lib->ms.DETBufferSizeC[k], - /* Output */ - &mode_lib->ms.UrgentBurstFactorLumaPre[k], - &mode_lib->ms.UrgentBurstFactorChromaPre[k], - &mode_lib->ms.NotEnoughUrgentLatencyHidingPre[k]); - } - - // Calculate urgent bandwidth required, both urg and non urg peak bandwidth - // assume flip bw is 0 at this point - for (k = 0; k < mode_lib->ms.num_active_planes; k++) - mode_lib->ms.final_flip_bw[k] = 0; - - calculate_peak_bandwidth_required( - &mode_lib->scratch, - mode_lib->ms.support.urg_vactive_bandwidth_required, - mode_lib->ms.support.urg_bandwidth_required, - mode_lib->ms.support.non_urg_bandwidth_required, - - display_cfg, - 0, // inc_flip_bw - mode_lib->ms.num_active_planes, - mode_lib->ms.NoOfDPP, - mode_lib->ms.dcc_dram_bw_nom_overhead_factor_p0, - mode_lib->ms.dcc_dram_bw_nom_overhead_factor_p1, - mode_lib->ms.dcc_dram_bw_pref_overhead_factor_p0, - mode_lib->ms.dcc_dram_bw_pref_overhead_factor_p1, - mode_lib->ms.mall_prefetch_sdp_overhead_factor, - mode_lib->ms.mall_prefetch_dram_overhead_factor, - - mode_lib->ms.SurfaceReadBandwidthLuma, - mode_lib->ms.SurfaceReadBandwidthChroma, - mode_lib->ms.RequiredPrefetchPixelDataBWLuma, - mode_lib->ms.RequiredPrefetchPixelDataBWChroma, - mode_lib->ms.cursor_bw, - mode_lib->ms.dpte_row_bw, - mode_lib->ms.meta_row_bw, - mode_lib->ms.prefetch_cursor_bw, - mode_lib->ms.prefetch_vmrow_bw, - mode_lib->ms.final_flip_bw, - mode_lib->ms.UrgentBurstFactorLuma, - mode_lib->ms.UrgentBurstFactorChroma, - mode_lib->ms.UrgentBurstFactorCursor, - mode_lib->ms.UrgentBurstFactorLumaPre, - mode_lib->ms.UrgentBurstFactorChromaPre, - mode_lib->ms.UrgentBurstFactorCursorPre); - - // Check urg peak bandwidth against available urg bw - // check at SDP and DRAM, for all soc states (SVP prefetch an Sys Active) - check_urgent_bandwidth_support( - &s->dummy_single[0], // double* frac_urg_bandwidth - &s->dummy_single[1], // double* frac_urg_bandwidth_mall - &mode_lib->ms.support.UrgVactiveBandwidthSupport, - &mode_lib->ms.support.PrefetchBandwidthSupported, - - mode_lib->soc.mall_allocated_for_dcn_mbytes, - mode_lib->ms.support.non_urg_bandwidth_required, - mode_lib->ms.support.urg_vactive_bandwidth_required, - mode_lib->ms.support.urg_bandwidth_required, - mode_lib->ms.support.urg_bandwidth_available); - - mode_lib->ms.support.PrefetchSupported &= mode_lib->ms.support.PrefetchBandwidthSupported; - dml2_printf("DML::%s: PrefetchBandwidthSupported=%0d\n", __func__, mode_lib->ms.support.PrefetchBandwidthSupported); - - for (k = 0; k < mode_lib->ms.num_active_planes; k++) { - if (mode_lib->ms.NotEnoughUrgentLatencyHidingPre[k]) { - mode_lib->ms.support.PrefetchSupported = false; - dml2_printf("DML::%s: k=%d, NotEnoughUrgentLatencyHidingPre=%d\n", __func__, k, mode_lib->ms.NotEnoughUrgentLatencyHidingPre[k]); - } - } - - - // Both prefetch schedule and BW okay - if (mode_lib->ms.support.PrefetchSupported == true && mode_lib->ms.support.VRatioInPrefetchSupported == true) { - mode_lib->ms.BandwidthAvailableForImmediateFlip = - get_bandwidth_available_for_immediate_flip(dml2_core_internal_soc_state_sys_active, - mode_lib->ms.support.urg_bandwidth_required, // no flip - mode_lib->ms.support.urg_bandwidth_available); - - mode_lib->ms.TotImmediateFlipBytes = 0; - for (k = 0; k < mode_lib->ms.num_active_planes; k++) { - if (display_cfg->plane_descriptors[k].immediate_flip) { - s->per_pipe_flip_bytes[k] = get_pipe_flip_bytes( - s->HostVMInefficiencyFactor, - mode_lib->ms.vm_bytes[k], - mode_lib->ms.DPTEBytesPerRow[k], - mode_lib->ms.meta_row_bytes[k]); - } else { - s->per_pipe_flip_bytes[k] = 0; - } - mode_lib->ms.TotImmediateFlipBytes += s->per_pipe_flip_bytes[k] * mode_lib->ms.NoOfDPP[k]; - - } - - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - CalculateFlipSchedule( - &mode_lib->scratch, - display_cfg->plane_descriptors[k].immediate_flip, - 1, // use_lb_flip_bw - s->HostVMInefficiencyFactor, - s->Tvm_trips_flip[k], - s->Tr0_trips_flip[k], - s->Tvm_trips_flip_rounded[k], - s->Tr0_trips_flip_rounded[k], - display_cfg->gpuvm_enable, - mode_lib->ms.vm_bytes[k], - mode_lib->ms.DPTEBytesPerRow[k], - mode_lib->ms.BandwidthAvailableForImmediateFlip, - mode_lib->ms.TotImmediateFlipBytes, - display_cfg->plane_descriptors[k].pixel_format, - (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)), - display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio, - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio, - mode_lib->ms.Tno_bw_flip[k], - mode_lib->ms.dpte_row_height[k], - 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, - s->per_pipe_flip_bytes[k], - mode_lib->ms.meta_row_bytes[k], - s->meta_row_height_luma[k], - s->meta_row_height_chroma[k], - mode_lib->ip.dcn_mrq_present && display_cfg->plane_descriptors[k].surface.dcc.enable, - - /* Output */ - &mode_lib->ms.dst_y_per_vm_flip[k], - &mode_lib->ms.dst_y_per_row_flip[k], - &mode_lib->ms.final_flip_bw[k], - &mode_lib->ms.ImmediateFlipSupportedForPipe[k]); - } - - calculate_peak_bandwidth_required( - &mode_lib->scratch, - s->dummy_bw, - mode_lib->ms.support.urg_bandwidth_required_flip, - mode_lib->ms.support.non_urg_bandwidth_required_flip, - - // Input - display_cfg, - 1, // inc_flip_bw - mode_lib->ms.num_active_planes, - mode_lib->ms.NoOfDPP, - - mode_lib->ms.dcc_dram_bw_nom_overhead_factor_p0, - mode_lib->ms.dcc_dram_bw_nom_overhead_factor_p1, - mode_lib->ms.dcc_dram_bw_pref_overhead_factor_p0, - mode_lib->ms.dcc_dram_bw_pref_overhead_factor_p1, - mode_lib->ms.mall_prefetch_sdp_overhead_factor, - mode_lib->ms.mall_prefetch_dram_overhead_factor, - - mode_lib->ms.SurfaceReadBandwidthLuma, - mode_lib->ms.SurfaceReadBandwidthChroma, - mode_lib->ms.RequiredPrefetchPixelDataBWLuma, - mode_lib->ms.RequiredPrefetchPixelDataBWChroma, - mode_lib->ms.cursor_bw, - mode_lib->ms.dpte_row_bw, - mode_lib->ms.meta_row_bw, - mode_lib->ms.prefetch_cursor_bw, - mode_lib->ms.prefetch_vmrow_bw, - mode_lib->ms.final_flip_bw, - mode_lib->ms.UrgentBurstFactorLuma, - mode_lib->ms.UrgentBurstFactorChroma, - mode_lib->ms.UrgentBurstFactorCursor, - mode_lib->ms.UrgentBurstFactorLumaPre, - mode_lib->ms.UrgentBurstFactorChromaPre, - mode_lib->ms.UrgentBurstFactorCursorPre); - - calculate_immediate_flip_bandwidth_support( - &s->dummy_single[0], // double* frac_urg_bandwidth_flip - &mode_lib->ms.support.ImmediateFlipSupport, - - dml2_core_internal_soc_state_sys_active, - mode_lib->ms.support.urg_bandwidth_required_flip, - mode_lib->ms.support.non_urg_bandwidth_required_flip, - mode_lib->ms.support.urg_bandwidth_available); - - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - if (display_cfg->plane_descriptors[k].immediate_flip == true && mode_lib->ms.ImmediateFlipSupportedForPipe[k] == false) - mode_lib->ms.support.ImmediateFlipSupport = false; - } - - } else { // if prefetch not support, assume iflip is not supported too - mode_lib->ms.support.ImmediateFlipSupport = false; - } - } // prefetch schedule - } - - s->mSOCParameters.UrgentLatency = mode_lib->ms.UrgLatency; - s->mSOCParameters.ExtraLatency = mode_lib->ms.ExtraLatency; - s->mSOCParameters.ExtraLatency_sr = mode_lib->ms.ExtraLatency_sr; - s->mSOCParameters.WritebackLatency = mode_lib->soc.qos_parameters.writeback.base_latency_us; - s->mSOCParameters.DRAMClockChangeLatency = mode_lib->soc.power_management_parameters.dram_clk_change_blackout_us; - s->mSOCParameters.FCLKChangeLatency = mode_lib->soc.power_management_parameters.fclk_change_blackout_us; - s->mSOCParameters.SRExitTime = mode_lib->soc.power_management_parameters.stutter_exit_latency_us; - s->mSOCParameters.SREnterPlusExitTime = mode_lib->soc.power_management_parameters.stutter_enter_plus_exit_latency_us; - s->mSOCParameters.SRExitZ8Time = mode_lib->soc.power_management_parameters.z8_stutter_exit_latency_us; - s->mSOCParameters.SREnterPlusExitZ8Time = mode_lib->soc.power_management_parameters.z8_stutter_enter_plus_exit_latency_us; - s->mSOCParameters.USRRetrainingLatency = 0; // FIXME_STAGE2: no USR related bbox value - s->mSOCParameters.SMNLatency = 0; // FIXME_STAGE2 - - CalculateWatermarks_params->display_cfg = display_cfg; - CalculateWatermarks_params->USRRetrainingRequired = false /*FIXME_STAGE2 was: mode_lib->ms.policy.USRRetrainingRequired, no new dml2 replacement*/; - CalculateWatermarks_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes; - CalculateWatermarks_params->MaxLineBufferLines = mode_lib->ip.max_line_buffer_lines; - CalculateWatermarks_params->LineBufferSize = mode_lib->ip.line_buffer_size_bits; - CalculateWatermarks_params->WritebackInterfaceBufferSize = mode_lib->ip.writeback_interface_buffer_size_kbytes; - CalculateWatermarks_params->DCFCLK = mode_lib->ms.DCFCLK; - CalculateWatermarks_params->SynchronizeTimings = display_cfg->overrides.synchronize_timings; - CalculateWatermarks_params->SynchronizeDRRDisplaysForUCLKPStateChange = display_cfg->overrides.synchronize_ddr_displays_for_uclk_pstate_change; - CalculateWatermarks_params->dpte_group_bytes = mode_lib->ms.dpte_group_bytes; - CalculateWatermarks_params->mmSOCParameters = s->mSOCParameters; - CalculateWatermarks_params->WritebackChunkSize = mode_lib->ip.writeback_chunk_size_kbytes; - CalculateWatermarks_params->SOCCLK = mode_lib->ms.SOCCLK; - CalculateWatermarks_params->DCFClkDeepSleep = mode_lib->ms.dcfclk_deepsleep; - CalculateWatermarks_params->DETBufferSizeY = mode_lib->ms.DETBufferSizeY; - 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; - CalculateWatermarks_params->BytePerPixelDETY = mode_lib->ms.BytePerPixelInDETY; - CalculateWatermarks_params->BytePerPixelDETC = mode_lib->ms.BytePerPixelInDETC; - CalculateWatermarks_params->DSTXAfterScaler = s->DSTXAfterScaler; - CalculateWatermarks_params->DSTYAfterScaler = s->DSTYAfterScaler; - CalculateWatermarks_params->UnboundedRequestEnabled = mode_lib->ms.UnboundedRequestEnabled; - CalculateWatermarks_params->CompressedBufferSizeInkByte = mode_lib->ms.CompressedBufferSizeInkByte; - CalculateWatermarks_params->meta_row_height_l = s->meta_row_height_luma; - CalculateWatermarks_params->meta_row_height_c = s->meta_row_height_chroma; - - // Output - CalculateWatermarks_params->Watermark = &s->dummy_watermark; // Watermarks *Watermark - CalculateWatermarks_params->DRAMClockChangeSupport = mode_lib->ms.support.DRAMClockChangeSupport; - CalculateWatermarks_params->global_dram_clock_change_supported = &mode_lib->ms.support.global_dram_clock_change_supported; - CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = &s->dummy_single_array[0]; // double *MaxActiveDRAMClockChangeLatencySupported[] - CalculateWatermarks_params->SubViewportLinesNeededInMALL = mode_lib->ms.SubViewportLinesNeededInMALL; // unsigned int SubViewportLinesNeededInMALL[] - CalculateWatermarks_params->FCLKChangeSupport = mode_lib->ms.support.FCLKChangeSupport; - CalculateWatermarks_params->global_fclk_change_supported = &mode_lib->ms.support.global_fclk_change_supported; - CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &s->dummy_single[0]; // double *MaxActiveFCLKChangeLatencySupported - CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->ms.support.USRRetrainingSupport; - CalculateWatermarks_params->VActiveLatencyHidingMargin = mode_lib->ms.VActiveLatencyHidingMargin; - CalculateWatermarks_params->VActiveLatencyHidingUs = mode_lib->ms.VActiveLatencyHidingUs; - - CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(&mode_lib->scratch, CalculateWatermarks_params); - } - - // End of Prefetch Check - - dml2_printf("DML::%s: Done prefetch calculation\n", __func__); - - //Re-ordering Buffer Support Check - mode_lib->ms.support.max_urgent_latency_us - = 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_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; - } else { - mode_lib->ms.support.ROBSupport = false; - } - } else { - 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; - } - } - -#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: 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 - && !mode_lib->ms.support.LinkRateDoesNotMatchDPVersion - && !mode_lib->ms.support.LinkRateForMultistreamNotIndicated - && !mode_lib->ms.support.BPPForMultistreamNotIndicated - && !mode_lib->ms.support.MultistreamWithHDMIOreDP - && !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.NotEnoughDSCUnits - && !mode_lib->ms.support.NotEnoughDSCSlices - && !mode_lib->ms.support.ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe - && !mode_lib->ms.support.InvalidCombinationOfMALLUseForPStateAndStaticScreen - && !mode_lib->ms.support.DSCCLKRequiredMoreThanSupported - && mode_lib->ms.support.PixelsPerLinePerDSCUnitSupport - && !mode_lib->ms.support.DTBCLKRequiredMoreThanSupported - && !mode_lib->ms.support.InvalidCombinationOfMALLUseForPState - && mode_lib->ms.support.ROBSupport - && mode_lib->ms.support.OutstandingRequestsSupport - && mode_lib->ms.support.OutstandingRequestsUrgencyAvoidance - && mode_lib->ms.support.DISPCLK_DPPCLK_Support - && mode_lib->ms.support.TotalAvailablePipesSupport - && mode_lib->ms.support.NumberOfOTGSupport - && mode_lib->ms.support.NumberOfHDMIFRLSupport - && mode_lib->ms.support.NumberOfDP2p0Support - && mode_lib->ms.support.EnoughWritebackUnits - && mode_lib->ms.support.WritebackLatencySupport - && mode_lib->ms.support.WritebackScaleRatioAndTapsSupport - && mode_lib->ms.support.CursorSupport - && mode_lib->ms.support.PitchSupport - && !mode_lib->ms.support.ViewportExceedsSurface - && mode_lib->ms.support.PrefetchSupported - && mode_lib->ms.support.EnoughUrgentLatencyHidingSupport - && mode_lib->ms.support.AvgBandwidthSupport - && mode_lib->ms.support.DynamicMetadataSupported - && mode_lib->ms.support.VRatioInPrefetchSupported - && mode_lib->ms.support.PTEBufferSizeNotExceeded - && mode_lib->ms.support.DCCMetaBufferSizeNotExceeded - && !mode_lib->ms.support.ExceededMALLSize - && ((!display_cfg->hostvm_enable && !s->ImmediateFlipRequired) || mode_lib->ms.support.ImmediateFlipSupport)) { - // && s->dram_clock_change_support == true - // && s->f_clock_change_support == true - // && (/*FIXME_STAGE2 was: mode_lib->ms.policy.USRRetrainingRequired, no new dml2 replacement || */ mode_lib->ms.support.USRRetrainingSupport)) { - dml2_printf("DML::%s: mode is supported\n", __func__); - mode_lib->ms.support.ModeSupport = true; - } else { - dml2_printf("DML::%s: mode is NOT supported\n", __func__); - mode_lib->ms.support.ModeSupport = false; - } - } - - // Since now the mode_support work on 1 particular power state, so there is only 1 state idx (index 0). - dml2_printf("DML::%s: ModeSupport = %u\n", __func__, mode_lib->ms.support.ModeSupport); - dml2_printf("DML::%s: ImmediateFlipSupport = %u\n", __func__, mode_lib->ms.support.ImmediateFlipSupport); - - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - mode_lib->ms.support.MPCCombineEnable[k] = mode_lib->ms.MPCCombine[k]; - mode_lib->ms.support.DPPPerSurface[k] = mode_lib->ms.NoOfDPP[k]; - } - - for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) { - if (display_cfg->plane_descriptors[k].stream_index == k) { - mode_lib->ms.support.ODMMode[k] = mode_lib->ms.ODMMode[k]; - } else { - mode_lib->ms.support.ODMMode[k] = dml2_odm_mode_bypass; - } - - mode_lib->ms.support.DSCEnabled[k] = mode_lib->ms.RequiresDSC[k]; - mode_lib->ms.support.FECEnabled[k] = mode_lib->ms.RequiresFEC[k]; - mode_lib->ms.support.OutputBpp[k] = mode_lib->ms.OutputBpp[k]; - mode_lib->ms.support.OutputType[k] = mode_lib->ms.OutputType[k]; - mode_lib->ms.support.OutputRate[k] = mode_lib->ms.OutputRate[k]; - -#if defined(__DML_VBA_DEBUG__) - dml2_printf("DML::%s: k=%d, ODMMode = %u\n", __func__, k, mode_lib->ms.support.ODMMode[k]); - dml2_printf("DML::%s: k=%d, DSCEnabled = %u\n", __func__, k, mode_lib->ms.support.DSCEnabled[k]); -#endif - } - -#if defined(__DML_VBA_DEBUG__) - if (!mode_lib->ms.support.ModeSupport) - dml2_print_dml_mode_support_info(&mode_lib->ms.support, true); - dml2_printf("DML::%s: is_mode_support = %u (min_clk_index=%d)\n", __func__, mode_lib->ms.support.ModeSupport, in_out_params->min_clk_index); - dml2_printf("DML::%s: --- DONE --- \n", __func__); -#endif - - if (mode_lib->ms.support.ModeSupport) { - *in_out_params->out_evaluation_info = in_out_params->mode_lib->ms.support; - return true; - } else { - return false; - } -} - -static void dml2_print_dml_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 = 0x%x\n", support->ImmediateFlipSupport); - if (!fail_only || support->WritebackLatencySupport == 0) - dml2_printf("DML: support: WritebackLatencySupport = 0x%x\n", support->WritebackLatencySupport); - if (!fail_only || support->ScaleRatioAndTapsSupport == 0) - dml2_printf("DML: support: ScaleRatioAndTapsSupport = 0x%x\n", support->ScaleRatioAndTapsSupport); - if (!fail_only || support->SourceFormatPixelAndScanSupport == 0) - dml2_printf("DML: support: SourceFormatPixelAndScanSupport = 0x%x\n", support->SourceFormatPixelAndScanSupport); - if (!fail_only || support->P2IWith420 == 1) - dml2_printf("DML: support: P2IWith420 = 0x%x\n", support->P2IWith420); - if (!fail_only || support->DSCOnlyIfNecessaryWithBPP == 1) - dml2_printf("DML: support: DSCOnlyIfNecessaryWithBPP = 0x%x\n", support->DSCOnlyIfNecessaryWithBPP); - if (!fail_only || support->DSC422NativeNotSupported == 1) - dml2_printf("DML: support: DSC422NativeNotSupported = 0x%x\n", support->DSC422NativeNotSupported); - if (!fail_only || support->LinkRateDoesNotMatchDPVersion == 1) - dml2_printf("DML: support: LinkRateDoesNotMatchDPVersion = 0x%x\n", support->LinkRateDoesNotMatchDPVersion); - if (!fail_only || support->LinkRateForMultistreamNotIndicated == 1) - dml2_printf("DML: support: LinkRateForMultistreamNotIndicated = 0x%x\n", support->LinkRateForMultistreamNotIndicated); - if (!fail_only || support->BPPForMultistreamNotIndicated == 1) - dml2_printf("DML: support: BPPForMultistreamNotIndicated = 0x%x\n", support->BPPForMultistreamNotIndicated); - if (!fail_only || support->MultistreamWithHDMIOreDP == 1) - dml2_printf("DML: support: MultistreamWithHDMIOreDP = 0x%x\n", support->MultistreamWithHDMIOreDP); - if (!fail_only || support->MSOOrODMSplitWithNonDPLink == 1) - dml2_printf("DML: support: MSOOrODMSplitWithNonDPLink = 0x%x\n", support->MSOOrODMSplitWithNonDPLink); - if (!fail_only || support->NotEnoughLanesForMSO == 1) - dml2_printf("DML: support: NotEnoughLanesForMSO = 0x%x\n", support->NotEnoughLanesForMSO); - if (!fail_only || support->NumberOfOTGSupport == 0) - dml2_printf("DML: support: NumberOfOTGSupport = 0x%x\n", support->NumberOfOTGSupport); - if (!fail_only || support->NumberOfHDMIFRLSupport == 0) - dml2_printf("DML: support: NumberOfHDMIFRLSupport = 0x%x\n", support->NumberOfHDMIFRLSupport); - if (!fail_only || support->NumberOfDP2p0Support == 0) - dml2_printf("DML: support: NumberOfDP2p0Support = 0x%x\n", support->NumberOfDP2p0Support); - if (!fail_only || support->WritebackScaleRatioAndTapsSupport == 0) - dml2_printf("DML: support: WritebackScaleRatioAndTapsSupport = 0x%x\n", support->WritebackScaleRatioAndTapsSupport); - if (!fail_only || support->CursorSupport == 0) - dml2_printf("DML: support: CursorSupport = 0x%x\n", support->CursorSupport); - if (!fail_only || support->PitchSupport == 0) - dml2_printf("DML: support: PitchSupport = 0x%x\n", support->PitchSupport); - if (!fail_only || support->ViewportExceedsSurface == 1) - dml2_printf("DML: support: ViewportExceedsSurface = 0x%x\n", support->ViewportExceedsSurface); - if (!fail_only || support->ExceededMALLSize == 1) - dml2_printf("DML: support: ExceededMALLSize = 0x%x\n", support->ExceededMALLSize); - if (!fail_only || support->EnoughWritebackUnits == 0) - dml2_printf("DML: support: EnoughWritebackUnits = 0x%x\n", support->EnoughWritebackUnits); - if (!fail_only || support->ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe == 1) - dml2_printf("DML: support: ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe = 0x%x\n", support->ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe); - if (!fail_only || support->InvalidCombinationOfMALLUseForPStateAndStaticScreen == 1) - dml2_printf("DML: support: InvalidCombinationOfMALLUseForPStateAndStaticScreen = 0x%x\n", support->InvalidCombinationOfMALLUseForPStateAndStaticScreen); - if (!fail_only || support->InvalidCombinationOfMALLUseForPState == 1) - dml2_printf("DML: support: InvalidCombinationOfMALLUseForPState = 0x%x\n", support->InvalidCombinationOfMALLUseForPState); - if (!fail_only || support->ExceededMultistreamSlots == 1) - dml2_printf("DML: support: ExceededMultistreamSlots = 0x%x\n", support->ExceededMultistreamSlots); - if (!fail_only || support->NotEnoughDSCUnits == 1) - dml2_printf("DML: support: NotEnoughDSCUnits = 0x%x\n", support->NotEnoughDSCUnits); - if (!fail_only || support->NotEnoughDSCSlices == 1) - dml2_printf("DML: support: NotEnoughDSCSlices = 0x%x\n", support->NotEnoughDSCSlices); - if (!fail_only || support->PixelsPerLinePerDSCUnitSupport == 0) - dml2_printf("DML: support: PixelsPerLinePerDSCUnitSupport = 0x%x\n", support->PixelsPerLinePerDSCUnitSupport); - if (!fail_only || support->DSCCLKRequiredMoreThanSupported == 1) - dml2_printf("DML: support: DSCCLKRequiredMoreThanSupported = 0x%x\n", support->DSCCLKRequiredMoreThanSupported); - if (!fail_only || support->DTBCLKRequiredMoreThanSupported == 1) - dml2_printf("DML: support: DTBCLKRequiredMoreThanSupported = 0x%x\n", support->DTBCLKRequiredMoreThanSupported); - if (!fail_only || support->LinkCapacitySupport == 0) - dml2_printf("DML: support: LinkCapacitySupport = 0x%x\n", support->LinkCapacitySupport); - 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->PrefetchSupported == 0) - dml2_printf("DML: support: PrefetchSupported = %d\n", support->PrefetchSupported); - 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->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"); -} - -static void 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 - } -} - -static unsigned int dml_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); -} - -static unsigned int dml_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; -} - -static void dml_calc_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++; - } - } -} - -static bool dml_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; -} - -static bool dml_get_is_phantom_pipe(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, unsigned int pipe_idx) -{ - unsigned int plane_idx = mode_lib->mp.pipe_plane[pipe_idx]; - - bool is_phantom = dml_is_phantom_pipe(&display_cfg->plane_descriptors[plane_idx]); - dml2_printf("DML::%s: pipe_idx=%d legacy_svp_config=%0d is_phantom=%d\n", __func__, pipe_idx, display_cfg->plane_descriptors[plane_idx].overrides.legacy_svp_config, is_phantom); - return is_phantom; -} - -static void CalculateMaxDETAndMinCompressedBufferSize( - unsigned int ConfigReturnBufferSizeInKByte, - unsigned int ConfigReturnBufferSegmentSizeInKByte, - unsigned int ROBBufferSizeInKByte, - unsigned int MaxNumDPP, - unsigned int nomDETInKByteOverrideEnable, // VBA_DELTA, allow DV to override default DET size - unsigned int nomDETInKByteOverrideValue, // VBA_DELTA - bool is_mrq_present, - - // Output - unsigned int *MaxTotalDETInKByte, - unsigned int *nomDETInKByte, - unsigned int *MinCompressedBufferSizeInKByte) -{ - if (is_mrq_present) - *MaxTotalDETInKByte = (unsigned int)math_ceil2((double)(ConfigReturnBufferSizeInKByte + ROBBufferSizeInKByte) * 4 / 5, 64); - else - *MaxTotalDETInKByte = ConfigReturnBufferSizeInKByte - ConfigReturnBufferSegmentSizeInKByte; - - *nomDETInKByte = (unsigned int)(math_floor2((double)*MaxTotalDETInKByte / (double)MaxNumDPP, ConfigReturnBufferSegmentSizeInKByte)); - *MinCompressedBufferSizeInKByte = ConfigReturnBufferSizeInKByte - *MaxTotalDETInKByte; - -#if defined(__DML_VBA_DEBUG__) - dml2_printf("DML::%s: is_mrq_present = %u\n", __func__, is_mrq_present); - dml2_printf("DML::%s: ConfigReturnBufferSizeInKByte = %u\n", __func__, ConfigReturnBufferSizeInKByte); - dml2_printf("DML::%s: ROBBufferSizeInKByte = %u\n", __func__, ROBBufferSizeInKByte); - dml2_printf("DML::%s: MaxNumDPP = %u\n", __func__, MaxNumDPP); - dml2_printf("DML::%s: MaxTotalDETInKByte = %u\n", __func__, *MaxTotalDETInKByte); - dml2_printf("DML::%s: nomDETInKByte = %u\n", __func__, *nomDETInKByte); - dml2_printf("DML::%s: MinCompressedBufferSizeInKByte = %u\n", __func__, *MinCompressedBufferSizeInKByte); -#endif - - if (nomDETInKByteOverrideEnable) { - *nomDETInKByte = nomDETInKByteOverrideValue; - dml2_printf("DML::%s: nomDETInKByte = %u (overrided)\n", __func__, *nomDETInKByte); - } -} - -static void PixelClockAdjustmentForProgressiveToInterlaceUnit(const struct dml2_display_cfg *display_cfg, bool ptoi_supported, double *PixelClockBackEnd) -{ - //unsigned int num_active_planes = display_cfg->num_planes; - - //Progressive To Interlace Unit Effect - for (unsigned int k = 0; k < display_cfg->num_planes; ++k) { - PixelClockBackEnd[k] = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000); - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced == 1 && ptoi_supported == true) { - // FIXME_STAGE2... can sw pass the pixel rate for interlaced directly - //display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz = 2 * display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz; - } - } -} - -bool dml2_core_shared_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; -} - -static unsigned int dml_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode) -{ - switch (sw_mode) { - case (dml2_sw_linear): - return 256; - case (dml2_sw_256b_2d): - return 256; - case (dml2_sw_4kb_2d): - return 4096; - case (dml2_sw_64kb_2d): - return 65536; - case (dml2_sw_256kb_2d): - return 262144; - case (dml2_gfx11_sw_linear): - return 256; - case (dml2_gfx11_sw_64kb_d): - return 65536; - case (dml2_gfx11_sw_64kb_d_t): - return 65536; - case (dml2_gfx11_sw_64kb_d_x): - return 65536; - case (dml2_gfx11_sw_64kb_r_x): - return 65536; - case (dml2_gfx11_sw_256kb_d_x): - return 262144; - case (dml2_gfx11_sw_256kb_r_x): - return 262144; - default: - DML2_ASSERT(0); - return 256; - } -} - -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 bool dml_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; -} - -static int unsigned dml_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; -} - -static void CalculateBytePerPixelAndBlockSizes( - enum dml2_source_format_class SourcePixelFormat, - enum dml2_swizzle_mode SurfaceTiling, - unsigned int pitch_y, - unsigned int pitch_c, - - // Output - unsigned int *BytePerPixelY, - unsigned int *BytePerPixelC, - double *BytePerPixelDETY, - double *BytePerPixelDETC, - unsigned int *BlockHeight256BytesY, - unsigned int *BlockHeight256BytesC, - unsigned int *BlockWidth256BytesY, - unsigned int *BlockWidth256BytesC, - unsigned int *MacroTileHeightY, - unsigned int *MacroTileHeightC, - unsigned int *MacroTileWidthY, - unsigned int *MacroTileWidthC, - bool *surf_linear128_l, - bool *surf_linear128_c) -{ - *BytePerPixelDETY = 0; - *BytePerPixelDETC = 0; - *BytePerPixelY = 0; - *BytePerPixelC = 0; - - if (SourcePixelFormat == dml2_444_64) { - *BytePerPixelDETY = 8; - *BytePerPixelDETC = 0; - *BytePerPixelY = 8; - *BytePerPixelC = 0; - } else if (SourcePixelFormat == dml2_444_32 || SourcePixelFormat == dml2_rgbe) { - *BytePerPixelDETY = 4; - *BytePerPixelDETC = 0; - *BytePerPixelY = 4; - *BytePerPixelC = 0; - } else if (SourcePixelFormat == dml2_444_16 || SourcePixelFormat == dml2_mono_16) { - *BytePerPixelDETY = 2; - *BytePerPixelDETC = 0; - *BytePerPixelY = 2; - *BytePerPixelC = 0; - } else if (SourcePixelFormat == dml2_444_8 || SourcePixelFormat == dml2_mono_8) { - *BytePerPixelDETY = 1; - *BytePerPixelDETC = 0; - *BytePerPixelY = 1; - *BytePerPixelC = 0; - } else if (SourcePixelFormat == dml2_rgbe_alpha) { - *BytePerPixelDETY = 4; - *BytePerPixelDETC = 1; - *BytePerPixelY = 4; - *BytePerPixelC = 1; - } else if (SourcePixelFormat == dml2_420_8) { - *BytePerPixelDETY = 1; - *BytePerPixelDETC = 2; - *BytePerPixelY = 1; - *BytePerPixelC = 2; - } else if (SourcePixelFormat == dml2_420_12) { - *BytePerPixelDETY = 2; - *BytePerPixelDETC = 4; - *BytePerPixelY = 2; - *BytePerPixelC = 4; - } else if (SourcePixelFormat == dml2_420_10) { - *BytePerPixelDETY = (double)(4.0 / 3); - *BytePerPixelDETC = (double)(8.0 / 3); - *BytePerPixelY = 2; - *BytePerPixelC = 4; - } else { - dml2_printf("ERROR: DML::%s: SourcePixelFormat = %u not supported!\n", __func__, SourcePixelFormat); - DML2_ASSERT(0); - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: SourcePixelFormat = %u\n", __func__, SourcePixelFormat); - dml2_printf("DML::%s: BytePerPixelDETY = %f\n", __func__, *BytePerPixelDETY); - dml2_printf("DML::%s: BytePerPixelDETC = %f\n", __func__, *BytePerPixelDETC); - dml2_printf("DML::%s: BytePerPixelY = %u\n", __func__, *BytePerPixelY); - dml2_printf("DML::%s: BytePerPixelC = %u\n", __func__, *BytePerPixelC); - dml2_printf("DML::%s: pitch_y = %u\n", __func__, pitch_y); - dml2_printf("DML::%s: pitch_c = %u\n", __func__, pitch_c); - dml2_printf("DML::%s: surf_linear128_l = %u\n", __func__, *surf_linear128_l); - dml2_printf("DML::%s: surf_linear128_c = %u\n", __func__, *surf_linear128_c); -#endif - - if (dml_get_gfx_version(SurfaceTiling) == 11) { - *surf_linear128_l = 0; - *surf_linear128_c = 0; - } else { - if (SurfaceTiling == dml2_sw_linear) { - *surf_linear128_l = (((pitch_y * *BytePerPixelY) % 256) != 0); - - if (dml2_core_shared_is_420(SourcePixelFormat) || SourcePixelFormat == dml2_rgbe_alpha) - *surf_linear128_c = (((pitch_c * *BytePerPixelC) % 256) != 0); - } - } - - if (!(dml2_core_shared_is_420(SourcePixelFormat) || SourcePixelFormat == dml2_rgbe_alpha)) { - if (SurfaceTiling == dml2_sw_linear) { - *BlockHeight256BytesY = 1; - } else if (SourcePixelFormat == dml2_444_64) { - *BlockHeight256BytesY = 4; - } else if (SourcePixelFormat == dml2_444_8) { - *BlockHeight256BytesY = 16; - } else { - *BlockHeight256BytesY = 8; - } - *BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY; - *BlockHeight256BytesC = 0; - *BlockWidth256BytesC = 0; - } else { // dual plane - if (SurfaceTiling == dml2_sw_linear) { - *BlockHeight256BytesY = 1; - *BlockHeight256BytesC = 1; - } else if (SourcePixelFormat == dml2_rgbe_alpha) { - *BlockHeight256BytesY = 8; - *BlockHeight256BytesC = 16; - } else if (SourcePixelFormat == dml2_420_8) { - *BlockHeight256BytesY = 16; - *BlockHeight256BytesC = 8; - } else { - *BlockHeight256BytesY = 8; - *BlockHeight256BytesC = 8; - } - *BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY; - *BlockWidth256BytesC = 256U / *BytePerPixelC / *BlockHeight256BytesC; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: BlockWidth256BytesY = %u\n", __func__, *BlockWidth256BytesY); - dml2_printf("DML::%s: BlockHeight256BytesY = %u\n", __func__, *BlockHeight256BytesY); - dml2_printf("DML::%s: BlockWidth256BytesC = %u\n", __func__, *BlockWidth256BytesC); - dml2_printf("DML::%s: BlockHeight256BytesC = %u\n", __func__, *BlockHeight256BytesC); -#endif - - if (dml_get_gfx_version(SurfaceTiling) == 11) { - if (SurfaceTiling == dml2_gfx11_sw_linear) { - *MacroTileHeightY = *BlockHeight256BytesY; - *MacroTileWidthY = 256 / *BytePerPixelY / *MacroTileHeightY; - *MacroTileHeightC = *BlockHeight256BytesC; - if (*MacroTileHeightC == 0) { - *MacroTileWidthC = 0; - } else { - *MacroTileWidthC = 256 / *BytePerPixelC / *MacroTileHeightC; - } - } else if (SurfaceTiling == dml2_gfx11_sw_64kb_d || SurfaceTiling == dml2_gfx11_sw_64kb_d_t || SurfaceTiling == dml2_gfx11_sw_64kb_d_x || SurfaceTiling == dml2_gfx11_sw_64kb_r_x) { - *MacroTileHeightY = 16 * *BlockHeight256BytesY; - *MacroTileWidthY = 65536 / *BytePerPixelY / *MacroTileHeightY; - *MacroTileHeightC = 16 * *BlockHeight256BytesC; - if (*MacroTileHeightC == 0) { - *MacroTileWidthC = 0; - } else { - *MacroTileWidthC = 65536 / *BytePerPixelC / *MacroTileHeightC; - } - } else { - *MacroTileHeightY = 32 * *BlockHeight256BytesY; - *MacroTileWidthY = 65536 * 4 / *BytePerPixelY / *MacroTileHeightY; - *MacroTileHeightC = 32 * *BlockHeight256BytesC; - if (*MacroTileHeightC == 0) { - *MacroTileWidthC = 0; - } else { - *MacroTileWidthC = 65536 * 4 / *BytePerPixelC / *MacroTileHeightC; - } - } - } else { - unsigned int macro_tile_size_bytes = dml_get_tile_block_size_bytes(SurfaceTiling); - unsigned int macro_tile_scale = 1; // macro tile to 256B req scaling - - if (SurfaceTiling == dml2_sw_linear) { - macro_tile_scale = 1; - } else if (SurfaceTiling == dml2_sw_4kb_2d) { - macro_tile_scale = 4; - } else if (SurfaceTiling == dml2_sw_64kb_2d) { - macro_tile_scale = 16; - } else if (SurfaceTiling == dml2_sw_256kb_2d) { - macro_tile_scale = 32; - } else { - dml2_printf("ERROR: Invalid SurfaceTiling setting! val=%u\n", SurfaceTiling); - DML2_ASSERT(0); - } - - *MacroTileHeightY = macro_tile_scale * *BlockHeight256BytesY; - *MacroTileWidthY = macro_tile_size_bytes / *BytePerPixelY / *MacroTileHeightY; - *MacroTileHeightC = macro_tile_scale * *BlockHeight256BytesC; - if (*MacroTileHeightC == 0) { - *MacroTileWidthC = 0; - } else { - *MacroTileWidthC = macro_tile_size_bytes / *BytePerPixelC / *MacroTileHeightC; - } - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: MacroTileWidthY = %u\n", __func__, *MacroTileWidthY); - dml2_printf("DML::%s: MacroTileHeightY = %u\n", __func__, *MacroTileHeightY); - dml2_printf("DML::%s: MacroTileWidthC = %u\n", __func__, *MacroTileWidthC); - dml2_printf("DML::%s: MacroTileHeightC = %u\n", __func__, *MacroTileHeightC); -#endif -} - -static void CalculateSinglePipeDPPCLKAndSCLThroughput( - double HRatio, - double HRatioChroma, - double VRatio, - double VRatioChroma, - double MaxDCHUBToPSCLThroughput, - double MaxPSCLToLBThroughput, - double PixelClock, - enum dml2_source_format_class SourcePixelFormat, - unsigned int HTaps, - unsigned int HTapsChroma, - unsigned int VTaps, - unsigned int VTapsChroma, - - // Output - double *PSCL_THROUGHPUT, - double *PSCL_THROUGHPUT_CHROMA, - double *DPPCLKUsingSingleDPP) -{ - if (HRatio > 1) { - *PSCL_THROUGHPUT = math_min2(MaxDCHUBToPSCLThroughput, MaxPSCLToLBThroughput * HRatio / math_ceil2((double)HTaps / 6.0, 1.0)); - } else { - *PSCL_THROUGHPUT = math_min2(MaxDCHUBToPSCLThroughput, MaxPSCLToLBThroughput); - } - - double DPPCLKUsingSingleDPPLuma; - double DPPCLKUsingSingleDPPChroma; - - DPPCLKUsingSingleDPPLuma = PixelClock * math_max3(VTaps / 6 * math_min2(1, HRatio), HRatio * VRatio / *PSCL_THROUGHPUT, 1); - - if ((HTaps > 6 || VTaps > 6) && DPPCLKUsingSingleDPPLuma < 2 * PixelClock) - DPPCLKUsingSingleDPPLuma = 2 * PixelClock; - - if (!dml2_core_shared_is_420(SourcePixelFormat) && SourcePixelFormat != dml2_rgbe_alpha) { - *PSCL_THROUGHPUT_CHROMA = 0; - *DPPCLKUsingSingleDPP = DPPCLKUsingSingleDPPLuma; - } else { - if (HRatioChroma > 1) { - *PSCL_THROUGHPUT_CHROMA = math_min2(MaxDCHUBToPSCLThroughput, MaxPSCLToLBThroughput * HRatioChroma / math_ceil2((double)HTapsChroma / 6.0, 1.0)); - } else { - *PSCL_THROUGHPUT_CHROMA = math_min2(MaxDCHUBToPSCLThroughput, MaxPSCLToLBThroughput); - } - DPPCLKUsingSingleDPPChroma = PixelClock * math_max3(VTapsChroma / 6 * math_min2(1, HRatioChroma), - HRatioChroma * VRatioChroma / *PSCL_THROUGHPUT_CHROMA, 1); - if ((HTapsChroma > 6 || VTapsChroma > 6) && DPPCLKUsingSingleDPPChroma < 2 * PixelClock) - DPPCLKUsingSingleDPPChroma = 2 * PixelClock; - *DPPCLKUsingSingleDPP = math_max2(DPPCLKUsingSingleDPPLuma, DPPCLKUsingSingleDPPChroma); - } -} - -static void CalculateSwathWidth( - const struct dml2_display_cfg *display_cfg, - bool ForceSingleDPP, - unsigned int NumberOfActiveSurfaces, - enum dml2_odm_mode ODMMode[], - unsigned int BytePerPixY[], - unsigned int BytePerPixC[], - unsigned int Read256BytesBlockHeightY[], - unsigned int Read256BytesBlockHeightC[], - unsigned int Read256BytesBlockWidthY[], - unsigned int Read256BytesBlockWidthC[], - bool surf_linear128_l[], - bool surf_linear128_c[], - unsigned int DPPPerSurface[], - - // Output - unsigned int req_per_swath_ub_l[], - unsigned int req_per_swath_ub_c[], - unsigned int SwathWidthSingleDPPY[], - unsigned int SwathWidthSingleDPPC[], - unsigned int SwathWidthY[], // per-pipe - unsigned int SwathWidthC[], // per-pipe - unsigned int MaximumSwathHeightY[], - unsigned int MaximumSwathHeightC[], - unsigned int swath_width_luma_ub[], // per-pipe - unsigned int swath_width_chroma_ub[]) // per-pipe -{ - enum dml2_odm_mode MainSurfaceODMMode; - double odm_hactive_factor = 1.0; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: ForceSingleDPP = %u\n", __func__, ForceSingleDPP); - dml2_printf("DML::%s: NumberOfActiveSurfaces = %u\n", __func__, NumberOfActiveSurfaces); -#endif - - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - if (!dml_is_vertical_rotation(display_cfg->plane_descriptors[k].composition.rotation_angle)) { - SwathWidthSingleDPPY[k] = (unsigned int)display_cfg->plane_descriptors[k].composition.viewport.plane0.width; - } else { - SwathWidthSingleDPPY[k] = (unsigned int)display_cfg->plane_descriptors[k].composition.viewport.plane0.height; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u ViewportWidth=%u\n", __func__, k, display_cfg->plane_descriptors[k].composition.viewport.plane0.width); - dml2_printf("DML::%s: k=%u ViewportHeight=%u\n", __func__, k, display_cfg->plane_descriptors[k].composition.viewport.plane0.height); - dml2_printf("DML::%s: k=%u DPPPerSurface=%u\n", __func__, k, DPPPerSurface[k]); -#endif - - MainSurfaceODMMode = ODMMode[k]; - for (unsigned int j = 0; j < NumberOfActiveSurfaces; ++j) { - if (display_cfg->plane_descriptors[k].stream_index == j) { - MainSurfaceODMMode = ODMMode[j]; - } - } - - if (ForceSingleDPP) { - SwathWidthY[k] = SwathWidthSingleDPPY[k]; - } else { - if (MainSurfaceODMMode == dml2_odm_mode_combine_4to1) - odm_hactive_factor = 4.0; - else if (MainSurfaceODMMode == dml2_odm_mode_combine_3to1) - odm_hactive_factor = 3.0; - else if (MainSurfaceODMMode == dml2_odm_mode_combine_2to1) - odm_hactive_factor = 2.0; - - if (MainSurfaceODMMode == dml2_odm_mode_combine_4to1 || MainSurfaceODMMode == dml2_odm_mode_combine_3to1 || MainSurfaceODMMode == dml2_odm_mode_combine_2to1) { - SwathWidthY[k] = (unsigned int)(math_min2((double)SwathWidthSingleDPPY[k], math_round((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_active / odm_hactive_factor * display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio))); - } else if (DPPPerSurface[k] == 2) { - SwathWidthY[k] = SwathWidthSingleDPPY[k] / 2; - } else { - SwathWidthY[k] = SwathWidthSingleDPPY[k]; - } - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u HActive=%u\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_active); - dml2_printf("DML::%s: k=%u HRatio=%f\n", __func__, k, display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio); - dml2_printf("DML::%s: k=%u MainSurfaceODMMode=%u\n", __func__, k, MainSurfaceODMMode); - dml2_printf("DML::%s: k=%u SwathWidthSingleDPPY=%u\n", __func__, k, SwathWidthSingleDPPY[k]); - dml2_printf("DML::%s: k=%u SwathWidthY=%u\n", __func__, k, SwathWidthY[k]); -#endif - - if (dml2_core_shared_is_420(display_cfg->plane_descriptors[k].pixel_format)) { - SwathWidthC[k] = SwathWidthY[k] / 2; - SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k] / 2; - } else { - SwathWidthC[k] = SwathWidthY[k]; - SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k]; - } - - if (ForceSingleDPP == true) { - SwathWidthY[k] = SwathWidthSingleDPPY[k]; - SwathWidthC[k] = SwathWidthSingleDPPC[k]; - } - - unsigned int req_width_horz_y = Read256BytesBlockWidthY[k]; - unsigned int req_width_horz_c = Read256BytesBlockWidthC[k]; - - if (surf_linear128_l[k]) - req_width_horz_y = req_width_horz_y / 2; - - if (surf_linear128_c[k]) - req_width_horz_c = req_width_horz_c / 2; - - unsigned int surface_width_ub_l = (unsigned int)math_ceil2((double)display_cfg->plane_descriptors[k].surface.plane0.width, req_width_horz_y); - unsigned int surface_height_ub_l = (unsigned int)math_ceil2((double)display_cfg->plane_descriptors[k].surface.plane0.height, Read256BytesBlockHeightY[k]); - unsigned int surface_width_ub_c = (unsigned int)math_ceil2((double)display_cfg->plane_descriptors[k].surface.plane1.width, req_width_horz_c); - unsigned int surface_height_ub_c = (unsigned int)math_ceil2((double)display_cfg->plane_descriptors[k].surface.plane1.height, Read256BytesBlockHeightC[k]); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u surface_width_ub_l=%u\n", __func__, k, surface_width_ub_l); - dml2_printf("DML::%s: k=%u surface_height_ub_l=%u\n", __func__, k, surface_height_ub_l); - dml2_printf("DML::%s: k=%u surface_width_ub_c=%u\n", __func__, k, surface_width_ub_c); - dml2_printf("DML::%s: k=%u surface_height_ub_c=%u\n", __func__, k, surface_height_ub_c); - dml2_printf("DML::%s: k=%u req_width_horz_y=%u\n", __func__, k, req_width_horz_y); - dml2_printf("DML::%s: k=%u req_width_horz_c=%u\n", __func__, k, req_width_horz_c); - dml2_printf("DML::%s: k=%u Read256BytesBlockWidthY=%u\n", __func__, k, Read256BytesBlockWidthY[k]); - dml2_printf("DML::%s: k=%u Read256BytesBlockHeightY=%u\n", __func__, k, Read256BytesBlockHeightY[k]); - dml2_printf("DML::%s: k=%u Read256BytesBlockWidthC=%u\n", __func__, k, Read256BytesBlockWidthC[k]); - dml2_printf("DML::%s: k=%u Read256BytesBlockHeightC=%u\n", __func__, k, Read256BytesBlockHeightC[k]); - dml2_printf("DML::%s: k=%u req_width_horz_y=%u\n", __func__, k, req_width_horz_y); - dml2_printf("DML::%s: k=%u req_width_horz_c=%u\n", __func__, k, req_width_horz_c); - dml2_printf("DML::%s: k=%u ViewportStationary=%u\n", __func__, k, display_cfg->plane_descriptors[k].composition.viewport.stationary); - dml2_printf("DML::%s: k=%u DPPPerSurface=%u\n", __func__, k, DPPPerSurface[k]); -#endif - - req_per_swath_ub_l[k] = 0; - req_per_swath_ub_c[k] = 0; - if (!dml_is_vertical_rotation(display_cfg->plane_descriptors[k].composition.rotation_angle)) { - MaximumSwathHeightY[k] = Read256BytesBlockHeightY[k]; - MaximumSwathHeightC[k] = Read256BytesBlockHeightC[k]; - if (display_cfg->plane_descriptors[k].composition.viewport.stationary && DPPPerSurface[k] == 1) { - swath_width_luma_ub[k] = (unsigned int)(math_min2(surface_width_ub_l, math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane0.x_start + SwathWidthY[k] + req_width_horz_y - 1, req_width_horz_y) - math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane0.x_start, req_width_horz_y))); - } else { - swath_width_luma_ub[k] = (unsigned int)(math_min2(surface_width_ub_l, math_ceil2((double)SwathWidthY[k] - 1, req_width_horz_y) + req_width_horz_y)); - } - req_per_swath_ub_l[k] = swath_width_luma_ub[k] / req_width_horz_y; - - if (BytePerPixC[k] > 0) { - if (display_cfg->plane_descriptors[k].composition.viewport.stationary && DPPPerSurface[k] == 1) { - swath_width_chroma_ub[k] = (unsigned int)(math_min2(surface_width_ub_c, math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start + SwathWidthC[k] + req_width_horz_c - 1, req_width_horz_c) - math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start, req_width_horz_c))); - } else { - swath_width_chroma_ub[k] = (unsigned int)(math_min2(surface_width_ub_c, math_ceil2((double)SwathWidthC[k] - 1, req_width_horz_c) + req_width_horz_c)); - } - req_per_swath_ub_c[k] = swath_width_chroma_ub[k] / req_width_horz_c; - } else { - swath_width_chroma_ub[k] = 0; - } - } else { - MaximumSwathHeightY[k] = Read256BytesBlockWidthY[k]; - MaximumSwathHeightC[k] = Read256BytesBlockWidthC[k]; - - if (display_cfg->plane_descriptors[k].composition.viewport.stationary && DPPPerSurface[k] == 1) { - swath_width_luma_ub[k] = (unsigned int)(math_min2(surface_height_ub_l, math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane0.y_start + SwathWidthY[k] + Read256BytesBlockHeightY[k] - 1, Read256BytesBlockHeightY[k]) - math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane0.y_start, Read256BytesBlockHeightY[k]))); - } else { - swath_width_luma_ub[k] = (unsigned int)(math_min2(surface_height_ub_l, math_ceil2((double)SwathWidthY[k] - 1, Read256BytesBlockHeightY[k]) + Read256BytesBlockHeightY[k])); - } - req_per_swath_ub_l[k] = swath_width_luma_ub[k] / Read256BytesBlockHeightY[k]; - if (BytePerPixC[k] > 0) { - if (display_cfg->plane_descriptors[k].composition.viewport.stationary && DPPPerSurface[k] == 1) { - swath_width_chroma_ub[k] = (unsigned int)(math_min2(surface_height_ub_c, math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start + SwathWidthC[k] + Read256BytesBlockHeightC[k] - 1, Read256BytesBlockHeightC[k]) - math_floor2(display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start, Read256BytesBlockHeightC[k]))); - } else { - swath_width_chroma_ub[k] = (unsigned int)(math_min2(surface_height_ub_c, math_ceil2((double)SwathWidthC[k] - 1, Read256BytesBlockHeightC[k]) + Read256BytesBlockHeightC[k])); - } - req_per_swath_ub_c[k] = swath_width_chroma_ub[k] / Read256BytesBlockHeightC[k]; - } else { - swath_width_chroma_ub[k] = 0; - } - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u swath_width_luma_ub=%u\n", __func__, k, swath_width_luma_ub[k]); - dml2_printf("DML::%s: k=%u swath_width_chroma_ub=%u\n", __func__, k, swath_width_chroma_ub[k]); - dml2_printf("DML::%s: k=%u MaximumSwathHeightY=%u\n", __func__, k, MaximumSwathHeightY[k]); - dml2_printf("DML::%s: k=%u MaximumSwathHeightC=%u\n", __func__, k, MaximumSwathHeightC[k]); - dml2_printf("DML::%s: k=%u req_per_swath_ub_l=%u\n", __func__, k, req_per_swath_ub_l[k]); - dml2_printf("DML::%s: k=%u req_per_swath_ub_c=%u\n", __func__, k, req_per_swath_ub_c[k]); -#endif - - } -} - -static bool UnboundedRequest(bool unb_req_force_en, bool unb_req_force_val, unsigned int TotalNumberOfActiveDPP, bool NoChromaOrLinear) -{ - bool unb_req_ok = false; - bool unb_req_en = false; - - unb_req_ok = (TotalNumberOfActiveDPP == 1 && NoChromaOrLinear); - unb_req_en = unb_req_ok; - - if (unb_req_force_en) { - unb_req_en = unb_req_force_val && unb_req_ok; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: unb_req_force_en = %u\n", __func__, unb_req_force_en); - dml2_printf("DML::%s: unb_req_force_val = %u\n", __func__, unb_req_force_val); - dml2_printf("DML::%s: unb_req_ok = %u\n", __func__, unb_req_ok); - dml2_printf("DML::%s: unb_req_en = %u\n", __func__, unb_req_en); -#endif - return (unb_req_en); -} - -static void CalculateDETBufferSize(struct dml2_core_shared_calculate_det_buffer_size_params *p) -{ - unsigned int DETBufferSizePoolInKByte; - unsigned int NextDETBufferPieceInKByte; - bool DETPieceAssignedToThisSurfaceAlready[DML2_MAX_PLANES]; - bool NextPotentialSurfaceToAssignDETPieceFound; - unsigned int NextSurfaceToAssignDETPiece; - double TotalBandwidth; - double BandwidthOfSurfacesNotAssignedDETPiece; - unsigned int max_minDET; - unsigned int minDET; - unsigned int minDET_pipe; - unsigned int TotalBandwidthPerStream[DML2_MAX_PLANES] = { 0 }; - unsigned int TotalPixelRate = 0; - unsigned int DETBudgetPerStream[DML2_MAX_PLANES] = { 0 }; - unsigned int RemainingDETBudgetPerStream[DML2_MAX_PLANES] = { 0 }; - unsigned int IdealDETBudget, DeltaDETBudget; - bool MinimizeReallocationSuccess = false; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: ForceSingleDPP = %u\n", __func__, p->ForceSingleDPP); - dml2_printf("DML::%s: nomDETInKByte = %u\n", __func__, p->nomDETInKByte); - dml2_printf("DML::%s: NumberOfActiveSurfaces = %u\n", __func__, p->NumberOfActiveSurfaces); - dml2_printf("DML::%s: UnboundedRequestEnabled = %u\n", __func__, p->UnboundedRequestEnabled); - dml2_printf("DML::%s: MaxTotalDETInKByte = %u\n", __func__, p->MaxTotalDETInKByte); - dml2_printf("DML::%s: ConfigReturnBufferSizeInKByte = %u\n", __func__, p->ConfigReturnBufferSizeInKByte); - dml2_printf("DML::%s: MinCompressedBufferSizeInKByte = %u\n", __func__, p->MinCompressedBufferSizeInKByte); - dml2_printf("DML::%s: CompressedBufferSegmentSizeInkByte = %u\n", __func__, p->CompressedBufferSegmentSizeInkByte); -#endif - - // Note: Will use default det size if that fits 2 swaths - if (p->UnboundedRequestEnabled) { - if (p->display_cfg->plane_descriptors[0].overrides.det_size_override_kb > 0) { - p->DETBufferSizeInKByte[0] = p->display_cfg->plane_descriptors[0].overrides.det_size_override_kb; - } else { - p->DETBufferSizeInKByte[0] = (unsigned int)math_max2(128.0, math_ceil2(2.0 * ((double)p->full_swath_bytes_l[0] + (double)p->full_swath_bytes_c[0]) / 1024.0, p->ConfigReturnBufferSegmentSizeInkByte)); - } - *p->CompressedBufferSizeInkByte = p->ConfigReturnBufferSizeInKByte - p->DETBufferSizeInKByte[0]; - } else { - DETBufferSizePoolInKByte = p->MaxTotalDETInKByte; - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - p->DETBufferSizeInKByte[k] = 0; - if (dml2_core_shared_is_420(p->display_cfg->plane_descriptors[k].pixel_format)) { - max_minDET = p->nomDETInKByte - p->ConfigReturnBufferSegmentSizeInkByte; - } else { - max_minDET = p->nomDETInKByte; - } - minDET = 128; - minDET_pipe = 0; - - // add DET resource until can hold 2 full swaths - while (minDET <= max_minDET && minDET_pipe == 0) { - if (2.0 * ((double)p->full_swath_bytes_l[k] + (double)p->full_swath_bytes_c[k]) / 1024.0 <= minDET) - minDET_pipe = minDET; - minDET = minDET + p->ConfigReturnBufferSegmentSizeInkByte; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u minDET = %u\n", __func__, k, minDET); - dml2_printf("DML::%s: k=%u max_minDET = %u\n", __func__, k, max_minDET); - dml2_printf("DML::%s: k=%u minDET_pipe = %u\n", __func__, k, minDET_pipe); - dml2_printf("DML::%s: k=%u full_swath_bytes_l = %u\n", __func__, k, p->full_swath_bytes_l[k]); - dml2_printf("DML::%s: k=%u full_swath_bytes_c = %u\n", __func__, k, p->full_swath_bytes_c[k]); -#endif - - if (minDET_pipe == 0) { - minDET_pipe = (unsigned int)(math_max2(128, math_ceil2(((double)p->full_swath_bytes_l[k] + (double)p->full_swath_bytes_c[k]) / 1024.0, p->ConfigReturnBufferSegmentSizeInkByte))); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u minDET_pipe = %u (assume each plane take half DET)\n", __func__, k, minDET_pipe); -#endif - } - - if (dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k])) { - p->DETBufferSizeInKByte[k] = 0; - } else if (p->display_cfg->plane_descriptors[k].overrides.det_size_override_kb > 0) { - p->DETBufferSizeInKByte[k] = p->display_cfg->plane_descriptors[k].overrides.det_size_override_kb; - DETBufferSizePoolInKByte = DETBufferSizePoolInKByte - (p->ForceSingleDPP ? 1 : p->DPPPerSurface[k]) * p->display_cfg->plane_descriptors[k].overrides.det_size_override_kb; - } else if ((p->ForceSingleDPP ? 1 : p->DPPPerSurface[k]) * minDET_pipe <= DETBufferSizePoolInKByte) { - p->DETBufferSizeInKByte[k] = minDET_pipe; - DETBufferSizePoolInKByte = DETBufferSizePoolInKByte - (p->ForceSingleDPP ? 1 : p->DPPPerSurface[k]) * minDET_pipe; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u DPPPerSurface = %u\n", __func__, k, p->DPPPerSurface[k]); - dml2_printf("DML::%s: k=%u DETSizeOverride = %u\n", __func__, k, p->display_cfg->plane_descriptors[k].overrides.det_size_override_kb); - dml2_printf("DML::%s: k=%u DETBufferSizeInKByte = %u\n", __func__, k, p->DETBufferSizeInKByte[k]); - dml2_printf("DML::%s: DETBufferSizePoolInKByte = %u\n", __func__, DETBufferSizePoolInKByte); -#endif - } - - if (p->display_cfg->minimize_det_reallocation) { - MinimizeReallocationSuccess = true; - // To minimize det reallocation, we don't distribute based on each surfaces bandwidth proportional to the global - // but rather distribute DET across streams proportionally based on pixel rate, and only distribute based on - // bandwidth between the planes on the same stream. This ensures that large scale re-distribution only on a - // stream count and/or pixel rate change, which is must less likely then general bandwidth changes per plane. - - // Calculate total pixel rate - for (unsigned int k = 0; k < p->display_cfg->num_streams; ++k) { - TotalPixelRate += p->display_cfg->stream_descriptors[k].timing.pixel_clock_khz; - } - - // Calculate per stream DET budget - for (unsigned int k = 0; k < p->display_cfg->num_streams; ++k) { - DETBudgetPerStream[k] = (unsigned int)((double)p->display_cfg->stream_descriptors[k].timing.pixel_clock_khz * p->MaxTotalDETInKByte / TotalPixelRate); - RemainingDETBudgetPerStream[k] = DETBudgetPerStream[k]; - } - - // Calculate the per stream total bandwidth - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - if (!dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k])) { - TotalBandwidthPerStream[p->display_cfg->plane_descriptors[k].stream_index] += (unsigned int)(p->ReadBandwidthLuma[k] + p->ReadBandwidthChroma[k]); - - // Check the minimum can be satisfied by budget - if (RemainingDETBudgetPerStream[p->display_cfg->plane_descriptors[k].stream_index] >= p->DETBufferSizeInKByte[k]) { - RemainingDETBudgetPerStream[p->display_cfg->plane_descriptors[k].stream_index] -= p->DETBufferSizeInKByte[k]; - } else { - MinimizeReallocationSuccess = false; - break; - } - } - } - - if (MinimizeReallocationSuccess) { - // Since a fixed budget per stream is sufficient to satisfy the minimums, just re-distribute each streams - // budget proportionally across its planes - - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - if (!dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k])) { - IdealDETBudget = (unsigned int)(((p->ReadBandwidthLuma[k] + p->ReadBandwidthChroma[k]) / TotalBandwidthPerStream[p->display_cfg->plane_descriptors[k].stream_index]) - * DETBudgetPerStream[p->display_cfg->plane_descriptors[k].stream_index]); - - if (IdealDETBudget > p->DETBufferSizeInKByte[k]) { - DeltaDETBudget = IdealDETBudget - p->DETBufferSizeInKByte[k]; - if (DeltaDETBudget > RemainingDETBudgetPerStream[p->display_cfg->plane_descriptors[k].stream_index]) - DeltaDETBudget = RemainingDETBudgetPerStream[p->display_cfg->plane_descriptors[k].stream_index]; - - p->DETBufferSizeInKByte[k] += DeltaDETBudget; - RemainingDETBudgetPerStream[p->display_cfg->plane_descriptors[k].stream_index] -= DeltaDETBudget; - } - - // Split among the pipes per the plane - p->DETBufferSizeInKByte[k] = (unsigned int)((double)p->DETBufferSizeInKByte[k] / (p->ForceSingleDPP ? 1 : p->DPPPerSurface[k])); - - // Round down to segment size - p->DETBufferSizeInKByte[k] = (p->DETBufferSizeInKByte[k] / p->CompressedBufferSegmentSizeInkByte) * p->CompressedBufferSegmentSizeInkByte; - } - } - } - } - - if (!MinimizeReallocationSuccess) { - TotalBandwidth = 0; - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - if (!dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k])) { - TotalBandwidth = TotalBandwidth + p->ReadBandwidthLuma[k] + p->ReadBandwidthChroma[k]; - } - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: --- Before bandwidth adjustment ---\n", __func__); - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - dml2_printf("DML::%s: k=%u DETBufferSizeInKByte = %u\n", __func__, k, p->DETBufferSizeInKByte[k]); - } - dml2_printf("DML::%s: --- DET allocation with bandwidth ---\n", __func__); -#endif - dml2_printf("DML::%s: TotalBandwidth = %f\n", __func__, TotalBandwidth); - BandwidthOfSurfacesNotAssignedDETPiece = TotalBandwidth; - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - - if (dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k])) { - DETPieceAssignedToThisSurfaceAlready[k] = true; - } else if (p->display_cfg->plane_descriptors[k].overrides.det_size_override_kb > 0 || (((double)(p->ForceSingleDPP ? 1 : p->DPPPerSurface[k]) * (double)p->DETBufferSizeInKByte[k] / (double)p->MaxTotalDETInKByte) >= ((p->ReadBandwidthLuma[k] + p->ReadBandwidthChroma[k]) / TotalBandwidth))) { - DETPieceAssignedToThisSurfaceAlready[k] = true; - BandwidthOfSurfacesNotAssignedDETPiece = BandwidthOfSurfacesNotAssignedDETPiece - p->ReadBandwidthLuma[k] - p->ReadBandwidthChroma[k]; - } else { - DETPieceAssignedToThisSurfaceAlready[k] = false; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u DETPieceAssignedToThisSurfaceAlready = %u\n", __func__, k, DETPieceAssignedToThisSurfaceAlready[k]); - dml2_printf("DML::%s: k=%u BandwidthOfSurfacesNotAssignedDETPiece = %f\n", __func__, k, BandwidthOfSurfacesNotAssignedDETPiece); -#endif - } - - for (unsigned int j = 0; j < p->NumberOfActiveSurfaces; ++j) { - NextPotentialSurfaceToAssignDETPieceFound = false; - NextSurfaceToAssignDETPiece = 0; - - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: j=%u k=%u, ReadBandwidthLuma[k] = %f\n", __func__, j, k, p->ReadBandwidthLuma[k]); - dml2_printf("DML::%s: j=%u k=%u, ReadBandwidthChroma[k] = %f\n", __func__, j, k, p->ReadBandwidthChroma[k]); - dml2_printf("DML::%s: j=%u k=%u, ReadBandwidthLuma[Next] = %f\n", __func__, j, k, p->ReadBandwidthLuma[NextSurfaceToAssignDETPiece]); - dml2_printf("DML::%s: j=%u k=%u, ReadBandwidthChroma[Next] = %f\n", __func__, j, k, p->ReadBandwidthChroma[NextSurfaceToAssignDETPiece]); - dml2_printf("DML::%s: j=%u k=%u, NextSurfaceToAssignDETPiece = %u\n", __func__, j, k, NextSurfaceToAssignDETPiece); -#endif - if (!DETPieceAssignedToThisSurfaceAlready[k] && (!NextPotentialSurfaceToAssignDETPieceFound || - p->ReadBandwidthLuma[k] + p->ReadBandwidthChroma[k] < p->ReadBandwidthLuma[NextSurfaceToAssignDETPiece] + p->ReadBandwidthChroma[NextSurfaceToAssignDETPiece])) { - NextSurfaceToAssignDETPiece = k; - NextPotentialSurfaceToAssignDETPieceFound = true; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: j=%u k=%u, DETPieceAssignedToThisSurfaceAlready = %u\n", __func__, j, k, DETPieceAssignedToThisSurfaceAlready[k]); - dml2_printf("DML::%s: j=%u k=%u, NextPotentialSurfaceToAssignDETPieceFound = %u\n", __func__, j, k, NextPotentialSurfaceToAssignDETPieceFound); -#endif - } - - if (NextPotentialSurfaceToAssignDETPieceFound) { - NextDETBufferPieceInKByte = (unsigned int)(math_min2( - math_round((double)DETBufferSizePoolInKByte * (p->ReadBandwidthLuma[NextSurfaceToAssignDETPiece] + p->ReadBandwidthChroma[NextSurfaceToAssignDETPiece]) / BandwidthOfSurfacesNotAssignedDETPiece / - ((p->ForceSingleDPP ? 1 : p->DPPPerSurface[NextSurfaceToAssignDETPiece]) * p->ConfigReturnBufferSegmentSizeInkByte)) - * (p->ForceSingleDPP ? 1 : p->DPPPerSurface[NextSurfaceToAssignDETPiece]) * p->ConfigReturnBufferSegmentSizeInkByte, - math_floor2((double)DETBufferSizePoolInKByte, (p->ForceSingleDPP ? 1 : p->DPPPerSurface[NextSurfaceToAssignDETPiece]) * p->ConfigReturnBufferSegmentSizeInkByte))); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: j=%u, DETBufferSizePoolInKByte = %u\n", __func__, j, DETBufferSizePoolInKByte); - dml2_printf("DML::%s: j=%u, NextSurfaceToAssignDETPiece = %u\n", __func__, j, NextSurfaceToAssignDETPiece); - dml2_printf("DML::%s: j=%u, ReadBandwidthLuma[%u] = %f\n", __func__, j, NextSurfaceToAssignDETPiece, p->ReadBandwidthLuma[NextSurfaceToAssignDETPiece]); - dml2_printf("DML::%s: j=%u, ReadBandwidthChroma[%u] = %f\n", __func__, j, NextSurfaceToAssignDETPiece, p->ReadBandwidthChroma[NextSurfaceToAssignDETPiece]); - dml2_printf("DML::%s: j=%u, BandwidthOfSurfacesNotAssignedDETPiece = %f\n", __func__, j, BandwidthOfSurfacesNotAssignedDETPiece); - dml2_printf("DML::%s: j=%u, NextDETBufferPieceInKByte = %u\n", __func__, j, NextDETBufferPieceInKByte); - dml2_printf("DML::%s: j=%u, DETBufferSizeInKByte[%u] increases from %u ", __func__, j, NextSurfaceToAssignDETPiece, p->DETBufferSizeInKByte[NextSurfaceToAssignDETPiece]); -#endif - - p->DETBufferSizeInKByte[NextSurfaceToAssignDETPiece] = p->DETBufferSizeInKByte[NextSurfaceToAssignDETPiece] + NextDETBufferPieceInKByte / (p->ForceSingleDPP ? 1 : p->DPPPerSurface[NextSurfaceToAssignDETPiece]); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("to %u\n", p->DETBufferSizeInKByte[NextSurfaceToAssignDETPiece]); -#endif - - DETBufferSizePoolInKByte = DETBufferSizePoolInKByte - NextDETBufferPieceInKByte; - DETPieceAssignedToThisSurfaceAlready[NextSurfaceToAssignDETPiece] = true; - BandwidthOfSurfacesNotAssignedDETPiece = BandwidthOfSurfacesNotAssignedDETPiece - (p->ReadBandwidthLuma[NextSurfaceToAssignDETPiece] + p->ReadBandwidthChroma[NextSurfaceToAssignDETPiece]); - } - } - } - *p->CompressedBufferSizeInkByte = p->MinCompressedBufferSizeInKByte; - } - *p->CompressedBufferSizeInkByte = *p->CompressedBufferSizeInkByte * p->CompressedBufferSegmentSizeInkByte / p->ConfigReturnBufferSegmentSizeInkByte; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: --- After bandwidth adjustment ---\n", __func__); - dml2_printf("DML::%s: CompressedBufferSizeInkByte = %u\n", __func__, *p->CompressedBufferSizeInkByte); - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - dml2_printf("DML::%s: k=%u DETBufferSizeInKByte = %u (TotalReadBandWidth=%f)\n", __func__, k, p->DETBufferSizeInKByte[k], p->ReadBandwidthLuma[k] + p->ReadBandwidthChroma[k]); - } -#endif -} - -static double CalculateRequiredDispclk( - enum dml2_odm_mode ODMMode, - double PixelClock) -{ - - if (ODMMode == dml2_odm_mode_combine_4to1) { - return PixelClock / 4.0; - } else if (ODMMode == dml2_odm_mode_combine_3to1) { - return PixelClock / 3.0; - } else if (ODMMode == dml2_odm_mode_combine_2to1) { - return PixelClock / 2.0; - } else { - return PixelClock; - } -} - -static double TruncToValidBPP( - struct dml2_core_shared_TruncToValidBPP_locals *l, - double LinkBitRate, - unsigned int Lanes, - unsigned int HTotal, - unsigned int HActive, - double PixelClock, - double DesiredBPP, - bool DSCEnable, - enum dml2_output_encoder_class Output, - enum dml2_output_format_class Format, - unsigned int DSCInputBitPerComponent, - unsigned int DSCSlices, - unsigned int AudioRate, - unsigned int AudioLayout, - enum dml2_odm_mode ODMModeNoDSC, - enum dml2_odm_mode ODMModeDSC, - - // Output - unsigned int *RequiredSlots) -{ - double MaxLinkBPP; - unsigned int MinDSCBPP; - double MaxDSCBPP; - unsigned int NonDSCBPP0; - unsigned int NonDSCBPP1; - unsigned int NonDSCBPP2; - enum dml2_odm_mode ODMMode; - - if (Format == dml2_420) { - NonDSCBPP0 = 12; - NonDSCBPP1 = 15; - NonDSCBPP2 = 18; - MinDSCBPP = 6; - MaxDSCBPP = 16; - } else if (Format == dml2_444) { - NonDSCBPP0 = 24; - NonDSCBPP1 = 30; - NonDSCBPP2 = 36; - MinDSCBPP = 8; - MaxDSCBPP = 16; - } else { - if (Output == dml2_hdmi || Output == dml2_hdmifrl) { - NonDSCBPP0 = 24; - NonDSCBPP1 = 24; - NonDSCBPP2 = 24; - } else { - NonDSCBPP0 = 16; - NonDSCBPP1 = 20; - NonDSCBPP2 = 24; - } - if (Format == dml2_n422 || Output == dml2_hdmifrl) { - MinDSCBPP = 7; - MaxDSCBPP = 16; - } else { - MinDSCBPP = 8; - MaxDSCBPP = 16; - } - } - if (Output == dml2_dp2p0) { - MaxLinkBPP = LinkBitRate * Lanes / PixelClock * 128.0 / 132.0 * 383.0 / 384.0 * 65536.0 / 65540.0; - } else if (DSCEnable && Output == dml2_dp) { - MaxLinkBPP = LinkBitRate / 10.0 * 8.0 * Lanes / PixelClock * (1 - 2.4 / 100); - } else { - MaxLinkBPP = LinkBitRate / 10.0 * 8.0 * Lanes / PixelClock; - } - - ODMMode = DSCEnable ? ODMModeDSC : ODMModeNoDSC; - - if (ODMMode == dml2_odm_mode_split_1to2) { - MaxLinkBPP = 2 * MaxLinkBPP; - } - - if (DesiredBPP == 0) { - if (DSCEnable) { - if (MaxLinkBPP < MinDSCBPP) { - return __DML2_CALCS_DPP_INVALID__; - } else if (MaxLinkBPP >= MaxDSCBPP) { - return MaxDSCBPP; - } else { - return math_floor2(16.0 * MaxLinkBPP, 1.0) / 16.0; - } - } else { - if (MaxLinkBPP >= NonDSCBPP2) { - return NonDSCBPP2; - } else if (MaxLinkBPP >= NonDSCBPP1) { - return NonDSCBPP1; - } else if (MaxLinkBPP >= NonDSCBPP0) { - return NonDSCBPP0; - } else { - return __DML2_CALCS_DPP_INVALID__; - } - } - } else { - if (!((DSCEnable == false && (DesiredBPP == NonDSCBPP2 || DesiredBPP == NonDSCBPP1 || DesiredBPP == NonDSCBPP0)) || - (DSCEnable && DesiredBPP >= MinDSCBPP && DesiredBPP <= MaxDSCBPP))) { - return __DML2_CALCS_DPP_INVALID__; - } else { - return DesiredBPP; - } - } -} - -// updated for dcn4 -static unsigned int dscceComputeDelay( - unsigned int bpc, - double BPP, - unsigned int sliceWidth, - unsigned int numSlices, - enum dml2_output_format_class pixelFormat, - enum dml2_output_encoder_class Output) -{ - // valid bpc = source bits per component in the set of {8, 10, 12} - // valid bpp = increments of 1/16 of a bit - // min = 6/7/8 in N420/N422/444, respectively - // max = such that compression is 1:1 - //valid sliceWidth = number of pixels per slice line, must be less than or equal to 5184/numSlices (or 4096/numSlices in 420 mode) - //valid numSlices = number of slices in the horiziontal direction per DSC engine in the set of {1, 2, 3, 4} - //valid pixelFormat = pixel/color format in the set of {:N444_RGB, :S422, :N422, :N420} - - // fixed value - unsigned int rcModelSize = 8192; - - // N422/N420 operate at 2 pixels per clock - unsigned int pixelsPerClock, padding_pixels, ssm_group_priming_delay, ssm_pipeline_delay, obsm_pipeline_delay, slice_padded_pixels, ixd_plus_padding, ixd_plus_padding_groups, cycles_per_group, group_delay, pipeline_delay, pixels, additional_group_delay, lines_to_reach_ixd, groups_to_reach_ixd, slice_width_groups, initial_xmit_delay, number_of_lines_to_reach_ixd, slice_width_modified; - - - if (pixelFormat == dml2_420) - pixelsPerClock = 2; - // #all other modes operate at 1 pixel per clock - else if (pixelFormat == dml2_444) - pixelsPerClock = 1; - else if (pixelFormat == dml2_n422 || Output == dml2_hdmifrl) - pixelsPerClock = 2; - else - pixelsPerClock = 1; - - //initial transmit delay as per PPS - initial_xmit_delay = (unsigned int)(math_round(rcModelSize / 2.0 / BPP / pixelsPerClock)); - - //slice width as seen by dscc_bcl in pixels or pixels pairs (depending on number of pixels per pixel container based on pixel format) - slice_width_modified = (pixelFormat == dml2_444 || pixelFormat == dml2_420 || Output == dml2_hdmifrl) ? sliceWidth / 2 : sliceWidth; - - padding_pixels = ((slice_width_modified % 3) != 0) ? (3 - (slice_width_modified % 3)) * (initial_xmit_delay / slice_width_modified) : 0; - - if ((3.0 * pixelsPerClock * BPP) >= ((double)((initial_xmit_delay + 2) / 3) * (double)(3 + (pixelFormat == dml2_n422)))) { - if ((initial_xmit_delay + padding_pixels) % 3 == 1) { - initial_xmit_delay++; - } - } - - - //sub-stream multiplexer balance fifo priming delay in groups as per dsc standard - if (bpc == 8) - ssm_group_priming_delay = 83; - else if (bpc == 10) - ssm_group_priming_delay = 91; - else if (bpc == 12) - ssm_group_priming_delay = 115; - else if (bpc == 14) - ssm_group_priming_delay = 123; - else - ssm_group_priming_delay = 128; - - //slice width in groups is rounded up to the nearest group as DSC adds padded pixels such that there are an integer number of groups per slice - slice_width_groups = (slice_width_modified + 2) / 3; - - //determine number of padded pixels in the last group of a slice line, computed as - slice_padded_pixels = 3 * slice_width_groups - slice_width_modified; - - - - - //determine integer number of complete slice lines required to reach initial transmit delay without ssm delay considered - number_of_lines_to_reach_ixd = initial_xmit_delay / slice_width_modified; - - //increase initial transmit delay by the number of padded pixels added to a slice line multipled by the integer number of complete lines to reach initial transmit delay - //this step is necessary as each padded pixel added takes up a clock cycle and, therefore, adds to the overall delay - ixd_plus_padding = initial_xmit_delay + slice_padded_pixels * number_of_lines_to_reach_ixd; - - //convert the padded initial transmit delay from pixels to groups by rounding up to the nearest group as DSC processes in groups of pixels - ixd_plus_padding_groups = (ixd_plus_padding + 2) / 3; - - //number of groups required for a slice to reach initial transmit delay is the sum of the padded initial transmit delay plus the ssm group priming delay - groups_to_reach_ixd = ixd_plus_padding_groups + ssm_group_priming_delay; - - - //number of lines required to reach padded initial transmit delay in groups in slices to the left of the last horizontal slice - //needs to be rounded up as a complete slice lines are buffered prior to initial transmit delay being reached in the last horizontal slice - lines_to_reach_ixd = (groups_to_reach_ixd + slice_width_groups - 1) / slice_width_groups; //round up lines to reach ixd to next - - //determine if there are non-zero number of pixels reached in the group where initial transmit delay is reached - //an additional group time (i.e., 3 pixel times) is required before the first output if there are no additional pixels beyond initial transmit delay - additional_group_delay = ((initial_xmit_delay - number_of_lines_to_reach_ixd * slice_width_modified) % 3) == 0 ? 1 : 0; - - //number of pipeline delay cycles in the ssm block (can be determined empirically or analytically by inspecting the ssm block) - ssm_pipeline_delay = 2; - - //number of pipe delay cycles in the obsm block (can be determined empirically or analytically by inspecting the obsm block) - obsm_pipeline_delay = 1; - - //a group of pixels is worth 6 pixels in N422/N420 mode or 3 pixels in all other modes - if (pixelFormat == dml2_420 || pixelFormat == dml2_444 || pixelFormat == dml2_n422 || Output == dml2_hdmifrl) - cycles_per_group = 6; - else - cycles_per_group = 3; - //delay of the bit stream contruction layer in pixels is the sum of: - //1. number of pixel containers in a slice line multipled by the number of lines required to reach initial transmit delay multipled by number of slices to the left of the last horizontal slice - //2. number of pixel containers required to reach initial transmit delay (specifically, in the last horizontal slice) - //3. additional group of delay if initial transmit delay is reached exactly in a group - //4. ssm and obsm pipeline delay (i.e., clock cycles of delay) - group_delay = (lines_to_reach_ixd * slice_width_groups * (numSlices - 1)) + groups_to_reach_ixd + additional_group_delay; - pipeline_delay = ssm_pipeline_delay + obsm_pipeline_delay; - - //pixel delay is group_delay (converted to pixels) + pipeline, however, first group is a special case since it is processed as soon as it arrives (i.e., in 3 cycles regardless of pixel format) - pixels = (group_delay - 1) * cycles_per_group + 3 + pipeline_delay; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: bpc: %u\n", __func__, bpc); - dml2_printf("DML::%s: BPP: %f\n", __func__, BPP); - dml2_printf("DML::%s: sliceWidth: %u\n", __func__, sliceWidth); - dml2_printf("DML::%s: numSlices: %u\n", __func__, numSlices); - dml2_printf("DML::%s: pixelFormat: %u\n", __func__, pixelFormat); - dml2_printf("DML::%s: Output: %u\n", __func__, Output); - dml2_printf("DML::%s: pixels: %u\n", __func__, pixels); -#endif - return pixels; -} - - -//updated in dcn4 -static unsigned int dscComputeDelay(enum dml2_output_format_class pixelFormat, enum dml2_output_encoder_class Output) -{ - unsigned int Delay = 0; - unsigned int dispclk_per_dscclk = 3; - - // sfr - Delay = Delay + 2; - - if (pixelFormat == dml2_420 || pixelFormat == dml2_n422 || (Output == dml2_hdmifrl && pixelFormat != dml2_444)) { - dispclk_per_dscclk = 3 * 2; - } - - if (pixelFormat == dml2_420) { - //dscc top delay for pixel compression layer - Delay = Delay + 16 * dispclk_per_dscclk; - - // dscc - input deserializer - Delay = Delay + 5; - - // dscc - input cdc fifo - Delay = Delay + 1 + 4 * dispclk_per_dscclk; - - // dscc - output cdc fifo - Delay = Delay + 3 + 1 * dispclk_per_dscclk; - - // dscc - cdc uncertainty - Delay = Delay + 3 + 3 * dispclk_per_dscclk; - } else if (pixelFormat == dml2_n422 || (Output == dml2_hdmifrl && pixelFormat != dml2_444)) { - //dscc top delay for pixel compression layer - Delay = Delay + 16 * dispclk_per_dscclk; - // dsccif - Delay = Delay + 1; - // dscc - input deserializer - Delay = Delay + 5; - // dscc - input cdc fifo - Delay = Delay + 1 + 4 * dispclk_per_dscclk; - - - // dscc - output cdc fifo - Delay = Delay + 3 + 1 * dispclk_per_dscclk; - // dscc - cdc uncertainty - Delay = Delay + 3 + 3 * dispclk_per_dscclk; - } else if (pixelFormat == dml2_s422) { - //dscc top delay for pixel compression layer - Delay = Delay + 17 * dispclk_per_dscclk; - - // dscc - input deserializer - Delay = Delay + 3; - // dscc - input cdc fifo - Delay = Delay + 1 + 4 * dispclk_per_dscclk; - // dscc - output cdc fifo - Delay = Delay + 3 + 1 * dispclk_per_dscclk; - // dscc - cdc uncertainty - Delay = Delay + 3 + 3 * dispclk_per_dscclk; - } else { - //dscc top delay for pixel compression layer - Delay = Delay + 16 * dispclk_per_dscclk; - // dscc - input deserializer - Delay = Delay + 3; - // dscc - input cdc fifo - Delay = Delay + 1 + 4 * dispclk_per_dscclk; - // dscc - output cdc fifo - Delay = Delay + 3 + 1 * dispclk_per_dscclk; - - // dscc - cdc uncertainty - Delay = Delay + 3 + 3 * dispclk_per_dscclk; - } - - // sft - Delay = Delay + 1; -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: pixelFormat = %u\n", __func__, pixelFormat); - dml2_printf("DML::%s: Delay = %u\n", __func__, Delay); -#endif - - return Delay; -} - -static unsigned int CalculateHostVMDynamicLevels( - bool GPUVMEnable, - bool HostVMEnable, - unsigned int HostVMMinPageSize, - unsigned int HostVMMaxNonCachedPageTableLevels) -{ - unsigned int HostVMDynamicLevels = 0; - - if (GPUVMEnable && HostVMEnable) { - if (HostVMMinPageSize < 2048) - HostVMDynamicLevels = HostVMMaxNonCachedPageTableLevels; - else if (HostVMMinPageSize >= 2048 && HostVMMinPageSize < 1048576) - HostVMDynamicLevels = (unsigned int)math_max2(0, (double)HostVMMaxNonCachedPageTableLevels - 1); - else - HostVMDynamicLevels = (unsigned int)math_max2(0, (double)HostVMMaxNonCachedPageTableLevels - 2); - } else { - HostVMDynamicLevels = 0; - } - return HostVMDynamicLevels; -} - -static unsigned int CalculateVMAndRowBytes(struct dml2_core_shared_calculate_vm_and_row_bytes_params *p) -{ - unsigned int extra_dpde_bytes; - unsigned int extra_mpde_bytes; - unsigned int MacroTileSizeBytes; - unsigned int vp_height_dpte_ub; - - unsigned int meta_surface_bytes; - unsigned int vm_bytes; - unsigned int vp_height_meta_ub; - - *p->MetaRequestHeight = 8 * p->BlockHeight256Bytes; - *p->MetaRequestWidth = 8 * p->BlockWidth256Bytes; - if (p->SurfaceTiling == dml2_sw_linear) { - *p->meta_row_height = 32; - *p->meta_row_width = (unsigned int)(math_floor2(p->ViewportXStart + p->SwathWidth + *p->MetaRequestWidth - 1, *p->MetaRequestWidth) - math_floor2(p->ViewportXStart, *p->MetaRequestWidth)); - *p->meta_row_bytes = (unsigned int)(*p->meta_row_width * *p->MetaRequestHeight * p->BytePerPixel / 256.0); // FIXME_DCN4SW missing in old code but no dcc for linear anyways? - } else if (!dml_is_vertical_rotation(p->RotationAngle)) { - *p->meta_row_height = *p->MetaRequestHeight; - if (p->ViewportStationary && p->NumberOfDPPs == 1) { - *p->meta_row_width = (unsigned int)(math_floor2(p->ViewportXStart + p->SwathWidth + *p->MetaRequestWidth - 1, *p->MetaRequestWidth) - math_floor2(p->ViewportXStart, *p->MetaRequestWidth)); - } else { - *p->meta_row_width = (unsigned int)(math_ceil2(p->SwathWidth - 1, *p->MetaRequestWidth) + *p->MetaRequestWidth); - } - *p->meta_row_bytes = (unsigned int)(*p->meta_row_width * *p->MetaRequestHeight * p->BytePerPixel / 256.0); - } else { - *p->meta_row_height = *p->MetaRequestWidth; - if (p->ViewportStationary && p->NumberOfDPPs == 1) { - *p->meta_row_width = (unsigned int)(math_floor2(p->ViewportYStart + p->ViewportHeight + *p->MetaRequestHeight - 1, *p->MetaRequestHeight) - math_floor2(p->ViewportYStart, *p->MetaRequestHeight)); - } else { - *p->meta_row_width = (unsigned int)(math_ceil2(p->SwathWidth - 1, *p->MetaRequestHeight) + *p->MetaRequestHeight); - } - *p->meta_row_bytes = (unsigned int)(*p->meta_row_width * *p->MetaRequestWidth * p->BytePerPixel / 256.0); - } - - if (p->ViewportStationary && p->is_phantom && (p->NumberOfDPPs == 1 || !dml_is_vertical_rotation(p->RotationAngle))) { - vp_height_meta_ub = (unsigned int)(math_floor2(p->ViewportYStart + p->ViewportHeight + 64 * p->BlockHeight256Bytes - 1, 64 * p->BlockHeight256Bytes) - math_floor2(p->ViewportYStart, 64 * p->BlockHeight256Bytes)); - } else if (!dml_is_vertical_rotation(p->RotationAngle)) { - vp_height_meta_ub = (unsigned int)(math_ceil2(p->ViewportHeight - 1, 64 * p->BlockHeight256Bytes) + 64 * p->BlockHeight256Bytes); - } else { - vp_height_meta_ub = (unsigned int)(math_ceil2(p->SwathWidth - 1, 64 * p->BlockHeight256Bytes) + 64 * p->BlockHeight256Bytes); - } - - meta_surface_bytes = (unsigned int)(p->DCCMetaPitch * vp_height_meta_ub * p->BytePerPixel / 256.0); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: DCCMetaPitch = %u\n", __func__, p->DCCMetaPitch); - dml2_printf("DML::%s: meta_surface_bytes = %u\n", __func__, meta_surface_bytes); -#endif - if (p->GPUVMEnable == true) { - double meta_vmpg_bytes = 4.0 * 1024.0; - *p->meta_pte_bytes_per_frame_ub = (unsigned int)((math_ceil2((double)(meta_surface_bytes - meta_vmpg_bytes) / (8 * meta_vmpg_bytes), 1) + 1) * 64); - extra_mpde_bytes = 128 * (p->GPUVMMaxPageTableLevels - 1); - } else { - *p->meta_pte_bytes_per_frame_ub = 0; - extra_mpde_bytes = 0; - } - - if (!p->DCCEnable || !p->mrq_present) { - *p->meta_pte_bytes_per_frame_ub = 0; - extra_mpde_bytes = 0; - *p->meta_row_bytes = 0; - } - - if (!p->GPUVMEnable) { - *p->PixelPTEBytesPerRow = 0; - *p->PixelPTEBytesPerRowStorage = 0; - *p->dpte_row_width_ub = 0; - *p->dpte_row_height = 0; - *p->dpte_row_height_linear = 0; - *p->PixelPTEBytesPerRow_one_row_per_frame = 0; - *p->dpte_row_width_ub_one_row_per_frame = 0; - *p->dpte_row_height_one_row_per_frame = 0; - *p->vmpg_width = 0; - *p->vmpg_height = 0; - *p->PixelPTEReqWidth = 0; - *p->PixelPTEReqHeight = 0; - *p->PTERequestSize = 0; - *p->dpde0_bytes_per_frame_ub = 0; - return 0; - } - - MacroTileSizeBytes = p->MacroTileWidth * p->BytePerPixel * p->MacroTileHeight; - - if (p->ViewportStationary && p->is_phantom && (p->NumberOfDPPs == 1 || !dml_is_vertical_rotation(p->RotationAngle))) { - vp_height_dpte_ub = (unsigned int)(math_floor2(p->ViewportYStart + p->ViewportHeight + p->MacroTileHeight - 1, p->MacroTileHeight) - math_floor2(p->ViewportYStart, p->MacroTileHeight)); - } else if (!dml_is_vertical_rotation(p->RotationAngle)) { - vp_height_dpte_ub = (unsigned int)(math_ceil2((double)p->ViewportHeight - 1, p->MacroTileHeight) + p->MacroTileHeight); - } else { - vp_height_dpte_ub = (unsigned int)(math_ceil2((double)p->SwathWidth - 1, p->MacroTileHeight) + p->MacroTileHeight); - } - - if (p->GPUVMEnable == true && p->GPUVMMaxPageTableLevels > 1) { - *p->dpde0_bytes_per_frame_ub = (unsigned int)(64 * (math_ceil2((double)(p->Pitch * vp_height_dpte_ub * p->BytePerPixel - MacroTileSizeBytes) / (double)(8 * 2097152), 1) + 1)); - extra_dpde_bytes = 128 * (p->GPUVMMaxPageTableLevels - 2); - } else { - *p->dpde0_bytes_per_frame_ub = 0; - extra_dpde_bytes = 0; - } - - vm_bytes = *p->meta_pte_bytes_per_frame_ub + extra_mpde_bytes + *p->dpde0_bytes_per_frame_ub + extra_dpde_bytes; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: DCCEnable = %u\n", __func__, p->DCCEnable); - dml2_printf("DML::%s: GPUVMEnable = %u\n", __func__, p->GPUVMEnable); - dml2_printf("DML::%s: SwModeLinear = %u\n", __func__, p->SurfaceTiling == dml2_sw_linear); - dml2_printf("DML::%s: BytePerPixel = %u\n", __func__, p->BytePerPixel); - dml2_printf("DML::%s: GPUVMMaxPageTableLevels = %u\n", __func__, p->GPUVMMaxPageTableLevels); - dml2_printf("DML::%s: BlockHeight256Bytes = %u\n", __func__, p->BlockHeight256Bytes); - dml2_printf("DML::%s: BlockWidth256Bytes = %u\n", __func__, p->BlockWidth256Bytes); - dml2_printf("DML::%s: MacroTileHeight = %u\n", __func__, p->MacroTileHeight); - dml2_printf("DML::%s: MacroTileWidth = %u\n", __func__, p->MacroTileWidth); - dml2_printf("DML::%s: meta_pte_bytes_per_frame_ub = %u\n", __func__, *p->meta_pte_bytes_per_frame_ub); - dml2_printf("DML::%s: dpde0_bytes_per_frame_ub = %u\n", __func__, *p->dpde0_bytes_per_frame_ub); - dml2_printf("DML::%s: extra_mpde_bytes = %u\n", __func__, extra_mpde_bytes); - dml2_printf("DML::%s: extra_dpde_bytes = %u\n", __func__, extra_dpde_bytes); - dml2_printf("DML::%s: vm_bytes = %u\n", __func__, vm_bytes); - dml2_printf("DML::%s: ViewportHeight = %u\n", __func__, p->ViewportHeight); - dml2_printf("DML::%s: SwathWidth = %u\n", __func__, p->SwathWidth); - dml2_printf("DML::%s: vp_height_dpte_ub = %u\n", __func__, vp_height_dpte_ub); -#endif - - unsigned int PixelPTEReqWidth_linear = 0; // VBA_DELTA. VBA doesn't calculate this - - if (p->SurfaceTiling == dml2_sw_linear) { - *p->PixelPTEReqHeight = 1; - *p->PixelPTEReqWidth = p->GPUVMMinPageSizeKBytes * 1024 * 8 / p->BytePerPixel; - PixelPTEReqWidth_linear = p->GPUVMMinPageSizeKBytes * 1024 * 8 / p->BytePerPixel; - *p->PTERequestSize = 64; - - *p->vmpg_height = 1; - *p->vmpg_width = p->GPUVMMinPageSizeKBytes * 1024 / p->BytePerPixel; - } else if (p->GPUVMMinPageSizeKBytes * 1024 >= dml_get_tile_block_size_bytes(p->SurfaceTiling)) { // 1 64B 8x1 PTE - *p->PixelPTEReqHeight = p->MacroTileHeight; - *p->PixelPTEReqWidth = 8 * 1024 * p->GPUVMMinPageSizeKBytes / (p->MacroTileHeight * p->BytePerPixel); - *p->PTERequestSize = 64; - - *p->vmpg_height = p->MacroTileHeight; - *p->vmpg_width = 1024 * p->GPUVMMinPageSizeKBytes / (p->MacroTileHeight * p->BytePerPixel); - - } else if (p->GPUVMMinPageSizeKBytes == 4 && dml_get_tile_block_size_bytes(p->SurfaceTiling) == 65536) { // 2 64B PTE requests to get 16 PTEs to cover the 64K tile - // one 64KB tile, is 16x16x256B req - *p->PixelPTEReqHeight = 16 * p->BlockHeight256Bytes; - *p->PixelPTEReqWidth = 16 * p->BlockWidth256Bytes; - *p->PTERequestSize = 128; - - *p->vmpg_height = *p->PixelPTEReqHeight; - *p->vmpg_width = *p->PixelPTEReqWidth; - } else { - // default for rest of calculation to go through, when vm is disable, the calulated pte related values shouldnt be used anyways - *p->PixelPTEReqHeight = p->MacroTileHeight; - *p->PixelPTEReqWidth = 8 * 1024 * p->GPUVMMinPageSizeKBytes / (p->MacroTileHeight * p->BytePerPixel); - *p->PTERequestSize = 64; - - *p->vmpg_height = p->MacroTileHeight; - *p->vmpg_width = 1024 * p->GPUVMMinPageSizeKBytes / (p->MacroTileHeight * p->BytePerPixel); - - if (p->GPUVMEnable == true) { - dml2_printf("DML::%s: GPUVMMinPageSizeKBytes=%u and sw_mode=%u (tile_size=%d) not supported!\n", - __func__, p->GPUVMMinPageSizeKBytes, p->SurfaceTiling, dml_get_tile_block_size_bytes(p->SurfaceTiling)); - DML2_ASSERT(0); - } - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: GPUVMMinPageSizeKBytes = %u\n", __func__, p->GPUVMMinPageSizeKBytes); - dml2_printf("DML::%s: PixelPTEReqHeight = %u\n", __func__, *p->PixelPTEReqHeight); - dml2_printf("DML::%s: PixelPTEReqWidth = %u\n", __func__, *p->PixelPTEReqWidth); - dml2_printf("DML::%s: PixelPTEReqWidth_linear = %u\n", __func__, PixelPTEReqWidth_linear); - dml2_printf("DML::%s: PTERequestSize = %u\n", __func__, *p->PTERequestSize); - dml2_printf("DML::%s: Pitch = %u\n", __func__, p->Pitch); - dml2_printf("DML::%s: vmpg_width = %u\n", __func__, *p->vmpg_width); - dml2_printf("DML::%s: vmpg_height = %u\n", __func__, *p->vmpg_height); -#endif - - *p->dpte_row_height_one_row_per_frame = vp_height_dpte_ub; - *p->dpte_row_width_ub_one_row_per_frame = (unsigned int)((math_ceil2(((double)p->Pitch * (double)*p->dpte_row_height_one_row_per_frame / (double)*p->PixelPTEReqHeight - 1) / (double)*p->PixelPTEReqWidth, 1) + 1) * (double)*p->PixelPTEReqWidth); - *p->PixelPTEBytesPerRow_one_row_per_frame = (unsigned int)((double)*p->dpte_row_width_ub_one_row_per_frame / (double)*p->PixelPTEReqWidth * *p->PTERequestSize); - - if (p->SurfaceTiling == dml2_sw_linear) { - *p->dpte_row_height = (unsigned int)(math_min2(128, (double)(1ULL << (unsigned int)math_floor2(math_log((float)(p->PTEBufferSizeInRequests * *p->PixelPTEReqWidth / p->Pitch), 2.0), 1)))); - *p->dpte_row_width_ub = (unsigned int)(math_ceil2(((double)p->Pitch * (double)*p->dpte_row_height - 1), (double)*p->PixelPTEReqWidth) + *p->PixelPTEReqWidth); - *p->PixelPTEBytesPerRow = (unsigned int)((double)*p->dpte_row_width_ub / (double)*p->PixelPTEReqWidth * *p->PTERequestSize); - *p->dpte_row_height_linear = 0; - - // VBA_DELTA, VBA doesn't have programming value for pte row height linear. - *p->dpte_row_height_linear = (unsigned int)1 << (unsigned int)math_floor2(math_log((float)(p->PTEBufferSizeInRequests * PixelPTEReqWidth_linear / p->Pitch), 2.0), 1); - if (*p->dpte_row_height_linear > 128) - *p->dpte_row_height_linear = 128; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: dpte_row_width_ub = %u (linear)\n", __func__, *p->dpte_row_width_ub); -#endif - - } else if (!dml_is_vertical_rotation(p->RotationAngle)) { - *p->dpte_row_height = *p->PixelPTEReqHeight; - - if (p->GPUVMMinPageSizeKBytes > 64) { - *p->dpte_row_width_ub = (unsigned int)((math_ceil2(((double)p->Pitch * (double)*p->dpte_row_height / (double)*p->PixelPTEReqHeight - 1) / (double)*p->PixelPTEReqWidth, 1) + 1) * *p->PixelPTEReqWidth); - } else if (p->ViewportStationary && (p->NumberOfDPPs == 1)) { - *p->dpte_row_width_ub = (unsigned int)(math_floor2(p->ViewportXStart + p->SwathWidth + *p->PixelPTEReqWidth - 1, *p->PixelPTEReqWidth) - math_floor2(p->ViewportXStart, *p->PixelPTEReqWidth)); - } else { - *p->dpte_row_width_ub = (unsigned int)((math_ceil2((double)(p->SwathWidth - 1) / (double)*p->PixelPTEReqWidth, 1) + 1.0) * *p->PixelPTEReqWidth); - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: dpte_row_width_ub = %u (tiled horz)\n", __func__, *p->dpte_row_width_ub); -#endif - - *p->PixelPTEBytesPerRow = *p->dpte_row_width_ub / *p->PixelPTEReqWidth * *p->PTERequestSize; - } else { - *p->dpte_row_height = (unsigned int)(math_min2(*p->PixelPTEReqWidth, p->MacroTileWidth)); - - if (p->ViewportStationary && (p->NumberOfDPPs == 1)) { - *p->dpte_row_width_ub = (unsigned int)(math_floor2(p->ViewportYStart + p->ViewportHeight + *p->PixelPTEReqHeight - 1, *p->PixelPTEReqHeight) - math_floor2(p->ViewportYStart, *p->PixelPTEReqHeight)); - } else { - *p->dpte_row_width_ub = (unsigned int)((math_ceil2((double)(p->SwathWidth - 1) / (double)*p->PixelPTEReqHeight, 1) + 1) * *p->PixelPTEReqHeight); - } - - *p->PixelPTEBytesPerRow = (unsigned int)((double)*p->dpte_row_width_ub / (double)*p->PixelPTEReqHeight * *p->PTERequestSize); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: dpte_row_width_ub = %u (tiled vert)\n", __func__, *p->dpte_row_width_ub); -#endif - } - - if (p->GPUVMEnable != true) { - *p->PixelPTEBytesPerRow = 0; - *p->PixelPTEBytesPerRow_one_row_per_frame = 0; - } - - *p->PixelPTEBytesPerRowStorage = *p->PixelPTEBytesPerRow; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: GPUVMMinPageSizeKBytes = %u\n", __func__, p->GPUVMMinPageSizeKBytes); - dml2_printf("DML::%s: GPUVMEnable = %u\n", __func__, p->GPUVMEnable); - dml2_printf("DML::%s: dpte_row_height = %u\n", __func__, *p->dpte_row_height); - dml2_printf("DML::%s: dpte_row_height_linear = %u\n", __func__, *p->dpte_row_height_linear); - dml2_printf("DML::%s: dpte_row_width_ub = %u\n", __func__, *p->dpte_row_width_ub); - dml2_printf("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, *p->PixelPTEBytesPerRow); - dml2_printf("DML::%s: PixelPTEBytesPerRowStorage = %u\n", __func__, *p->PixelPTEBytesPerRowStorage); - dml2_printf("DML::%s: PTEBufferSizeInRequests = %u\n", __func__, p->PTEBufferSizeInRequests); - dml2_printf("DML::%s: dpte_row_height_one_row_per_frame = %u\n", __func__, *p->dpte_row_height_one_row_per_frame); - dml2_printf("DML::%s: dpte_row_width_ub_one_row_per_frame = %u\n", __func__, *p->dpte_row_width_ub_one_row_per_frame); - dml2_printf("DML::%s: PixelPTEBytesPerRow_one_row_per_frame = %u\n", __func__, *p->PixelPTEBytesPerRow_one_row_per_frame); -#endif - - return vm_bytes; -} // CalculateVMAndRowBytes - -static unsigned int CalculatePrefetchSourceLines( - double VRatio, - unsigned int VTaps, - bool Interlace, - bool ProgressiveToInterlaceUnitInOPP, - unsigned int SwathHeight, - enum dml2_rotation_angle RotationAngle, - bool mirrored, - bool ViewportStationary, - unsigned int SwathWidth, - unsigned int ViewportHeight, - unsigned int ViewportXStart, - unsigned int ViewportYStart, - - // Output - unsigned int *VInitPreFill, - unsigned int *MaxNumSwath) -{ - - unsigned int vp_start_rot = 0; - unsigned int sw0_tmp = 0; - unsigned int MaxPartialSwath = 0; - double numLines = 0; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: VRatio = %f\n", __func__, VRatio); - dml2_printf("DML::%s: VTaps = %u\n", __func__, VTaps); - dml2_printf("DML::%s: ViewportXStart = %u\n", __func__, ViewportXStart); - dml2_printf("DML::%s: ViewportYStart = %u\n", __func__, ViewportYStart); - dml2_printf("DML::%s: ViewportStationary = %u\n", __func__, ViewportStationary); - dml2_printf("DML::%s: SwathHeight = %u\n", __func__, SwathHeight); -#endif - if (ProgressiveToInterlaceUnitInOPP) - *VInitPreFill = (unsigned int)(math_floor2((VRatio + (double)VTaps + 1) / 2.0, 1)); - else - *VInitPreFill = (unsigned int)(math_floor2((VRatio + (double)VTaps + 1 + (Interlace ? 1 : 0) * 0.5 * VRatio) / 2.0, 1)); - - if (ViewportStationary) { - if (RotationAngle == dml2_rotation_180) { - vp_start_rot = SwathHeight - (((unsigned int)(ViewportYStart + ViewportHeight - 1) % SwathHeight) + 1); - } else if ((RotationAngle == dml2_rotation_270 && !mirrored) || (RotationAngle == dml2_rotation_90 && mirrored)) { - vp_start_rot = ViewportXStart; - } else if ((RotationAngle == dml2_rotation_90 && !mirrored) || (RotationAngle == dml2_rotation_270 && mirrored)) { - vp_start_rot = SwathHeight - (((unsigned int)(ViewportYStart + SwathWidth - 1) % SwathHeight) + 1); - } else { - vp_start_rot = ViewportYStart; - } - sw0_tmp = SwathHeight - (vp_start_rot % SwathHeight); - if (sw0_tmp < *VInitPreFill) { - *MaxNumSwath = (unsigned int)(math_ceil2((*VInitPreFill - sw0_tmp) / (double)SwathHeight, 1) + 1); - } else { - *MaxNumSwath = 1; - } - MaxPartialSwath = (unsigned int)(math_max2(1, (unsigned int)(vp_start_rot + *VInitPreFill - 1) % SwathHeight)); - } else { - *MaxNumSwath = (unsigned int)(math_ceil2((*VInitPreFill - 1.0) / (double)SwathHeight, 1) + 1); - if (*VInitPreFill > 1) { - MaxPartialSwath = (unsigned int)(math_max2(1, (unsigned int)(*VInitPreFill - 2) % SwathHeight)); - } else { - MaxPartialSwath = (unsigned int)(math_max2(1, (unsigned int)(*VInitPreFill + SwathHeight - 2) % SwathHeight)); - } - } - numLines = *MaxNumSwath * SwathHeight + MaxPartialSwath; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: vp_start_rot = %u\n", __func__, vp_start_rot); - dml2_printf("DML::%s: VInitPreFill = %u\n", __func__, *VInitPreFill); - dml2_printf("DML::%s: MaxPartialSwath = %u\n", __func__, MaxPartialSwath); - dml2_printf("DML::%s: MaxNumSwath = %u\n", __func__, *MaxNumSwath); - dml2_printf("DML::%s: Prefetch source lines = %3.2f\n", __func__, numLines); -#endif - return (unsigned int)(numLines); - -} - -static void CalculateRowBandwidth( - bool GPUVMEnable, - bool use_one_row_for_frame, - enum dml2_source_format_class SourcePixelFormat, - double VRatio, - double VRatioChroma, - bool DCCEnable, - double LineTime, - unsigned int PixelPTEBytesPerRowLuma, - unsigned int PixelPTEBytesPerRowChroma, - unsigned int dpte_row_height_luma, - unsigned int dpte_row_height_chroma, - - bool mrq_present, - unsigned int meta_row_bytes_per_row_ub_l, - unsigned int meta_row_bytes_per_row_ub_c, - unsigned int meta_row_height_luma, - unsigned int meta_row_height_chroma, - - // Output - double *dpte_row_bw, - double *meta_row_bw) -{ - if (!DCCEnable || !mrq_present) { - *meta_row_bw = 0; - } else if (dml2_core_shared_is_420(SourcePixelFormat) || SourcePixelFormat == dml2_rgbe_alpha) { - *meta_row_bw = VRatio * meta_row_bytes_per_row_ub_l / (meta_row_height_luma * LineTime) - + VRatioChroma * meta_row_bytes_per_row_ub_c / (meta_row_height_chroma * LineTime); - } else { - *meta_row_bw = VRatio * meta_row_bytes_per_row_ub_l / (meta_row_height_luma * LineTime); - } - - if (GPUVMEnable != true) { - *dpte_row_bw = 0; - } else if (dml2_core_shared_is_420(SourcePixelFormat) || SourcePixelFormat == dml2_rgbe_alpha) { - *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime) - + VRatioChroma * PixelPTEBytesPerRowChroma / (dpte_row_height_chroma * LineTime); - } else { - *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime); - } -} - -static void CalculateMALLUseForStaticScreen( - const struct dml2_display_cfg *display_cfg, - unsigned int NumberOfActiveSurfaces, - unsigned int MALLAllocatedForDCN, - unsigned int SurfaceSizeInMALL[], - bool one_row_per_frame_fits_in_buffer[], - - // Output - bool is_using_mall_for_ss[]) -{ - - unsigned int SurfaceToAddToMALL; - bool CanAddAnotherSurfaceToMALL; - unsigned int TotalSurfaceSizeInMALL; - - TotalSurfaceSizeInMALL = 0; - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - is_using_mall_for_ss[k] = (display_cfg->plane_descriptors[k].overrides.refresh_from_mall == dml2_refresh_from_mall_mode_override_force_enable); - if (is_using_mall_for_ss[k]) - TotalSurfaceSizeInMALL = TotalSurfaceSizeInMALL + SurfaceSizeInMALL[k]; -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, is_using_mall_for_ss = %u\n", __func__, k, is_using_mall_for_ss[k]); - dml2_printf("DML::%s: k=%u, TotalSurfaceSizeInMALL = %u\n", __func__, k, TotalSurfaceSizeInMALL); -#endif - } - - SurfaceToAddToMALL = 0; - CanAddAnotherSurfaceToMALL = true; - while (CanAddAnotherSurfaceToMALL) { - CanAddAnotherSurfaceToMALL = false; - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - if (TotalSurfaceSizeInMALL + SurfaceSizeInMALL[k] <= MALLAllocatedForDCN * 1024 * 1024 && - !is_using_mall_for_ss[k] && display_cfg->plane_descriptors[k].overrides.refresh_from_mall != dml2_refresh_from_mall_mode_override_force_disable && one_row_per_frame_fits_in_buffer[k] && - (!CanAddAnotherSurfaceToMALL || SurfaceSizeInMALL[k] < SurfaceSizeInMALL[SurfaceToAddToMALL])) { - CanAddAnotherSurfaceToMALL = true; - SurfaceToAddToMALL = k; - dml2_printf("DML::%s: k=%u, UseMALLForStaticScreen = %u (dis, en, optimize)\n", __func__, k, display_cfg->plane_descriptors[k].overrides.refresh_from_mall); - } - } - if (CanAddAnotherSurfaceToMALL) { - is_using_mall_for_ss[SurfaceToAddToMALL] = true; - TotalSurfaceSizeInMALL = TotalSurfaceSizeInMALL + SurfaceSizeInMALL[SurfaceToAddToMALL]; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: SurfaceToAddToMALL = %u\n", __func__, SurfaceToAddToMALL); - dml2_printf("DML::%s: TotalSurfaceSizeInMALL = %u\n", __func__, TotalSurfaceSizeInMALL); -#endif - } - } -} - -static void CalculateDCCConfiguration( - bool DCCEnabled, - bool DCCProgrammingAssumesScanDirectionUnknown, - enum dml2_source_format_class SourcePixelFormat, - unsigned int SurfaceWidthLuma, - unsigned int SurfaceWidthChroma, - unsigned int SurfaceHeightLuma, - unsigned int SurfaceHeightChroma, - unsigned int nomDETInKByte, - unsigned int RequestHeight256ByteLuma, - unsigned int RequestHeight256ByteChroma, - enum dml2_swizzle_mode TilingFormat, - unsigned int BytePerPixelY, - unsigned int BytePerPixelC, - double BytePerPixelDETY, - double BytePerPixelDETC, - enum dml2_rotation_angle RotationAngle, - - // Output - enum dml2_core_internal_request_type *RequestLuma, - enum dml2_core_internal_request_type *RequestChroma, - unsigned int *MaxUncompressedBlockLuma, - unsigned int *MaxUncompressedBlockChroma, - unsigned int *MaxCompressedBlockLuma, - unsigned int *MaxCompressedBlockChroma, - unsigned int *IndependentBlockLuma, - unsigned int *IndependentBlockChroma) -{ - unsigned int DETBufferSizeForDCC = nomDETInKByte * 1024; - - unsigned int yuv420; - unsigned int horz_div_l; - unsigned int horz_div_c; - unsigned int vert_div_l; - unsigned int vert_div_c; - - unsigned int swath_buf_size; - double detile_buf_vp_horz_limit; - double detile_buf_vp_vert_limit; - - yuv420 = dml2_core_shared_is_420(SourcePixelFormat); - horz_div_l = 1; - horz_div_c = 1; - vert_div_l = 1; - vert_div_c = 1; - - if (BytePerPixelY == 1) - vert_div_l = 0; - if (BytePerPixelC == 1) - vert_div_c = 0; - - if (BytePerPixelC == 0) { - swath_buf_size = DETBufferSizeForDCC / 2 - 2 * 256; - detile_buf_vp_horz_limit = (double)swath_buf_size / ((double)RequestHeight256ByteLuma * BytePerPixelY / (1 + horz_div_l)); - detile_buf_vp_vert_limit = (double)swath_buf_size / (256.0 / RequestHeight256ByteLuma / (1 + vert_div_l)); - } else { - swath_buf_size = DETBufferSizeForDCC / 2 - 2 * 2 * 256; - detile_buf_vp_horz_limit = (double)swath_buf_size / ((double)RequestHeight256ByteLuma * BytePerPixelY / (1 + horz_div_l) + (double)RequestHeight256ByteChroma * BytePerPixelC / (1 + horz_div_c) / (1 + yuv420)); - detile_buf_vp_vert_limit = (double)swath_buf_size / (256.0 / RequestHeight256ByteLuma / (1 + vert_div_l) + 256.0 / RequestHeight256ByteChroma / (1 + vert_div_c) / (1 + yuv420)); - } - - if (SourcePixelFormat == dml2_420_10) { - detile_buf_vp_horz_limit = 1.5 * detile_buf_vp_horz_limit; - detile_buf_vp_vert_limit = 1.5 * detile_buf_vp_vert_limit; - } - - detile_buf_vp_horz_limit = math_floor2(detile_buf_vp_horz_limit - 1, 16); - detile_buf_vp_vert_limit = math_floor2(detile_buf_vp_vert_limit - 1, 16); - - unsigned int MAS_vp_horz_limit; - unsigned int MAS_vp_vert_limit; - unsigned int max_vp_horz_width; - unsigned int max_vp_vert_height; - unsigned int eff_surf_width_l; - unsigned int eff_surf_width_c; - unsigned int eff_surf_height_l; - unsigned int eff_surf_height_c; - - unsigned int full_swath_bytes_horz_wc_l; - unsigned int full_swath_bytes_horz_wc_c; - unsigned int full_swath_bytes_vert_wc_l; - unsigned int full_swath_bytes_vert_wc_c; - - MAS_vp_horz_limit = SourcePixelFormat == dml2_rgbe_alpha ? 3840 : 6144; - MAS_vp_vert_limit = SourcePixelFormat == dml2_rgbe_alpha ? 3840 : (BytePerPixelY == 8 ? 3072 : 6144); - max_vp_horz_width = (unsigned int)(math_min2((double)MAS_vp_horz_limit, detile_buf_vp_horz_limit)); - max_vp_vert_height = (unsigned int)(math_min2((double)MAS_vp_vert_limit, detile_buf_vp_vert_limit)); - eff_surf_width_l = (SurfaceWidthLuma > max_vp_horz_width ? max_vp_horz_width : SurfaceWidthLuma); - eff_surf_width_c = eff_surf_width_l / (1 + yuv420); - eff_surf_height_l = (SurfaceHeightLuma > max_vp_vert_height ? max_vp_vert_height : SurfaceHeightLuma); - eff_surf_height_c = eff_surf_height_l / (1 + yuv420); - - full_swath_bytes_horz_wc_l = eff_surf_width_l * RequestHeight256ByteLuma * BytePerPixelY; - full_swath_bytes_vert_wc_l = eff_surf_height_l * 256 / RequestHeight256ByteLuma; - if (BytePerPixelC > 0) { - full_swath_bytes_horz_wc_c = eff_surf_width_c * RequestHeight256ByteChroma * BytePerPixelC; - full_swath_bytes_vert_wc_c = eff_surf_height_c * 256 / RequestHeight256ByteChroma; - } else { - full_swath_bytes_horz_wc_c = 0; - full_swath_bytes_vert_wc_c = 0; - } - - if (SourcePixelFormat == dml2_420_10) { - full_swath_bytes_horz_wc_l = (unsigned int)(math_ceil2((double)full_swath_bytes_horz_wc_l * 2.0 / 3.0, 256.0)); - full_swath_bytes_horz_wc_c = (unsigned int)(math_ceil2((double)full_swath_bytes_horz_wc_c * 2.0 / 3.0, 256.0)); - full_swath_bytes_vert_wc_l = (unsigned int)(math_ceil2((double)full_swath_bytes_vert_wc_l * 2.0 / 3.0, 256.0)); - full_swath_bytes_vert_wc_c = (unsigned int)(math_ceil2((double)full_swath_bytes_vert_wc_c * 2.0 / 3.0, 256.0)); - } - - unsigned int req128_horz_wc_l; - unsigned int req128_horz_wc_c; - unsigned int req128_vert_wc_l; - unsigned int req128_vert_wc_c; - - if (2 * full_swath_bytes_horz_wc_l + 2 * full_swath_bytes_horz_wc_c <= DETBufferSizeForDCC) { - req128_horz_wc_l = 0; - req128_horz_wc_c = 0; - } else if (full_swath_bytes_horz_wc_l < 1.5 * full_swath_bytes_horz_wc_c && 2 * full_swath_bytes_horz_wc_l + full_swath_bytes_horz_wc_c <= DETBufferSizeForDCC) { - req128_horz_wc_l = 0; - req128_horz_wc_c = 1; - } else if (full_swath_bytes_horz_wc_l >= 1.5 * full_swath_bytes_horz_wc_c && full_swath_bytes_horz_wc_l + 2 * full_swath_bytes_horz_wc_c <= DETBufferSizeForDCC) { - req128_horz_wc_l = 1; - req128_horz_wc_c = 0; - } else { - req128_horz_wc_l = 1; - req128_horz_wc_c = 1; - } - - if (2 * full_swath_bytes_vert_wc_l + 2 * full_swath_bytes_vert_wc_c <= DETBufferSizeForDCC) { - req128_vert_wc_l = 0; - req128_vert_wc_c = 0; - } else if (full_swath_bytes_vert_wc_l < 1.5 * full_swath_bytes_vert_wc_c && 2 * full_swath_bytes_vert_wc_l + full_swath_bytes_vert_wc_c <= DETBufferSizeForDCC) { - req128_vert_wc_l = 0; - req128_vert_wc_c = 1; - } else if (full_swath_bytes_vert_wc_l >= 1.5 * full_swath_bytes_vert_wc_c && full_swath_bytes_vert_wc_l + 2 * full_swath_bytes_vert_wc_c <= DETBufferSizeForDCC) { - req128_vert_wc_l = 1; - req128_vert_wc_c = 0; - } else { - req128_vert_wc_l = 1; - req128_vert_wc_c = 1; - } - - unsigned int segment_order_horz_contiguous_luma; - unsigned int segment_order_horz_contiguous_chroma; - unsigned int segment_order_vert_contiguous_luma; - unsigned int segment_order_vert_contiguous_chroma; - - if (BytePerPixelY == 2) { - segment_order_horz_contiguous_luma = 0; - segment_order_vert_contiguous_luma = 1; - } else { - segment_order_horz_contiguous_luma = 1; - segment_order_vert_contiguous_luma = 0; - } - - if (BytePerPixelC == 2) { - segment_order_horz_contiguous_chroma = 0; - segment_order_vert_contiguous_chroma = 1; - } else { - segment_order_horz_contiguous_chroma = 1; - segment_order_vert_contiguous_chroma = 0; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: DCCEnabled = %u\n", __func__, DCCEnabled); - dml2_printf("DML::%s: nomDETInKByte = %u\n", __func__, nomDETInKByte); - dml2_printf("DML::%s: DETBufferSizeForDCC = %u\n", __func__, DETBufferSizeForDCC); - dml2_printf("DML::%s: req128_horz_wc_l = %u\n", __func__, req128_horz_wc_l); - dml2_printf("DML::%s: req128_horz_wc_c = %u\n", __func__, req128_horz_wc_c); - dml2_printf("DML::%s: full_swath_bytes_horz_wc_l = %u\n", __func__, full_swath_bytes_horz_wc_l); - dml2_printf("DML::%s: full_swath_bytes_vert_wc_c = %u\n", __func__, full_swath_bytes_vert_wc_c); - dml2_printf("DML::%s: segment_order_horz_contiguous_luma = %u\n", __func__, segment_order_horz_contiguous_luma); - dml2_printf("DML::%s: segment_order_horz_contiguous_chroma = %u\n", __func__, segment_order_horz_contiguous_chroma); -#endif - if (DCCProgrammingAssumesScanDirectionUnknown == true) { - if (req128_horz_wc_l == 0 && req128_vert_wc_l == 0) { - *RequestLuma = dml2_core_internal_request_type_256_bytes; - } else if ((req128_horz_wc_l == 1 && segment_order_horz_contiguous_luma == 0) || (req128_vert_wc_l == 1 && segment_order_vert_contiguous_luma == 0)) { - *RequestLuma = dml2_core_internal_request_type_128_bytes_non_contiguous; - } else { - *RequestLuma = dml2_core_internal_request_type_128_bytes_contiguous; - } - if (req128_horz_wc_c == 0 && req128_vert_wc_c == 0) { - *RequestChroma = dml2_core_internal_request_type_256_bytes; - } else if ((req128_horz_wc_c == 1 && segment_order_horz_contiguous_chroma == 0) || (req128_vert_wc_c == 1 && segment_order_vert_contiguous_chroma == 0)) { - *RequestChroma = dml2_core_internal_request_type_128_bytes_non_contiguous; - } else { - *RequestChroma = dml2_core_internal_request_type_128_bytes_contiguous; - } - } else if (!dml_is_vertical_rotation(RotationAngle)) { - if (req128_horz_wc_l == 0) { - *RequestLuma = dml2_core_internal_request_type_256_bytes; - } else if (segment_order_horz_contiguous_luma == 0) { - *RequestLuma = dml2_core_internal_request_type_128_bytes_non_contiguous; - } else { - *RequestLuma = dml2_core_internal_request_type_128_bytes_contiguous; - } - if (req128_horz_wc_c == 0) { - *RequestChroma = dml2_core_internal_request_type_256_bytes; - } else if (segment_order_horz_contiguous_chroma == 0) { - *RequestChroma = dml2_core_internal_request_type_128_bytes_non_contiguous; - } else { - *RequestChroma = dml2_core_internal_request_type_128_bytes_contiguous; - } - } else { - if (req128_vert_wc_l == 0) { - *RequestLuma = dml2_core_internal_request_type_256_bytes; - } else if (segment_order_vert_contiguous_luma == 0) { - *RequestLuma = dml2_core_internal_request_type_128_bytes_non_contiguous; - } else { - *RequestLuma = dml2_core_internal_request_type_128_bytes_contiguous; - } - if (req128_vert_wc_c == 0) { - *RequestChroma = dml2_core_internal_request_type_256_bytes; - } else if (segment_order_vert_contiguous_chroma == 0) { - *RequestChroma = dml2_core_internal_request_type_128_bytes_non_contiguous; - } else { - *RequestChroma = dml2_core_internal_request_type_128_bytes_contiguous; - } - } - - if (*RequestLuma == dml2_core_internal_request_type_256_bytes) { - *MaxUncompressedBlockLuma = 256; - *MaxCompressedBlockLuma = 256; - *IndependentBlockLuma = 0; - } else if (*RequestLuma == dml2_core_internal_request_type_128_bytes_contiguous) { - *MaxUncompressedBlockLuma = 256; - *MaxCompressedBlockLuma = 128; - *IndependentBlockLuma = 128; - } else { - *MaxUncompressedBlockLuma = 256; - *MaxCompressedBlockLuma = 64; - *IndependentBlockLuma = 64; - } - - if (*RequestChroma == dml2_core_internal_request_type_256_bytes) { - *MaxUncompressedBlockChroma = 256; - *MaxCompressedBlockChroma = 256; - *IndependentBlockChroma = 0; - } else if (*RequestChroma == dml2_core_internal_request_type_128_bytes_contiguous) { - *MaxUncompressedBlockChroma = 256; - *MaxCompressedBlockChroma = 128; - *IndependentBlockChroma = 128; - } else { - *MaxUncompressedBlockChroma = 256; - *MaxCompressedBlockChroma = 64; - *IndependentBlockChroma = 64; - } - - if (DCCEnabled != true || BytePerPixelC == 0) { - *MaxUncompressedBlockChroma = 0; - *MaxCompressedBlockChroma = 0; - *IndependentBlockChroma = 0; - } - - if (DCCEnabled != true) { - *MaxUncompressedBlockLuma = 0; - *MaxCompressedBlockLuma = 0; - *IndependentBlockLuma = 0; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: MaxUncompressedBlockLuma = %u\n", __func__, *MaxUncompressedBlockLuma); - dml2_printf("DML::%s: MaxCompressedBlockLuma = %u\n", __func__, *MaxCompressedBlockLuma); - dml2_printf("DML::%s: IndependentBlockLuma = %u\n", __func__, *IndependentBlockLuma); - dml2_printf("DML::%s: MaxUncompressedBlockChroma = %u\n", __func__, *MaxUncompressedBlockChroma); - dml2_printf("DML::%s: MaxCompressedBlockChroma = %u\n", __func__, *MaxCompressedBlockChroma); - dml2_printf("DML::%s: IndependentBlockChroma = %u\n", __func__, *IndependentBlockChroma); -#endif - -} - -static void calculate_mcache_row_bytes( - struct dml2_core_internal_scratch *scratch, - struct dml2_core_calcs_calculate_mcache_row_bytes_params *p) -{ - unsigned int vmpg_bytes = 0; - unsigned int blk_bytes = 0; - float meta_per_mvmpg_per_channel = 0; - unsigned int est_blk_per_vmpg = 2; - unsigned int mvmpg_per_row_ub = 0; - unsigned int full_vp_width_mvmpg_aligned = 0; - unsigned int full_vp_height_mvmpg_aligned = 0; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: num_chans = %u\n", __func__, p->num_chans); - dml2_printf("DML::%s: mem_word_bytes = %u\n", __func__, p->mem_word_bytes); - dml2_printf("DML::%s: mcache_line_size_bytes = %u\n", __func__, p->mcache_line_size_bytes); - dml2_printf("DML::%s: mcache_size_bytes = %u\n", __func__, p->mcache_size_bytes); - dml2_printf("DML::%s: gpuvm_enable = %u\n", __func__, p->gpuvm_enable); - dml2_printf("DML::%s: gpuvm_page_size_kbytes = %u\n", __func__, p->gpuvm_page_size_kbytes); - dml2_printf("DML::%s: vp_stationary = %u\n", __func__, p->vp_stationary); - dml2_printf("DML::%s: tiling_mode = %u\n", __func__, p->tiling_mode); - dml2_printf("DML::%s: vp_start_x = %u\n", __func__, p->vp_start_x); - dml2_printf("DML::%s: vp_start_y = %u\n", __func__, p->vp_start_y); - dml2_printf("DML::%s: full_vp_width = %u\n", __func__, p->full_vp_width); - dml2_printf("DML::%s: full_vp_height = %u\n", __func__, p->full_vp_height); - dml2_printf("DML::%s: blk_width = %u\n", __func__, p->blk_width); - dml2_printf("DML::%s: blk_height = %u\n", __func__, p->blk_height); - dml2_printf("DML::%s: vmpg_width = %u\n", __func__, p->vmpg_width); - dml2_printf("DML::%s: vmpg_height = %u\n", __func__, p->vmpg_height); - dml2_printf("DML::%s: full_swath_bytes = %u\n", __func__, p->full_swath_bytes); -#endif - DML2_ASSERT(p->mcache_line_size_bytes != 0); - DML2_ASSERT(p->mcache_size_bytes != 0); - - *p->mvmpg_width = 0; - *p->mvmpg_height = 0; - - if (p->full_vp_height == 0 && p->full_vp_width == 0) { - *p->num_mcaches = 0; - *p->mcache_row_bytes = 0; - } else { - blk_bytes = dml_get_tile_block_size_bytes(p->tiling_mode); - - // if gpuvm is not enable, the alignment boundary should be in terms of tiling block size - vmpg_bytes = p->gpuvm_page_size_kbytes * 1024; - - //With vmpg_bytes >= tile blk_bytes, the meta_row_width alignment equations are relative to the vmpg_width/height. - // But for 4KB page with 64KB tile block, we need the meta for all pages in the tile block. - // Therefore, the alignment is relative to the blk_width/height. The factor of 16 vmpg per 64KB tile block is applied at the end. - *p->mvmpg_width = p->blk_width; - *p->mvmpg_height = p->blk_height; - if (p->gpuvm_enable) { - if (vmpg_bytes >= blk_bytes) { - *p->mvmpg_width = p->vmpg_width; - *p->mvmpg_height = p->vmpg_height; - } else if (!((blk_bytes == 65536) && (vmpg_bytes == 4096))) { - dml2_printf("ERROR: DML::%s: Tiling size and vm page size combination not supported\n", __func__); - DML2_ASSERT(0); - } - } - - //For plane0 & 1, first calculate full_vp_width/height_l/c aligned to vmpg_width/height_l/c - full_vp_width_mvmpg_aligned = (unsigned int)(math_floor2((p->vp_start_x + p->full_vp_width) + *p->mvmpg_width - 1, *p->mvmpg_width) - math_floor2(p->vp_start_x, *p->mvmpg_width)); - full_vp_height_mvmpg_aligned = (unsigned int)(math_floor2((p->vp_start_y + p->full_vp_height) + *p->mvmpg_height - 1, *p->mvmpg_height) - math_floor2(p->vp_start_y, *p->mvmpg_height)); - - *p->full_vp_access_width_mvmpg_aligned = p->surf_vert ? full_vp_height_mvmpg_aligned : full_vp_width_mvmpg_aligned; - - //Use the equation for the exact alignment when possible. Note that the exact alignment cannot be used for horizontal access if vmpg_bytes > blk_bytes. - if (!p->surf_vert) { //horizontal access - if (p->vp_stationary == 1 && vmpg_bytes <= blk_bytes) - *p->meta_row_width_ub = full_vp_width_mvmpg_aligned; - else - *p->meta_row_width_ub = (unsigned int)math_ceil2((double)p->full_vp_width - 1, *p->mvmpg_width) + *p->mvmpg_width; - mvmpg_per_row_ub = *p->meta_row_width_ub / *p->mvmpg_width; - } else { //vertical access - if (p->vp_stationary == 1) - *p->meta_row_width_ub = full_vp_height_mvmpg_aligned; - else - *p->meta_row_width_ub = (unsigned int)math_ceil2((double)p->full_vp_height - 1, *p->mvmpg_height) + *p->mvmpg_height; - mvmpg_per_row_ub = *p->meta_row_width_ub / *p->mvmpg_height; - } - - unsigned int meta_per_mvmpg_per_channel_ub = 0; - - if (p->gpuvm_enable) { - 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; - } - - *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 / (float)256 / p->num_chans; - - if (!p->surf_vert) - *p->dcc_dram_bw_nom_overhead_factor = 1 + 1.0 / 256.0; - else - *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)); - } - - meta_per_mvmpg_per_channel_ub = (unsigned int)math_ceil2((double)meta_per_mvmpg_per_channel, p->mcache_line_size_bytes); - - //but for 4KB vmpg with 64KB tile blk - if (p->gpuvm_enable && (blk_bytes == 65536) && (vmpg_bytes == 4096)) - meta_per_mvmpg_per_channel_ub = 16 * meta_per_mvmpg_per_channel_ub; - - // If this mcache_row_bytes for the full viewport of the surface is less than or equal to mcache_bytes, - // then one mcache can be used for this request stream. If not, it is useful to know the width of the viewport that can be supported in the mcache_bytes. - if (p->gpuvm_enable || !p->surf_vert) { - *p->mcache_row_bytes = mvmpg_per_row_ub * meta_per_mvmpg_per_channel_ub; - } else { // horizontal and gpuvm disable - *p->mcache_row_bytes = *p->meta_row_width_ub * p->blk_height * p->bytes_per_pixel / 256; - *p->mcache_row_bytes = (unsigned int)math_ceil2((double)*p->mcache_row_bytes / p->num_chans, p->mcache_line_size_bytes); - } - - *p->dcc_dram_bw_pref_overhead_factor = 1 + math_max2(1.0 / 256.0, *p->mcache_row_bytes / p->full_swath_bytes); // dcc_dr_oh_pref - *p->num_mcaches = (unsigned int)math_ceil2((double)*p->mcache_row_bytes / p->mcache_size_bytes, 1); - - unsigned int mvmpg_per_mcache = p->mcache_size_bytes / meta_per_mvmpg_per_channel_ub; - *p->mvmpg_per_mcache_lb = (unsigned int)math_floor2(mvmpg_per_mcache, 1); - - DML2_ASSERT(*p->num_mcaches > 0); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: gpuvm_enable = %u\n", __func__, p->gpuvm_enable); - dml2_printf("DML::%s: vmpg_bytes = %u\n", __func__, vmpg_bytes); - dml2_printf("DML::%s: blk_bytes = %u\n", __func__, blk_bytes); - dml2_printf("DML::%s: meta_per_mvmpg_per_channel = %f\n", __func__, meta_per_mvmpg_per_channel); - dml2_printf("DML::%s: mvmpg_per_row_ub = %u\n", __func__, mvmpg_per_row_ub); - dml2_printf("DML::%s: meta_row_width_ub = %u\n", __func__, *p->meta_row_width_ub); - dml2_printf("DML::%s: mvmpg_width = %u\n", __func__, *p->mvmpg_width); - dml2_printf("DML::%s: mvmpg_height = %u\n", __func__, *p->mvmpg_height); - dml2_printf("DML::%s: num_mcaches = %u\n", __func__, *p->num_mcaches); - dml2_printf("DML::%s: dcc_dram_bw_nom_overhead_factor = %f\n", __func__, *p->dcc_dram_bw_nom_overhead_factor); - dml2_printf("DML::%s: dcc_dram_bw_pref_overhead_factor = %f\n", __func__, *p->dcc_dram_bw_pref_overhead_factor); -#endif - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: mcache_row_bytes = %u\n", __func__, *p->mcache_row_bytes); - dml2_printf("DML::%s: num_mcaches = %u\n", __func__, *p->num_mcaches); -#endif -} - -static void calculate_mcache_setting( - struct dml2_core_internal_scratch *scratch, - struct dml2_core_calcs_calculate_mcache_setting_params *p) -{ - unsigned int n; - - struct dml2_core_shared_calculate_mcache_setting_locals *l = &scratch->calculate_mcache_setting_locals; - memset(l, 0, sizeof(struct dml2_core_shared_calculate_mcache_setting_locals)); - - *p->num_mcaches_l = 0; - *p->mcache_row_bytes_l = 0; - *p->dcc_dram_bw_nom_overhead_factor_l = 1.0; - *p->dcc_dram_bw_pref_overhead_factor_l = 1.0; - - *p->num_mcaches_c = 0; - *p->mcache_row_bytes_c = 0; - *p->dcc_dram_bw_nom_overhead_factor_c = 1.0; - *p->dcc_dram_bw_pref_overhead_factor_c = 1.0; - - *p->mall_comb_mcache_l = 0; - *p->mall_comb_mcache_c = 0; - *p->lc_comb_mcache = 0; - - if (!p->dcc_enable) - return; - - l->is_dual_plane = dml2_core_shared_is_420(p->source_format) || p->source_format == dml2_rgbe_alpha; - - l->l_p.num_chans = p->num_chans; - l->l_p.mem_word_bytes = p->mem_word_bytes; - l->l_p.mcache_size_bytes = p->mcache_size_bytes; - l->l_p.mcache_line_size_bytes = p->mcache_line_size_bytes; - l->l_p.gpuvm_enable = p->gpuvm_enable; - l->l_p.gpuvm_page_size_kbytes = p->gpuvm_page_size_kbytes; - l->l_p.surf_vert = p->surf_vert; - l->l_p.vp_stationary = p->vp_stationary; - l->l_p.tiling_mode = p->tiling_mode; - l->l_p.vp_start_x = p->vp_start_x_l; - l->l_p.vp_start_y = p->vp_start_y_l; - l->l_p.full_vp_width = p->full_vp_width_l; - l->l_p.full_vp_height = p->full_vp_height_l; - l->l_p.blk_width = p->blk_width_l; - l->l_p.blk_height = p->blk_height_l; - l->l_p.vmpg_width = p->vmpg_width_l; - l->l_p.vmpg_height = p->vmpg_height_l; - l->l_p.full_swath_bytes = p->full_swath_bytes_l; - l->l_p.bytes_per_pixel = p->bytes_per_pixel_l; - - // output - l->l_p.num_mcaches = p->num_mcaches_l; - l->l_p.mcache_row_bytes = p->mcache_row_bytes_l; - l->l_p.dcc_dram_bw_nom_overhead_factor = p->dcc_dram_bw_nom_overhead_factor_l; - l->l_p.dcc_dram_bw_pref_overhead_factor = p->dcc_dram_bw_pref_overhead_factor_l; - l->l_p.mvmpg_width = &l->mvmpg_width_l; - l->l_p.mvmpg_height = &l->mvmpg_height_l; - l->l_p.full_vp_access_width_mvmpg_aligned = &l->full_vp_access_width_mvmpg_aligned_l; - l->l_p.meta_row_width_ub = &l->meta_row_width_l; - l->l_p.mvmpg_per_mcache_lb = &l->mvmpg_per_mcache_lb_l; - - calculate_mcache_row_bytes(scratch, &l->l_p); - dml2_assert(*p->num_mcaches_l > 0); - - if (l->is_dual_plane) { - l->c_p.num_chans = p->num_chans; - l->c_p.mem_word_bytes = p->mem_word_bytes; - l->c_p.mcache_size_bytes = p->mcache_size_bytes; - l->c_p.mcache_line_size_bytes = p->mcache_line_size_bytes; - l->c_p.gpuvm_enable = p->gpuvm_enable; - l->c_p.gpuvm_page_size_kbytes = p->gpuvm_page_size_kbytes; - l->c_p.surf_vert = p->surf_vert; - l->c_p.vp_stationary = p->vp_stationary; - l->c_p.tiling_mode = p->tiling_mode; - l->c_p.vp_start_x = p->vp_start_x_c; - l->c_p.vp_start_y = p->vp_start_y_c; - l->c_p.full_vp_width = p->full_vp_width_c; - l->c_p.full_vp_height = p->full_vp_height_c; - l->c_p.blk_width = p->blk_width_c; - l->c_p.blk_height = p->blk_height_c; - l->c_p.vmpg_width = p->vmpg_width_c; - l->c_p.vmpg_height = p->vmpg_height_c; - l->c_p.full_swath_bytes = p->full_swath_bytes_c; - l->c_p.bytes_per_pixel = p->bytes_per_pixel_c; - - // output - l->c_p.num_mcaches = p->num_mcaches_c; - l->c_p.mcache_row_bytes = p->mcache_row_bytes_c; - l->c_p.dcc_dram_bw_nom_overhead_factor = p->dcc_dram_bw_nom_overhead_factor_c; - l->c_p.dcc_dram_bw_pref_overhead_factor = p->dcc_dram_bw_pref_overhead_factor_c; - l->c_p.mvmpg_width = &l->mvmpg_width_c; - l->c_p.mvmpg_height = &l->mvmpg_height_c; - l->c_p.full_vp_access_width_mvmpg_aligned = &l->full_vp_access_width_mvmpg_aligned_c; - l->c_p.meta_row_width_ub = &l->meta_row_width_c; - l->c_p.mvmpg_per_mcache_lb = &l->mvmpg_per_mcache_lb_c; - - calculate_mcache_row_bytes(scratch, &l->c_p); - dml2_assert(*p->num_mcaches_c > 0); - } - - // Sharing for iMALL access - l->mcache_remainder_l = *p->mcache_row_bytes_l % p->mcache_size_bytes; - l->mcache_remainder_c = *p->mcache_row_bytes_c % p->mcache_size_bytes; - l->mvmpg_access_width_l = p->surf_vert ? l->mvmpg_height_l : l->mvmpg_width_l; - l->mvmpg_access_width_c = p->surf_vert ? l->mvmpg_height_c : l->mvmpg_width_c; - - if (p->imall_enable) { - *p->mall_comb_mcache_l = (2 * l->mcache_remainder_l <= p->mcache_size_bytes); - - if (l->is_dual_plane) - *p->mall_comb_mcache_c = (2 * l->mcache_remainder_c <= p->mcache_size_bytes); - } - - if (!p->surf_vert) // horizonatal access - l->luma_time_factor = (double)l->mvmpg_height_c / l->mvmpg_height_l * 2; - else // vertical access - 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) { - 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)) { - l->lc_comb_last_mcache_size = (unsigned int)((l->mcache_remainder_l * (*p->mall_comb_mcache_l ? 2 : 1) * l->luma_time_factor) + - (l->mcache_remainder_c * (*p->mall_comb_mcache_c ? 2 : 1))); - } - *p->lc_comb_mcache = (l->lc_comb_last_mcache_size <= p->mcache_size_bytes) && (*p->mall_comb_mcache_l == *p->mall_comb_mcache_c); - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: imall_enable = %u\n", __func__, p->imall_enable); - dml2_printf("DML::%s: is_dual_plane = %u\n", __func__, l->is_dual_plane); - dml2_printf("DML::%s: surf_vert = %u\n", __func__, p->surf_vert); - dml2_printf("DML::%s: mvmpg_width_l = %u\n", __func__, l->mvmpg_width_l); - dml2_printf("DML::%s: mvmpg_height_l = %u\n", __func__, l->mvmpg_height_l); - dml2_printf("DML::%s: mcache_remainder_l = %f\n", __func__, l->mcache_remainder_l); - dml2_printf("DML::%s: num_mcaches_l = %u\n", __func__, *p->num_mcaches_l); - dml2_printf("DML::%s: avg_mcache_element_size_l = %u\n", __func__, l->avg_mcache_element_size_l); - dml2_printf("DML::%s: mvmpg_access_width_l = %u\n", __func__, l->mvmpg_access_width_l); - dml2_printf("DML::%s: mall_comb_mcache_l = %u\n", __func__, *p->mall_comb_mcache_l); - - if (l->is_dual_plane) { - dml2_printf("DML::%s: mvmpg_width_c = %u\n", __func__, l->mvmpg_width_c); - dml2_printf("DML::%s: mvmpg_height_c = %u\n", __func__, l->mvmpg_height_c); - dml2_printf("DML::%s: mcache_remainder_c = %f\n", __func__, l->mcache_remainder_c); - dml2_printf("DML::%s: luma_time_factor = %f\n", __func__, l->luma_time_factor); - dml2_printf("DML::%s: num_mcaches_c = %u\n", __func__, *p->num_mcaches_c); - dml2_printf("DML::%s: avg_mcache_element_size_c = %u\n", __func__, l->avg_mcache_element_size_c); - dml2_printf("DML::%s: mvmpg_access_width_c = %u\n", __func__, l->mvmpg_access_width_c); - dml2_printf("DML::%s: mall_comb_mcache_c = %u\n", __func__, *p->mall_comb_mcache_c); - dml2_printf("DML::%s: lc_comb_last_mcache_size = %u\n", __func__, l->lc_comb_last_mcache_size); - dml2_printf("DML::%s: lc_comb_mcache = %u\n", __func__, *p->lc_comb_mcache); - } -#endif - // calculate split_coordinate - l->full_vp_access_width_l = p->surf_vert ? p->full_vp_height_l : p->full_vp_width_l; - l->full_vp_access_width_c = p->surf_vert ? p->full_vp_height_c : p->full_vp_width_c; - - for (n = 0; n < *p->num_mcaches_l - 1; n++) { - p->mcache_offsets_l[n] = (unsigned int)(math_floor2((n + 1) * l->avg_mcache_element_size_l / l->mvmpg_access_width_l, 1)) * l->mvmpg_access_width_l; - } - p->mcache_offsets_l[*p->num_mcaches_l - 1] = l->full_vp_access_width_l; - - if (l->is_dual_plane) { - for (n = 0; n < *p->num_mcaches_c - 1; n++) { - p->mcache_offsets_c[n] = (unsigned int)(math_floor2((n + 1) * l->avg_mcache_element_size_c / l->mvmpg_access_width_c, 1)) * l->mvmpg_access_width_c; - } - p->mcache_offsets_c[*p->num_mcaches_c - 1] = l->full_vp_access_width_c; - } -#ifdef __DML_VBA_DEBUG__ - for (n = 0; n < *p->num_mcaches_l; n++) - dml2_printf("DML::%s: mcache_offsets_l[%u] = %u\n", __func__, n, p->mcache_offsets_l[n]); - - if (l->is_dual_plane) { - for (n = 0; n < *p->num_mcaches_c; n++) - dml2_printf("DML::%s: mcache_offsets_c[%u] = %u\n", __func__, n, p->mcache_offsets_c[n]); - } -#endif - - // Luma/Chroma combine in the last mcache - // In the case of Luma/Chroma combine-mCache (with lc_comb_mcache==1), all mCaches except the last segment are filled as much as possible, when stay aligned to mvmpg boundary - if (*p->lc_comb_mcache && l->is_dual_plane) { - for (n = 0; n < *p->num_mcaches_l - 1; n++) - p->mcache_offsets_l[n] = (n + 1) * l->mvmpg_per_mcache_lb_l * l->mvmpg_access_width_l; - p->mcache_offsets_l[*p->num_mcaches_l - 1] = l->full_vp_access_width_l; - - for (n = 0; n < *p->num_mcaches_c - 1; n++) - p->mcache_offsets_c[n] = (n + 1) * l->mvmpg_per_mcache_lb_c * l->mvmpg_access_width_c; - p->mcache_offsets_c[*p->num_mcaches_c - 1] = l->full_vp_access_width_c; - -#ifdef __DML_VBA_DEBUG__ - for (n = 0; n < *p->num_mcaches_l; n++) - dml2_printf("DML::%s: mcache_offsets_l[%u] = %u\n", __func__, n, p->mcache_offsets_l[n]); - - for (n = 0; n < *p->num_mcaches_c; n++) - dml2_printf("DML::%s: mcache_offsets_c[%u] = %u\n", __func__, n, p->mcache_offsets_c[n]); -#endif - } - - *p->mcache_shift_granularity_l = l->mvmpg_access_width_l; - *p->mcache_shift_granularity_c = l->mvmpg_access_width_c; -} - -static void calculate_mall_bw_overhead_factor( - double mall_prefetch_sdp_overhead_factor[], //mall_sdp_oh_nom/pref - double mall_prefetch_dram_overhead_factor[], //mall_dram_oh_nom/pref - - // input - const struct dml2_display_cfg *display_cfg, - unsigned int num_active_planes) -{ - for (unsigned int k = 0; k < num_active_planes; ++k) { - mall_prefetch_sdp_overhead_factor[k] = 1.0; - mall_prefetch_dram_overhead_factor[k] = 1.0; - - // SDP - on the return side - if (display_cfg->plane_descriptors[k].overrides.legacy_svp_config == dml2_svp_mode_override_imall) // always no data return - mall_prefetch_sdp_overhead_factor[k] = 1.25; - else if (display_cfg->plane_descriptors[k].overrides.legacy_svp_config == dml2_svp_mode_override_phantom_pipe_no_data_return) - mall_prefetch_sdp_overhead_factor[k] = 0.25; - - // DRAM - if (display_cfg->plane_descriptors[k].overrides.legacy_svp_config == dml2_svp_mode_override_imall) - mall_prefetch_dram_overhead_factor[k] = 2.0; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, mall_prefetch_sdp_overhead_factor = %f\n", __func__, k, mall_prefetch_sdp_overhead_factor[k]); - dml2_printf("DML::%s: k=%u, mall_prefetch_dram_overhead_factor = %f\n", __func__, k, mall_prefetch_dram_overhead_factor[k]); -#endif - } -} - -static double dml_get_return_bandwidth_available( - const struct dml2_soc_bb *soc, - enum dml2_core_internal_soc_state_type state_type, - enum dml2_core_internal_bw_type bw_type, - bool is_avg_bw, - bool is_hvm_en, - bool is_hvm_only, - double dcflk_mhz, - double fclk_mhz, - double dram_bw_mbps) -{ - double return_bw_mbps = 0.; - double ideal_sdp_bandwidth = (double)soc->return_bus_width_bytes * dcflk_mhz; - 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; - - if (is_avg_bw) { - if (state_type == dml2_core_internal_soc_state_svp_prefetch) { - derate_sdp_factor = soc->qos_parameters.derate_table.dcn_mall_prefetch_average.dcfclk_derate_percent / 100.0; - derate_fabric_factor = soc->qos_parameters.derate_table.dcn_mall_prefetch_average.fclk_derate_percent / 100.0; - derate_dram_factor = soc->qos_parameters.derate_table.dcn_mall_prefetch_average.dram_derate_percent_pixel / 100.0; - } else { // just assume sys_active - derate_sdp_factor = soc->qos_parameters.derate_table.system_active_average.dcfclk_derate_percent / 100.0; - derate_fabric_factor = soc->qos_parameters.derate_table.system_active_average.fclk_derate_percent / 100.0; - derate_dram_factor = soc->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100.0; - } - } else { // urgent bw - if (state_type == dml2_core_internal_soc_state_svp_prefetch) { - derate_sdp_factor = soc->qos_parameters.derate_table.dcn_mall_prefetch_urgent.dcfclk_derate_percent / 100.0; - derate_fabric_factor = soc->qos_parameters.derate_table.dcn_mall_prefetch_urgent.fclk_derate_percent / 100.0; - derate_dram_factor = soc->qos_parameters.derate_table.dcn_mall_prefetch_urgent.dram_derate_percent_pixel / 100.0; - - if (is_hvm_en) { - if (is_hvm_only) - derate_dram_factor = soc->qos_parameters.derate_table.dcn_mall_prefetch_urgent.dram_derate_percent_vm / 100.0; - else - derate_dram_factor = soc->qos_parameters.derate_table.dcn_mall_prefetch_urgent.dram_derate_percent_pixel_and_vm / 100.0; - } else { - derate_dram_factor = soc->qos_parameters.derate_table.dcn_mall_prefetch_urgent.dram_derate_percent_pixel / 100.0; - } - } else { // just assume sys_active - derate_sdp_factor = soc->qos_parameters.derate_table.system_active_urgent.dcfclk_derate_percent / 100.0; - derate_fabric_factor = soc->qos_parameters.derate_table.system_active_urgent.fclk_derate_percent / 100.0; - - if (is_hvm_en) { - if (is_hvm_only) - derate_dram_factor = soc->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_vm / 100.0; - else - derate_dram_factor = soc->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel_and_vm / 100.0; - } else { - derate_dram_factor = soc->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100.0; - } - } - } - - double derate_sdp_bandwidth = ideal_sdp_bandwidth * derate_sdp_factor; - double derate_fabric_bandwidth = ideal_fabric_bandwidth * derate_fabric_factor; - double derate_dram_bandwidth = ideal_dram_bandwidth * derate_dram_factor; - - if (bw_type == dml2_core_internal_bw_sdp) - return_bw_mbps = math_min2(derate_sdp_bandwidth, derate_fabric_bandwidth); - else // dml2_core_internal_bw_dram - return_bw_mbps = derate_dram_bandwidth; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: is_avg_bw = %u\n", __func__, is_avg_bw); - dml2_printf("DML::%s: is_hvm_en = %u\n", __func__, is_hvm_en); - dml2_printf("DML::%s: is_hvm_only = %u\n", __func__, is_hvm_only); - dml2_printf("DML::%s: state_type = %s\n", __func__, dml2_core_internal_soc_state_type_str(state_type)); - dml2_printf("DML::%s: bw_type = %s\n", __func__, dml2_core_internal_bw_type_str(bw_type)); - dml2_printf("DML::%s: dcflk_mhz = %f\n", __func__, dcflk_mhz); - dml2_printf("DML::%s: fclk_mhz = %f\n", __func__, fclk_mhz); - dml2_printf("DML::%s: ideal_sdp_bandwidth = %f\n", __func__, ideal_sdp_bandwidth); - dml2_printf("DML::%s: ideal_fabric_bandwidth = %f\n", __func__, ideal_fabric_bandwidth); - dml2_printf("DML::%s: ideal_dram_bandwidth = %f\n", __func__, ideal_dram_bandwidth); - dml2_printf("DML::%s: derate_sdp_bandwidth = %f (derate %f)\n", __func__, derate_sdp_bandwidth, derate_sdp_factor); - dml2_printf("DML::%s: derate_fabric_bandwidth = %f (derate %f)\n", __func__, derate_fabric_bandwidth, derate_fabric_factor); - dml2_printf("DML::%s: derate_dram_bandwidth = %f (derate %f)\n", __func__, derate_dram_bandwidth, derate_dram_factor); - dml2_printf("DML::%s: return_bw_mbps = %f\n", __func__, return_bw_mbps); -#endif - return return_bw_mbps; -} - -static void calculate_bandwidth_available( - double avg_bandwidth_available_min[dml2_core_internal_soc_state_max], - double avg_bandwidth_available[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_bandwidth_available_min[dml2_core_internal_soc_state_max], // min between SDP and DRAM - double urg_bandwidth_available[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_bandwidth_available_vm_only[dml2_core_internal_soc_state_max], - double urg_bandwidth_available_pixel_and_vm[dml2_core_internal_soc_state_max], - - const struct dml2_soc_bb *soc, - bool HostVMEnable, - double dcfclk_mhz, - double fclk_mhz, - double dram_bw_mbps) -{ - unsigned int n, m; - - dml2_printf("DML::%s: dcfclk_mhz = %f\n", __func__, dcfclk_mhz); - dml2_printf("DML::%s: fclk_mhz = %f\n", __func__, fclk_mhz); - dml2_printf("DML::%s: dram_bw_mbps = %f\n", __func__, dram_bw_mbps); - - // Calculate all the bandwidth availabe - for (m = 0; m < dml2_core_internal_soc_state_max; m++) { - for (n = 0; n < dml2_core_internal_bw_max; n++) { - avg_bandwidth_available[m][n] = dml_get_return_bandwidth_available(soc, - m, // soc_state - n, // bw_type - 1, // avg_bw - HostVMEnable, - 0, // hvm_only - dcfclk_mhz, - fclk_mhz, - dram_bw_mbps); - - urg_bandwidth_available[m][n] = dml_get_return_bandwidth_available(soc, m, n, 0, HostVMEnable, 0, dcfclk_mhz, fclk_mhz, dram_bw_mbps); - - - dml2_printf("DML::%s: avg_bandwidth_available[%s][%s]=%f\n", __func__, dml2_core_internal_soc_state_type_str(m), dml2_core_internal_bw_type_str(n), avg_bandwidth_available[m][n]); - dml2_printf("DML::%s: urg_bandwidth_available[%s][%s]=%f\n", __func__, dml2_core_internal_soc_state_type_str(m), dml2_core_internal_bw_type_str(n), urg_bandwidth_available[m][n]); - - // urg_bandwidth_available_vm_only is indexed by soc_state - if (n == dml2_core_internal_bw_dram) { - urg_bandwidth_available_vm_only[m] = dml_get_return_bandwidth_available(soc, m, n, 0, HostVMEnable, 1, dcfclk_mhz, fclk_mhz, dram_bw_mbps); - urg_bandwidth_available_pixel_and_vm[m] = dml_get_return_bandwidth_available(soc, m, n, 0, HostVMEnable, 0, dcfclk_mhz, fclk_mhz, dram_bw_mbps); - } - } - - avg_bandwidth_available_min[m] = math_min2(avg_bandwidth_available[m][dml2_core_internal_bw_dram], avg_bandwidth_available[m][dml2_core_internal_bw_sdp]); - urg_bandwidth_available_min[m] = math_min2(urg_bandwidth_available[m][dml2_core_internal_bw_dram], urg_bandwidth_available[m][dml2_core_internal_bw_sdp]); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: avg_bandwidth_available_min[%s]=%f\n", __func__, dml2_core_internal_soc_state_type_str(m), avg_bandwidth_available_min[m]); - dml2_printf("DML::%s: urg_bandwidth_available_min[%s]=%f\n", __func__, dml2_core_internal_soc_state_type_str(m), urg_bandwidth_available_min[m]); - dml2_printf("DML::%s: urg_bandwidth_available_vm_only[%s]=%f\n", __func__, dml2_core_internal_soc_state_type_str(m), urg_bandwidth_available_vm_only[n]); -#endif - } -} - -static void calculate_avg_bandwidth_required( - double avg_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - - // input - const struct dml2_display_cfg *display_cfg, - unsigned int num_active_planes, - double ReadBandwidthLuma[], - double ReadBandwidthChroma[], - double cursor_bw[], - double dcc_dram_bw_nom_overhead_factor_p0[], - double dcc_dram_bw_nom_overhead_factor_p1[], - double mall_prefetch_dram_overhead_factor[], - double mall_prefetch_sdp_overhead_factor[]) -{ - unsigned int n, m, k; - - // Average BW support check - for (m = 0; m < dml2_core_internal_soc_state_max; m++) { - for (n = 0; n < dml2_core_internal_bw_max; n++) { // sdp, dram - avg_bandwidth_required[m][n] = 0; - } - } - - // SysActive and SVP Prefetch AVG bandwidth Check - for (k = 0; k < num_active_planes; ++k) { -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: plane %0d\n", __func__, k); - dml2_printf("DML::%s: ReadBandwidthLuma=%f\n", __func__, ReadBandwidthLuma[k]); - dml2_printf("DML::%s: ReadBandwidthChroma=%f\n", __func__, ReadBandwidthChroma[k]); - dml2_printf("DML::%s: dcc_dram_bw_nom_overhead_factor_p0=%f\n", __func__, dcc_dram_bw_nom_overhead_factor_p0[k]); - dml2_printf("DML::%s: dcc_dram_bw_nom_overhead_factor_p1=%f\n", __func__, dcc_dram_bw_nom_overhead_factor_p1[k]); - dml2_printf("DML::%s: mall_prefetch_dram_overhead_factor=%f\n", __func__, mall_prefetch_dram_overhead_factor[k]); - dml2_printf("DML::%s: mall_prefetch_sdp_overhead_factor=%f\n", __func__, mall_prefetch_sdp_overhead_factor[k]); -#endif - - double sdp_overhead_factor = mall_prefetch_sdp_overhead_factor[k]; - double dram_overhead_factor_p0 = dcc_dram_bw_nom_overhead_factor_p0[k] * mall_prefetch_dram_overhead_factor[k]; - double dram_overhead_factor_p1 = dcc_dram_bw_nom_overhead_factor_p1[k] * mall_prefetch_dram_overhead_factor[k]; - - // FIXME_DCN4, was missing cursor_bw in here, but do I actually need that and tdlut bw for average bandwidth calculation? - // active avg bw not include phantom, but svp_prefetch avg bw should include phantom pipes - if (!dml_is_phantom_pipe(&display_cfg->plane_descriptors[k])) { - avg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp] += sdp_overhead_factor * (ReadBandwidthLuma[k] + ReadBandwidthChroma[k]) + cursor_bw[k]; - avg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram] += dram_overhead_factor_p0 * ReadBandwidthLuma[k] + dram_overhead_factor_p1 * ReadBandwidthChroma[k] + cursor_bw[k]; - } - avg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp] += sdp_overhead_factor * (ReadBandwidthLuma[k] + ReadBandwidthChroma[k]) + cursor_bw[k]; - avg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram] += dram_overhead_factor_p0 * ReadBandwidthLuma[k] + dram_overhead_factor_p1 * ReadBandwidthChroma[k] + cursor_bw[k]; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: avg_bandwidth_required[%s][%s]=%f\n", __func__, dml2_core_internal_soc_state_type_str(dml2_core_internal_soc_state_sys_active), dml2_core_internal_bw_type_str(dml2_core_internal_bw_sdp), avg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]); - dml2_printf("DML::%s: avg_bandwidth_required[%s][%s]=%f\n", __func__, dml2_core_internal_soc_state_type_str(dml2_core_internal_soc_state_sys_active), dml2_core_internal_bw_type_str(dml2_core_internal_bw_dram), avg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram]); - dml2_printf("DML::%s: avg_bandwidth_required[%s][%s]=%f\n", __func__, dml2_core_internal_soc_state_type_str(dml2_core_internal_soc_state_svp_prefetch), dml2_core_internal_bw_type_str(dml2_core_internal_bw_sdp), avg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp]); - dml2_printf("DML::%s: avg_bandwidth_required[%s][%s]=%f\n", __func__, dml2_core_internal_soc_state_type_str(dml2_core_internal_soc_state_svp_prefetch), dml2_core_internal_bw_type_str(dml2_core_internal_bw_dram), avg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram]); -#endif - } -} - -static void CalculateVMRowAndSwath(struct dml2_core_internal_scratch *scratch, - struct dml2_core_calcs_CalculateVMRowAndSwath_params *p) -{ - struct dml2_core_calcs_CalculateVMRowAndSwath_locals *s = &scratch->CalculateVMRowAndSwath_locals; - - 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) { - 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; - } - - if (dml2_core_shared_is_420(p->myPipe[k].SourcePixelFormat) || p->myPipe[k].SourcePixelFormat == dml2_rgbe_alpha) { - if ((p->myPipe[k].SourcePixelFormat == dml2_420_10 || p->myPipe[k].SourcePixelFormat == dml2_420_12) && !dml_is_vertical_rotation(p->myPipe[k].RotationAngle)) { - s->PTEBufferSizeInRequestsForLuma[k] = (p->PTEBufferSizeInRequestsLuma + p->PTEBufferSizeInRequestsChroma) / 2; - s->PTEBufferSizeInRequestsForChroma[k] = s->PTEBufferSizeInRequestsForLuma[k]; - } else { - s->PTEBufferSizeInRequestsForLuma[k] = p->PTEBufferSizeInRequestsLuma; - s->PTEBufferSizeInRequestsForChroma[k] = p->PTEBufferSizeInRequestsChroma; - } - - scratch->calculate_vm_and_row_bytes_params.ViewportStationary = p->myPipe[k].ViewportStationary; - scratch->calculate_vm_and_row_bytes_params.DCCEnable = p->myPipe[k].DCCEnable; - scratch->calculate_vm_and_row_bytes_params.NumberOfDPPs = p->myPipe[k].DPPPerSurface; - scratch->calculate_vm_and_row_bytes_params.BlockHeight256Bytes = p->myPipe[k].BlockHeight256BytesC; - scratch->calculate_vm_and_row_bytes_params.BlockWidth256Bytes = p->myPipe[k].BlockWidth256BytesC; - scratch->calculate_vm_and_row_bytes_params.SourcePixelFormat = p->myPipe[k].SourcePixelFormat; - scratch->calculate_vm_and_row_bytes_params.SurfaceTiling = p->myPipe[k].SurfaceTiling; - scratch->calculate_vm_and_row_bytes_params.BytePerPixel = p->myPipe[k].BytePerPixelC; - scratch->calculate_vm_and_row_bytes_params.RotationAngle = p->myPipe[k].RotationAngle; - scratch->calculate_vm_and_row_bytes_params.SwathWidth = p->SwathWidthC[k]; - scratch->calculate_vm_and_row_bytes_params.ViewportHeight = p->myPipe[k].ViewportHeightC; - scratch->calculate_vm_and_row_bytes_params.ViewportXStart = p->myPipe[k].ViewportXStartC; - scratch->calculate_vm_and_row_bytes_params.ViewportYStart = p->myPipe[k].ViewportYStartC; - scratch->calculate_vm_and_row_bytes_params.GPUVMEnable = p->display_cfg->gpuvm_enable; - scratch->calculate_vm_and_row_bytes_params.GPUVMMaxPageTableLevels = p->display_cfg->gpuvm_max_page_table_levels; - scratch->calculate_vm_and_row_bytes_params.GPUVMMinPageSizeKBytes = p->display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes; - scratch->calculate_vm_and_row_bytes_params.PTEBufferSizeInRequests = s->PTEBufferSizeInRequestsForChroma[k]; - scratch->calculate_vm_and_row_bytes_params.Pitch = p->myPipe[k].PitchC; - scratch->calculate_vm_and_row_bytes_params.MacroTileWidth = p->myPipe[k].BlockWidthC; - scratch->calculate_vm_and_row_bytes_params.MacroTileHeight = p->myPipe[k].BlockHeightC; - scratch->calculate_vm_and_row_bytes_params.is_phantom = dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k]); - scratch->calculate_vm_and_row_bytes_params.DCCMetaPitch = p->myPipe[k].DCCMetaPitchC; - scratch->calculate_vm_and_row_bytes_params.mrq_present = p->mrq_present; - - scratch->calculate_vm_and_row_bytes_params.PixelPTEBytesPerRow = &s->PixelPTEBytesPerRowC[k]; - scratch->calculate_vm_and_row_bytes_params.PixelPTEBytesPerRowStorage = &s->PixelPTEBytesPerRowStorageC[k]; - scratch->calculate_vm_and_row_bytes_params.dpte_row_width_ub = &p->dpte_row_width_chroma_ub[k]; - scratch->calculate_vm_and_row_bytes_params.dpte_row_height = &p->dpte_row_height_chroma[k]; - scratch->calculate_vm_and_row_bytes_params.dpte_row_height_linear = &p->dpte_row_height_linear_chroma[k]; - scratch->calculate_vm_and_row_bytes_params.PixelPTEBytesPerRow_one_row_per_frame = &s->PixelPTEBytesPerRowC_one_row_per_frame[k]; - scratch->calculate_vm_and_row_bytes_params.dpte_row_width_ub_one_row_per_frame = &s->dpte_row_width_chroma_ub_one_row_per_frame[k]; - scratch->calculate_vm_and_row_bytes_params.dpte_row_height_one_row_per_frame = &s->dpte_row_height_chroma_one_row_per_frame[k]; - scratch->calculate_vm_and_row_bytes_params.vmpg_width = &p->vmpg_width_c[k]; - scratch->calculate_vm_and_row_bytes_params.vmpg_height = &p->vmpg_height_c[k]; - scratch->calculate_vm_and_row_bytes_params.PixelPTEReqWidth = &p->PixelPTEReqWidthC[k]; - scratch->calculate_vm_and_row_bytes_params.PixelPTEReqHeight = &p->PixelPTEReqHeightC[k]; - scratch->calculate_vm_and_row_bytes_params.PTERequestSize = &p->PTERequestSizeC[k]; - scratch->calculate_vm_and_row_bytes_params.dpde0_bytes_per_frame_ub = &p->dpde0_bytes_per_frame_ub_c[k]; - - scratch->calculate_vm_and_row_bytes_params.meta_row_bytes = &s->meta_row_bytes_per_row_ub_c[k]; - scratch->calculate_vm_and_row_bytes_params.MetaRequestWidth = &p->meta_req_width_chroma[k]; - scratch->calculate_vm_and_row_bytes_params.MetaRequestHeight = &p->meta_req_height_chroma[k]; - scratch->calculate_vm_and_row_bytes_params.meta_row_width = &p->meta_row_width_chroma[k]; - scratch->calculate_vm_and_row_bytes_params.meta_row_height = &p->meta_row_height_chroma[k]; - scratch->calculate_vm_and_row_bytes_params.meta_pte_bytes_per_frame_ub = &p->meta_pte_bytes_per_frame_ub_c[k]; - - s->vm_bytes_c = CalculateVMAndRowBytes(&scratch->calculate_vm_and_row_bytes_params); - - p->PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines( - p->myPipe[k].VRatioChroma, - p->myPipe[k].VTapsChroma, - p->myPipe[k].InterlaceEnable, - p->myPipe[k].ProgressiveToInterlaceUnitInOPP, - p->myPipe[k].SwathHeightC, - p->myPipe[k].RotationAngle, - p->myPipe[k].mirrored, - p->myPipe[k].ViewportStationary, - p->SwathWidthC[k], - p->myPipe[k].ViewportHeightC, - p->myPipe[k].ViewportXStartC, - p->myPipe[k].ViewportYStartC, - - // Output - &p->VInitPreFillC[k], - &p->MaxNumSwathC[k]); - } else { - s->PTEBufferSizeInRequestsForLuma[k] = p->PTEBufferSizeInRequestsLuma + p->PTEBufferSizeInRequestsChroma; - s->PTEBufferSizeInRequestsForChroma[k] = 0; - s->PixelPTEBytesPerRowC[k] = 0; - s->PixelPTEBytesPerRowStorageC[k] = 0; - s->vm_bytes_c = 0; - p->MaxNumSwathC[k] = 0; - p->PrefetchSourceLinesC[k] = 0; - s->dpte_row_height_chroma_one_row_per_frame[k] = 0; - s->dpte_row_width_chroma_ub_one_row_per_frame[k] = 0; - s->PixelPTEBytesPerRowC_one_row_per_frame[k] = 0; - } - - scratch->calculate_vm_and_row_bytes_params.ViewportStationary = p->myPipe[k].ViewportStationary; - scratch->calculate_vm_and_row_bytes_params.DCCEnable = p->myPipe[k].DCCEnable; - scratch->calculate_vm_and_row_bytes_params.NumberOfDPPs = p->myPipe[k].DPPPerSurface; - scratch->calculate_vm_and_row_bytes_params.BlockHeight256Bytes = p->myPipe[k].BlockHeight256BytesY; - scratch->calculate_vm_and_row_bytes_params.BlockWidth256Bytes = p->myPipe[k].BlockWidth256BytesY; - scratch->calculate_vm_and_row_bytes_params.SourcePixelFormat = p->myPipe[k].SourcePixelFormat; - scratch->calculate_vm_and_row_bytes_params.SurfaceTiling = p->myPipe[k].SurfaceTiling; - scratch->calculate_vm_and_row_bytes_params.BytePerPixel = p->myPipe[k].BytePerPixelY; - scratch->calculate_vm_and_row_bytes_params.RotationAngle = p->myPipe[k].RotationAngle; - scratch->calculate_vm_and_row_bytes_params.SwathWidth = p->SwathWidthY[k]; - scratch->calculate_vm_and_row_bytes_params.ViewportHeight = p->myPipe[k].ViewportHeight; - scratch->calculate_vm_and_row_bytes_params.ViewportXStart = p->myPipe[k].ViewportXStart; - scratch->calculate_vm_and_row_bytes_params.ViewportYStart = p->myPipe[k].ViewportYStart; - scratch->calculate_vm_and_row_bytes_params.GPUVMEnable = p->display_cfg->gpuvm_enable; - scratch->calculate_vm_and_row_bytes_params.GPUVMMaxPageTableLevels = p->display_cfg->gpuvm_max_page_table_levels; - scratch->calculate_vm_and_row_bytes_params.GPUVMMinPageSizeKBytes = p->display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes; - scratch->calculate_vm_and_row_bytes_params.PTEBufferSizeInRequests = s->PTEBufferSizeInRequestsForLuma[k]; - scratch->calculate_vm_and_row_bytes_params.Pitch = p->myPipe[k].PitchY; - scratch->calculate_vm_and_row_bytes_params.MacroTileWidth = p->myPipe[k].BlockWidthY; - scratch->calculate_vm_and_row_bytes_params.MacroTileHeight = p->myPipe[k].BlockHeightY; - scratch->calculate_vm_and_row_bytes_params.is_phantom = dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k]); - scratch->calculate_vm_and_row_bytes_params.DCCMetaPitch = p->myPipe[k].DCCMetaPitchY; - scratch->calculate_vm_and_row_bytes_params.mrq_present = p->mrq_present; - - scratch->calculate_vm_and_row_bytes_params.PixelPTEBytesPerRow = &s->PixelPTEBytesPerRowY[k]; - scratch->calculate_vm_and_row_bytes_params.PixelPTEBytesPerRowStorage = &s->PixelPTEBytesPerRowStorageY[k]; - scratch->calculate_vm_and_row_bytes_params.dpte_row_width_ub = &p->dpte_row_width_luma_ub[k]; - scratch->calculate_vm_and_row_bytes_params.dpte_row_height = &p->dpte_row_height_luma[k]; - scratch->calculate_vm_and_row_bytes_params.dpte_row_height_linear = &p->dpte_row_height_linear_luma[k]; - scratch->calculate_vm_and_row_bytes_params.PixelPTEBytesPerRow_one_row_per_frame = &s->PixelPTEBytesPerRowY_one_row_per_frame[k]; - scratch->calculate_vm_and_row_bytes_params.dpte_row_width_ub_one_row_per_frame = &s->dpte_row_width_luma_ub_one_row_per_frame[k]; - scratch->calculate_vm_and_row_bytes_params.dpte_row_height_one_row_per_frame = &s->dpte_row_height_luma_one_row_per_frame[k]; - scratch->calculate_vm_and_row_bytes_params.vmpg_width = &p->vmpg_width_y[k]; - scratch->calculate_vm_and_row_bytes_params.vmpg_height = &p->vmpg_height_y[k]; - scratch->calculate_vm_and_row_bytes_params.PixelPTEReqWidth = &p->PixelPTEReqWidthY[k]; - scratch->calculate_vm_and_row_bytes_params.PixelPTEReqHeight = &p->PixelPTEReqHeightY[k]; - scratch->calculate_vm_and_row_bytes_params.PTERequestSize = &p->PTERequestSizeY[k]; - scratch->calculate_vm_and_row_bytes_params.dpde0_bytes_per_frame_ub = &p->dpde0_bytes_per_frame_ub_l[k]; - - scratch->calculate_vm_and_row_bytes_params.meta_row_bytes = &s->meta_row_bytes_per_row_ub_l[k]; - scratch->calculate_vm_and_row_bytes_params.MetaRequestWidth = &p->meta_req_width_luma[k]; - scratch->calculate_vm_and_row_bytes_params.MetaRequestHeight = &p->meta_req_height_luma[k]; - scratch->calculate_vm_and_row_bytes_params.meta_row_width = &p->meta_row_width_luma[k]; - scratch->calculate_vm_and_row_bytes_params.meta_row_height = &p->meta_row_height_luma[k]; - scratch->calculate_vm_and_row_bytes_params.meta_pte_bytes_per_frame_ub = &p->meta_pte_bytes_per_frame_ub_l[k]; - - s->vm_bytes_l = CalculateVMAndRowBytes(&scratch->calculate_vm_and_row_bytes_params); - - p->PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines( - p->myPipe[k].VRatio, - p->myPipe[k].VTaps, - p->myPipe[k].InterlaceEnable, - p->myPipe[k].ProgressiveToInterlaceUnitInOPP, - p->myPipe[k].SwathHeightY, - p->myPipe[k].RotationAngle, - p->myPipe[k].mirrored, - p->myPipe[k].ViewportStationary, - p->SwathWidthY[k], - p->myPipe[k].ViewportHeight, - p->myPipe[k].ViewportXStart, - p->myPipe[k].ViewportYStart, - - // Output - &p->VInitPreFillY[k], - &p->MaxNumSwathY[k]); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, vm_bytes_l = %u (before hvm level)\n", __func__, k, s->vm_bytes_l); - dml2_printf("DML::%s: k=%u, vm_bytes_c = %u (before hvm level)\n", __func__, k, s->vm_bytes_c); - dml2_printf("DML::%s: k=%u, meta_row_bytes_per_row_ub_l = %u\n", __func__, k, s->meta_row_bytes_per_row_ub_l[k]); - dml2_printf("DML::%s: k=%u, meta_row_bytes_per_row_ub_c = %u\n", __func__, k, s->meta_row_bytes_per_row_ub_c[k]); -#endif - p->vm_bytes[k] = (s->vm_bytes_l + s->vm_bytes_c) * (1 + 8 * s->HostVMDynamicLevels); - p->meta_row_bytes[k] = s->meta_row_bytes_per_row_ub_l[k] + s->meta_row_bytes_per_row_ub_c[k]; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, meta_row_bytes = %u\n", __func__, k, p->meta_row_bytes[k]); - dml2_printf("DML::%s: k=%u, vm_bytes = %u (after hvm level)\n", __func__, k, p->vm_bytes[k]); -#endif - if (s->PixelPTEBytesPerRowStorageY[k] <= 64 * s->PTEBufferSizeInRequestsForLuma[k] && s->PixelPTEBytesPerRowStorageC[k] <= 64 * s->PTEBufferSizeInRequestsForChroma[k]) { - p->PTEBufferSizeNotExceeded[k] = true; - } else { - p->PTEBufferSizeNotExceeded[k] = false; - } - - s->one_row_per_frame_fits_in_buffer[k] = (s->PixelPTEBytesPerRowY_one_row_per_frame[k] <= 64 * 2 * s->PTEBufferSizeInRequestsForLuma[k] && - s->PixelPTEBytesPerRowC_one_row_per_frame[k] <= 64 * 2 * s->PTEBufferSizeInRequestsForChroma[k]); -#ifdef __DML_VBA_DEBUG__ - if (p->PTEBufferSizeNotExceeded[k] == 0 || s->one_row_per_frame_fits_in_buffer[k] == 0) { - dml2_printf("DML::%s: k=%u, PixelPTEBytesPerRowY = %u (before hvm level)\n", __func__, k, s->PixelPTEBytesPerRowY[k]); - dml2_printf("DML::%s: k=%u, PixelPTEBytesPerRowC = %u (before hvm level)\n", __func__, k, s->PixelPTEBytesPerRowC[k]); - dml2_printf("DML::%s: k=%u, PixelPTEBytesPerRowStorageY = %u\n", __func__, k, s->PixelPTEBytesPerRowStorageY[k]); - dml2_printf("DML::%s: k=%u, PixelPTEBytesPerRowStorageC = %u\n", __func__, k, s->PixelPTEBytesPerRowStorageC[k]); - dml2_printf("DML::%s: k=%u, PTEBufferSizeInRequestsForLuma = %u\n", __func__, k, s->PTEBufferSizeInRequestsForLuma[k]); - dml2_printf("DML::%s: k=%u, PTEBufferSizeInRequestsForChroma = %u\n", __func__, k, s->PTEBufferSizeInRequestsForChroma[k]); - dml2_printf("DML::%s: k=%u, PTEBufferSizeNotExceeded (not one_row_per_frame) = %u\n", __func__, k, p->PTEBufferSizeNotExceeded[k]); - - dml2_printf("DML::%s: k=%u, HostVMDynamicLevels = %u\n", __func__, k, s->HostVMDynamicLevels); - dml2_printf("DML::%s: k=%u, PixelPTEBytesPerRowY_one_row_per_frame = %u\n", __func__, k, s->PixelPTEBytesPerRowY_one_row_per_frame[k]); - dml2_printf("DML::%s: k=%u, PixelPTEBytesPerRowC_one_row_per_frame = %u\n", __func__, k, s->PixelPTEBytesPerRowC_one_row_per_frame[k]); - dml2_printf("DML::%s: k=%u, one_row_per_frame_fits_in_buffer = %u\n", __func__, k, s->one_row_per_frame_fits_in_buffer[k]); - } -#endif - } - - CalculateMALLUseForStaticScreen( - p->display_cfg, - p->NumberOfActiveSurfaces, - p->MALLAllocatedForDCN, - p->SurfaceSizeInMALL, - s->one_row_per_frame_fits_in_buffer, - // Output - p->is_using_mall_for_ss); - - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - if (p->display_cfg->gpuvm_enable) { - if (p->display_cfg->plane_descriptors[k].overrides.hw.force_pte_buffer_mode.enable == 1) { - p->PTE_BUFFER_MODE[k] = p->display_cfg->plane_descriptors[k].overrides.hw.force_pte_buffer_mode.value; - } - p->PTE_BUFFER_MODE[k] = p->myPipe[k].FORCE_ONE_ROW_FOR_FRAME || p->is_using_mall_for_ss[k] || (p->display_cfg->plane_descriptors[k].overrides.legacy_svp_config == dml2_svp_mode_override_main_pipe) || - dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k]) || (p->display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes > 64); - p->BIGK_FRAGMENT_SIZE[k] = (unsigned int)(math_log((float)p->display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes * 1024, 2) - 12); - } else { - p->PTE_BUFFER_MODE[k] = 0; - p->BIGK_FRAGMENT_SIZE[k] = 0; - } - } - - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - p->DCCMetaBufferSizeNotExceeded[k] = true; -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, SurfaceSizeInMALL = %u\n", __func__, k, p->SurfaceSizeInMALL[k]); - dml2_printf("DML::%s: k=%u, is_using_mall_for_ss = %u\n", __func__, k, p->is_using_mall_for_ss[k]); -#endif - p->use_one_row_for_frame[k] = p->myPipe[k].FORCE_ONE_ROW_FOR_FRAME || p->is_using_mall_for_ss[k] || (p->display_cfg->plane_descriptors[k].overrides.legacy_svp_config == dml2_svp_mode_override_main_pipe) || - (dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k])) || (p->display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes > 64 && dml_is_vertical_rotation(p->myPipe[k].RotationAngle)); - - p->use_one_row_for_frame_flip[k] = p->use_one_row_for_frame[k] && !(p->display_cfg->plane_descriptors[k].overrides.uclk_pstate_change_strategy == dml2_uclk_pstate_change_strategy_force_mall_full_frame); - - if (p->use_one_row_for_frame[k]) { - p->dpte_row_height_luma[k] = s->dpte_row_height_luma_one_row_per_frame[k]; - p->dpte_row_width_luma_ub[k] = s->dpte_row_width_luma_ub_one_row_per_frame[k]; - s->PixelPTEBytesPerRowY[k] = s->PixelPTEBytesPerRowY_one_row_per_frame[k]; - p->dpte_row_height_chroma[k] = s->dpte_row_height_chroma_one_row_per_frame[k]; - p->dpte_row_width_chroma_ub[k] = s->dpte_row_width_chroma_ub_one_row_per_frame[k]; - s->PixelPTEBytesPerRowC[k] = s->PixelPTEBytesPerRowC_one_row_per_frame[k]; - p->PTEBufferSizeNotExceeded[k] = s->one_row_per_frame_fits_in_buffer[k]; - } - - if (p->meta_row_bytes[k] <= p->DCCMetaBufferSizeBytes) { - p->DCCMetaBufferSizeNotExceeded[k] = true; - } else { - p->DCCMetaBufferSizeNotExceeded[k] = false; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%d, meta_row_bytes = %d\n", __func__, k, p->meta_row_bytes[k]); - dml2_printf("DML::%s: k=%d, DCCMetaBufferSizeBytes = %d\n", __func__, k, p->DCCMetaBufferSizeBytes); - dml2_printf("DML::%s: k=%d, DCCMetaBufferSizeNotExceeded = %d\n", __func__, k, p->DCCMetaBufferSizeNotExceeded[k]); -#endif - } - - s->PixelPTEBytesPerRowY[k] = s->PixelPTEBytesPerRowY[k] * (1 + 8 * s->HostVMDynamicLevels); - s->PixelPTEBytesPerRowC[k] = s->PixelPTEBytesPerRowC[k] * (1 + 8 * s->HostVMDynamicLevels); - p->PixelPTEBytesPerRow[k] = s->PixelPTEBytesPerRowY[k] + s->PixelPTEBytesPerRowC[k]; - - // if one row of dPTEs is meant to span the entire frame, then for these calculations, we will pretend like that one big row is fetched in two halfs - if (p->use_one_row_for_frame[k]) - p->PixelPTEBytesPerRow[k] = p->PixelPTEBytesPerRow[k] / 2; - - CalculateRowBandwidth( - p->display_cfg->gpuvm_enable, - p->use_one_row_for_frame[k], - p->myPipe[k].SourcePixelFormat, - p->myPipe[k].VRatio, - p->myPipe[k].VRatioChroma, - p->myPipe[k].DCCEnable, - p->myPipe[k].HTotal / p->myPipe[k].PixelClock, - s->PixelPTEBytesPerRowY[k], - s->PixelPTEBytesPerRowC[k], - p->dpte_row_height_luma[k], - p->dpte_row_height_chroma[k], - - p->mrq_present, - s->meta_row_bytes_per_row_ub_l[k], - s->meta_row_bytes_per_row_ub_c[k], - p->meta_row_height_luma[k], - p->meta_row_height_chroma[k], - - // Output - &p->dpte_row_bw[k], - &p->meta_row_bw[k]); -#ifdef __DML_VBA_DEBUG__ - 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, use_one_row_for_frame_flip = %u\n", __func__, k, p->use_one_row_for_frame_flip[k]); - dml2_printf("DML::%s: k=%u, UseMALLForPStateChange = %u\n", __func__, k, p->display_cfg->plane_descriptors[k].overrides.legacy_svp_config); - dml2_printf("DML::%s: k=%u, dpte_row_height_luma = %u\n", __func__, k, p->dpte_row_height_luma[k]); - dml2_printf("DML::%s: k=%u, dpte_row_width_luma_ub = %u\n", __func__, k, p->dpte_row_width_luma_ub[k]); - dml2_printf("DML::%s: k=%u, PixelPTEBytesPerRowY = %u (after hvm level)\n", __func__, k, s->PixelPTEBytesPerRowY[k]); - dml2_printf("DML::%s: k=%u, dpte_row_height_chroma = %u\n", __func__, k, p->dpte_row_height_chroma[k]); - 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, PixelPTEBytesPerRowC = %u (after hvm level)\n", __func__, k, s->PixelPTEBytesPerRowC[k]); - dml2_printf("DML::%s: k=%u, PixelPTEBytesPerRow = %u\n", __func__, k, p->PixelPTEBytesPerRow[k]); - dml2_printf("DML::%s: k=%u, PTEBufferSizeNotExceeded = %u\n", __func__, k, p->PTEBufferSizeNotExceeded[k]); - dml2_printf("DML::%s: k=%u, gpuvm_enable = %u\n", __func__, k, p->display_cfg->gpuvm_enable); - dml2_printf("DML::%s: k=%u, PTE_BUFFER_MODE = %u\n", __func__, k, p->PTE_BUFFER_MODE[k]); - dml2_printf("DML::%s: k=%u, BIGK_FRAGMENT_SIZE = %u\n", __func__, k, p->BIGK_FRAGMENT_SIZE[k]); -#endif - } -} - -static double CalculateUrgentLatency( - double UrgentLatencyPixelDataOnly, - double UrgentLatencyPixelMixedWithVMData, - double UrgentLatencyVMDataOnly, - bool DoUrgentLatencyAdjustment, - double UrgentLatencyAdjustmentFabricClockComponent, - double UrgentLatencyAdjustmentFabricClockReference, - double FabricClock, - double uclk_freq_mhz, - enum dml2_qos_param_type qos_type, - unsigned int urgent_ramp_uclk_cycles, - unsigned int df_qos_response_time_fclk_cycles, - unsigned int max_round_trip_to_furthest_cs_fclk_cycles, - unsigned int mall_overhead_fclk_cycles, - double umc_urgent_ramp_latency_margin, - double fabric_max_transport_latency_margin) -{ - double urgent_latency = 0; - 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); - } else { - urgent_latency = math_max3(UrgentLatencyPixelDataOnly, UrgentLatencyPixelMixedWithVMData, UrgentLatencyVMDataOnly); - if (DoUrgentLatencyAdjustment == true) { - urgent_latency = urgent_latency + UrgentLatencyAdjustmentFabricClockComponent * (UrgentLatencyAdjustmentFabricClockReference / FabricClock - 1); - } - } -#ifdef __DML_VBA_DEBUG__ - 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); - dml2_printf("DML::%s: umc_urgent_ramp_latency_margin = %f\n", __func__, umc_urgent_ramp_latency_margin); - } else { - dml2_printf("DML::%s: UrgentLatencyPixelDataOnly = %f\n", __func__, UrgentLatencyPixelDataOnly); - dml2_printf("DML::%s: UrgentLatencyPixelMixedWithVMData = %f\n", __func__, UrgentLatencyPixelMixedWithVMData); - dml2_printf("DML::%s: UrgentLatencyVMDataOnly = %f\n", __func__, UrgentLatencyVMDataOnly); - dml2_printf("DML::%s: UrgentLatencyAdjustmentFabricClockComponent = %f\n", __func__, UrgentLatencyAdjustmentFabricClockComponent); - dml2_printf("DML::%s: UrgentLatencyAdjustmentFabricClockReference = %f\n", __func__, UrgentLatencyAdjustmentFabricClockReference); - } - dml2_printf("DML::%s: FabricClock = %f\n", __func__, FabricClock); - dml2_printf("DML::%s: UrgentLatency = %f\n", __func__, urgent_latency); -#endif - return urgent_latency; -} - -static double CalculateTripToMemory( - double UrgLatency, - double FabricClock, - double uclk_freq_mhz, - enum dml2_qos_param_type qos_type, - unsigned int trip_to_memory_uclk_cycles, - unsigned int max_round_trip_to_furthest_cs_fclk_cycles, - unsigned int mall_overhead_fclk_cycles, - double umc_max_latency_margin, - double fabric_max_transport_latency_margin) -{ - double trip_to_memory_us; - 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); - } else { - trip_to_memory_us = UrgLatency; - } - -#ifdef __DML_VBA_DEBUG__ - 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); - dml2_printf("DML::%s: trip_to_memory_uclk_cycles = %d\n", __func__, trip_to_memory_uclk_cycles); - dml2_printf("DML::%s: uclk_freq_mhz = %f\n", __func__, uclk_freq_mhz); - dml2_printf("DML::%s: FabricClock = %f\n", __func__, FabricClock); - dml2_printf("DML::%s: fabric_max_transport_latency_margin = %f\n", __func__, fabric_max_transport_latency_margin); - dml2_printf("DML::%s: umc_max_latency_margin = %f\n", __func__, umc_max_latency_margin); - } else { - dml2_printf("DML::%s: UrgLatency = %f\n", __func__, UrgLatency); - } - dml2_printf("DML::%s: trip_to_memory_us = %f\n", __func__, trip_to_memory_us); -#endif - - - return trip_to_memory_us; -} - -static double CalculateMetaTripToMemory( - double UrgLatency, - double FabricClock, - double uclk_freq_mhz, - enum dml2_qos_param_type qos_type, - unsigned int meta_trip_to_memory_uclk_cycles, - unsigned int meta_trip_to_memory_fclk_cycles, - double umc_max_latency_margin, - double fabric_max_transport_latency_margin) -{ - double meta_trip_to_memory_us; - 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 { - meta_trip_to_memory_us = UrgLatency; - } - -#ifdef __DML_VBA_DEBUG__ - 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); - dml2_printf("DML::%s: uclk_freq_mhz = %f\n", __func__, uclk_freq_mhz); - } else { - dml2_printf("DML::%s: UrgLatency = %f\n", __func__, UrgLatency); - } - dml2_printf("DML::%s: meta_trip_to_memory_us = %f\n", __func__, meta_trip_to_memory_us); -#endif - - - return meta_trip_to_memory_us; -} - -static void calculate_cursor_req_attributes( - unsigned int cursor_width, - unsigned int cursor_bpp, - - // output - unsigned int *cursor_lines_per_chunk, - unsigned int *cursor_bytes_per_line, - unsigned int *cursor_bytes_per_chunk, - unsigned int *cursor_bytes) -{ - unsigned int cursor_pitch = 0; - unsigned int cursor_bytes_per_req = 0; - unsigned int cursor_width_bytes = 0; - unsigned int cursor_height = 0; - - //SW determines the cursor pitch to support the maximum cursor_width that will be used but the following restrictions apply. - //- For 2bpp, cursor_pitch = 256 pixels due to min cursor request size of 64B - //- For 32 or 64 bpp, cursor_pitch = 64, 128 or 256 pixels depending on the cursor width - if (cursor_bpp == 2) - cursor_pitch = 256; - else - cursor_pitch = (unsigned int)1 << (unsigned int)math_ceil2(math_log((float)cursor_width, 2), 1); - - //The cursor requestor uses a cursor request size of 64B, 128B, or 256B depending on the cursor_width and cursor_bpp as follows. - - cursor_width_bytes = (unsigned int)math_ceil2((double)cursor_width * cursor_bpp / 8, 1); - if (cursor_width_bytes <= 64) - cursor_bytes_per_req = 64; - else if (cursor_width_bytes <= 128) - cursor_bytes_per_req = 128; - else - cursor_bytes_per_req = 256; - - //If cursor_width_bytes is greater than 256B, then multiple 256B requests are issued to fetch the entire cursor line. - *cursor_bytes_per_line = (unsigned int)math_ceil2((double)cursor_width_bytes, cursor_bytes_per_req); - - //Nominally, the cursor chunk is 1KB or 2KB but it is restricted to a power of 2 number of lines with a maximum of 16 lines. - if (cursor_bpp == 2) { - *cursor_lines_per_chunk = 16; - } else if (cursor_bpp == 32) { - if (cursor_width <= 32) - *cursor_lines_per_chunk = 16; - else if (cursor_width <= 64) - *cursor_lines_per_chunk = 8; - else if (cursor_width <= 128) - *cursor_lines_per_chunk = 4; - else - *cursor_lines_per_chunk = 2; - } else if (cursor_bpp == 64) { - if (cursor_width <= 16) - *cursor_lines_per_chunk = 16; - else if (cursor_width <= 32) - *cursor_lines_per_chunk = 8; - else if (cursor_width <= 64) - *cursor_lines_per_chunk = 4; - else if (cursor_width <= 128) - *cursor_lines_per_chunk = 2; - else - *cursor_lines_per_chunk = 1; - } else { - if (cursor_width > 0) { - dml2_printf("DML::%s: Invalid cursor_bpp = %d\n", __func__, cursor_bpp); - dml2_assert(0); - } - } - - *cursor_bytes_per_chunk = *cursor_bytes_per_line * *cursor_lines_per_chunk; - - // For the cursor implementation, all requested data is stored in the return buffer. Given this fact, the cursor_bytes can be directly compared with the CursorBufferSize. - // Only cursor_width is provided for worst case sizing so assume that the cursor is square - cursor_height = cursor_width; - *cursor_bytes = *cursor_bytes_per_line * cursor_height; -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: cursor_bpp = %d\n", __func__, cursor_bpp); - dml2_printf("DML::%s: cursor_width = %d\n", __func__, cursor_width); - dml2_printf("DML::%s: cursor_width_bytes = %d\n", __func__, cursor_width_bytes); - dml2_printf("DML::%s: cursor_bytes_per_req = %d\n", __func__, cursor_bytes_per_req); - dml2_printf("DML::%s: cursor_lines_per_chunk = %d\n", __func__, *cursor_lines_per_chunk); - dml2_printf("DML::%s: cursor_bytes_per_line = %d\n", __func__, *cursor_bytes_per_line); - dml2_printf("DML::%s: cursor_bytes_per_chunk = %d\n", __func__, *cursor_bytes_per_chunk); - dml2_printf("DML::%s: cursor_bytes = %d\n", __func__, *cursor_bytes); - dml2_printf("DML::%s: cursor_pitch = %d\n", __func__, cursor_pitch); -#endif -} - -static void calculate_cursor_urgent_burst_factor( - unsigned int CursorBufferSize, - unsigned int CursorWidth, - unsigned int cursor_bytes_per_chunk, - unsigned int cursor_lines_per_chunk, - double LineTime, - double UrgentLatency, - - double *UrgentBurstFactorCursor, - bool *NotEnoughUrgentLatencyHiding) -{ - unsigned int LinesInCursorBuffer = 0; - double CursorBufferSizeInTime = 0; - - if (CursorWidth > 0) { - LinesInCursorBuffer = (unsigned int)math_floor2(CursorBufferSize * 1024.0 / (double)cursor_bytes_per_chunk, 1) * cursor_lines_per_chunk; - - CursorBufferSizeInTime = LinesInCursorBuffer * LineTime; - if (CursorBufferSizeInTime - UrgentLatency <= 0) { - *NotEnoughUrgentLatencyHiding = 1; - *UrgentBurstFactorCursor = 0; - } else { - *NotEnoughUrgentLatencyHiding = 0; - *UrgentBurstFactorCursor = CursorBufferSizeInTime / (CursorBufferSizeInTime - UrgentLatency); - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: LinesInCursorBuffer = %u\n", __func__, LinesInCursorBuffer); - dml2_printf("DML::%s: CursorBufferSizeInTime = %f\n", __func__, CursorBufferSizeInTime); - dml2_printf("DML::%s: CursorBufferSize = %u (kbytes)\n", __func__, CursorBufferSize); - dml2_printf("DML::%s: cursor_bytes_per_chunk = %u\n", __func__, cursor_bytes_per_chunk); - dml2_printf("DML::%s: cursor_lines_per_chunk = %u\n", __func__, cursor_lines_per_chunk); - dml2_printf("DML::%s: UrgentBurstFactorCursor = %f\n", __func__, *UrgentBurstFactorCursor); - dml2_printf("DML::%s: NotEnoughUrgentLatencyHiding = %d\n", __func__, *NotEnoughUrgentLatencyHiding); -#endif - - } -} - -static void CalculateUrgentBurstFactor( - const struct dml2_plane_parameters *plane_cfg, - unsigned int swath_width_luma_ub, - unsigned int swath_width_chroma_ub, - unsigned int SwathHeightY, - unsigned int SwathHeightC, - double LineTime, - double UrgentLatency, - double VRatio, - double VRatioC, - double BytePerPixelInDETY, - double BytePerPixelInDETC, - unsigned int DETBufferSizeY, - unsigned int DETBufferSizeC, - // Output - double *UrgentBurstFactorLuma, - double *UrgentBurstFactorChroma, - bool *NotEnoughUrgentLatencyHiding) -{ - double LinesInDETLuma; - double LinesInDETChroma; - double DETBufferSizeInTimeLuma; - double DETBufferSizeInTimeChroma; - - *NotEnoughUrgentLatencyHiding = 0; - *UrgentBurstFactorLuma = 0; - *UrgentBurstFactorChroma = 0; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: VRatio = %f\n", __func__, VRatio); - dml2_printf("DML::%s: VRatioC = %f\n", __func__, VRatioC); - dml2_printf("DML::%s: DETBufferSizeY = %d\n", __func__, DETBufferSizeY); - dml2_printf("DML::%s: DETBufferSizeC = %d\n", __func__, DETBufferSizeC); - dml2_printf("DML::%s: BytePerPixelInDETY = %f\n", __func__, BytePerPixelInDETY); - dml2_printf("DML::%s: swath_width_luma_ub = %d\n", __func__, swath_width_luma_ub); - dml2_printf("DML::%s: LineTime = %f\n", __func__, LineTime); -#endif - DML2_ASSERT(VRatio > 0); - - LinesInDETLuma = (dml_is_phantom_pipe(plane_cfg) ? 1024 * 1024 : DETBufferSizeY) / BytePerPixelInDETY / swath_width_luma_ub; - - DETBufferSizeInTimeLuma = math_floor2(LinesInDETLuma, SwathHeightY) * LineTime / VRatio; - if (DETBufferSizeInTimeLuma - UrgentLatency <= 0) { - *NotEnoughUrgentLatencyHiding = 1; - *UrgentBurstFactorLuma = 0; - } else { - *UrgentBurstFactorLuma = DETBufferSizeInTimeLuma / (DETBufferSizeInTimeLuma - UrgentLatency); - } - - if (BytePerPixelInDETC > 0) { - LinesInDETChroma = (dml_is_phantom_pipe(plane_cfg) ? 1024 * 1024 : DETBufferSizeC) / BytePerPixelInDETC / swath_width_chroma_ub; - - DETBufferSizeInTimeChroma = math_floor2(LinesInDETChroma, SwathHeightC) * LineTime / VRatioC; - if (DETBufferSizeInTimeChroma - UrgentLatency <= 0) { - *NotEnoughUrgentLatencyHiding = 1; - *UrgentBurstFactorChroma = 0; - } else { - *UrgentBurstFactorChroma = DETBufferSizeInTimeChroma / (DETBufferSizeInTimeChroma - UrgentLatency); - } - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: LinesInDETLuma = %f\n", __func__, LinesInDETLuma); - dml2_printf("DML::%s: UrgentLatency = %f\n", __func__, UrgentLatency); - dml2_printf("DML::%s: DETBufferSizeInTimeLuma = %f\n", __func__, DETBufferSizeInTimeLuma); - dml2_printf("DML::%s: UrgentBurstFactorLuma = %f\n", __func__, *UrgentBurstFactorLuma); - dml2_printf("DML::%s: UrgentBurstFactorChroma = %f\n", __func__, *UrgentBurstFactorChroma); - dml2_printf("DML::%s: NotEnoughUrgentLatencyHiding = %d\n", __func__, *NotEnoughUrgentLatencyHiding); -#endif - -} - -static void CalculateDCFCLKDeepSleep( - const struct dml2_display_cfg *display_cfg, - unsigned int NumberOfActiveSurfaces, - unsigned int BytePerPixelY[], - unsigned int BytePerPixelC[], - unsigned int SwathWidthY[], - unsigned int SwathWidthC[], - unsigned int DPPPerSurface[], - double PSCL_THROUGHPUT[], - double PSCL_THROUGHPUT_CHROMA[], - double Dppclk[], - double ReadBandwidthLuma[], - double ReadBandwidthChroma[], - unsigned int ReturnBusWidth, - - // Output - double *DCFClkDeepSleep) -{ - double DisplayPipeLineDeliveryTimeLuma; - double DisplayPipeLineDeliveryTimeChroma; - double DCFClkDeepSleepPerSurface[DML2_MAX_PLANES]; - - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - double pixel_rate_mhz = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000); - - if (display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio <= 1) { - DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] * DPPPerSurface[k] / display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio / pixel_rate_mhz; - } else { - DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] / PSCL_THROUGHPUT[k] / Dppclk[k]; - } - if (BytePerPixelC[k] == 0) { - DisplayPipeLineDeliveryTimeChroma = 0; - } else { - if (display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio <= 1) { - DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] * DPPPerSurface[k] / display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio / pixel_rate_mhz; - } else { - DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] / PSCL_THROUGHPUT_CHROMA[k] / Dppclk[k]; - } - } - - if (BytePerPixelC[k] > 0) { - DCFClkDeepSleepPerSurface[k] = math_max2(__DML2_CALCS_DCFCLK_FACTOR__ * SwathWidthY[k] * BytePerPixelY[k] / 32.0 / DisplayPipeLineDeliveryTimeLuma, - __DML2_CALCS_DCFCLK_FACTOR__ * SwathWidthC[k] * BytePerPixelC[k] / 32.0 / DisplayPipeLineDeliveryTimeChroma); - } else { - DCFClkDeepSleepPerSurface[k] = __DML2_CALCS_DCFCLK_FACTOR__ * SwathWidthY[k] * BytePerPixelY[k] / 64.0 / DisplayPipeLineDeliveryTimeLuma; - } - DCFClkDeepSleepPerSurface[k] = math_max2(DCFClkDeepSleepPerSurface[k], pixel_rate_mhz / 16); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, PixelClock = %f\n", __func__, k, pixel_rate_mhz); - dml2_printf("DML::%s: k=%u, DCFClkDeepSleepPerSurface = %f\n", __func__, k, DCFClkDeepSleepPerSurface[k]); -#endif - } - - double ReadBandwidth = 0.0; - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - ReadBandwidth = ReadBandwidth + ReadBandwidthLuma[k] + ReadBandwidthChroma[k]; - } - - *DCFClkDeepSleep = math_max2(8.0, __DML2_CALCS_DCFCLK_FACTOR__ * ReadBandwidth / (double)ReturnBusWidth); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: __DML2_CALCS_DCFCLK_FACTOR__ = %f\n", __func__, __DML2_CALCS_DCFCLK_FACTOR__); - dml2_printf("DML::%s: ReadBandwidth = %f\n", __func__, ReadBandwidth); - dml2_printf("DML::%s: ReturnBusWidth = %u\n", __func__, ReturnBusWidth); - dml2_printf("DML::%s: DCFClkDeepSleep = %f\n", __func__, *DCFClkDeepSleep); -#endif - - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - *DCFClkDeepSleep = math_max2(*DCFClkDeepSleep, DCFClkDeepSleepPerSurface[k]); - } - dml2_printf("DML::%s: DCFClkDeepSleep = %f (final)\n", __func__, *DCFClkDeepSleep); -} - -static double CalculateWriteBackDelay( - enum dml2_source_format_class WritebackPixelFormat, - double WritebackHRatio, - double WritebackVRatio, - unsigned int WritebackVTaps, - unsigned int WritebackDestinationWidth, - unsigned int WritebackDestinationHeight, - unsigned int WritebackSourceHeight, - unsigned int HTotal) -{ - double CalculateWriteBackDelay; - double Line_length; - double Output_lines_last_notclamped; - double WritebackVInit; - - WritebackVInit = (WritebackVRatio + WritebackVTaps + 1) / 2; - Line_length = math_max2((double)WritebackDestinationWidth, math_ceil2((double)WritebackDestinationWidth / 6.0, 1.0) * WritebackVTaps); - Output_lines_last_notclamped = WritebackDestinationHeight - 1 - math_ceil2(((double)WritebackSourceHeight - (double)WritebackVInit) / (double)WritebackVRatio, 1.0); - if (Output_lines_last_notclamped < 0) { - CalculateWriteBackDelay = 0; - } else { - CalculateWriteBackDelay = Output_lines_last_notclamped * Line_length + (HTotal - WritebackDestinationWidth) + 80; - } - return CalculateWriteBackDelay; -} - -static unsigned int CalculateMaxVStartup( - bool ptoi_supported, - unsigned int vblank_nom_default_us, - const struct dml2_timing_cfg *timing, - double write_back_delay_us) -{ - unsigned int vblank_size = 0; - unsigned int max_vstartup_lines = 0; - - double line_time_us = (double)timing->h_total / ((double)timing->pixel_clock_khz / 1000); - unsigned int vblank_actual = timing->v_total - timing->v_active; - unsigned int vblank_nom_default_in_line = (unsigned int)math_floor2((double)vblank_nom_default_us / line_time_us, 1.0); - unsigned int vblank_nom_input = (unsigned int)math_min2(timing->vblank_nom, vblank_nom_default_in_line); - unsigned int vblank_avail = (vblank_nom_input == 0) ? vblank_nom_default_in_line : vblank_nom_input; - - vblank_size = (unsigned int)math_min2(vblank_actual, vblank_avail); - - if (timing->interlaced && !ptoi_supported) - max_vstartup_lines = (unsigned int)(math_floor2(vblank_size / 2.0, 1.0)); - else - max_vstartup_lines = vblank_size - (unsigned int)math_max2(1.0, math_ceil2(write_back_delay_us / line_time_us, 1.0)); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: VBlankNom = %u\n", __func__, timing->vblank_nom); - dml2_printf("DML::%s: vblank_nom_default_us = %u\n", __func__, vblank_nom_default_us); - dml2_printf("DML::%s: line_time_us = %f\n", __func__, line_time_us); - dml2_printf("DML::%s: vblank_actual = %u\n", __func__, vblank_actual); - dml2_printf("DML::%s: vblank_avail = %u\n", __func__, vblank_avail); - dml2_printf("DML::%s: max_vstartup_lines = %u\n", __func__, max_vstartup_lines); -#endif - return max_vstartup_lines; -} - -static void CalculateSwathAndDETConfiguration(struct dml2_core_internal_scratch *scratch, - struct dml2_core_calcs_CalculateSwathAndDETConfiguration_params *p) -{ - struct dml2_core_shared_CalculateSwathAndDETConfiguration_locals *l = &scratch->CalculateSwathAndDETConfiguration_locals; - memset(l, 0, sizeof(struct dml2_core_shared_CalculateSwathAndDETConfiguration_locals)); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: ForceSingleDPP = %u\n", __func__, p->ForceSingleDPP); - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - dml2_printf("DML::%s: DPPPerSurface[%u] = %u\n", __func__, k, p->DPPPerSurface[k]); - } -#endif - CalculateSwathWidth( - p->display_cfg, - p->ForceSingleDPP, - p->NumberOfActiveSurfaces, - p->ODMMode, - p->BytePerPixY, - p->BytePerPixC, - p->Read256BytesBlockHeightY, - p->Read256BytesBlockHeightC, - p->Read256BytesBlockWidthY, - p->Read256BytesBlockWidthC, - p->surf_linear128_l, - p->surf_linear128_c, - p->DPPPerSurface, - - // Output - p->req_per_swath_ub_l, - p->req_per_swath_ub_c, - l->SwathWidthSingleDPP, - l->SwathWidthSingleDPPChroma, - p->SwathWidth, - p->SwathWidthChroma, - l->MaximumSwathHeightY, - l->MaximumSwathHeightC, - p->swath_width_luma_ub, - p->swath_width_chroma_ub); - - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - p->full_swath_bytes_l[k] = (unsigned int)(p->swath_width_luma_ub[k] * p->BytePerPixDETY[k] * l->MaximumSwathHeightY[k]); - p->full_swath_bytes_c[k] = (unsigned int)(p->swath_width_chroma_ub[k] * p->BytePerPixDETC[k] * l->MaximumSwathHeightC[k]); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u DPPPerSurface = %u\n", __func__, k, p->DPPPerSurface[k]); - dml2_printf("DML::%s: k=%u swath_width_luma_ub = %u\n", __func__, k, p->swath_width_luma_ub[k]); - dml2_printf("DML::%s: k=%u BytePerPixDETY = %f\n", __func__, k, p->BytePerPixDETY[k]); - dml2_printf("DML::%s: k=%u MaximumSwathHeightY = %u\n", __func__, k, l->MaximumSwathHeightY[k]); - dml2_printf("DML::%s: k=%u full_swath_bytes_l = %u\n", __func__, k, p->full_swath_bytes_l[k]); - dml2_printf("DML::%s: k=%u swath_width_chroma_ub = %u\n", __func__, k, p->swath_width_chroma_ub[k]); - dml2_printf("DML::%s: k=%u BytePerPixDETC = %f\n", __func__, k, p->BytePerPixDETC[k]); - dml2_printf("DML::%s: k=%u MaximumSwathHeightC = %u\n", __func__, k, l->MaximumSwathHeightC[k]); - dml2_printf("DML::%s: k=%u full_swath_bytes_c = %u\n", __func__, k, p->full_swath_bytes_c[k]); -#endif - if (p->display_cfg->plane_descriptors[k].pixel_format == dml2_420_10) { - p->full_swath_bytes_l[k] = (unsigned int)(math_ceil2((double)p->full_swath_bytes_l[k], 256)); - p->full_swath_bytes_c[k] = (unsigned int)(math_ceil2((double)p->full_swath_bytes_c[k], 256)); - } - } - - unsigned int TotalActiveDPP = 0; - bool NoChromaOrLinear = true; - unsigned int SurfaceDoingUnboundedRequest = 0; - - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - TotalActiveDPP = TotalActiveDPP + (p->ForceSingleDPP ? 1 : p->DPPPerSurface[k]); - if (p->DPPPerSurface[k] > 0) - SurfaceDoingUnboundedRequest = k; - if (dml2_core_shared_is_420(p->display_cfg->plane_descriptors[k].pixel_format) || p->display_cfg->plane_descriptors[k].pixel_format == dml2_rgbe_alpha - || p->display_cfg->plane_descriptors[k].surface.tiling == dml2_sw_linear) { - NoChromaOrLinear = false; - } - l->SwathTimeValueUs[k] = (unsigned int) ((double)l->MaximumSwathHeightY[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total - / p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz * 1000); - } - - *p->UnboundedRequestEnabled = UnboundedRequest(p->display_cfg->overrides.hw.force_unbounded_requesting.enable, p->display_cfg->overrides.hw.force_unbounded_requesting.value, TotalActiveDPP, NoChromaOrLinear); - - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.display_cfg = p->display_cfg; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.ForceSingleDPP = p->ForceSingleDPP; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.NumberOfActiveSurfaces = p->NumberOfActiveSurfaces; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.UnboundedRequestEnabled = *p->UnboundedRequestEnabled; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.nomDETInKByte = p->nomDETInKByte; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.MaxTotalDETInKByte = p->MaxTotalDETInKByte; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.ConfigReturnBufferSizeInKByte = p->ConfigReturnBufferSizeInKByte; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.MinCompressedBufferSizeInKByte = p->MinCompressedBufferSizeInKByte; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.ConfigReturnBufferSegmentSizeInkByte = p->ConfigReturnBufferSegmentSizeInkByte; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.CompressedBufferSegmentSizeInkByte = p->CompressedBufferSegmentSizeInkByte; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.ReadBandwidthLuma = p->ReadBandwidthLuma; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.ReadBandwidthChroma = p->ReadBandwidthChroma; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.full_swath_bytes_l = p->full_swath_bytes_l; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.full_swath_bytes_c = p->full_swath_bytes_c; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.DPPPerSurface = p->DPPPerSurface; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.DETBufferSizeInKByte = p->DETBufferSizeInKByte; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.CompressedBufferSizeInkByte = p->CompressedBufferSizeInkByte; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.swath_time_value_us = l->SwathTimeValueUs; - scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params.bestEffortMinActiveLatencyHidingUs = p->display_cfg->overrides.best_effort_min_active_latency_hiding_us; - if (p->funcs->calculate_det_buffer_size) { - p->funcs->calculate_det_buffer_size(&scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params); - } else { - CalculateDETBufferSize(&scratch->CalculateSwathAndDETConfiguration_locals.calculate_det_buffer_size_params); - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: TotalActiveDPP = %u\n", __func__, TotalActiveDPP); - dml2_printf("DML::%s: nomDETInKByte = %u\n", __func__, p->nomDETInKByte); - dml2_printf("DML::%s: ConfigReturnBufferSizeInKByte = %u\n", __func__, p->ConfigReturnBufferSizeInKByte); - dml2_printf("DML::%s: UnboundedRequestEnabled = %u\n", __func__, *p->UnboundedRequestEnabled); - dml2_printf("DML::%s: CompressedBufferSizeInkByte = %u\n", __func__, *p->CompressedBufferSizeInkByte); -#endif - - unsigned int DETBufferSizeInKByteForSwathCalculation; - *p->ViewportSizeSupport = true; - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - - DETBufferSizeInKByteForSwathCalculation = (dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k]) ? 1024 : p->DETBufferSizeInKByte[k]); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u DETBufferSizeInKByteForSwathCalculation = %u\n", __func__, k, DETBufferSizeInKByteForSwathCalculation); -#endif - - if (p->full_swath_bytes_l[k] + p->full_swath_bytes_c[k] <= DETBufferSizeInKByteForSwathCalculation * 1024 / 2) { - p->SwathHeightY[k] = l->MaximumSwathHeightY[k]; - p->SwathHeightC[k] = l->MaximumSwathHeightC[k]; - l->RoundedUpSwathSizeBytesY[k] = p->full_swath_bytes_l[k]; - l->RoundedUpSwathSizeBytesC[k] = p->full_swath_bytes_c[k]; - p->request_size_bytes_luma[k] = 256; - p->request_size_bytes_chroma[k] = 256; - - } else if (p->full_swath_bytes_l[k] >= 1.5 * p->full_swath_bytes_c[k] && p->full_swath_bytes_l[k] / 2 + p->full_swath_bytes_c[k] <= DETBufferSizeInKByteForSwathCalculation * 1024 / 2) { - p->SwathHeightY[k] = l->MaximumSwathHeightY[k] / 2; - p->SwathHeightC[k] = l->MaximumSwathHeightC[k]; - l->RoundedUpSwathSizeBytesY[k] = p->full_swath_bytes_l[k] / 2; - l->RoundedUpSwathSizeBytesC[k] = p->full_swath_bytes_c[k]; - 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] = 256; - - } else if (p->full_swath_bytes_l[k] < 1.5 * p->full_swath_bytes_c[k] && p->full_swath_bytes_l[k] + p->full_swath_bytes_c[k] / 2 <= DETBufferSizeInKByteForSwathCalculation * 1024 / 2) { - p->SwathHeightY[k] = l->MaximumSwathHeightY[k]; - p->SwathHeightC[k] = l->MaximumSwathHeightC[k] / 2; - l->RoundedUpSwathSizeBytesY[k] = p->full_swath_bytes_l[k]; - l->RoundedUpSwathSizeBytesC[k] = p->full_swath_bytes_c[k] / 2; - p->request_size_bytes_luma[k] = 256; - 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; - - } else { - p->SwathHeightY[k] = l->MaximumSwathHeightY[k] / 2; - 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; - } - - if (p->SwathHeightC[k] == 0) - p->request_size_bytes_chroma[k] = 0; - - if ((p->full_swath_bytes_l[k] / 2 + p->full_swath_bytes_c[k] / 2 > DETBufferSizeInKByteForSwathCalculation * 1024 / 2) || - p->SwathWidth[k] > p->MaximumSwathWidthLuma[k] || (p->SwathHeightC[k] > 0 && p->SwathWidthChroma[k] > p->MaximumSwathWidthChroma[k])) { - *p->ViewportSizeSupport = false; - p->ViewportSizeSupportPerSurface[k] = false; - } else { - p->ViewportSizeSupportPerSurface[k] = true; - } - - if (p->SwathHeightC[k] == 0) { -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, All DET will be used for plane0\n", __func__, k); -#endif - p->DETBufferSizeY[k] = p->DETBufferSizeInKByte[k] * 1024; - p->DETBufferSizeC[k] = 0; - } else if (l->RoundedUpSwathSizeBytesY[k] <= 1.5 * l->RoundedUpSwathSizeBytesC[k]) { -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, Half DET will be used for plane0, and half for plane1\n", __func__, k); -#endif - p->DETBufferSizeY[k] = p->DETBufferSizeInKByte[k] * 1024 / 2; - p->DETBufferSizeC[k] = p->DETBufferSizeInKByte[k] * 1024 / 2; - } else { -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, 2/3 DET will be used for plane0, and 1/3 for plane1\n", __func__, k); -#endif - p->DETBufferSizeY[k] = (unsigned int)(math_floor2(p->DETBufferSizeInKByte[k] * 1024 * 2 / 3, 1024)); - p->DETBufferSizeC[k] = p->DETBufferSizeInKByte[k] * 1024 - p->DETBufferSizeY[k]; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u SwathHeightY = %u\n", __func__, k, p->SwathHeightY[k]); - dml2_printf("DML::%s: k=%u SwathHeightC = %u\n", __func__, k, p->SwathHeightC[k]); - dml2_printf("DML::%s: k=%u full_swath_bytes_l = %u\n", __func__, k, p->full_swath_bytes_l[k]); - dml2_printf("DML::%s: k=%u full_swath_bytes_c = %u\n", __func__, k, p->full_swath_bytes_c[k]); - dml2_printf("DML::%s: k=%u RoundedUpSwathSizeBytesY = %u\n", __func__, k, l->RoundedUpSwathSizeBytesY[k]); - dml2_printf("DML::%s: k=%u RoundedUpSwathSizeBytesC = %u\n", __func__, k, l->RoundedUpSwathSizeBytesC[k]); - dml2_printf("DML::%s: k=%u DETBufferSizeInKByte = %u\n", __func__, k, p->DETBufferSizeInKByte[k]); - dml2_printf("DML::%s: k=%u DETBufferSizeY = %u\n", __func__, k, p->DETBufferSizeY[k]); - dml2_printf("DML::%s: k=%u DETBufferSizeC = %u\n", __func__, k, p->DETBufferSizeC[k]); - dml2_printf("DML::%s: k=%u ViewportSizeSupportPerSurface = %u\n", __func__, k, p->ViewportSizeSupportPerSurface[k]); -#endif - - } - - const long TTUFIFODEPTH = 8; - const long MAXIMUMCOMPRESSION = 4; - *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)(l->RoundedUpSwathSizeBytesY[SurfaceDoingUnboundedRequest] * TTUFIFODEPTH / 64)), 1.0); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: RoundedUpSwathSizeBytesY[%d] = %u\n", __func__, SurfaceDoingUnboundedRequest, l->RoundedUpSwathSizeBytesY[SurfaceDoingUnboundedRequest]); - dml2_printf("DML::%s: rob_buffer_size_kbytes = %u\n", __func__, p->rob_buffer_size_kbytes); -#endif - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: compbuf_reserved_space_64b = %u\n", __func__, *p->compbuf_reserved_space_64b); -#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 * (l->RoundedUpSwathSizeBytesY[k] + l->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, l->RoundedUpSwathSizeBytesC[k]); - dml2_printf("DML::%s: k=%u hw_debug5 = %u\n", __func__, k, *p->hw_debug5); -#endif - } - } -} - -static void CalculateODMMode( - unsigned int MaximumPixelsPerLinePerDSCUnit, - unsigned int HActive, - enum dml2_output_encoder_class Output, - enum dml2_odm_mode ODMUse, - double MaxDispclk, - bool DSCEnable, - unsigned int TotalNumberOfActiveDPP, - unsigned int MaxNumDPP, - double PixelClock, - - // Output - bool *TotalAvailablePipesSupport, - unsigned int *NumberOfDPP, - enum dml2_odm_mode *ODMMode, - double *RequiredDISPCLKPerSurface) -{ - double SurfaceRequiredDISPCLKWithoutODMCombine; - double SurfaceRequiredDISPCLKWithODMCombineTwoToOne; - double SurfaceRequiredDISPCLKWithODMCombineThreeToOne; - double SurfaceRequiredDISPCLKWithODMCombineFourToOne; - - SurfaceRequiredDISPCLKWithoutODMCombine = CalculateRequiredDispclk(dml2_odm_mode_bypass, PixelClock); - SurfaceRequiredDISPCLKWithODMCombineTwoToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_2to1, PixelClock); - SurfaceRequiredDISPCLKWithODMCombineThreeToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_3to1, PixelClock); - SurfaceRequiredDISPCLKWithODMCombineFourToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_4to1, PixelClock); - *TotalAvailablePipesSupport = true; - - if (ODMUse == dml2_odm_mode_bypass || ODMUse == dml2_odm_mode_auto) - *ODMMode = dml2_odm_mode_bypass; - else if (ODMUse == dml2_odm_mode_combine_2to1) - *ODMMode = dml2_odm_mode_combine_2to1; - else if (ODMUse == dml2_odm_mode_combine_3to1) - *ODMMode = dml2_odm_mode_combine_3to1; - else if (ODMUse == dml2_odm_mode_combine_4to1) - *ODMMode = dml2_odm_mode_combine_4to1; - else if (ODMUse == dml2_odm_mode_split_1to2) - *ODMMode = dml2_odm_mode_split_1to2; - else if (ODMUse == dml2_odm_mode_mso_1to2) - *ODMMode = dml2_odm_mode_mso_1to2; - else if (ODMUse == dml2_odm_mode_mso_1to4) - *ODMMode = dml2_odm_mode_mso_1to4; - - *RequiredDISPCLKPerSurface = SurfaceRequiredDISPCLKWithoutODMCombine; - *NumberOfDPP = 0; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: ODMUse = %d\n", __func__, ODMUse); - dml2_printf("DML::%s: Output = %d\n", __func__, Output); - dml2_printf("DML::%s: DSCEnable = %d\n", __func__, DSCEnable); - dml2_printf("DML::%s: MaxDispclk = %f\n", __func__, MaxDispclk); - dml2_printf("DML::%s: MaximumPixelsPerLinePerDSCUnit = %d\n", __func__, MaximumPixelsPerLinePerDSCUnit); - dml2_printf("DML::%s: SurfaceRequiredDISPCLKWithoutODMCombine = %f\n", __func__, SurfaceRequiredDISPCLKWithoutODMCombine); - dml2_printf("DML::%s: SurfaceRequiredDISPCLKWithODMCombineTwoToOne = %f\n", __func__, SurfaceRequiredDISPCLKWithODMCombineTwoToOne); - dml2_printf("DML::%s: SurfaceRequiredDISPCLKWithODMCombineThreeToOne = %f\n", __func__, SurfaceRequiredDISPCLKWithODMCombineThreeToOne); - dml2_printf("DML::%s: SurfaceRequiredDISPCLKWithODMCombineFourToOne = %f\n", __func__, SurfaceRequiredDISPCLKWithODMCombineFourToOne); -#endif - - if (ODMUse == dml2_odm_mode_combine_4to1 || (ODMUse == dml2_odm_mode_auto && - (SurfaceRequiredDISPCLKWithODMCombineThreeToOne > MaxDispclk || (DSCEnable && (HActive > 3 * MaximumPixelsPerLinePerDSCUnit))))) { - if (TotalNumberOfActiveDPP + 4 <= MaxNumDPP) { - *ODMMode = dml2_odm_mode_combine_4to1; - *RequiredDISPCLKPerSurface = SurfaceRequiredDISPCLKWithODMCombineFourToOne; - *NumberOfDPP = 4; - } else { - *TotalAvailablePipesSupport = false; - } - } else if (ODMUse == dml2_odm_mode_combine_3to1 || (ODMUse == dml2_odm_mode_auto && - ((SurfaceRequiredDISPCLKWithODMCombineTwoToOne > MaxDispclk && SurfaceRequiredDISPCLKWithODMCombineThreeToOne <= MaxDispclk) || - (DSCEnable && (HActive > 2 * MaximumPixelsPerLinePerDSCUnit))))) { - if (TotalNumberOfActiveDPP + 3 <= MaxNumDPP) { - *ODMMode = dml2_odm_mode_combine_3to1; - *RequiredDISPCLKPerSurface = SurfaceRequiredDISPCLKWithODMCombineThreeToOne; - *NumberOfDPP = 3; - } else { - *TotalAvailablePipesSupport = false; - } - - } else if (ODMUse == dml2_odm_mode_combine_2to1 || (ODMUse == dml2_odm_mode_auto && - ((SurfaceRequiredDISPCLKWithoutODMCombine > MaxDispclk && SurfaceRequiredDISPCLKWithODMCombineTwoToOne <= MaxDispclk) || - (DSCEnable && (HActive > MaximumPixelsPerLinePerDSCUnit))))) { - if (TotalNumberOfActiveDPP + 2 <= MaxNumDPP) { - *ODMMode = dml2_odm_mode_combine_2to1; - *RequiredDISPCLKPerSurface = SurfaceRequiredDISPCLKWithODMCombineTwoToOne; - *NumberOfDPP = 2; - } else { - *TotalAvailablePipesSupport = false; - } - - } else { - if (TotalNumberOfActiveDPP + 1 <= MaxNumDPP) { - *NumberOfDPP = 1; - } else { - *TotalAvailablePipesSupport = false; - } - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: ODMMode = %d\n", __func__, *ODMMode); - dml2_printf("DML::%s: NumberOfDPP = %d\n", __func__, *NumberOfDPP); - dml2_printf("DML::%s: TotalAvailablePipesSupport = %d\n", __func__, *TotalAvailablePipesSupport); - dml2_printf("DML::%s: RequiredDISPCLKPerSurface = %f\n", __func__, *RequiredDISPCLKPerSurface); -#endif - -} - -static void CalculateOutputLink( - struct dml2_core_internal_scratch *s, - double PHYCLK, - double PHYCLKD18, - double PHYCLKD32, - double Downspreading, - bool IsMainSurfaceUsingTheIndicatedTiming, - enum dml2_output_encoder_class Output, - enum dml2_output_format_class OutputFormat, - unsigned int HTotal, - unsigned int HActive, - double PixelClockBackEnd, - double ForcedOutputLinkBPP, - unsigned int DSCInputBitPerComponent, - unsigned int NumberOfDSCSlices, - double AudioSampleRate, - unsigned int AudioSampleLayout, - enum dml2_odm_mode ODMModeNoDSC, - enum dml2_odm_mode ODMModeDSC, - enum dml2_dsc_enable_option DSCEnable, - unsigned int OutputLinkDPLanes, - enum dml2_output_link_dp_rate OutputLinkDPRate, - - // Output - bool *RequiresDSC, - bool *RequiresFEC, - double *OutBpp, - enum dml2_core_internal_output_type *OutputType, - enum dml2_core_internal_output_type_rate *OutputRate, - unsigned int *RequiredSlots) -{ - bool LinkDSCEnable; - unsigned int dummy; - *RequiresDSC = false; - *RequiresFEC = false; - *OutBpp = 0; - - *OutputType = dml2_core_internal_output_type_unknown; - *OutputRate = dml2_core_internal_output_rate_unknown; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: DSCEnable = %u (dis, en, en_if_necessary)\n", __func__, DSCEnable); - dml2_printf("DML::%s: IsMainSurfaceUsingTheIndicatedTiming = %u\n", __func__, IsMainSurfaceUsingTheIndicatedTiming); - dml2_printf("DML::%s: PHYCLK = %f\n", __func__, PHYCLK); - dml2_printf("DML::%s: PixelClockBackEnd = %f\n", __func__, PixelClockBackEnd); - dml2_printf("DML::%s: AudioSampleRate = %f\n", __func__, AudioSampleRate); - dml2_printf("DML::%s: HActive = %u\n", __func__, HActive); - dml2_printf("DML::%s: HTotal = %u\n", __func__, HTotal); - dml2_printf("DML::%s: ODMModeNoDSC = %u\n", __func__, ODMModeNoDSC); - dml2_printf("DML::%s: ODMModeDSC = %u\n", __func__, ODMModeDSC); - dml2_printf("DML::%s: ForcedOutputLinkBPP = %f\n", __func__, ForcedOutputLinkBPP); - dml2_printf("DML::%s: Output (encoder) = %u\n", __func__, Output); - dml2_printf("DML::%s: OutputLinkDPRate = %u\n", __func__, OutputLinkDPRate); -#endif - if (IsMainSurfaceUsingTheIndicatedTiming) { - if (Output == dml2_hdmi) { - *RequiresDSC = false; - *RequiresFEC = false; - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, math_min2(600, PHYCLK) * 10, 3, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, false, Output, - OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy); - //OutputTypeAndRate = "HDMI"; - *OutputType = dml2_core_internal_output_type_hdmi; - } else if (Output == dml2_dp || Output == dml2_dp2p0 || Output == dml2_edp) { - if (DSCEnable == dml2_dsc_enable) { - *RequiresDSC = true; - LinkDSCEnable = true; - if (Output == dml2_dp || Output == dml2_dp2p0) { - *RequiresFEC = true; - } else { - *RequiresFEC = false; - } - } else { - *RequiresDSC = false; - LinkDSCEnable = false; - if (Output == dml2_dp2p0) { - *RequiresFEC = true; - } else { - *RequiresFEC = false; - } - } - if (Output == dml2_dp2p0) { - *OutBpp = 0; - if ((OutputLinkDPRate == dml2_dp_rate_na || OutputLinkDPRate == dml2_dp_rate_uhbr10) && PHYCLKD32 >= 10000.0 / 32) { - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, (1 - Downspreading / 100) * 10000, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, - OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots); - if (*OutBpp == 0 && PHYCLKD32 < 13500.0 / 32 && DSCEnable == dml2_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0) { - *RequiresDSC = true; - LinkDSCEnable = true; - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, (1 - Downspreading / 100) * 10000, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, - OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots); - } - //OutputTypeAndRate = Output & " UHBR10"; - *OutputType = dml2_core_internal_output_type_dp2p0; - *OutputRate = dml2_core_internal_output_rate_dp_rate_uhbr10; - } - if ((OutputLinkDPRate == dml2_dp_rate_na || OutputLinkDPRate == dml2_dp_rate_uhbr13p5) && *OutBpp == 0 && PHYCLKD32 >= 13500.0 / 32) { - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, (1 - Downspreading / 100) * 13500, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, - OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots); - - if (*OutBpp == 0 && PHYCLKD32 < 20000 / 32 && DSCEnable == dml2_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0) { - *RequiresDSC = true; - LinkDSCEnable = true; - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, (1 - Downspreading / 100) * 13500, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, - OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots); - } - //OutputTypeAndRate = Output & " UHBR13p5"; - *OutputType = dml2_core_internal_output_type_dp2p0; - *OutputRate = dml2_core_internal_output_rate_dp_rate_uhbr13p5; - } - if ((OutputLinkDPRate == dml2_dp_rate_na || OutputLinkDPRate == dml2_dp_rate_uhbr20) && *OutBpp == 0 && PHYCLKD32 >= 20000 / 32) { - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, (1 - Downspreading / 100) * 20000, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, - OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots); - if (*OutBpp == 0 && DSCEnable == dml2_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0) { - *RequiresDSC = true; - LinkDSCEnable = true; - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, (1 - Downspreading / 100) * 20000, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, - OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots); - } - //OutputTypeAndRate = Output & " UHBR20"; - *OutputType = dml2_core_internal_output_type_dp2p0; - *OutputRate = dml2_core_internal_output_rate_dp_rate_uhbr20; - } - } else { // output is dp or edp - *OutBpp = 0; - if ((OutputLinkDPRate == dml2_dp_rate_na || OutputLinkDPRate == dml2_dp_rate_hbr) && PHYCLK >= 270) { - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, (1 - Downspreading / 100) * 2700, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, - OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots); - if (*OutBpp == 0 && PHYCLK < 540 && DSCEnable == dml2_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0) { - *RequiresDSC = true; - LinkDSCEnable = true; - if (Output == dml2_dp) { - *RequiresFEC = true; - } - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, (1 - Downspreading / 100) * 2700, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, - OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots); - } - //OutputTypeAndRate = Output & " HBR"; - *OutputType = (Output == dml2_dp) ? dml2_core_internal_output_type_dp : dml2_core_internal_output_type_edp; - *OutputRate = dml2_core_internal_output_rate_dp_rate_hbr; - } - if ((OutputLinkDPRate == dml2_dp_rate_na || OutputLinkDPRate == dml2_dp_rate_hbr2) && *OutBpp == 0 && PHYCLK >= 540) { - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, (1 - Downspreading / 100) * 5400, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, - OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots); - - if (*OutBpp == 0 && PHYCLK < 810 && DSCEnable == dml2_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0) { - *RequiresDSC = true; - LinkDSCEnable = true; - if (Output == dml2_dp) { - *RequiresFEC = true; - } - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, (1 - Downspreading / 100) * 5400, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, - OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots); - } - //OutputTypeAndRate = Output & " HBR2"; - *OutputType = (Output == dml2_dp) ? dml2_core_internal_output_type_dp : dml2_core_internal_output_type_edp; - *OutputRate = dml2_core_internal_output_rate_dp_rate_hbr2; - } - if ((OutputLinkDPRate == dml2_dp_rate_na || OutputLinkDPRate == dml2_dp_rate_hbr3) && *OutBpp == 0 && PHYCLK >= 810) { // VBA_ERROR, vba code doesn't have hbr3 check - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, (1 - Downspreading / 100) * 8100, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, - OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots); - - if (*OutBpp == 0 && DSCEnable == dml2_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0) { - *RequiresDSC = true; - LinkDSCEnable = true; - if (Output == dml2_dp) { - *RequiresFEC = true; - } - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, (1 - Downspreading / 100) * 8100, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, - OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots); - } - //OutputTypeAndRate = Output & " HBR3"; - *OutputType = (Output == dml2_dp) ? dml2_core_internal_output_type_dp : dml2_core_internal_output_type_edp; - *OutputRate = dml2_core_internal_output_rate_dp_rate_hbr3; - } - } - } else if (Output == dml2_hdmifrl) { - if (DSCEnable == dml2_dsc_enable) { - *RequiresDSC = true; - LinkDSCEnable = true; - *RequiresFEC = true; - } else { - *RequiresDSC = false; - LinkDSCEnable = false; - *RequiresFEC = false; - } - *OutBpp = 0; - if (PHYCLKD18 >= 3000.0 / 18) { - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, 3000, 3, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy); - //OutputTypeAndRate = Output & "3x3"; - *OutputType = dml2_core_internal_output_type_hdmifrl; - *OutputRate = dml2_core_internal_output_rate_hdmi_rate_3x3; - } - if (*OutBpp == 0 && PHYCLKD18 >= 6000.0 / 18) { - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, 6000, 3, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy); - //OutputTypeAndRate = Output & "6x3"; - *OutputType = dml2_core_internal_output_type_hdmifrl; - *OutputRate = dml2_core_internal_output_rate_hdmi_rate_6x3; - } - if (*OutBpp == 0 && PHYCLKD18 >= 6000.0 / 18) { - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, 6000, 4, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy); - //OutputTypeAndRate = Output & "6x4"; - *OutputType = dml2_core_internal_output_type_hdmifrl; - *OutputRate = dml2_core_internal_output_rate_hdmi_rate_6x4; - } - if (*OutBpp == 0 && PHYCLKD18 >= 8000.0 / 18) { - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, 8000, 4, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy); - //OutputTypeAndRate = Output & "8x4"; - *OutputType = dml2_core_internal_output_type_hdmifrl; - *OutputRate = dml2_core_internal_output_rate_hdmi_rate_8x4; - } - if (*OutBpp == 0 && PHYCLKD18 >= 10000.0 / 18) { - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, 10000, 4, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy); - if (*OutBpp == 0 && DSCEnable == dml2_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0 && PHYCLKD18 < 12000.0 / 18) { - *RequiresDSC = true; - LinkDSCEnable = true; - *RequiresFEC = true; - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, 10000, 4, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy); - } - //OutputTypeAndRate = Output & "10x4"; - *OutputType = dml2_core_internal_output_type_hdmifrl; - *OutputRate = dml2_core_internal_output_rate_hdmi_rate_10x4; - } - if (*OutBpp == 0 && PHYCLKD18 >= 12000.0 / 18) { - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, 12000, 4, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy); - if (*OutBpp == 0 && DSCEnable == dml2_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0) { - *RequiresDSC = true; - LinkDSCEnable = true; - *RequiresFEC = true; - *OutBpp = TruncToValidBPP(&s->TruncToValidBPP_locals, 12000, 4, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy); - } - //OutputTypeAndRate = Output & "12x4"; - *OutputType = dml2_core_internal_output_type_hdmifrl; - *OutputRate = dml2_core_internal_output_rate_hdmi_rate_12x4; - } - } - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: RequiresDSC = %u\n", __func__, *RequiresDSC); - dml2_printf("DML::%s: RequiresFEC = %u\n", __func__, *RequiresFEC); - dml2_printf("DML::%s: OutBpp = %f\n", __func__, *OutBpp); -#endif -} - -static double CalculateWriteBackDISPCLK( - enum dml2_source_format_class WritebackPixelFormat, - double PixelClock, - double WritebackHRatio, - double WritebackVRatio, - unsigned int WritebackHTaps, - unsigned int WritebackVTaps, - unsigned int WritebackSourceWidth, - unsigned int WritebackDestinationWidth, - unsigned int HTotal, - unsigned int WritebackLineBufferSize) -{ - double DISPCLK_H, DISPCLK_V, DISPCLK_HB; - - DISPCLK_H = PixelClock * math_ceil2((double)WritebackHTaps / 8.0, 1) / WritebackHRatio; - DISPCLK_V = PixelClock * (WritebackVTaps * math_ceil2((double)WritebackDestinationWidth / 6.0, 1) + 8.0) / (double)HTotal; - DISPCLK_HB = PixelClock * WritebackVTaps * (WritebackDestinationWidth * WritebackVTaps - WritebackLineBufferSize / 57.0) / 6.0 / (double)WritebackSourceWidth; - return math_max3(DISPCLK_H, DISPCLK_V, DISPCLK_HB); -} - -static double RequiredDTBCLK( - bool DSCEnable, - double PixelClock, - enum dml2_output_format_class OutputFormat, - double OutputBpp, - unsigned int DSCSlices, - unsigned int HTotal, - unsigned int HActive, - unsigned int AudioRate, - unsigned int AudioLayout) -{ - if (DSCEnable != true) { - return math_max2(PixelClock / 4.0 * OutputBpp / 24.0, 25.0); - } else { - double PixelWordRate = PixelClock / (OutputFormat == dml2_444 ? 1 : 2); - double HCActive = math_ceil2(DSCSlices * math_ceil2(OutputBpp * math_ceil2(HActive / DSCSlices, 1) / 8.0, 1) / 3.0, 1); - double HCBlank = 64 + 32 * math_ceil2(AudioRate * (AudioLayout == 1 ? 1 : 0.25) * HTotal / (PixelClock * 1000), 1); - double AverageTribyteRate = PixelWordRate * (HCActive + HCBlank) / HTotal; - double HActiveTribyteRate = PixelWordRate * HCActive / HActive; - return math_max4(PixelWordRate / 4.0, AverageTribyteRate / 4.0, HActiveTribyteRate / 4.0, 25.0) * 1.002; - } -} - -static unsigned int DSCDelayRequirement( - bool DSCEnabled, - enum dml2_odm_mode ODMMode, - unsigned int DSCInputBitPerComponent, - double OutputBpp, - unsigned int HActive, - unsigned int HTotal, - unsigned int NumberOfDSCSlices, - enum dml2_output_format_class OutputFormat, - enum dml2_output_encoder_class Output, - double PixelClock, - double PixelClockBackEnd) -{ - unsigned int DSCDelayRequirement_val = 0; - unsigned int NumberOfDSCSlicesFactor = 1; - - if (DSCEnabled == true && OutputBpp != 0) { - - if (ODMMode == dml2_odm_mode_combine_4to1) - NumberOfDSCSlicesFactor = 4; - else if (ODMMode == dml2_odm_mode_combine_3to1) - NumberOfDSCSlicesFactor = 3; - else if (ODMMode == dml2_odm_mode_combine_2to1) - NumberOfDSCSlicesFactor = 2; - - DSCDelayRequirement_val = NumberOfDSCSlicesFactor * (dscceComputeDelay(DSCInputBitPerComponent, OutputBpp, (unsigned int)(math_ceil2((double)HActive / (double)NumberOfDSCSlices, 1.0)), - (NumberOfDSCSlices / NumberOfDSCSlicesFactor), OutputFormat, Output) + dscComputeDelay(OutputFormat, Output)); - - DSCDelayRequirement_val = (unsigned int)(DSCDelayRequirement_val + (HTotal - HActive) * math_ceil2((double)DSCDelayRequirement_val / (double)HActive, 1.0)); - DSCDelayRequirement_val = (unsigned int)(DSCDelayRequirement_val * PixelClock / PixelClockBackEnd); - - } else { - DSCDelayRequirement_val = 0; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: DSCEnabled= %u\n", __func__, DSCEnabled); - dml2_printf("DML::%s: ODMMode = %u\n", __func__, ODMMode); - dml2_printf("DML::%s: OutputBpp = %f\n", __func__, OutputBpp); - dml2_printf("DML::%s: HActive = %u\n", __func__, HActive); - dml2_printf("DML::%s: HTotal = %u\n", __func__, HTotal); - dml2_printf("DML::%s: PixelClock = %f\n", __func__, PixelClock); - dml2_printf("DML::%s: PixelClockBackEnd = %f\n", __func__, PixelClockBackEnd); - dml2_printf("DML::%s: OutputFormat = %u\n", __func__, OutputFormat); - dml2_printf("DML::%s: DSCInputBitPerComponent = %u\n", __func__, DSCInputBitPerComponent); - dml2_printf("DML::%s: NumberOfDSCSlices = %u\n", __func__, NumberOfDSCSlices); - dml2_printf("DML::%s: DSCDelayRequirement_val = %u\n", __func__, DSCDelayRequirement_val); -#endif - - return DSCDelayRequirement_val; -} - -static void CalculateSurfaceSizeInMall( - const struct dml2_display_cfg *display_cfg, - unsigned int NumberOfActiveSurfaces, - unsigned int MALLAllocatedForDCN, - unsigned int BytesPerPixelY[], - unsigned int BytesPerPixelC[], - unsigned int Read256BytesBlockWidthY[], - unsigned int Read256BytesBlockWidthC[], - unsigned int Read256BytesBlockHeightY[], - unsigned int Read256BytesBlockHeightC[], - unsigned int ReadBlockWidthY[], - unsigned int ReadBlockWidthC[], - unsigned int ReadBlockHeightY[], - unsigned int ReadBlockHeightC[], - - // Output - unsigned int SurfaceSizeInMALL[], - bool *ExceededMALLSize) -{ - unsigned int TotalSurfaceSizeInMALLForSS = 0; - unsigned int TotalSurfaceSizeInMALLForSubVP = 0; - unsigned int MALLAllocatedForDCNInBytes = MALLAllocatedForDCN * 1024 * 1024; - - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - const struct dml2_composition_cfg *composition = &display_cfg->plane_descriptors[k].composition; - const struct dml2_surface_cfg *surface = &display_cfg->plane_descriptors[k].surface; - - if (composition->viewport.stationary) { - SurfaceSizeInMALL[k] = (unsigned int)(math_min2(math_ceil2((double)surface->plane0.width, ReadBlockWidthY[k]), - math_floor2(composition->viewport.plane0.x_start + composition->viewport.plane0.width + ReadBlockWidthY[k] - 1, ReadBlockWidthY[k]) - - math_floor2((double)composition->viewport.plane0.x_start, ReadBlockWidthY[k])) * - math_min2(math_ceil2((double)surface->plane0.height, ReadBlockHeightY[k]), - math_floor2((double)composition->viewport.plane0.y_start + composition->viewport.plane0.height + ReadBlockHeightY[k] - 1, ReadBlockHeightY[k]) - - math_floor2((double)composition->viewport.plane0.y_start, ReadBlockHeightY[k])) * BytesPerPixelY[k]); - - if (ReadBlockWidthC[k] > 0) { - SurfaceSizeInMALL[k] = (unsigned int)(SurfaceSizeInMALL[k] + - math_min2(math_ceil2((double)surface->plane1.width, ReadBlockWidthC[k]), - math_floor2((double)composition->viewport.plane1.y_start + composition->viewport.plane1.width + ReadBlockWidthC[k] - 1, ReadBlockWidthC[k]) - - math_floor2((double)composition->viewport.plane1.y_start, ReadBlockWidthC[k])) * - math_min2(math_ceil2((double)surface->plane1.height, ReadBlockHeightC[k]), - math_floor2((double)composition->viewport.plane1.y_start + composition->viewport.plane1.height + ReadBlockHeightC[k] - 1, ReadBlockHeightC[k]) - - math_floor2(composition->viewport.plane1.y_start, ReadBlockHeightC[k])) * BytesPerPixelC[k]); - } - if (surface->dcc.enable) { - SurfaceSizeInMALL[k] = (unsigned int)(SurfaceSizeInMALL[k] + - math_min2(math_ceil2(surface->plane0.width, 8 * Read256BytesBlockWidthY[k]), - math_floor2(composition->viewport.plane0.x_start + composition->viewport.plane0.width + 8 * Read256BytesBlockWidthY[k] - 1, 8 * Read256BytesBlockWidthY[k]) - - math_floor2(composition->viewport.plane0.x_start, 8 * Read256BytesBlockWidthY[k])) * - math_min2(math_ceil2(surface->plane0.height, 8 * Read256BytesBlockHeightY[k]), - math_floor2(composition->viewport.plane0.y_start + composition->viewport.plane0.height + 8 * Read256BytesBlockHeightY[k] - 1, 8 * Read256BytesBlockHeightY[k]) - - math_floor2(composition->viewport.plane0.y_start, 8 * Read256BytesBlockHeightY[k])) * BytesPerPixelY[k] / 256) + (64 * 1024); - if (Read256BytesBlockWidthC[k] > 0) { - SurfaceSizeInMALL[k] = (unsigned int)(SurfaceSizeInMALL[k] + - math_min2(math_ceil2(surface->plane1.width, 8 * Read256BytesBlockWidthC[k]), - math_floor2(composition->viewport.plane1.y_start + composition->viewport.plane1.width + 8 * Read256BytesBlockWidthC[k] - 1, 8 * Read256BytesBlockWidthC[k]) - - math_floor2(composition->viewport.plane1.y_start, 8 * Read256BytesBlockWidthC[k])) * - math_min2(math_ceil2(surface->plane1.height, 8 * Read256BytesBlockHeightC[k]), - math_floor2(composition->viewport.plane1.y_start + composition->viewport.plane1.height + 8 * Read256BytesBlockHeightC[k] - 1, 8 * Read256BytesBlockHeightC[k]) - - math_floor2(composition->viewport.plane1.y_start, 8 * Read256BytesBlockHeightC[k])) * BytesPerPixelC[k] / 256); - } - } - } else { - SurfaceSizeInMALL[k] = (unsigned int)(math_ceil2(math_min2(surface->plane0.width, composition->viewport.plane0.width + ReadBlockWidthY[k] - 1), ReadBlockWidthY[k]) * - math_ceil2(math_min2(surface->plane0.height, composition->viewport.plane0.height + ReadBlockHeightY[k] - 1), ReadBlockHeightY[k]) * BytesPerPixelY[k]); - if (ReadBlockWidthC[k] > 0) { - SurfaceSizeInMALL[k] = (unsigned int)(SurfaceSizeInMALL[k] + - math_ceil2(math_min2(surface->plane1.width, composition->viewport.plane1.width + ReadBlockWidthC[k] - 1), ReadBlockWidthC[k]) * - math_ceil2(math_min2(surface->plane1.height, composition->viewport.plane1.height + ReadBlockHeightC[k] - 1), ReadBlockHeightC[k]) * BytesPerPixelC[k]); - } - if (surface->dcc.enable) { - SurfaceSizeInMALL[k] = (unsigned int)(SurfaceSizeInMALL[k] + - math_ceil2(math_min2(surface->plane0.width, composition->viewport.plane0.width + 8 * Read256BytesBlockWidthY[k] - 1), 8 * Read256BytesBlockWidthY[k]) * - math_ceil2(math_min2(surface->plane0.height, composition->viewport.plane0.height + 8 * Read256BytesBlockHeightY[k] - 1), 8 * Read256BytesBlockHeightY[k]) * BytesPerPixelY[k] / 256) + (64 * 1024); - - if (Read256BytesBlockWidthC[k] > 0) { - SurfaceSizeInMALL[k] = (unsigned int)(SurfaceSizeInMALL[k] + - math_ceil2(math_min2(surface->plane1.width, composition->viewport.plane1.width + 8 * Read256BytesBlockWidthC[k] - 1), 8 * Read256BytesBlockWidthC[k]) * - math_ceil2(math_min2(surface->plane1.height, composition->viewport.plane1.height + 8 * Read256BytesBlockHeightC[k] - 1), 8 * Read256BytesBlockHeightC[k]) * BytesPerPixelC[k] / 256); - } - } - } - } - - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - /* SS and Subvp counted separate as they are never used at the same time */ - if (dml_is_phantom_pipe(&display_cfg->plane_descriptors[k])) - TotalSurfaceSizeInMALLForSubVP += SurfaceSizeInMALL[k]; - else if (display_cfg->plane_descriptors[k].overrides.refresh_from_mall == dml2_refresh_from_mall_mode_override_force_enable) - TotalSurfaceSizeInMALLForSS += SurfaceSizeInMALL[k]; - } - - *ExceededMALLSize = (TotalSurfaceSizeInMALLForSS > MALLAllocatedForDCNInBytes) || - (TotalSurfaceSizeInMALLForSubVP > MALLAllocatedForDCNInBytes); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: MALLAllocatedForDCN = %u\n", __func__, MALLAllocatedForDCN * 1024 * 1024); - dml2_printf("DML::%s: TotalSurfaceSizeInMALLForSubVP = %u\n", __func__, TotalSurfaceSizeInMALLForSubVP); - dml2_printf("DML::%s: TotalSurfaceSizeInMALLForSS = %u\n", __func__, TotalSurfaceSizeInMALLForSS); - dml2_printf("DML::%s: ExceededMALLSize = %u\n", __func__, *ExceededMALLSize); -#endif -} - -static void calculate_tdlut_setting( - struct dml2_core_internal_scratch *scratch, - struct dml2_core_calcs_calculate_tdlut_setting_params *p) -{ - 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; - *p->tdlut_pte_bytes_per_frame = 0; - *p->tdlut_bytes_per_frame = 0; - return; - } - - // locals - unsigned int tdlut_bpe = 8; - unsigned int tdlut_width; - unsigned int tdlut_pitch_bytes; - unsigned int tdlut_footprint_bytes; - unsigned int vmpg_bytes; - unsigned int tdlut_vmpg_per_frame; - unsigned int tdlut_pte_req_per_frame; - unsigned int tdlut_bytes_per_line; - unsigned int tdlut_delivery_cycles; - double tdlut_drain_rate; - unsigned int tdlut_mpc_width; - unsigned int tdlut_bytes_per_group_simple; - - if (p->tdlut_mpc_width_flag) { - tdlut_mpc_width = 33; - tdlut_bytes_per_group_simple = 39 * 256; - } else { - tdlut_mpc_width = 17; - tdlut_bytes_per_group_simple = 10 * 256; - } - - vmpg_bytes = p->gpuvm_page_size_kbytes * 1024; - - if (p->tdlut_addressing_mode == dml2_tdlut_simple_linear) { - if (p->tdlut_width_mode == dml2_tdlut_width_17_cube) - tdlut_width = 4916; - else - tdlut_width = 35940; - } else { - if (p->tdlut_width_mode == dml2_tdlut_width_17_cube) - tdlut_width = 17; - else // dml2_tdlut_width_33_cube - tdlut_width = 33; - } - - if (p->is_gfx11) - tdlut_pitch_bytes = (unsigned int)math_ceil2(tdlut_width * tdlut_bpe, 256); //256B alignment - else - tdlut_pitch_bytes = (unsigned int)math_ceil2(tdlut_width * tdlut_bpe, 128); //128B alignment - - if (p->tdlut_addressing_mode == dml2_tdlut_sw_linear) - tdlut_footprint_bytes = tdlut_pitch_bytes * tdlut_width * tdlut_width; - else - tdlut_footprint_bytes = tdlut_pitch_bytes; - - if (!p->gpuvm_enable) { - tdlut_vmpg_per_frame = 0; - tdlut_pte_req_per_frame = 0; - } else { - tdlut_vmpg_per_frame = (unsigned int)math_ceil2(tdlut_footprint_bytes - 1, vmpg_bytes) / vmpg_bytes + 1; - tdlut_pte_req_per_frame = (unsigned int)math_ceil2(tdlut_vmpg_per_frame - 1, 8) / 8 + 1; - } - tdlut_bytes_per_line = (unsigned int)math_ceil2(tdlut_width * tdlut_bpe, 64); //64b request - *p->tdlut_pte_bytes_per_frame = tdlut_pte_req_per_frame * 64; - - if (p->tdlut_addressing_mode == dml2_tdlut_sw_linear) { - //the tdlut_width is either 17 or 33 but the 33x33x33 is subsampled every other line/slice - *p->tdlut_bytes_per_frame = tdlut_bytes_per_line * tdlut_mpc_width * tdlut_mpc_width; - *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 / 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); - *p->tdlut_bytes_per_group = tdlut_bytes_per_group_simple; - tdlut_delivery_cycles = (unsigned int)math_ceil2(tdlut_width / 2.0, 1); - tdlut_drain_rate = 2 * tdlut_bpe * p->dispclk_mhz; - } - - //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_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; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: gpuvm_enable = %d\n", __func__, p->gpuvm_enable); - dml2_printf("DML::%s: vmpg_bytes = %d\n", __func__, vmpg_bytes); - dml2_printf("DML::%s: tdlut_vmpg_per_frame = %d\n", __func__, tdlut_vmpg_per_frame); - dml2_printf("DML::%s: tdlut_pte_req_per_frame = %d\n", __func__, tdlut_pte_req_per_frame); - 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_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); - dml2_printf("DML::%s: tdlut_bytes_per_line = %u\n", __func__, tdlut_bytes_per_line); - dml2_printf("DML::%s: tdlut_bytes_per_group = %u\n", __func__, *p->tdlut_bytes_per_group); - dml2_printf("DML::%s: tdlut_drain_rate = %f\n", __func__, tdlut_drain_rate); - dml2_printf("DML::%s: tdlut_delivery_cycles = %u\n", __func__, tdlut_delivery_cycles); - dml2_printf("DML::%s: tdlut_opt_time = %f\n", __func__, *p->tdlut_opt_time); - dml2_printf("DML::%s: tdlut_drain_time = %f\n", __func__, *p->tdlut_drain_time); - dml2_printf("DML::%s: tdlut_groups_per_2row_ub = %d\n", __func__, *p->tdlut_groups_per_2row_ub); -#endif -} - -static void CalculateTarb( - const struct dml2_display_cfg *display_cfg, - unsigned int PixelChunkSizeInKByte, - unsigned int NumberOfActiveSurfaces, - unsigned int NumberOfDPP[], - unsigned int dpte_group_bytes[], - unsigned int tdlut_bytes_per_group[], - double HostVMInefficiencyFactor, - double HostVMInefficiencyFactorPrefetch, - unsigned int HostVMMinPageSize, - double ReturnBW, - unsigned int MetaChunkSize, - - // output - double *Tarb, - double *Tarb_prefetch) -{ - double extra_bytes = 0; - double extra_bytes_prefetch = 0; - double HostVMDynamicLevels = CalculateHostVMDynamicLevels(display_cfg->gpuvm_enable, display_cfg->hostvm_enable, HostVMMinPageSize, display_cfg->hostvm_max_non_cached_page_table_levels); - - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - extra_bytes = extra_bytes + (NumberOfDPP[k] * PixelChunkSizeInKByte * 1024); - - if (display_cfg->plane_descriptors[k].surface.dcc.enable) - extra_bytes = extra_bytes + (MetaChunkSize * 1024); - - if (display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut) - extra_bytes = extra_bytes + tdlut_bytes_per_group[k]; - } - - extra_bytes_prefetch = extra_bytes; - - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - if (display_cfg->gpuvm_enable == true) { - extra_bytes = extra_bytes + NumberOfDPP[k] * dpte_group_bytes[k] * (1 + 8 * HostVMDynamicLevels) * HostVMInefficiencyFactor; - extra_bytes_prefetch = extra_bytes_prefetch + NumberOfDPP[k] * dpte_group_bytes[k] * (1 + 8 * HostVMDynamicLevels) * HostVMInefficiencyFactorPrefetch; - } - } - *Tarb = extra_bytes / ReturnBW; - *Tarb_prefetch = extra_bytes_prefetch / ReturnBW; -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: PixelChunkSizeInKByte = %d\n", __func__, PixelChunkSizeInKByte); - dml2_printf("DML::%s: MetaChunkSize = %d\n", __func__, MetaChunkSize); - dml2_printf("DML::%s: extra_bytes = %f\n", __func__, extra_bytes); - dml2_printf("DML::%s: extra_bytes_prefetch = %f\n", __func__, extra_bytes_prefetch); -#endif -} - -static double CalculateTWait( - long reserved_vblank_time_ns, - double UrgentLatency, - double Ttrip) -{ - double TWait; - double t_urg_trip = math_max2(UrgentLatency, Ttrip); - TWait = reserved_vblank_time_ns / 1000.0 + t_urg_trip; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: reserved_vblank_time_ns = %d\n", __func__, reserved_vblank_time_ns); - dml2_printf("DML::%s: UrgentLatency = %f\n", __func__, UrgentLatency); - dml2_printf("DML::%s: Ttrip = %f\n", __func__, Ttrip); - dml2_printf("DML::%s: TWait = %f\n", __func__, TWait); -#endif - return TWait; -} - - -static void CalculateVUpdateAndDynamicMetadataParameters( - unsigned int MaxInterDCNTileRepeaters, - double Dppclk, - double Dispclk, - double DCFClkDeepSleep, - double PixelClock, - unsigned int HTotal, - unsigned int VBlank, - unsigned int DynamicMetadataTransmittedBytes, - unsigned int DynamicMetadataLinesBeforeActiveRequired, - unsigned int InterlaceEnable, - bool ProgressiveToInterlaceUnitInOPP, - - // Output - double *TSetup, - double *Tdmbf, - double *Tdmec, - double *Tdmsks, - unsigned int *VUpdateOffsetPix, - unsigned int *VUpdateWidthPix, - unsigned int *VReadyOffsetPix) -{ - double TotalRepeaterDelayTime; - TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2 / Dppclk + 3 / Dispclk); - *VUpdateWidthPix = (unsigned int)(math_ceil2((14.0 / DCFClkDeepSleep + 12.0 / Dppclk + TotalRepeaterDelayTime) * PixelClock, 1.0)); - *VReadyOffsetPix = (unsigned int)(math_ceil2(math_max2(150.0 / Dppclk, TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / Dppclk) * PixelClock, 1.0)); - *VUpdateOffsetPix = (unsigned int)(math_ceil2(HTotal / 4.0, 1.0)); - *TSetup = (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / PixelClock; - *Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / Dispclk; - *Tdmec = HTotal / PixelClock; - - if (DynamicMetadataLinesBeforeActiveRequired == 0) { - *Tdmsks = VBlank * HTotal / PixelClock / 2.0; - } else { - *Tdmsks = DynamicMetadataLinesBeforeActiveRequired * HTotal / PixelClock; - } - if (InterlaceEnable == 1 && ProgressiveToInterlaceUnitInOPP == false) { - *Tdmsks = *Tdmsks / 2; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: DynamicMetadataLinesBeforeActiveRequired = %u\n", __func__, DynamicMetadataLinesBeforeActiveRequired); - dml2_printf("DML::%s: VBlank = %u\n", __func__, VBlank); - dml2_printf("DML::%s: HTotal = %u\n", __func__, HTotal); - dml2_printf("DML::%s: PixelClock = %f\n", __func__, PixelClock); - dml2_printf("DML::%s: Dppclk = %f\n", __func__, Dppclk); - dml2_printf("DML::%s: DCFClkDeepSleep = %f\n", __func__, DCFClkDeepSleep); - dml2_printf("DML::%s: MaxInterDCNTileRepeaters = %u\n", __func__, MaxInterDCNTileRepeaters); - dml2_printf("DML::%s: TotalRepeaterDelayTime = %f\n", __func__, TotalRepeaterDelayTime); - - dml2_printf("DML::%s: VUpdateWidthPix = %u\n", __func__, *VUpdateWidthPix); - dml2_printf("DML::%s: VReadyOffsetPix = %u\n", __func__, *VReadyOffsetPix); - dml2_printf("DML::%s: VUpdateOffsetPix = %u\n", __func__, *VUpdateOffsetPix); - - dml2_printf("DML::%s: Tdmsks = %f\n", __func__, *Tdmsks); -#endif -} - -static double get_urgent_bandwidth_required( - struct dml2_core_shared_get_urgent_bandwidth_required_locals *l, - const struct dml2_display_cfg *display_cfg, - enum dml2_core_internal_soc_state_type state_type, - enum dml2_core_internal_bw_type bw_type, - bool inc_flip_bw, // including flip bw - unsigned int NumberOfActiveSurfaces, - unsigned int NumberOfDPP[], - double dcc_dram_bw_nom_overhead_factor_p0[], - double dcc_dram_bw_nom_overhead_factor_p1[], - double dcc_dram_bw_pref_overhead_factor_p0[], - double dcc_dram_bw_pref_overhead_factor_p1[], - double mall_prefetch_sdp_overhead_factor[], - double mall_prefetch_dram_overhead_factor[], - double ReadBandwidthLuma[], - double ReadBandwidthChroma[], - double PrefetchBandwidthLuma[], - double PrefetchBandwidthChroma[], - double cursor_bw[], - double dpte_row_bw[], - double meta_row_bw[], - double prefetch_cursor_bw[], - double prefetch_vmrow_bw[], - double flip_bw[], - double UrgentBurstFactorLuma[], - double UrgentBurstFactorChroma[], - double UrgentBurstFactorCursor[], - double UrgentBurstFactorLumaPre[], - double UrgentBurstFactorChromaPre[], - double UrgentBurstFactorCursorPre[]) -{ - memset(l, 0, sizeof(struct dml2_core_shared_get_urgent_bandwidth_required_locals)); - - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - l->mall_svp_prefetch_factor = (state_type == dml2_core_internal_soc_state_svp_prefetch) ? (bw_type == dml2_core_internal_bw_dram ? mall_prefetch_dram_overhead_factor[k] : mall_prefetch_sdp_overhead_factor[k]) : 1.0; - l->tmp_nom_adj_factor_p0 = (bw_type == dml2_core_internal_bw_dram ? dcc_dram_bw_nom_overhead_factor_p0[k] : 1.0) * l->mall_svp_prefetch_factor; - l->tmp_nom_adj_factor_p1 = (bw_type == dml2_core_internal_bw_dram ? dcc_dram_bw_nom_overhead_factor_p1[k] : 1.0) * l->mall_svp_prefetch_factor; - l->tmp_pref_adj_factor_p0 = (bw_type == dml2_core_internal_bw_dram ? dcc_dram_bw_pref_overhead_factor_p0[k] : 1.0) * l->mall_svp_prefetch_factor; - l->tmp_pref_adj_factor_p1 = (bw_type == dml2_core_internal_bw_dram ? dcc_dram_bw_pref_overhead_factor_p1[k] : 1.0) * l->mall_svp_prefetch_factor; - - l->adj_factor_p0 = UrgentBurstFactorLuma[k] * l->tmp_nom_adj_factor_p0; - l->adj_factor_p1 = UrgentBurstFactorChroma[k] * l->tmp_nom_adj_factor_p1; - l->adj_factor_cur = UrgentBurstFactorCursor[k]; - l->adj_factor_p0_pre = UrgentBurstFactorLumaPre[k] * l->tmp_pref_adj_factor_p0; - l->adj_factor_p1_pre = UrgentBurstFactorChromaPre[k] * l->tmp_pref_adj_factor_p1; - l->adj_factor_cur_pre = UrgentBurstFactorCursorPre[k]; - - // both dchub_urgent_bw_at_sdp_noflip and dchub_urgent_bw_at_dram_noflip don't include the phantom_pipe because iflips dont occur while phantom_pipe is active - bool is_phantom = dml_is_phantom_pipe(&display_cfg->plane_descriptors[k]); - bool exclude_this_plane = 0; - - // Exclude phantom pipe in bw calculation for non svp prefetch state - if (state_type != dml2_core_internal_soc_state_svp_prefetch && is_phantom) - exclude_this_plane = 1; - - if (display_cfg->plane_descriptors[k].immediate_flip == false || !inc_flip_bw) - l->per_plane_flip_bw[k] = NumberOfDPP[k] * (dpte_row_bw[k] + meta_row_bw[k]); - else - l->per_plane_flip_bw[k] = NumberOfDPP[k] * flip_bw[k]; - - - if (!exclude_this_plane) { - l->required_bandwidth_mbps_this_surface = math_max3(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); - - l->required_bandwidth_mbps = l->required_bandwidth_mbps + l->required_bandwidth_mbps_this_surface; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%d, NumberOfDPP=%d\n", __func__, k, NumberOfDPP[k]); - 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); - dml2_printf("DML::%s: k=%d, adj_factor_cur=%f\n", __func__, k, l->adj_factor_cur); - - dml2_printf("DML::%s: k=%d, adj_factor_p0_pre=%f\n", __func__, k, l->adj_factor_p0_pre); - dml2_printf("DML::%s: k=%d, adj_factor_p1_pre=%f\n", __func__, k, l->adj_factor_p1_pre); - dml2_printf("DML::%s: k=%d, adj_factor_cur_pre=%f\n", __func__, k, l->adj_factor_cur_pre); - - dml2_printf("DML::%s: k=%d, per_plane_flip_bw=%f\n", __func__, k, l->per_plane_flip_bw[k]); - 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, 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]); - dml2_printf("DML::%s: k=%d, dpte_row_bw=%f\n", __func__, k, dpte_row_bw[k]); - dml2_printf("DML::%s: k=%d, PrefetchBandwidthLuma=%f\n", __func__, k, PrefetchBandwidthLuma[k]); - dml2_printf("DML::%s: k=%d, PrefetchBandwidthChroma=%f\n", __func__, k, PrefetchBandwidthChroma[k]); - dml2_printf("DML::%s: k=%d, prefetch_cursor_bw=%f\n", __func__, k, prefetch_cursor_bw[k]); - dml2_printf("DML::%s: k=%d, required_bandwidth_mbps=%f (total), inc_flip_bw=%d, is_phantom=%d exclude_this_plane=%d\n", __func__, k, l->required_bandwidth_mbps, inc_flip_bw, is_phantom, exclude_this_plane); -#endif - } - - return l->required_bandwidth_mbps; -} - -static void CalculateExtraLatency( - const struct dml2_display_cfg *display_cfg, - unsigned int ROBBufferSizeInKByte, - unsigned int RoundTripPingLatencyCycles, - unsigned int ReorderingBytes, - double DCFCLK, - double FabricClock, - unsigned int PixelChunkSizeInKByte, - double ReturnBW, - unsigned int NumberOfActiveSurfaces, - unsigned int NumberOfDPP[], - unsigned int dpte_group_bytes[], - unsigned int tdlut_bytes_per_group[], - double HostVMInefficiencyFactor, - double HostVMInefficiencyFactorPrefetch, - unsigned int HostVMMinPageSize, - enum dml2_qos_param_type qos_type, - bool max_oustanding_when_urgent_expected, - unsigned int max_outstanding_requests, - unsigned int request_size_bytes_luma[], - unsigned int request_size_bytes_chroma[], - unsigned int MetaChunkSize, - unsigned int dchub_arb_to_ret_delay, - double Ttrip, - unsigned int hostvm_mode, - - // output - double *ExtraLatency, - double *ExtraLatency_sr, - double *ExtraLatencyPrefetch) -{ - double Tarb; - double Tarb_prefetch; - - CalculateTarb( - display_cfg, - PixelChunkSizeInKByte, - NumberOfActiveSurfaces, - NumberOfDPP, - dpte_group_bytes, - tdlut_bytes_per_group, - HostVMInefficiencyFactor, - HostVMInefficiencyFactorPrefetch, - HostVMMinPageSize, - ReturnBW, - MetaChunkSize, - // output - &Tarb, - &Tarb_prefetch); - - unsigned int max_request_size_bytes = 0; - double Tex_trips = (display_cfg->hostvm_enable && hostvm_mode == 1) ? (2.0 * Ttrip) : 0.0; - - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - if (request_size_bytes_luma[k] > max_request_size_bytes) - max_request_size_bytes = request_size_bytes_luma[k]; - if (request_size_bytes_chroma[k] > max_request_size_bytes) - max_request_size_bytes = request_size_bytes_chroma[k]; - } - - 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) - *ExtraLatency = *ExtraLatency + (ROBBufferSizeInKByte * 1024 - max_outstanding_requests * max_request_size_bytes) / ReturnBW; - } else { - *ExtraLatency_sr = dchub_arb_to_ret_delay / DCFCLK + RoundTripPingLatencyCycles / FabricClock + ReorderingBytes / ReturnBW; - *ExtraLatency = *ExtraLatency_sr; - } - *ExtraLatency = *ExtraLatency + Tex_trips; - *ExtraLatencyPrefetch = *ExtraLatency + Tarb_prefetch; - *ExtraLatency = *ExtraLatency + Tarb; - *ExtraLatency_sr = *ExtraLatency_sr + Tarb; - -#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); - dml2_printf("DML::%s: ExtraLatencyPrefetch=%f\n", __func__, *ExtraLatencyPrefetch); -#endif -} - -static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch, struct dml2_core_calcs_CalculatePrefetchSchedule_params *p) -{ - struct dml2_core_calcs_CalculatePrefetchSchedule_locals *s = &scratch->CalculatePrefetchSchedule_locals; - - s->NoTimeToPrefetch = false; - s->DPPCycles = 0; - s->DISPCLKCycles = 0; - s->DSTTotalPixelsAfterScaler = 0.0; - s->LineTime = 0.0; - s->dst_y_prefetch_equ = 0.0; - s->prefetch_bw_oto = 0.0; - s->Tvm_oto = 0.0; - s->Tr0_oto = 0.0; - s->Tvm_oto_lines = 0.0; - s->Tr0_oto_lines = 0.0; - s->dst_y_prefetch_oto = 0.0; - s->TimeForFetchingVM = 0.0; - s->TimeForFetchingRowInVBlank = 0.0; - s->LinesToRequestPrefetchPixelData = 0.0; - s->HostVMDynamicLevelsTrips = 0; - s->trip_to_mem = 0.0; - *p->Tvm_trips = 0.0; - *p->Tr0_trips = 0.0; - s->Tvm_trips_rounded = 0.0; - s->Tr0_trips_rounded = 0.0; - s->max_Tsw = 0.0; - s->Lsw_oto = 0.0; - s->Tpre_rounded = 0.0; - s->prefetch_bw_equ = 0.0; - s->Tvm_equ = 0.0; - s->Tr0_equ = 0.0; - s->Tdmbf = 0.0; - s->Tdmec = 0.0; - s->Tdmsks = 0.0; - s->prefetch_sw_bytes = 0.0; - s->prefetch_bw_pr = 0.0; - s->bytes_pp = 0.0; - s->dep_bytes = 0.0; - s->min_Lsw_oto = 0.0; - s->Tsw_est1 = 0.0; - s->Tsw_est3 = 0.0; - s->cursor_prefetch_bytes = 0; - *p->prefetch_cursor_bw = 0; - bool dcc_mrq_enable = (p->dcc_enable && p->mrq_present); - - s->TWait_p = p->TWait - p->Ttrip; // TWait includes max(Turg, Ttrip) - - if (p->display_cfg->gpuvm_enable == true && p->display_cfg->hostvm_enable == true) { - s->HostVMDynamicLevelsTrips = p->display_cfg->hostvm_max_non_cached_page_table_levels; - } else { - s->HostVMDynamicLevelsTrips = 0; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: dcc_enable = %u\n", __func__, p->dcc_enable); - dml2_printf("DML::%s: mrq_present = %u\n", __func__, p->mrq_present); - dml2_printf("DML::%s: dcc_mrq_enable = %u\n", __func__, dcc_mrq_enable); - dml2_printf("DML::%s: GPUVMEnable = %u\n", __func__, p->display_cfg->gpuvm_enable); - 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); - dml2_printf("DML::%s: TWait_p = %f\n", __func__, s->TWait_p); - dml2_printf("DML::%s: Ttrip = %f\n", __func__, p->Ttrip); - dml2_printf("DML::%s: myPipe->Dppclk = %f\n", __func__, p->myPipe->Dppclk); - dml2_printf("DML::%s: myPipe->Dispclk = %f\n", __func__, p->myPipe->Dispclk); -#endif - CalculateVUpdateAndDynamicMetadataParameters( - p->MaxInterDCNTileRepeaters, - p->myPipe->Dppclk, - p->myPipe->Dispclk, - p->myPipe->DCFClkDeepSleep, - p->myPipe->PixelClock, - p->myPipe->HTotal, - p->myPipe->VBlank, - p->DynamicMetadataTransmittedBytes, - p->DynamicMetadataLinesBeforeActiveRequired, - p->myPipe->InterlaceEnable, - p->myPipe->ProgressiveToInterlaceUnitInOPP, - p->TSetup, - - // Output - &s->Tdmbf, - &s->Tdmec, - &s->Tdmsks, - p->VUpdateOffsetPix, - p->VUpdateWidthPix, - p->VReadyOffsetPix); - - s->LineTime = p->myPipe->HTotal / p->myPipe->PixelClock; - s->trip_to_mem = p->Ttrip; - *p->Tvm_trips = p->ExtraLatencyPrefetch + s->trip_to_mem * (p->display_cfg->gpuvm_max_page_table_levels * (s->HostVMDynamicLevelsTrips + 1)); - if (dcc_mrq_enable) - *p->Tvm_trips_flip = *p->Tvm_trips; - else - *p->Tvm_trips_flip = *p->Tvm_trips - s->trip_to_mem; - *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); - - 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 - } - - if (p->DynamicMetadataEnable == true) { - if (p->VStartup * s->LineTime < *p->TSetup + *p->Tdmdl + s->Tdmbf + s->Tdmec + s->Tdmsks) { - *p->NotEnoughTimeForDynamicMetadata = true; - dml2_printf("DML::%s: Not Enough Time for Dynamic Meta!\n", __func__); - dml2_printf("DML::%s: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", __func__, s->Tdmbf); - dml2_printf("DML::%s: Tdmec: %fus - time dio takes to transfer dmd\n", __func__, s->Tdmec); - dml2_printf("DML::%s: Tdmsks: %fus - time before active dmd must complete transmission at dio\n", __func__, s->Tdmsks); - dml2_printf("DML::%s: Tdmdl: %fus - time for fabric to become ready and fetch dmd \n", __func__, *p->Tdmdl); - } else { - *p->NotEnoughTimeForDynamicMetadata = false; - } - } else { - *p->NotEnoughTimeForDynamicMetadata = false; - } - - if (p->myPipe->ScalerEnabled) - s->DPPCycles = (unsigned int)(p->DPPCLKDelaySubtotalPlusCNVCFormater + p->DPPCLKDelaySCL); - else - s->DPPCycles = (unsigned int)(p->DPPCLKDelaySubtotalPlusCNVCFormater + p->DPPCLKDelaySCLLBOnly); - - s->DPPCycles = (unsigned int)(s->DPPCycles + p->myPipe->NumberOfCursors * p->DPPCLKDelayCNVCCursor); - - s->DISPCLKCycles = (unsigned int)p->DISPCLKDelaySubtotal; - - if (p->myPipe->Dppclk == 0.0 || p->myPipe->Dispclk == 0.0) - return true; - - *p->DSTXAfterScaler = (unsigned int)math_round(s->DPPCycles * p->myPipe->PixelClock / p->myPipe->Dppclk + s->DISPCLKCycles * p->myPipe->PixelClock / p->myPipe->Dispclk + p->DSCDelay); - *p->DSTXAfterScaler = (unsigned int)math_round(*p->DSTXAfterScaler + (p->myPipe->ODMMode != dml2_odm_mode_bypass ? 18 : 0) + (p->myPipe->DPPPerSurface - 1) * p->DPP_RECOUT_WIDTH + - ((p->myPipe->ODMMode == dml2_odm_mode_split_1to2 || p->myPipe->ODMMode == dml2_odm_mode_mso_1to2) ? (double)p->myPipe->HActive / 2.0 : 0) + - ((p->myPipe->ODMMode == dml2_odm_mode_mso_1to4) ? (double)p->myPipe->HActive * 3.0 / 4.0 : 0)); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: DynamicMetadataVMEnabled = %u\n", __func__, p->DynamicMetadataVMEnabled); - dml2_printf("DML::%s: DPPCycles = %u\n", __func__, s->DPPCycles); - dml2_printf("DML::%s: PixelClock = %f\n", __func__, p->myPipe->PixelClock); - dml2_printf("DML::%s: Dppclk = %f\n", __func__, p->myPipe->Dppclk); - dml2_printf("DML::%s: DISPCLKCycles = %u\n", __func__, s->DISPCLKCycles); - dml2_printf("DML::%s: DISPCLK = %f\n", __func__, p->myPipe->Dispclk); - dml2_printf("DML::%s: DSCDelay = %u\n", __func__, p->DSCDelay); - dml2_printf("DML::%s: ODMMode = %u\n", __func__, p->myPipe->ODMMode); - dml2_printf("DML::%s: DPP_RECOUT_WIDTH = %u\n", __func__, p->DPP_RECOUT_WIDTH); - dml2_printf("DML::%s: DSTXAfterScaler = %u\n", __func__, *p->DSTXAfterScaler); - - dml2_printf("DML::%s: setup_for_tdlut = %u\n", __func__, p->setup_for_tdlut); - dml2_printf("DML::%s: tdlut_opt_time = %f\n", __func__, p->tdlut_opt_time); - dml2_printf("DML::%s: tdlut_pte_bytes_per_frame = %u\n", __func__, p->tdlut_pte_bytes_per_frame); -#endif - - if (p->OutputFormat == dml2_420 || (p->myPipe->InterlaceEnable && p->myPipe->ProgressiveToInterlaceUnitInOPP)) - *p->DSTYAfterScaler = 1; - else - *p->DSTYAfterScaler = 0; - - s->DSTTotalPixelsAfterScaler = *p->DSTYAfterScaler * p->myPipe->HTotal + *p->DSTXAfterScaler; - *p->DSTYAfterScaler = (unsigned int)(math_floor2(s->DSTTotalPixelsAfterScaler / p->myPipe->HTotal, 1)); - *p->DSTXAfterScaler = (unsigned int)(s->DSTTotalPixelsAfterScaler - ((double)(*p->DSTYAfterScaler * p->myPipe->HTotal))); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: DSTXAfterScaler = %u (final)\n", __func__, *p->DSTXAfterScaler); - 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); - dml2_printf("DML::%s: trip_to_mem = %f\n", __func__, s->trip_to_mem); - dml2_printf("DML::%s: ExtraLatencyPrefetch = %f\n", __func__, p->ExtraLatencyPrefetch); - dml2_printf("DML::%s: GPUVMPageTableLevels = %u\n", __func__, p->display_cfg->gpuvm_max_page_table_levels); - dml2_printf("DML::%s: HostVMDynamicLevelsTrips = %u\n", __func__, s->HostVMDynamicLevelsTrips); -#endif - if (p->display_cfg->gpuvm_enable) { - 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 { - s->Tvm_trips_rounded = s->LineTime / 4.0; - *p->Tvm_trips_flip_rounded = s->LineTime / 4.0; - } - s->Tvm_trips_rounded = math_max2(s->Tvm_trips_rounded, s->LineTime / 4.0); - *p->Tvm_trips_flip_rounded = math_max2(*p->Tvm_trips_flip_rounded, s->LineTime / 4.0); - - if (p->display_cfg->gpuvm_enable == true || p->setup_for_tdlut || dcc_mrq_enable) { - s->Tr0_trips_rounded = math_ceil2(4.0 * *p->Tr0_trips / s->LineTime, 1.0) / 4.0 * s->LineTime; - *p->Tr0_trips_flip_rounded = math_ceil2(4.0 * *p->Tr0_trips_flip / s->LineTime, 1.0) / 4.0 * s->LineTime; - } else { - s->Tr0_trips_rounded = s->LineTime / 4.0; - *p->Tr0_trips_flip_rounded = s->LineTime / 4.0; - } - s->Tr0_trips_rounded = math_max2(s->Tr0_trips_rounded, s->LineTime / 4.0); - *p->Tr0_trips_flip_rounded = math_max2(*p->Tr0_trips_flip_rounded, s->LineTime / 4.0); - - *p->Tno_bw_flip = 0; - if (p->display_cfg->gpuvm_enable == true) { - if (p->display_cfg->gpuvm_max_page_table_levels >= 3) { - *p->Tno_bw = p->ExtraLatencyPrefetch + s->trip_to_mem * (double)((p->display_cfg->gpuvm_max_page_table_levels - 2) * (s->HostVMDynamicLevelsTrips + 1)); - } else if (p->display_cfg->gpuvm_max_page_table_levels == 1 && !dcc_mrq_enable && !p->setup_for_tdlut) { - *p->Tno_bw = p->ExtraLatencyPrefetch; - } else { - *p->Tno_bw = 0; - } - *p->Tno_bw_flip = *p->Tno_bw; - } else { - *p->Tno_bw = 0; - } - - if (dml2_core_shared_is_420(p->myPipe->SourcePixelFormat)) { - s->bytes_pp = p->myPipe->BytePerPixelY + p->myPipe->BytePerPixelC / 4.0; - } else { - s->bytes_pp = p->myPipe->BytePerPixelY + p->myPipe->BytePerPixelC; - } - - s->prefetch_bw_pr = s->bytes_pp * p->myPipe->PixelClock / (double)p->myPipe->DPPPerSurface; - if (p->myPipe->VRatio < 1.0) - s->prefetch_bw_pr = p->myPipe->VRatio * s->prefetch_bw_pr; - 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); - - 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); - - unsigned int vm_bytes = p->vm_bytes; // vm_bytes is dpde0_bytes_per_frame_ub_l + dpde0_bytes_per_frame_ub_c + 2*extra_dpde_bytes; - unsigned int 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); - - unsigned long tdlut_row_bytes = (unsigned long) math_ceil2(p->tdlut_bytes_per_frame/2.0, 1.0); - 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)); - 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, - *p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw_oto, - s->LineTime / 4.0); - -#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); -#endif - - } else - s->Tvm_oto = s->LineTime / 4.0; - - if ((p->display_cfg->gpuvm_enable == true || p->setup_for_tdlut || dcc_mrq_enable)) { - s->Tr0_oto = math_max3( - *p->Tr0_trips, - (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / s->prefetch_bw_oto, - s->LineTime / 4.0); -#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; - - 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; - s->dst_y_prefetch_oto = s->Tvm_oto_lines + 2 * s->Tr0_oto_lines + s->Lsw_oto; - - //To (time for delay after scaler) in line time - unsigned int Lo = (unsigned int)(*p->DSTYAfterScaler + (double)*p->DSTXAfterScaler / (double)p->myPipe->HTotal); - - //Tpre_equ in line time - s->dst_y_prefetch_equ = p->VStartup - (*p->TSetup + math_max2(s->TWait_p + p->TCalc, *p->Tdmdl - p->Ttrip)) / s->LineTime - Lo; - 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: 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); - dml2_printf("DML::%s: trip_to_mem = %f\n", __func__, s->trip_to_mem); - dml2_printf("DML::%s: mall_prefetch_sdp_overhead_factor = %f\n", __func__, p->mall_prefetch_sdp_overhead_factor); - dml2_printf("DML::%s: BytePerPixelY = %u\n", __func__, p->myPipe->BytePerPixelY); - dml2_printf("DML::%s: PrefetchSourceLinesY = %f\n", __func__, p->PrefetchSourceLinesY); - dml2_printf("DML::%s: swath_width_luma_ub = %u\n", __func__, p->swath_width_luma_ub); - dml2_printf("DML::%s: BytePerPixelC = %u\n", __func__, p->myPipe->BytePerPixelC); - dml2_printf("DML::%s: PrefetchSourceLinesC = %f\n", __func__, p->PrefetchSourceLinesC); - dml2_printf("DML::%s: swath_width_chroma_ub = %u\n", __func__, p->swath_width_chroma_ub); - dml2_printf("DML::%s: prefetch_sw_bytes = %f\n", __func__, s->prefetch_sw_bytes); - dml2_printf("DML::%s: max_Tsw = %f\n", __func__, s->max_Tsw); - dml2_printf("DML::%s: bytes_pp = %f\n", __func__, s->bytes_pp); - dml2_printf("DML::%s: vm_bytes = %u\n", __func__, vm_bytes); - dml2_printf("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, p->PixelPTEBytesPerRow); - dml2_printf("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, p->HostVMInefficiencyFactor); - dml2_printf("DML::%s: Tvm_trips = %f\n", __func__, *p->Tvm_trips); - dml2_printf("DML::%s: Tr0_trips = %f\n", __func__, *p->Tr0_trips); - dml2_printf("DML::%s: Tvm_trips_flip = %f\n", __func__, *p->Tvm_trips_flip); - dml2_printf("DML::%s: Tr0_trips_flip = %f\n", __func__, *p->Tr0_trips_flip); - dml2_printf("DML::%s: prefetch_bw_pr = %f\n", __func__, s->prefetch_bw_pr); - dml2_printf("DML::%s: prefetch_bw_oto = %f\n", __func__, s->prefetch_bw_oto); - dml2_printf("DML::%s: Tr0_oto = %f\n", __func__, s->Tr0_oto); - dml2_printf("DML::%s: Tvm_oto = %f\n", __func__, s->Tvm_oto); - dml2_printf("DML::%s: Tvm_oto_lines = %f\n", __func__, s->Tvm_oto_lines); - dml2_printf("DML::%s: Tr0_oto_lines = %f\n", __func__, s->Tr0_oto_lines); - dml2_printf("DML::%s: Lsw_oto = %f\n", __func__, s->Lsw_oto); - dml2_printf("DML::%s: dst_y_prefetch_oto = %f\n", __func__, s->dst_y_prefetch_oto); - dml2_printf("DML::%s: dst_y_prefetch_equ = %f\n", __func__, s->dst_y_prefetch_equ); - dml2_printf("DML::%s: tdlut_row_bytes = %d\n", __func__, tdlut_row_bytes); - dml2_printf("DML::%s: meta_row_bytes = %d\n", __func__, p->meta_row_bytes); -#endif - - 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; - - 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); - dml2_printf("DML::%s: Tvstartup: %fus - time between vstartup and first pixel of active\n", __func__, p->VStartup * s->LineTime); - dml2_printf("DML::%s: TSetup: %fus - time from vstartup to vready\n", __func__, *p->TSetup); - dml2_printf("DML::%s: TCalc: %fus - time for calculations in dchub starting at vready\n", __func__, p->TCalc); - dml2_printf("DML::%s: TWait: %fus - time for fabric to become ready max(pstate exit,cstate enter/exit, urgent latency) after TCalc\n", __func__, p->TWait); - dml2_printf("DML::%s: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", __func__, s->Tdmbf); - dml2_printf("DML::%s: Tdmec: %fus - time dio takes to transfer dmd\n", __func__, s->Tdmec); - dml2_printf("DML::%s: Tdmsks: %fus - time before active dmd must complete transmission at dio\n", __func__, s->Tdmsks); - dml2_printf("DML::%s: Tdmdl_vm: %fus - time for vm stages of dmd \n", __func__, *p->Tdmdl_vm); - dml2_printf("DML::%s: Tdmdl: %fus - time for fabric to become ready and fetch dmd \n", __func__, *p->Tdmdl); - dml2_printf("DML::%s: TWait_p: %fus\n", __func__, s->TWait_p); - 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); - } - - *p->dst_y_per_vm_vblank = 0; - *p->dst_y_per_row_vblank = 0; - *p->VRatioPrefetchY = 0; - *p->VRatioPrefetchC = 0; - *p->RequiredPrefetchPixelDataBWLuma = 0; - - if (s->dst_y_prefetch_equ > 1) { - s->prefetch_bw1 = 0.; - s->prefetch_bw2 = 0.; - s->prefetch_bw3 = 0.; - s->prefetch_bw4 = 0.; - - if (s->Tpre_rounded - *p->Tno_bw > 0) { - s->prefetch_bw1 = (vm_bytes * p->HostVMInefficiencyFactor - + 2 * (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) - + s->prefetch_sw_bytes) - / (s->Tpre_rounded - *p->Tno_bw); - s->Tsw_est1 = s->prefetch_sw_bytes / s->prefetch_bw1; - } else - 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) { - 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); - dml2_printf("DML::%s: prefetch_bw1: %f (updated)\n", __func__, s->prefetch_bw1); - } - - if (s->Tpre_rounded - *p->Tno_bw - 2 * 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->prefetch_bw2 = 0; - - 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) / - (s->Tpre_rounded - s->Tvm_trips_rounded); - s->Tsw_est3 = s->prefetch_sw_bytes / s->prefetch_bw3; - } else - 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); - dml2_printf("DML::%s: prefetch_bw3: %f (updated)\n", __func__, s->prefetch_bw3); - } - - if (s->Tpre_rounded - s->Tvm_trips_rounded - 2 * s->Tr0_trips_rounded > 0) - s->prefetch_bw4 = s->prefetch_sw_bytes / (s->Tpre_rounded - s->Tvm_trips_rounded - 2 * s->Tr0_trips_rounded); - else - s->prefetch_bw4 = 0; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: Tpre_rounded: %f\n", __func__, s->Tpre_rounded); - dml2_printf("DML::%s: Tno_bw: %f\n", __func__, *p->Tno_bw); - dml2_printf("DML::%s: Tvm_trips_rounded: %f\n", __func__, s->Tvm_trips_rounded); - dml2_printf("DML::%s: Tr0_trips_rounded: %f\n", __func__, 2 * s->Tr0_trips_rounded); - dml2_printf("DML::%s: Tsw_est1: %f\n", __func__, s->Tsw_est1); - 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); - dml2_printf("DML::%s: prefetch_bw3: %f (final)\n", __func__, s->prefetch_bw3); - dml2_printf("DML::%s: prefetch_bw4: %f (final)\n", __func__, s->prefetch_bw4); -#endif - - { - bool Case1OK = false; - bool Case2OK = false; - bool Case3OK = false; - - 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) { - Case1OK = true; - } - } - - 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) { - Case2OK = true; - } - } - - 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) { - Case3OK = true; - } - } - - if (Case1OK) { - s->prefetch_bw_equ = s->prefetch_bw1; - } else if (Case2OK) { - s->prefetch_bw_equ = s->prefetch_bw2; - } else if (Case3OK) { - s->prefetch_bw_equ = s->prefetch_bw3; - } else { - s->prefetch_bw_equ = s->prefetch_bw4; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: Case1OK: %u\n", __func__, Case1OK); - dml2_printf("DML::%s: Case2OK: %u\n", __func__, Case2OK); - dml2_printf("DML::%s: Case3OK: %u\n", __func__, Case3OK); - dml2_printf("DML::%s: prefetch_bw_equ: %f\n", __func__, s->prefetch_bw_equ); -#endif - 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)); - - if (s->prefetch_bw_equ > 0) { - if (p->display_cfg->gpuvm_enable == true) { - s->Tvm_equ = math_max3(*p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw_equ, *p->Tvm_trips, s->LineTime / 4); - } else { - s->Tvm_equ = s->LineTime / 4; - } - - if (p->display_cfg->gpuvm_enable == true || dcc_mrq_enable || p->setup_for_tdlut) { - s->Tr0_equ = math_max3((p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / s->prefetch_bw_equ, // PixelPTEBytesPerRow is dpte_row_bytes - *p->Tr0_trips, - s->LineTime / 4); - } else { - s->Tr0_equ = s->LineTime / 4; - } - } else { - s->Tvm_equ = 0; - s->Tr0_equ = 0; - dml2_printf("DML::%s: prefetch_bw_equ equals 0!\n", __func__); - } - } -#ifdef __DML_VBA_DEBUG__ - 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 - - if (s->dst_y_prefetch_oto < s->dst_y_prefetch_equ) { - *p->dst_y_prefetch = s->dst_y_prefetch_oto; - s->TimeForFetchingVM = s->Tvm_oto; - s->TimeForFetchingRowInVBlank = s->Tr0_oto; - - *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; -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: Using oto bw 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; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: Using equ bw scheduling for prefetch\n", __func__); -#endif - } - dml2_assert(*p->dst_y_prefetch < 64); - - // 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 - - 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); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: TimeForFetchingVM = %f\n", __func__, s->TimeForFetchingVM); - dml2_printf("DML::%s: TimeForFetchingRowInVBlank = %f\n", __func__, s->TimeForFetchingRowInVBlank); - dml2_printf("DML::%s: LineTime = %f\n", __func__, s->LineTime); - dml2_printf("DML::%s: dst_y_prefetch = %f\n", __func__, *p->dst_y_prefetch); - dml2_printf("DML::%s: dst_y_per_vm_vblank = %f\n", __func__, *p->dst_y_per_vm_vblank); - dml2_printf("DML::%s: dst_y_per_row_vblank = %f\n", __func__, *p->dst_y_per_row_vblank); - dml2_printf("DML::%s: LinesToRequestPrefetchPixelData = %f\n", __func__, s->LinesToRequestPrefetchPixelData); - dml2_printf("DML::%s: PrefetchSourceLinesY = %f\n", __func__, p->PrefetchSourceLinesY); - - dml2_printf("DML::%s: cursor_bytes_per_chunk = %d\n", __func__, p->cursor_bytes_per_chunk); - dml2_printf("DML::%s: cursor_bytes_per_line = %d\n", __func__, p->cursor_bytes_per_line); - dml2_printf("DML::%s: cursor_prefetch_bytes = %d\n", __func__, s->cursor_prefetch_bytes); - dml2_printf("DML::%s: prefetch_cursor_bw = %f\n", __func__, *p->prefetch_cursor_bw); -#endif - unsigned int min_lsw_required = (unsigned int)math_max2(2, p->tdlut_drain_time / s->LineTime); - - if (s->LinesToRequestPrefetchPixelData >= min_lsw_required && s->prefetch_bw_equ > 0) { - *p->VRatioPrefetchY = (double)p->PrefetchSourceLinesY / s->LinesToRequestPrefetchPixelData; - *p->VRatioPrefetchY = math_max2(*p->VRatioPrefetchY, 1.0); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: VRatioPrefetchY = %f\n", __func__, *p->VRatioPrefetchY); - dml2_printf("DML::%s: SwathHeightY = %u\n", __func__, p->SwathHeightY); - dml2_printf("DML::%s: VInitPreFillY = %u\n", __func__, p->VInitPreFillY); -#endif - if ((p->SwathHeightY > 4) && (p->VInitPreFillY > 3)) { - if (s->LinesToRequestPrefetchPixelData > (p->VInitPreFillY - 3.0) / 2.0) { - *p->VRatioPrefetchY = math_max2(*p->VRatioPrefetchY, - (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); - *p->VRatioPrefetchY = 0; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: VRatioPrefetchY = %f\n", __func__, *p->VRatioPrefetchY); - dml2_printf("DML::%s: PrefetchSourceLinesY = %f\n", __func__, p->PrefetchSourceLinesY); - dml2_printf("DML::%s: MaxNumSwathY = %u\n", __func__, p->MaxNumSwathY); -#endif - } - - *p->VRatioPrefetchC = (double)p->PrefetchSourceLinesC / s->LinesToRequestPrefetchPixelData; - *p->VRatioPrefetchC = math_max2(*p->VRatioPrefetchC, 1.0); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: VRatioPrefetchC = %f\n", __func__, *p->VRatioPrefetchC); - dml2_printf("DML::%s: SwathHeightC = %u\n", __func__, p->SwathHeightC); - dml2_printf("DML::%s: VInitPreFillC = %u\n", __func__, p->VInitPreFillC); -#endif - if ((p->SwathHeightC > 4) && (p->VInitPreFillC > 3)) { - if (s->LinesToRequestPrefetchPixelData > (p->VInitPreFillC - 3.0) / 2.0) { - *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); - *p->VRatioPrefetchC = 0; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: VRatioPrefetchC = %f\n", __func__, *p->VRatioPrefetchC); - dml2_printf("DML::%s: PrefetchSourceLinesC = %f\n", __func__, p->PrefetchSourceLinesC); - dml2_printf("DML::%s: MaxNumSwathC = %u\n", __func__, p->MaxNumSwathC); -#endif - } - - *p->RequiredPrefetchPixelDataBWLuma = (double)p->PrefetchSourceLinesY / s->LinesToRequestPrefetchPixelData * p->myPipe->BytePerPixelY * p->swath_width_luma_ub / s->LineTime; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: BytePerPixelY = %u\n", __func__, p->myPipe->BytePerPixelY); - dml2_printf("DML::%s: swath_width_luma_ub = %u\n", __func__, p->swath_width_luma_ub); - dml2_printf("DML::%s: LineTime = %f\n", __func__, s->LineTime); - dml2_printf("DML::%s: RequiredPrefetchPixelDataBWLuma = %f\n", __func__, *p->RequiredPrefetchPixelDataBWLuma); -#endif - *p->RequiredPrefetchPixelDataBWChroma = (double)p->PrefetchSourceLinesC / s->LinesToRequestPrefetchPixelData * p->myPipe->BytePerPixelC * p->swath_width_chroma_ub / s->LineTime; - } 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); - *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); - dml2_printf("DML: Tsw: %fus = time to fetch enough pixel data and cursor data to feed the scalers init position and detile\n", (double)s->LinesToRequestPrefetchPixelData * s->LineTime); - dml2_printf("DML: To: %fus - time for propagation from scaler to optc\n", (*p->DSTYAfterScaler + ((double)(*p->DSTXAfterScaler) / (double)p->myPipe->HTotal)) * s->LineTime); - dml2_printf("DML: Tvstartup - TSetup - Tcalc - TWait - Tpre - To > 0\n"); - dml2_printf("DML: Tslack(pre): %fus - time left over in schedule\n", p->VStartup * s->LineTime - s->TimeForFetchingVM - 2 * s->TimeForFetchingRowInVBlank - (*p->DSTYAfterScaler + ((double)(*p->DSTXAfterScaler) / (double)p->myPipe->HTotal)) * s->LineTime - p->TWait - p->TCalc - *p->TSetup); - 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); - s->NoTimeToPrefetch = true; - s->TimeForFetchingVM = 0; - s->TimeForFetchingRowInVBlank = 0; - *p->dst_y_per_vm_vblank = 0; - *p->dst_y_per_row_vblank = 0; - s->LinesToRequestPrefetchPixelData = 0; - *p->VRatioPrefetchY = 0; - *p->VRatioPrefetchC = 0; - *p->RequiredPrefetchPixelDataBWLuma = 0; - *p->RequiredPrefetchPixelDataBWChroma = 0; - } - - { - double prefetch_vm_bw; - double prefetch_row_bw; - - if (vm_bytes == 0) { - prefetch_vm_bw = 0; - } else if (*p->dst_y_per_vm_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); -#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); - } - - 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); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, p->PixelPTEBytesPerRow); - dml2_printf("DML::%s: dst_y_per_row_vblank = %f\n", __func__, *p->dst_y_per_row_vblank); - dml2_printf("DML::%s: prefetch_row_bw = %f\n", __func__, prefetch_row_bw); -#endif - } 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); - } - - *p->prefetch_vmrow_bw = math_max2(prefetch_vm_bw, prefetch_row_bw); - } - - if (s->NoTimeToPrefetch) { - s->TimeForFetchingVM = 0; - s->TimeForFetchingRowInVBlank = 0; - *p->dst_y_per_vm_vblank = 0; - *p->dst_y_per_row_vblank = 0; - *p->dst_y_prefetch = 0; - s->LinesToRequestPrefetchPixelData = 0; - *p->VRatioPrefetchY = 0; - *p->VRatioPrefetchC = 0; - *p->RequiredPrefetchPixelDataBWLuma = 0; - *p->RequiredPrefetchPixelDataBWChroma = 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: NoTimeToPrefetch=%d\n", __func__, s->NoTimeToPrefetch); - return s->NoTimeToPrefetch; -} - -static void calculate_peak_bandwidth_required( - struct dml2_core_internal_scratch *s, - - // output - double urg_vactive_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double non_urg_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - - // input - const struct dml2_display_cfg *display_cfg, - unsigned int inc_flip_bw, - unsigned int NumberOfActiveSurfaces, - unsigned int NumberOfDPP[], - double dcc_dram_bw_nom_overhead_factor_p0[], - double dcc_dram_bw_nom_overhead_factor_p1[], - double dcc_dram_bw_pref_overhead_factor_p0[], - double dcc_dram_bw_pref_overhead_factor_p1[], - double mall_prefetch_sdp_overhead_factor[], - double mall_prefetch_dram_overhead_factor[], - double ReadBandwidthLuma[], - double ReadBandwidthChroma[], - double PrefetchBandwidthLuma[], - double PrefetchBandwidthChroma[], - double cursor_bw[], - double dpte_row_bw[], - double meta_row_bw[], - double prefetch_cursor_bw[], - double prefetch_vmrow_bw[], - double flip_bw[], - double UrgentBurstFactorLuma[], - double UrgentBurstFactorChroma[], - double UrgentBurstFactorCursor[], - double UrgentBurstFactorLumaPre[], - double UrgentBurstFactorChromaPre[], - double UrgentBurstFactorCursorPre[]) -{ - unsigned int n; - unsigned int m; - - struct dml2_core_shared_calculate_peak_bandwidth_required_locals *l = &s->calculate_peak_bandwidth_required_locals; - - memset(l, 0, sizeof(struct dml2_core_shared_calculate_peak_bandwidth_required_locals)); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: inc_flip_bw = %d\n", __func__, inc_flip_bw); - dml2_printf("DML::%s: NumberOfActiveSurfaces = %d\n", __func__, NumberOfActiveSurfaces); -#endif - - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - l->unity_array[k] = 1.0; - l->zero_array[k] = 0.0; - } - - for (m = 0; m < dml2_core_internal_soc_state_max; m++) { - for (n = 0; n < dml2_core_internal_bw_max; n++) { - urg_vactive_bandwidth_required[m][n] = get_urgent_bandwidth_required( - &s->get_urgent_bandwidth_required_locals, - display_cfg, - m, - n, - 0, //inc_flip_bw, - NumberOfActiveSurfaces, - NumberOfDPP, - dcc_dram_bw_nom_overhead_factor_p0, - dcc_dram_bw_nom_overhead_factor_p1, - dcc_dram_bw_pref_overhead_factor_p0, - dcc_dram_bw_pref_overhead_factor_p1, - mall_prefetch_sdp_overhead_factor, - mall_prefetch_dram_overhead_factor, - ReadBandwidthLuma, - ReadBandwidthChroma, - l->zero_array, //PrefetchBandwidthLuma, - l->zero_array, //PrefetchBandwidthChroma, - cursor_bw, - dpte_row_bw, - meta_row_bw, - l->zero_array, //prefetch_cursor_bw, - l->zero_array, //prefetch_vmrow_bw, - l->zero_array, //flip_bw, - UrgentBurstFactorLuma, - UrgentBurstFactorChroma, - UrgentBurstFactorCursor, - UrgentBurstFactorLumaPre, - UrgentBurstFactorChromaPre, - UrgentBurstFactorCursorPre); - - - urg_bandwidth_required[m][n] = get_urgent_bandwidth_required( - &s->get_urgent_bandwidth_required_locals, - display_cfg, - m, - n, - inc_flip_bw, - NumberOfActiveSurfaces, - NumberOfDPP, - dcc_dram_bw_nom_overhead_factor_p0, - dcc_dram_bw_nom_overhead_factor_p1, - dcc_dram_bw_pref_overhead_factor_p0, - dcc_dram_bw_pref_overhead_factor_p1, - mall_prefetch_sdp_overhead_factor, - mall_prefetch_dram_overhead_factor, - ReadBandwidthLuma, - ReadBandwidthChroma, - PrefetchBandwidthLuma, - PrefetchBandwidthChroma, - cursor_bw, - dpte_row_bw, - meta_row_bw, - prefetch_cursor_bw, - prefetch_vmrow_bw, - flip_bw, - UrgentBurstFactorLuma, - UrgentBurstFactorChroma, - UrgentBurstFactorCursor, - UrgentBurstFactorLumaPre, - UrgentBurstFactorChromaPre, - UrgentBurstFactorCursorPre); - - non_urg_bandwidth_required[m][n] = get_urgent_bandwidth_required( - &s->get_urgent_bandwidth_required_locals, - display_cfg, - m, - n, - inc_flip_bw, - NumberOfActiveSurfaces, - NumberOfDPP, - dcc_dram_bw_nom_overhead_factor_p0, - dcc_dram_bw_nom_overhead_factor_p1, - dcc_dram_bw_pref_overhead_factor_p0, - dcc_dram_bw_pref_overhead_factor_p1, - mall_prefetch_sdp_overhead_factor, - mall_prefetch_dram_overhead_factor, - ReadBandwidthLuma, - ReadBandwidthChroma, - PrefetchBandwidthLuma, - PrefetchBandwidthChroma, - cursor_bw, - dpte_row_bw, - meta_row_bw, - prefetch_cursor_bw, - prefetch_vmrow_bw, - flip_bw, - l->unity_array, - l->unity_array, - l->unity_array, - l->unity_array, - l->unity_array, - l->unity_array); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: urg_vactive_bandwidth_required%s[%s][%s]=%f\n", __func__, (inc_flip_bw ? "_flip" : ""), dml2_core_internal_soc_state_type_str(m), dml2_core_internal_bw_type_str(n), urg_vactive_bandwidth_required[m][n]); - dml2_printf("DML::%s: urg_bandwidth_required%s[%s][%s]=%f\n", __func__, (inc_flip_bw ? "_flip" : ""), dml2_core_internal_soc_state_type_str(m), dml2_core_internal_bw_type_str(n), urg_bandwidth_required[m][n]); - dml2_printf("DML::%s: non_urg_bandwidth_required%s[%s][%s]=%f\n", __func__, (inc_flip_bw ? "_flip" : ""), dml2_core_internal_soc_state_type_str(m), dml2_core_internal_bw_type_str(n), non_urg_bandwidth_required[m][n]); -#endif - dml2_assert(urg_bandwidth_required[m][n] >= non_urg_bandwidth_required[m][n]); - } - } -} - -static void check_urgent_bandwidth_support( - double *frac_urg_bandwidth_nom, - double *frac_urg_bandwidth_mall, - bool *vactive_bandwidth_support_ok, // vactive ok - bool *bandwidth_support_ok, // max of vm, prefetch, vactive all ok - - unsigned int mall_allocated_for_dcn_mbytes, - double non_urg_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_vactive_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_bandwidth_available[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max]) -{ - *bandwidth_support_ok = 1; - *vactive_bandwidth_support_ok = 1; - - double frac_urg_bandwidth_nom_sdp = non_urg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp] / urg_bandwidth_available[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]; - double frac_urg_bandwidth_nom_dram = non_urg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram] / urg_bandwidth_available[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram]; - double frac_urg_bandwidth_mall_sdp = non_urg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp] / urg_bandwidth_available[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp]; - double frac_urg_bandwidth_mall_dram = non_urg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram] / urg_bandwidth_available[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram]; - - // Check urgent bandwidth required at sdp vs urgent bandwidth avail at sdp -> FractionOfUrgentBandwidth - // Check urgent bandwidth required at dram vs urgent bandwidth avail at dram - // Check urgent bandwidth required at sdp vs urgent bandwidth avail at sdp, svp_prefetch -> FractionOfUrgentBandwidthMALL - // Check urgent bandwidth required at dram vs urgent bandwidth avail at dram, svp_prefetch - - *bandwidth_support_ok &= urg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp] <= urg_bandwidth_available[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]; - *bandwidth_support_ok &= urg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram] <= urg_bandwidth_available[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram]; - - if (mall_allocated_for_dcn_mbytes > 0) { - *bandwidth_support_ok &= urg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp] <= urg_bandwidth_available[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp]; - *bandwidth_support_ok &= urg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram] <= urg_bandwidth_available[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram]; - } - - *frac_urg_bandwidth_nom = math_max2(frac_urg_bandwidth_nom_sdp, frac_urg_bandwidth_nom_dram); - *frac_urg_bandwidth_mall = math_max2(frac_urg_bandwidth_mall_sdp, frac_urg_bandwidth_mall_dram); - - *bandwidth_support_ok &= (*frac_urg_bandwidth_nom <= 1.0); - - if (mall_allocated_for_dcn_mbytes > 0) - *bandwidth_support_ok &= (*frac_urg_bandwidth_mall <= 1.0); - - *vactive_bandwidth_support_ok &= urg_vactive_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp] <= urg_bandwidth_available[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]; - *vactive_bandwidth_support_ok &= urg_vactive_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram] <= urg_bandwidth_available[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram]; - if (mall_allocated_for_dcn_mbytes > 0) { - *vactive_bandwidth_support_ok &= urg_vactive_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp] <= urg_bandwidth_available[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp]; - *vactive_bandwidth_support_ok &= urg_vactive_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram] <= urg_bandwidth_available[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram]; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: frac_urg_bandwidth_nom_sdp = %f\n", __func__, frac_urg_bandwidth_nom_sdp); - dml2_printf("DML::%s: frac_urg_bandwidth_nom_dram = %f\n", __func__, frac_urg_bandwidth_nom_dram); - dml2_printf("DML::%s: frac_urg_bandwidth_nom = %f\n", __func__, *frac_urg_bandwidth_nom); - - dml2_printf("DML::%s: frac_urg_bandwidth_mall_sdp = %f\n", __func__, frac_urg_bandwidth_mall_sdp); - dml2_printf("DML::%s: frac_urg_bandwidth_mall_dram = %f\n", __func__, frac_urg_bandwidth_mall_dram); - dml2_printf("DML::%s: frac_urg_bandwidth_mall = %f\n", __func__, *frac_urg_bandwidth_mall); - dml2_printf("DML::%s: bandwidth_support_ok = %d\n", __func__, *bandwidth_support_ok); -#endif - -} - -static double get_bandwidth_available_for_immediate_flip(enum dml2_core_internal_soc_state_type eval_state, - double urg_bandwidth_required[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], // no flip - double urg_bandwidth_available[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max]) -{ - double flip_bw_available_mbps; - double flip_bw_available_sdp_mbps; - double flip_bw_available_dram_mbps; - - flip_bw_available_sdp_mbps = urg_bandwidth_available[eval_state][dml2_core_internal_bw_sdp] - urg_bandwidth_required[eval_state][dml2_core_internal_bw_sdp]; - flip_bw_available_dram_mbps = urg_bandwidth_available[eval_state][dml2_core_internal_bw_dram] - urg_bandwidth_required[eval_state][dml2_core_internal_bw_dram]; - flip_bw_available_mbps = flip_bw_available_sdp_mbps < flip_bw_available_dram_mbps ? flip_bw_available_sdp_mbps : flip_bw_available_dram_mbps; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: eval_state = %s\n", __func__, dml2_core_internal_soc_state_type_str(eval_state)); - dml2_printf("DML::%s: urg_bandwidth_available_sdp_mbps = %f\n", __func__, urg_bandwidth_available[eval_state][dml2_core_internal_bw_sdp]); - dml2_printf("DML::%s: urg_bandwidth_available_dram_mbps = %f\n", __func__, urg_bandwidth_available[eval_state][dml2_core_internal_bw_dram]); - dml2_printf("DML::%s: urg_bandwidth_required_sdp_mbps = %f\n", __func__, urg_bandwidth_required[eval_state][dml2_core_internal_bw_sdp]); - dml2_printf("DML::%s: urg_bandwidth_required_dram_mbps = %f\n", __func__, urg_bandwidth_required[eval_state][dml2_core_internal_bw_dram]); - dml2_printf("DML::%s: flip_bw_available_sdp_mbps = %f\n", __func__, flip_bw_available_sdp_mbps); - dml2_printf("DML::%s: flip_bw_available_dram_mbps = %f\n", __func__, flip_bw_available_dram_mbps); - dml2_printf("DML::%s: flip_bw_available_mbps = %f\n", __func__, flip_bw_available_mbps); -#endif - - return flip_bw_available_mbps; -} - -static void calculate_immediate_flip_bandwidth_support( - // Output - double *frac_urg_bandwidth_flip, - bool *flip_bandwidth_support_ok, - - // Input - enum dml2_core_internal_soc_state_type eval_state, - double urg_bandwidth_required_flip[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double non_urg_bandwidth_required_flip[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max], - double urg_bandwidth_available[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max]) -{ - double frac_urg_bw_flip_sdp = non_urg_bandwidth_required_flip[eval_state][dml2_core_internal_bw_sdp] / urg_bandwidth_available[eval_state][dml2_core_internal_bw_sdp]; - double frac_urg_bw_flip_dram = non_urg_bandwidth_required_flip[eval_state][dml2_core_internal_bw_dram] / urg_bandwidth_available[eval_state][dml2_core_internal_bw_dram]; - - *flip_bandwidth_support_ok = true; - for (unsigned int n = 0; n < dml2_core_internal_bw_max; n++) { // check sdp and dram - *flip_bandwidth_support_ok &= urg_bandwidth_available[eval_state][n] >= urg_bandwidth_required_flip[eval_state][n]; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: n = %s\n", __func__, dml2_core_internal_bw_type_str((enum dml2_core_internal_bw_type) eval_state)); - dml2_printf("DML::%s: urg_bandwidth_available = %f\n", __func__, urg_bandwidth_available[eval_state][n]); - dml2_printf("DML::%s: non_urg_bandwidth_required_flip = %f\n", __func__, non_urg_bandwidth_required_flip[eval_state][n]); - dml2_printf("DML::%s: urg_bandwidth_required_flip = %f\n", __func__, urg_bandwidth_required_flip[eval_state][n]); - dml2_printf("DML::%s: flip_bandwidth_support_ok = %d\n", __func__, *flip_bandwidth_support_ok); -#endif - dml2_assert(urg_bandwidth_required_flip[eval_state][n] > non_urg_bandwidth_required_flip[eval_state][n]); - } - - *frac_urg_bandwidth_flip = (frac_urg_bw_flip_sdp > frac_urg_bw_flip_dram) ? frac_urg_bw_flip_sdp : frac_urg_bw_flip_dram; - *flip_bandwidth_support_ok &= (*frac_urg_bandwidth_flip <= 1); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: eval_state = %s\n", __func__, dml2_core_internal_soc_state_type_str(eval_state)); - dml2_printf("DML::%s: frac_urg_bw_flip_sdp = %f\n", __func__, frac_urg_bw_flip_sdp); - dml2_printf("DML::%s: frac_urg_bw_flip_dram = %f\n", __func__, frac_urg_bw_flip_dram); - dml2_printf("DML::%s: frac_urg_bandwidth_flip = %f\n", __func__, *frac_urg_bandwidth_flip); - dml2_printf("DML::%s: flip_bandwidth_support_ok = %d\n", __func__, *flip_bandwidth_support_ok); - - for (unsigned int m = 0; m < dml2_core_internal_soc_state_max; m++) { - for (unsigned int n = 0; n < dml2_core_internal_bw_max; n++) { - dml2_printf("DML::%s: state:%s bw_type:%s, urg_bandwidth_available=%f %s urg_bandwidth_required=%f\n", - __func__, dml2_core_internal_soc_state_type_str(m), dml2_core_internal_bw_type_str(n), - urg_bandwidth_available[m][n], (urg_bandwidth_available[m][n] < urg_bandwidth_required_flip[m][n]) ? "<" : ">=", urg_bandwidth_required_flip[m][n]); - } - } -#endif -} - -static void CalculateFlipSchedule( - struct dml2_core_internal_scratch *s, - bool iflip_enable, - bool use_lb_flip_bw, - double HostVMInefficiencyFactor, - double Tvm_trips_flip, - double Tr0_trips_flip, - double Tvm_trips_flip_rounded, - double Tr0_trips_flip_rounded, - bool GPUVMEnable, - double vm_bytes, // vm_bytes - double DPTEBytesPerRow, // dpte_row_bytes - double BandwidthAvailableForImmediateFlip, - unsigned int TotImmediateFlipBytes, - enum dml2_source_format_class SourcePixelFormat, - double LineTime, - double VRatio, - double VRatioChroma, - double Tno_bw_flip, - unsigned int dpte_row_height, - unsigned int dpte_row_height_chroma, - bool use_one_row_for_frame_flip, - unsigned int max_flip_time_us, - unsigned int per_pipe_flip_bytes, - unsigned int meta_row_bytes, - unsigned int meta_row_height, - unsigned int meta_row_height_chroma, - bool dcc_mrq_enable, - - // Output - double *dst_y_per_vm_flip, - double *dst_y_per_row_flip, - double *final_flip_bw, - bool *ImmediateFlipSupportedForPipe) -{ - struct dml2_core_shared_CalculateFlipSchedule_locals *l = &s->CalculateFlipSchedule_locals; - - l->dual_plane = dml2_core_shared_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: 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); - dml2_printf("DML::%s: iflip_enable = %u\n", __func__, iflip_enable); - dml2_printf("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, HostVMInefficiencyFactor); - dml2_printf("DML::%s: LineTime = %f\n", __func__, LineTime); - dml2_printf("DML::%s: Tno_bw_flip = %f\n", __func__, Tno_bw_flip); - dml2_printf("DML::%s: Tvm_trips_flip = %f\n", __func__, Tvm_trips_flip); - dml2_printf("DML::%s: Tr0_trips_flip = %f\n", __func__, Tr0_trips_flip); - dml2_printf("DML::%s: Tvm_trips_flip_rounded = %f\n", __func__, Tvm_trips_flip_rounded); - dml2_printf("DML::%s: Tr0_trips_flip_rounded = %f\n", __func__, Tr0_trips_flip_rounded); - dml2_printf("DML::%s: vm_bytes = %f\n", __func__, vm_bytes); - dml2_printf("DML::%s: DPTEBytesPerRow = %f\n", __func__, DPTEBytesPerRow); - dml2_printf("DML::%s: meta_row_bytes = %d\n", __func__, meta_row_bytes); - dml2_printf("DML::%s: dpte_row_bytes = %f\n", __func__, l->dpte_row_bytes); - dml2_printf("DML::%s: dpte_row_height = %d\n", __func__, dpte_row_height); - dml2_printf("DML::%s: meta_row_height = %d\n", __func__, meta_row_height); - dml2_printf("DML::%s: VRatio = %f\n", __func__, VRatio); -#endif - - if (TotImmediateFlipBytes > 0 && (GPUVMEnable || dcc_mrq_enable)) { - if (l->dual_plane) { - if (dcc_mrq_enable & GPUVMEnable) { - l->min_row_height = math_min2(dpte_row_height, meta_row_height); - l->min_row_height_chroma = math_min2(dpte_row_height_chroma, meta_row_height_chroma); - } else if (GPUVMEnable) { - l->min_row_height = dpte_row_height; - l->min_row_height_chroma = dpte_row_height_chroma; - } else { - l->min_row_height = meta_row_height; - l->min_row_height_chroma = meta_row_height_chroma; - } - l->min_row_time = math_min2(l->min_row_height * LineTime / VRatio, l->min_row_height_chroma * LineTime / VRatioChroma); - } else { - if (dcc_mrq_enable & GPUVMEnable) - l->min_row_height = math_min2(dpte_row_height, meta_row_height); - else if (GPUVMEnable) - l->min_row_height = dpte_row_height; - else - l->min_row_height = meta_row_height; - - l->min_row_time = l->min_row_height * LineTime / VRatio; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: min_row_time = %f\n", __func__, l->min_row_time); -#endif - dml2_assert(l->min_row_time > 0); - - 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)); - - //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 - l->lb_flip_bw = 0; - - if (iflip_enable) { - l->hvm_scaled_vm_bytes = vm_bytes * HostVMInefficiencyFactor; - l->num_rows = 2; - l->hvm_scaled_row_bytes = (l->num_rows * l->dpte_row_bytes * HostVMInefficiencyFactor + l->num_rows * meta_row_bytes); - l->hvm_scaled_vm_row_bytes = l->hvm_scaled_vm_bytes + l->hvm_scaled_row_bytes; - l->lb_flip_bw = math_max3( - l->hvm_scaled_vm_row_bytes / (l->max_flip_time - Tno_bw_flip), - l->hvm_scaled_vm_bytes / (l->max_flip_time - Tno_bw_flip - 2 * Tr0_trips_flip_rounded), - l->hvm_scaled_row_bytes / (l->max_flip_time - Tvm_trips_flip_rounded)); -#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 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)); - dml2_printf("DML::%s: lb_flip_bw for row = %f\n", __func__, l->hvm_scaled_row_bytes / (l->max_flip_time - Tvm_trips_flip_rounded)); - - if (l->lb_flip_bw > 0) { - dml2_printf("DML::%s: mode_support est Tvm_flip = %f (bw-based)\n", __func__, Tno_bw_flip + l->hvm_scaled_vm_bytes / l->lb_flip_bw); - 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); - } -#endif - l->lb_flip_bw = math_max3(l->lb_flip_bw, - l->hvm_scaled_vm_bytes / (31 * LineTime) - Tno_bw_flip, - (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / (15 * LineTime)); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: lb_flip_bw for vm reg limit = %f\n", __func__, l->hvm_scaled_vm_bytes / (31 * LineTime) - Tno_bw_flip); - dml2_printf("DML::%s: lb_flip_bw for row reg limit = %f\n", __func__, (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / (15 * LineTime)); -#endif - } - - *final_flip_bw = l->lb_flip_bw; - - *dst_y_per_vm_flip = 1; // not used - *dst_y_per_row_flip = 1; // not used - *ImmediateFlipSupportedForPipe = true; - } else { - if (iflip_enable) { - l->ImmediateFlipBW = (double)per_pipe_flip_bytes * BandwidthAvailableForImmediateFlip / (double)TotImmediateFlipBytes; // flip_bw(i) - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: per_pipe_flip_bytes = %d\n", __func__, per_pipe_flip_bytes); - dml2_printf("DML::%s: BandwidthAvailableForImmediateFlip = %f\n", __func__, BandwidthAvailableForImmediateFlip); - dml2_printf("DML::%s: ImmediateFlipBW = %f\n", __func__, l->ImmediateFlipBW); -#endif - if (l->ImmediateFlipBW == 0) { - l->Tvm_flip = 0; - l->Tr0_flip = 0; - } else { - l->Tvm_flip = math_max3(Tvm_trips_flip, - Tno_bw_flip + vm_bytes * HostVMInefficiencyFactor / l->ImmediateFlipBW, - LineTime / 4.0); - - l->Tr0_flip = math_max3(Tr0_trips_flip, - (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / l->ImmediateFlipBW, - LineTime / 4.0); - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: total vm bytes (hvm ineff scaled) = %f\n", __func__, vm_bytes * HostVMInefficiencyFactor); - dml2_printf("DML::%s: total row bytes (hvm ineff scaled, one row) = %f\n", __func__, (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes)); - - dml2_printf("DML::%s: Tvm_flip = %f (bw-based), Tvm_trips_flip = %f (latency-based)\n", __func__, Tno_bw_flip + vm_bytes * HostVMInefficiencyFactor / l->ImmediateFlipBW, Tvm_trips_flip); - dml2_printf("DML::%s: Tr0_flip = %f (bw-based), Tr0_trips_flip = %f (latency-based)\n", __func__, (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / l->ImmediateFlipBW, Tr0_trips_flip); -#endif - *dst_y_per_vm_flip = math_ceil2(4.0 * (l->Tvm_flip / LineTime), 1.0) / 4.0; - *dst_y_per_row_flip = math_ceil2(4.0 * (l->Tr0_flip / LineTime), 1.0) / 4.0; - - *final_flip_bw = math_max2(vm_bytes * HostVMInefficiencyFactor / (*dst_y_per_vm_flip * LineTime), - (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / (*dst_y_per_row_flip * LineTime)); - - if (*dst_y_per_vm_flip >= 32 || *dst_y_per_row_flip >= 16 || l->Tvm_flip + 2 * l->Tr0_flip > l->min_row_time) { - *ImmediateFlipSupportedForPipe = false; - } else { - *ImmediateFlipSupportedForPipe = iflip_enable; - } - } else { - l->Tvm_flip = 0; - l->Tr0_flip = 0; - *dst_y_per_vm_flip = 0; - *dst_y_per_row_flip = 0; - *final_flip_bw = 0; - *ImmediateFlipSupportedForPipe = iflip_enable; - } - } - } else { - l->Tvm_flip = 0; - l->Tr0_flip = 0; - *dst_y_per_vm_flip = 0; - *dst_y_per_row_flip = 0; - *final_flip_bw = 0; - *ImmediateFlipSupportedForPipe = iflip_enable; - } - -#ifdef __DML_VBA_DEBUG__ - if (!use_lb_flip_bw) { - dml2_printf("DML::%s: dst_y_per_vm_flip = %f (should be < 32)\n", __func__, *dst_y_per_vm_flip); - 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: final_flip_bw = %f\n", __func__, *final_flip_bw); - dml2_printf("DML::%s: ImmediateFlipSupportedForPipe = %u\n", __func__, *ImmediateFlipSupportedForPipe); -#endif -} - -static void CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport( - struct dml2_core_internal_scratch *scratch, - struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params *p) -{ - struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_locals *s = &scratch->CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_locals; - - s->TotalActiveWriteback = 0; - p->Watermark->UrgentWatermark = p->mmSOCParameters.UrgentLatency + p->mmSOCParameters.ExtraLatency; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: UrgentWatermark = %f\n", __func__, p->Watermark->UrgentWatermark); -#endif - - p->Watermark->USRRetrainingWatermark = p->mmSOCParameters.UrgentLatency + p->mmSOCParameters.ExtraLatency + p->mmSOCParameters.USRRetrainingLatency + p->mmSOCParameters.SMNLatency; - p->Watermark->DRAMClockChangeWatermark = p->mmSOCParameters.DRAMClockChangeLatency + p->Watermark->UrgentWatermark; - p->Watermark->FCLKChangeWatermark = p->mmSOCParameters.FCLKChangeLatency + p->Watermark->UrgentWatermark; - p->Watermark->StutterExitWatermark = p->mmSOCParameters.SRExitTime + p->mmSOCParameters.ExtraLatency_sr + 10 / p->DCFClkDeepSleep; - 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; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: UrgentLatency = %f\n", __func__, p->mmSOCParameters.UrgentLatency); - dml2_printf("DML::%s: ExtraLatency = %f\n", __func__, p->mmSOCParameters.ExtraLatency); - dml2_printf("DML::%s: DRAMClockChangeLatency = %f\n", __func__, p->mmSOCParameters.DRAMClockChangeLatency); - dml2_printf("DML::%s: SREnterPlusExitZ8Time = %f\n", __func__, p->mmSOCParameters.SREnterPlusExitZ8Time); - dml2_printf("DML::%s: SREnterPlusExitTime = %f\n", __func__, p->mmSOCParameters.SREnterPlusExitTime); - dml2_printf("DML::%s: UrgentWatermark = %f\n", __func__, p->Watermark->UrgentWatermark); - dml2_printf("DML::%s: USRRetrainingWatermark = %f\n", __func__, p->Watermark->USRRetrainingWatermark); - dml2_printf("DML::%s: DRAMClockChangeWatermark = %f\n", __func__, p->Watermark->DRAMClockChangeWatermark); - dml2_printf("DML::%s: FCLKChangeWatermark = %f\n", __func__, p->Watermark->FCLKChangeWatermark); - dml2_printf("DML::%s: StutterExitWatermark = %f\n", __func__, p->Watermark->StutterExitWatermark); - dml2_printf("DML::%s: StutterEnterPlusExitWatermark = %f\n", __func__, p->Watermark->StutterEnterPlusExitWatermark); - dml2_printf("DML::%s: Z8StutterExitWatermark = %f\n", __func__, p->Watermark->Z8StutterExitWatermark); - dml2_printf("DML::%s: Z8StutterEnterPlusExitWatermark = %f\n", __func__, p->Watermark->Z8StutterEnterPlusExitWatermark); -#endif - - s->TotalActiveWriteback = 0; - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - if (p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.enable == true) { - s->TotalActiveWriteback = s->TotalActiveWriteback + 1; - } - } - - if (s->TotalActiveWriteback <= 1) { - p->Watermark->WritebackUrgentWatermark = p->mmSOCParameters.WritebackLatency; - } else { - p->Watermark->WritebackUrgentWatermark = p->mmSOCParameters.WritebackLatency + p->WritebackChunkSize * 1024.0 / 32.0 / p->SOCCLK; - } - if (p->USRRetrainingRequired) - p->Watermark->WritebackUrgentWatermark = p->Watermark->WritebackUrgentWatermark + p->mmSOCParameters.USRRetrainingLatency; - - if (s->TotalActiveWriteback <= 1) { - p->Watermark->WritebackDRAMClockChangeWatermark = p->mmSOCParameters.DRAMClockChangeLatency + p->mmSOCParameters.WritebackLatency; - p->Watermark->WritebackFCLKChangeWatermark = p->mmSOCParameters.FCLKChangeLatency + p->mmSOCParameters.WritebackLatency; - } else { - p->Watermark->WritebackDRAMClockChangeWatermark = p->mmSOCParameters.DRAMClockChangeLatency + p->mmSOCParameters.WritebackLatency + p->WritebackChunkSize * 1024.0 / 32.0 / p->SOCCLK; - p->Watermark->WritebackFCLKChangeWatermark = p->mmSOCParameters.FCLKChangeLatency + p->mmSOCParameters.WritebackLatency + p->WritebackChunkSize * 1024 / 32 / p->SOCCLK; - } - - if (p->USRRetrainingRequired) - p->Watermark->WritebackDRAMClockChangeWatermark = p->Watermark->WritebackDRAMClockChangeWatermark + p->mmSOCParameters.USRRetrainingLatency; - - if (p->USRRetrainingRequired) - p->Watermark->WritebackFCLKChangeWatermark = p->Watermark->WritebackFCLKChangeWatermark + p->mmSOCParameters.USRRetrainingLatency; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: WritebackDRAMClockChangeWatermark = %f\n", __func__, p->Watermark->WritebackDRAMClockChangeWatermark); - dml2_printf("DML::%s: WritebackFCLKChangeWatermark = %f\n", __func__, p->Watermark->WritebackFCLKChangeWatermark); - dml2_printf("DML::%s: WritebackUrgentWatermark = %f\n", __func__, p->Watermark->WritebackUrgentWatermark); - dml2_printf("DML::%s: USRRetrainingRequired = %u\n", __func__, p->USRRetrainingRequired); - dml2_printf("DML::%s: USRRetrainingLatency = %f\n", __func__, p->mmSOCParameters.USRRetrainingLatency); -#endif - - s->TotalPixelBW = 0.0; - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - double h_total = (double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total; - double pixel_clock_mhz = p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000.0; - double v_ratio = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio; - double v_ratio_c = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio; - - s->TotalPixelBW = s->TotalPixelBW + p->DPPPerSurface[k] - * (p->SwathWidthY[k] * p->BytePerPixelDETY[k] * v_ratio + p->SwathWidthC[k] * p->BytePerPixelDETC[k] * v_ratio_c) / (h_total / pixel_clock_mhz); - } - - *p->global_fclk_change_supported = true; - *p->global_dram_clock_change_supported = true; - - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - double h_total = (double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total; - double pixel_clock_mhz = p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000.0; - double v_ratio = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio; - double v_ratio_c = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio; - double v_taps = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps; - double v_taps_c = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps; - double h_ratio = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio; - double h_ratio_c = p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio; - double LBBitPerPixel = 57; - - s->LBLatencyHidingSourceLinesY[k] = (unsigned int)(math_min2((double)p->MaxLineBufferLines, math_floor2((double)p->LineBufferSize / LBBitPerPixel / ((double)p->SwathWidthY[k] / math_max2(h_ratio, 1.0)), 1)) - (v_taps - 1)); - s->LBLatencyHidingSourceLinesC[k] = (unsigned int)(math_min2((double)p->MaxLineBufferLines, math_floor2((double)p->LineBufferSize / LBBitPerPixel / ((double)p->SwathWidthC[k] / math_max2(h_ratio_c, 1.0)), 1)) - (v_taps_c - 1)); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, MaxLineBufferLines= %u\n", __func__, k, p->MaxLineBufferLines); - dml2_printf("DML::%s: k=%u, LineBufferSize = %u\n", __func__, k, p->LineBufferSize); - dml2_printf("DML::%s: k=%u, LBBitPerPixel = %u\n", __func__, k, LBBitPerPixel); - dml2_printf("DML::%s: k=%u, HRatio = %f\n", __func__, k, h_ratio); - dml2_printf("DML::%s: k=%u, VTaps = %f\n", __func__, k, v_taps); -#endif - - s->EffectiveLBLatencyHidingY = s->LBLatencyHidingSourceLinesY[k] / v_ratio * (h_total / pixel_clock_mhz); - s->EffectiveLBLatencyHidingC = s->LBLatencyHidingSourceLinesC[k] / v_ratio_c * (h_total / pixel_clock_mhz); - - s->EffectiveDETBufferSizeY = p->DETBufferSizeY[k]; - if (p->UnboundedRequestEnabled) { - s->EffectiveDETBufferSizeY = s->EffectiveDETBufferSizeY + p->CompressedBufferSizeInkByte * 1024 * (p->SwathWidthY[k] * p->BytePerPixelDETY[k] * v_ratio) / (h_total / pixel_clock_mhz) / s->TotalPixelBW; - } - - s->LinesInDETY[k] = (double)s->EffectiveDETBufferSizeY / p->BytePerPixelDETY[k] / p->SwathWidthY[k]; - s->LinesInDETYRoundedDownToSwath[k] = (unsigned int)(math_floor2(s->LinesInDETY[k], p->SwathHeightY[k])); - s->FullDETBufferingTimeY = s->LinesInDETYRoundedDownToSwath[k] * (h_total / pixel_clock_mhz) / v_ratio; - - s->ActiveClockChangeLatencyHidingY = s->EffectiveLBLatencyHidingY + s->FullDETBufferingTimeY - ((double)p->DSTXAfterScaler[k] / h_total + (double)p->DSTYAfterScaler[k]) * h_total / pixel_clock_mhz; - - if (p->NumberOfActiveSurfaces > 1) { - s->ActiveClockChangeLatencyHidingY = s->ActiveClockChangeLatencyHidingY - (1.0 - 1.0 / (double)p->NumberOfActiveSurfaces) * (double)p->SwathHeightY[k] * (double)h_total / pixel_clock_mhz / v_ratio; - } - - if (p->BytePerPixelDETC[k] > 0) { - s->LinesInDETC[k] = p->DETBufferSizeC[k] / p->BytePerPixelDETC[k] / p->SwathWidthC[k]; - s->LinesInDETCRoundedDownToSwath[k] = (unsigned int)(math_floor2(s->LinesInDETC[k], p->SwathHeightC[k])); - s->FullDETBufferingTimeC = s->LinesInDETCRoundedDownToSwath[k] * (h_total / pixel_clock_mhz) / v_ratio_c; - s->ActiveClockChangeLatencyHidingC = s->EffectiveLBLatencyHidingC + s->FullDETBufferingTimeC - ((double)p->DSTXAfterScaler[k] / (double)h_total + (double)p->DSTYAfterScaler[k]) * (double)h_total / pixel_clock_mhz; - if (p->NumberOfActiveSurfaces > 1) { - s->ActiveClockChangeLatencyHidingC = s->ActiveClockChangeLatencyHidingC - (1.0 - 1.0 / (double)p->NumberOfActiveSurfaces) * (double)p->SwathHeightC[k] * (double)h_total / pixel_clock_mhz / v_ratio_c; - } - s->ActiveClockChangeLatencyHiding = math_min2(s->ActiveClockChangeLatencyHidingY, s->ActiveClockChangeLatencyHidingC); - } else { - s->ActiveClockChangeLatencyHiding = s->ActiveClockChangeLatencyHidingY; - } - - s->ActiveDRAMClockChangeLatencyMargin[k] = s->ActiveClockChangeLatencyHiding - p->Watermark->DRAMClockChangeWatermark; - s->ActiveFCLKChangeLatencyMargin[k] = s->ActiveClockChangeLatencyHiding - p->Watermark->FCLKChangeWatermark; - s->USRRetrainingLatencyMargin[k] = s->ActiveClockChangeLatencyHiding - p->Watermark->USRRetrainingWatermark; - - if (p->VActiveLatencyHidingMargin) - p->VActiveLatencyHidingMargin[k] = s->ActiveDRAMClockChangeLatencyMargin[k]; - - p->VActiveLatencyHidingUs[k] = s->ActiveClockChangeLatencyHiding; - - if (p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.enable) { - s->WritebackLatencyHiding = (double)p->WritebackInterfaceBufferSize * 1024.0 / ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.output_height * (double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.output_width / ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.input_height * (double)h_total / pixel_clock_mhz) * 4.0); - if (p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.pixel_format == dml2_444_64) { - s->WritebackLatencyHiding = s->WritebackLatencyHiding / 2; - } - s->WritebackDRAMClockChangeLatencyMargin = s->WritebackLatencyHiding - p->Watermark->WritebackDRAMClockChangeWatermark; - - s->WritebackFCLKChangeLatencyMargin = s->WritebackLatencyHiding - p->Watermark->WritebackFCLKChangeWatermark; - - s->ActiveDRAMClockChangeLatencyMargin[k] = math_min2(s->ActiveDRAMClockChangeLatencyMargin[k], s->WritebackDRAMClockChangeLatencyMargin); - s->ActiveFCLKChangeLatencyMargin[k] = math_min2(s->ActiveFCLKChangeLatencyMargin[k], s->WritebackFCLKChangeLatencyMargin); - } - p->MaxActiveDRAMClockChangeLatencySupported[k] = dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k]) ? 0 : (s->ActiveDRAMClockChangeLatencyMargin[k] + p->mmSOCParameters.DRAMClockChangeLatency); - - enum dml2_uclk_pstate_change_strategy uclk_pstate_change_strategy = p->display_cfg->plane_descriptors[k].overrides.uclk_pstate_change_strategy; - double reserved_vblank_time_us = (double)p->display_cfg->plane_descriptors[k].overrides.reserved_vblank_time_ns / 1000; - - p->FCLKChangeSupport[k] = dml2_fclock_change_unsupported; - if (s->ActiveFCLKChangeLatencyMargin[k] > 0) - p->FCLKChangeSupport[k] = dml2_fclock_change_vactive; - else if (reserved_vblank_time_us >= p->mmSOCParameters.FCLKChangeLatency) - p->FCLKChangeSupport[k] = dml2_fclock_change_vblank; - - if (p->FCLKChangeSupport[k] == dml2_fclock_change_unsupported) - *p->global_fclk_change_supported = false; - - 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) - p->DRAMClockChangeSupport[k] = dml2_dram_clock_change_vblank_and_vactive; - else if (s->ActiveDRAMClockChangeLatencyMargin[k] > 0) - p->DRAMClockChangeSupport[k] = dml2_dram_clock_change_vactive; - else if (reserved_vblank_time_us >= p->mmSOCParameters.DRAMClockChangeLatency) - p->DRAMClockChangeSupport[k] = dml2_dram_clock_change_vblank; - } else if (uclk_pstate_change_strategy == dml2_uclk_pstate_change_strategy_force_vactive && s->ActiveDRAMClockChangeLatencyMargin[k] > 0) - p->DRAMClockChangeSupport[k] = dml2_dram_clock_change_vactive; - else if (uclk_pstate_change_strategy == dml2_uclk_pstate_change_strategy_force_vblank && reserved_vblank_time_us >= p->mmSOCParameters.DRAMClockChangeLatency) - p->DRAMClockChangeSupport[k] = dml2_dram_clock_change_vblank; - else if (uclk_pstate_change_strategy == dml2_uclk_pstate_change_strategy_force_drr) - p->DRAMClockChangeSupport[k] = dml2_dram_clock_change_drr; - else if (uclk_pstate_change_strategy == dml2_uclk_pstate_change_strategy_force_mall_svp) - p->DRAMClockChangeSupport[k] = dml2_dram_clock_change_mall_svp; - else if (uclk_pstate_change_strategy == dml2_uclk_pstate_change_strategy_force_mall_full_frame) - p->DRAMClockChangeSupport[k] = dml2_dram_clock_change_mall_full_frame; - - if (p->DRAMClockChangeSupport[k] == dml2_dram_clock_change_unsupported) - *p->global_dram_clock_change_supported = false; - - s->dst_y_pstate = (unsigned int)(math_ceil2((p->mmSOCParameters.DRAMClockChangeLatency + p->mmSOCParameters.UrgentLatency) / (h_total / pixel_clock_mhz), 1)); - s->src_y_pstate_l = (unsigned int)(math_ceil2(s->dst_y_pstate * v_ratio, p->SwathHeightY[k])); - s->src_y_ahead_l = (unsigned int)(math_floor2(p->DETBufferSizeY[k] / p->BytePerPixelDETY[k] / p->SwathWidthY[k], p->SwathHeightY[k]) + s->LBLatencyHidingSourceLinesY[k]); - s->sub_vp_lines_l = s->src_y_pstate_l + s->src_y_ahead_l + p->meta_row_height_l[k]; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, DETBufferSizeY = %u\n", __func__, k, p->DETBufferSizeY[k]); - dml2_printf("DML::%s: k=%u, BytePerPixelDETY = %f\n", __func__, k, p->BytePerPixelDETY[k]); - dml2_printf("DML::%s: k=%u, SwathWidthY = %u\n", __func__, k, p->SwathWidthY[k]); - dml2_printf("DML::%s: k=%u, SwathHeightY = %u\n", __func__, k, p->SwathHeightY[k]); - dml2_printf("DML::%s: k=%u, LBLatencyHidingSourceLinesY = %u\n", __func__, k, s->LBLatencyHidingSourceLinesY[k]); - dml2_printf("DML::%s: k=%u, dst_y_pstate = %u\n", __func__, k, s->dst_y_pstate); - dml2_printf("DML::%s: k=%u, src_y_pstate_l = %u\n", __func__, k, s->src_y_pstate_l); - dml2_printf("DML::%s: k=%u, src_y_ahead_l = %u\n", __func__, k, s->src_y_ahead_l); - dml2_printf("DML::%s: k=%u, meta_row_height_l = %u\n", __func__, p->meta_row_height_l[k]); - dml2_printf("DML::%s: k=%u, sub_vp_lines_l = %u\n", __func__, k, s->sub_vp_lines_l); -#endif - p->SubViewportLinesNeededInMALL[k] = s->sub_vp_lines_l; - - if (p->BytePerPixelDETC[k] > 0) { - s->src_y_pstate_c = (unsigned int)(math_ceil2(s->dst_y_pstate * v_ratio_c, p->SwathHeightC[k])); - 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)) - 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, 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); -#endif - } - } - - bool FoundCriticalSurface = false; - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - if ((!dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k])) && ((!FoundCriticalSurface) - || ((s->ActiveFCLKChangeLatencyMargin[k] + p->mmSOCParameters.FCLKChangeLatency) < *p->MaxActiveFCLKChangeLatencySupported))) { - FoundCriticalSurface = true; - *p->MaxActiveFCLKChangeLatencySupported = s->ActiveFCLKChangeLatencyMargin[k] + p->mmSOCParameters.FCLKChangeLatency; - } - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: DRAMClockChangeSupport = %u\n", __func__, *p->global_dram_clock_change_supported); - dml2_printf("DML::%s: FCLKChangeSupport = %u\n", __func__, *p->global_fclk_change_supported); - dml2_printf("DML::%s: MaxActiveFCLKChangeLatencySupported = %f\n", __func__, *p->MaxActiveFCLKChangeLatencySupported); - dml2_printf("DML::%s: USRRetrainingSupport = %u\n", __func__, *p->USRRetrainingSupport); -#endif -} - -static double uclk_khz_to_dram_bw_mbps(unsigned long uclk_khz, const struct dml2_dram_params *dram_config) -{ - double bw_mbps = 0; - bw_mbps = ((double)uclk_khz * dram_config->channel_count * dram_config->channel_width_bytes * dram_config->transactions_per_clock) / 1000.0; - - return bw_mbps; -} - -static double dram_bw_kbps_to_uclk_mhz(unsigned long long bw_kbps, const struct dml2_dram_params *dram_config) -{ - double uclk_mhz = 0; - - uclk_mhz = (double)bw_kbps / (dram_config->channel_count * dram_config->channel_width_bytes * dram_config->transactions_per_clock) / 1000.0; - - return uclk_mhz; -} - -static unsigned int 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; -} - -static unsigned int 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; -} - -static unsigned int get_pipe_flip_bytes( - double hostvm_inefficiency_factor, - unsigned int vm_bytes, - unsigned int dpte_row_bytes, - unsigned int meta_row_bytes) -{ - unsigned int flip_bytes = 0; - - flip_bytes += (unsigned int)((vm_bytes * hostvm_inefficiency_factor) + 2 * meta_row_bytes); - flip_bytes += (unsigned int)(2 * dpte_row_bytes * hostvm_inefficiency_factor); - - return flip_bytes; -} - -static void calculate_hostvm_inefficiency_factor( - double *HostVMInefficiencyFactor, - double *HostVMInefficiencyFactorPrefetch, - - bool gpuvm_enable, - bool hostvm_enable, - unsigned int remote_iommu_outstanding_translations, - unsigned int max_outstanding_reqs, - double urg_bandwidth_avail_active_pixel_and_vm, - double urg_bandwidth_avail_active_vm_only) -{ - *HostVMInefficiencyFactor = 1; - *HostVMInefficiencyFactorPrefetch = 1; - - if (gpuvm_enable && hostvm_enable) { - *HostVMInefficiencyFactor = urg_bandwidth_avail_active_pixel_and_vm / urg_bandwidth_avail_active_vm_only; - *HostVMInefficiencyFactorPrefetch = *HostVMInefficiencyFactor; - - if ((*HostVMInefficiencyFactorPrefetch < 4) && (remote_iommu_outstanding_translations < max_outstanding_reqs)) - *HostVMInefficiencyFactorPrefetch = 4; -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: urg_bandwidth_avail_active_pixel_and_vm = %f\n", __func__, urg_bandwidth_avail_active_pixel_and_vm); - dml2_printf("DML::%s: urg_bandwidth_avail_active_vm_only = %f\n", __func__, urg_bandwidth_avail_active_vm_only); - dml2_printf("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, *HostVMInefficiencyFactor); - dml2_printf("DML::%s: HostVMInefficiencyFactorPrefetch = %f\n", __func__, *HostVMInefficiencyFactorPrefetch); -#endif - } -} - -static void CalculatePixelDeliveryTimes( - const struct dml2_display_cfg *display_cfg, - const struct core_display_cfg_support_info *cfg_support_info, - unsigned int NumberOfActiveSurfaces, - double VRatioPrefetchY[], - double VRatioPrefetchC[], - unsigned int swath_width_luma_ub[], - unsigned int swath_width_chroma_ub[], - double PSCL_THROUGHPUT[], - double PSCL_THROUGHPUT_CHROMA[], - double Dppclk[], - unsigned int BytePerPixelC[], - unsigned int req_per_swath_ub_l[], - unsigned int req_per_swath_ub_c[], - - // Output - double DisplayPipeLineDeliveryTimeLuma[], - double DisplayPipeLineDeliveryTimeChroma[], - double DisplayPipeLineDeliveryTimeLumaPrefetch[], - double DisplayPipeLineDeliveryTimeChromaPrefetch[], - double DisplayPipeRequestDeliveryTimeLuma[], - double DisplayPipeRequestDeliveryTimeChroma[], - double DisplayPipeRequestDeliveryTimeLumaPrefetch[], - double DisplayPipeRequestDeliveryTimeChromaPrefetch[]) -{ - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - double pixel_clock_mhz = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u : HRatio = %f\n", __func__, k, display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio); - dml2_printf("DML::%s: k=%u : VRatio = %f\n", __func__, k, display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio); - dml2_printf("DML::%s: k=%u : HRatioChroma = %f\n", __func__, k, display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio); - dml2_printf("DML::%s: k=%u : VRatioChroma = %f\n", __func__, k, display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio); - dml2_printf("DML::%s: k=%u : VRatioPrefetchY = %f\n", __func__, k, VRatioPrefetchY[k]); - dml2_printf("DML::%s: k=%u : VRatioPrefetchC = %f\n", __func__, k, VRatioPrefetchC[k]); - dml2_printf("DML::%s: k=%u : swath_width_luma_ub = %u\n", __func__, k, swath_width_luma_ub[k]); - dml2_printf("DML::%s: k=%u : swath_width_chroma_ub = %u\n", __func__, k, swath_width_chroma_ub[k]); - dml2_printf("DML::%s: k=%u : PSCL_THROUGHPUT = %f\n", __func__, k, PSCL_THROUGHPUT[k]); - dml2_printf("DML::%s: k=%u : PSCL_THROUGHPUT_CHROMA = %f\n", __func__, k, PSCL_THROUGHPUT_CHROMA[k]); - dml2_printf("DML::%s: k=%u : DPPPerSurface = %u\n", __func__, k, cfg_support_info->plane_support_info[k].dpps_used); - dml2_printf("DML::%s: k=%u : pixel_clock_mhz = %f\n", __func__, k, pixel_clock_mhz); - dml2_printf("DML::%s: k=%u : Dppclk = %f\n", __func__, k, Dppclk[k]); -#endif - if (display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio <= 1) { - DisplayPipeLineDeliveryTimeLuma[k] = swath_width_luma_ub[k] * cfg_support_info->plane_support_info[k].dpps_used / display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio / pixel_clock_mhz; - } else { - DisplayPipeLineDeliveryTimeLuma[k] = swath_width_luma_ub[k] / PSCL_THROUGHPUT[k] / Dppclk[k]; - } - - if (BytePerPixelC[k] == 0) { - DisplayPipeLineDeliveryTimeChroma[k] = 0; - } else { - if (display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio <= 1) { - DisplayPipeLineDeliveryTimeChroma[k] = swath_width_chroma_ub[k] * cfg_support_info->plane_support_info[k].dpps_used / display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio / pixel_clock_mhz; - } else { - DisplayPipeLineDeliveryTimeChroma[k] = swath_width_chroma_ub[k] / PSCL_THROUGHPUT_CHROMA[k] / Dppclk[k]; - } - } - - if (VRatioPrefetchY[k] <= 1) { - DisplayPipeLineDeliveryTimeLumaPrefetch[k] = swath_width_luma_ub[k] * cfg_support_info->plane_support_info[k].dpps_used / display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio / pixel_clock_mhz; - } else { - DisplayPipeLineDeliveryTimeLumaPrefetch[k] = swath_width_luma_ub[k] / PSCL_THROUGHPUT[k] / Dppclk[k]; - } - - if (BytePerPixelC[k] == 0) { - DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0; - } else { - if (VRatioPrefetchC[k] <= 1) { - DisplayPipeLineDeliveryTimeChromaPrefetch[k] = swath_width_chroma_ub[k] * cfg_support_info->plane_support_info[k].dpps_used / display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio / pixel_clock_mhz; - } else { - DisplayPipeLineDeliveryTimeChromaPrefetch[k] = swath_width_chroma_ub[k] / PSCL_THROUGHPUT_CHROMA[k] / Dppclk[k]; - } - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u : DisplayPipeLineDeliveryTimeLuma = %f\n", __func__, k, DisplayPipeLineDeliveryTimeLuma[k]); - dml2_printf("DML::%s: k=%u : DisplayPipeLineDeliveryTimeLumaPrefetch = %f\n", __func__, k, DisplayPipeLineDeliveryTimeLumaPrefetch[k]); - dml2_printf("DML::%s: k=%u : DisplayPipeLineDeliveryTimeChroma = %f\n", __func__, k, DisplayPipeLineDeliveryTimeChroma[k]); - dml2_printf("DML::%s: k=%u : DisplayPipeLineDeliveryTimeChromaPrefetch = %f\n", __func__, k, DisplayPipeLineDeliveryTimeChromaPrefetch[k]); -#endif - } - - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - - DisplayPipeRequestDeliveryTimeLuma[k] = DisplayPipeLineDeliveryTimeLuma[k] / req_per_swath_ub_l[k]; - DisplayPipeRequestDeliveryTimeLumaPrefetch[k] = DisplayPipeLineDeliveryTimeLumaPrefetch[k] / req_per_swath_ub_l[k]; - if (BytePerPixelC[k] == 0) { - DisplayPipeRequestDeliveryTimeChroma[k] = 0; - DisplayPipeRequestDeliveryTimeChromaPrefetch[k] = 0; - } else { - DisplayPipeRequestDeliveryTimeChroma[k] = DisplayPipeLineDeliveryTimeChroma[k] / req_per_swath_ub_c[k]; - DisplayPipeRequestDeliveryTimeChromaPrefetch[k] = DisplayPipeLineDeliveryTimeChromaPrefetch[k] / req_per_swath_ub_c[k]; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u : DisplayPipeRequestDeliveryTimeLuma = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeLuma[k]); - dml2_printf("DML::%s: k=%u : DisplayPipeRequestDeliveryTimeLumaPrefetch = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeLumaPrefetch[k]); - dml2_printf("DML::%s: k=%u : req_per_swath_ub_l = %d\n", __func__, k, req_per_swath_ub_l[k]); - dml2_printf("DML::%s: k=%u : DisplayPipeRequestDeliveryTimeChroma = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeChroma[k]); - dml2_printf("DML::%s: k=%u : DisplayPipeRequestDeliveryTimeChromaPrefetch = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeChromaPrefetch[k]); - dml2_printf("DML::%s: k=%u : req_per_swath_ub_c = %d\n", __func__, k, req_per_swath_ub_c[k]); -#endif - } -} - -static void CalculateMetaAndPTETimes(struct dml2_core_shared_CalculateMetaAndPTETimes_params *p) -{ - unsigned int meta_chunk_width; - unsigned int min_meta_chunk_width; - unsigned int meta_chunk_per_row_int; - unsigned int meta_row_remainder; - unsigned int meta_chunk_threshold; - unsigned int meta_chunks_per_row_ub; - unsigned int meta_chunk_width_chroma; - unsigned int min_meta_chunk_width_chroma; - unsigned int meta_chunk_per_row_int_chroma; - unsigned int meta_row_remainder_chroma; - unsigned int meta_chunk_threshold_chroma; - unsigned int meta_chunks_per_row_ub_chroma; - unsigned int dpte_group_width_luma; - unsigned int dpte_groups_per_row_luma_ub; - unsigned int dpte_group_width_chroma; - unsigned int dpte_groups_per_row_chroma_ub; - double pixel_clock_mhz; - - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - p->DST_Y_PER_PTE_ROW_NOM_L[k] = p->dpte_row_height[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio; - if (p->BytePerPixelC[k] == 0) { - p->DST_Y_PER_PTE_ROW_NOM_C[k] = 0; - } else { - p->DST_Y_PER_PTE_ROW_NOM_C[k] = p->dpte_row_height_chroma[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio; - } - p->DST_Y_PER_META_ROW_NOM_L[k] = p->meta_row_height[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio; - if (p->BytePerPixelC[k] == 0) { - p->DST_Y_PER_META_ROW_NOM_C[k] = 0; - } else { - p->DST_Y_PER_META_ROW_NOM_C[k] = p->meta_row_height_chroma[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio; - } - } - - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - if (p->display_cfg->plane_descriptors[k].surface.dcc.enable == true && p->mrq_present) { - meta_chunk_width = p->MetaChunkSize * 1024 * 256 / p->BytePerPixelY[k] / p->meta_row_height[k]; - min_meta_chunk_width = p->MinMetaChunkSizeBytes * 256 / p->BytePerPixelY[k] / p->meta_row_height[k]; - meta_chunk_per_row_int = p->meta_row_width[k] / meta_chunk_width; - meta_row_remainder = p->meta_row_width[k] % meta_chunk_width; - if (!dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) { - meta_chunk_threshold = 2 * min_meta_chunk_width - p->meta_req_width[k]; - } else { - meta_chunk_threshold = 2 * min_meta_chunk_width - p->meta_req_height[k]; - } - if (meta_row_remainder <= meta_chunk_threshold) { - meta_chunks_per_row_ub = meta_chunk_per_row_int + 1; - } else { - meta_chunks_per_row_ub = meta_chunk_per_row_int + 2; - } - p->TimePerMetaChunkNominal[k] = p->meta_row_height[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio * - p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / - (p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) / meta_chunks_per_row_ub; - p->TimePerMetaChunkVBlank[k] = p->dst_y_per_row_vblank[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / - (p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) / meta_chunks_per_row_ub; - p->TimePerMetaChunkFlip[k] = p->dst_y_per_row_flip[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / - (p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) / meta_chunks_per_row_ub; - if (p->BytePerPixelC[k] == 0) { - p->TimePerChromaMetaChunkNominal[k] = 0; - p->TimePerChromaMetaChunkVBlank[k] = 0; - p->TimePerChromaMetaChunkFlip[k] = 0; - } else { - meta_chunk_width_chroma = p->MetaChunkSize * 1024 * 256 / p->BytePerPixelC[k] / p->meta_row_height_chroma[k]; - min_meta_chunk_width_chroma = p->MinMetaChunkSizeBytes * 256 / p->BytePerPixelC[k] / p->meta_row_height_chroma[k]; - meta_chunk_per_row_int_chroma = (unsigned int)((double)p->meta_row_width_chroma[k] / meta_chunk_width_chroma); - meta_row_remainder_chroma = p->meta_row_width_chroma[k] % meta_chunk_width_chroma; - if (!dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) { - meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - p->meta_req_width_chroma[k]; - } else { - meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - p->meta_req_height_chroma[k]; - } - if (meta_row_remainder_chroma <= meta_chunk_threshold_chroma) { - meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 1; - } else { - meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 2; - } - p->TimePerChromaMetaChunkNominal[k] = p->meta_row_height_chroma[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / (p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) / meta_chunks_per_row_ub_chroma; - p->TimePerChromaMetaChunkVBlank[k] = p->dst_y_per_row_vblank[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / (p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) / meta_chunks_per_row_ub_chroma; - p->TimePerChromaMetaChunkFlip[k] = p->dst_y_per_row_flip[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / (p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) / meta_chunks_per_row_ub_chroma; - } - } else { - p->TimePerMetaChunkNominal[k] = 0; - p->TimePerMetaChunkVBlank[k] = 0; - p->TimePerMetaChunkFlip[k] = 0; - p->TimePerChromaMetaChunkNominal[k] = 0; - p->TimePerChromaMetaChunkVBlank[k] = 0; - p->TimePerChromaMetaChunkFlip[k] = 0; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%d, DST_Y_PER_META_ROW_NOM_L = %f\n", __func__, k, p->DST_Y_PER_META_ROW_NOM_L[k]); - dml2_printf("DML::%s: k=%d, DST_Y_PER_META_ROW_NOM_C = %f\n", __func__, k, p->DST_Y_PER_META_ROW_NOM_C[k]); - dml2_printf("DML::%s: k=%d, TimePerMetaChunkNominal = %f\n", __func__, k, p->TimePerMetaChunkNominal[k]); - dml2_printf("DML::%s: k=%d, TimePerMetaChunkVBlank = %f\n", __func__, k, p->TimePerMetaChunkVBlank[k]); - dml2_printf("DML::%s: k=%d, TimePerMetaChunkFlip = %f\n", __func__, k, p->TimePerMetaChunkFlip[k]); - dml2_printf("DML::%s: k=%d, TimePerChromaMetaChunkNominal = %f\n", __func__, k, p->TimePerChromaMetaChunkNominal[k]); - dml2_printf("DML::%s: k=%d, TimePerChromaMetaChunkVBlank = %f\n", __func__, k, p->TimePerChromaMetaChunkVBlank[k]); - dml2_printf("DML::%s: k=%d, TimePerChromaMetaChunkFlip = %f\n", __func__, k, p->TimePerChromaMetaChunkFlip[k]); -#endif - } - - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - p->DST_Y_PER_PTE_ROW_NOM_L[k] = p->dpte_row_height[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio; - if (p->BytePerPixelC[k] == 0) { - p->DST_Y_PER_PTE_ROW_NOM_C[k] = 0; - } else { - p->DST_Y_PER_PTE_ROW_NOM_C[k] = p->dpte_row_height_chroma[k] / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio; - } - } - - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - pixel_clock_mhz = ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000); - - if (p->display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut) - p->time_per_tdlut_group[k] = 2 * p->dst_y_per_row_vblank[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / p->tdlut_groups_per_2row_ub[k]; - else - p->time_per_tdlut_group[k] = 0; - - dml2_printf("DML::%s: k=%u, time_per_tdlut_group = %f\n", __func__, k, p->time_per_tdlut_group[k]); - - if (p->display_cfg->gpuvm_enable == true) { - if (!dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) { - dpte_group_width_luma = (unsigned int)((double)p->dpte_group_bytes[k] / (double)p->PTERequestSizeY[k] * p->PixelPTEReqWidthY[k]); - } else { - dpte_group_width_luma = (unsigned int)((double)p->dpte_group_bytes[k] / (double)p->PTERequestSizeY[k] * p->PixelPTEReqHeightY[k]); - } - if (p->use_one_row_for_frame[k]) { - dpte_groups_per_row_luma_ub = (unsigned int)(math_ceil2((double)p->dpte_row_width_luma_ub[k] / (double)dpte_group_width_luma / 2.0, 1.0)); - } 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)); - } - - 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]); - dml2_printf("DML::%s: k=%u, PixelPTEReqWidthY = %u\n", __func__, k, p->PixelPTEReqWidthY[k]); - dml2_printf("DML::%s: k=%u, PixelPTEReqHeightY = %u\n", __func__, k, p->PixelPTEReqHeightY[k]); - dml2_printf("DML::%s: k=%u, dpte_row_width_luma_ub = %u\n", __func__, k, p->dpte_row_width_luma_ub[k]); - dml2_printf("DML::%s: k=%u, dpte_group_width_luma = %u\n", __func__, k, dpte_group_width_luma); - dml2_printf("DML::%s: k=%u, dpte_groups_per_row_luma_ub = %u\n", __func__, k, dpte_groups_per_row_luma_ub); - - p->time_per_pte_group_nom_luma[k] = p->DST_Y_PER_PTE_ROW_NOM_L[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / dpte_groups_per_row_luma_ub; - p->time_per_pte_group_vblank_luma[k] = p->dst_y_per_row_vblank[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / dpte_groups_per_row_luma_ub; - p->time_per_pte_group_flip_luma[k] = p->dst_y_per_row_flip[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / dpte_groups_per_row_luma_ub; - if (p->BytePerPixelC[k] == 0) { - p->time_per_pte_group_nom_chroma[k] = 0; - p->time_per_pte_group_vblank_chroma[k] = 0; - p->time_per_pte_group_flip_chroma[k] = 0; - } else { - if (!dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle)) { - dpte_group_width_chroma = (unsigned int)((double)p->dpte_group_bytes[k] / (double)p->PTERequestSizeC[k] * p->PixelPTEReqWidthC[k]); - } else { - dpte_group_width_chroma = (unsigned int)((double)p->dpte_group_bytes[k] / (double)p->PTERequestSizeC[k] * p->PixelPTEReqHeightC[k]); - } - - if (p->use_one_row_for_frame[k]) { - dpte_groups_per_row_chroma_ub = (unsigned int)(math_ceil2((double)p->dpte_row_width_chroma_ub[k] / (double)dpte_group_width_chroma / 2.0, 1.0)); - } 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); - - p->time_per_pte_group_nom_chroma[k] = p->DST_Y_PER_PTE_ROW_NOM_C[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / dpte_groups_per_row_chroma_ub; - p->time_per_pte_group_vblank_chroma[k] = p->dst_y_per_row_vblank[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / dpte_groups_per_row_chroma_ub; - p->time_per_pte_group_flip_chroma[k] = p->dst_y_per_row_flip[k] * p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / pixel_clock_mhz / dpte_groups_per_row_chroma_ub; - } - } else { - p->time_per_pte_group_nom_luma[k] = 0; - p->time_per_pte_group_vblank_luma[k] = 0; - p->time_per_pte_group_flip_luma[k] = 0; - p->time_per_pte_group_nom_chroma[k] = 0; - p->time_per_pte_group_vblank_chroma[k] = 0; - p->time_per_pte_group_flip_chroma[k] = 0; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, dst_y_per_row_vblank = %f\n", __func__, k, p->dst_y_per_row_vblank[k]); - dml2_printf("DML::%s: k=%u, dst_y_per_row_flip = %f\n", __func__, k, p->dst_y_per_row_flip[k]); - - dml2_printf("DML::%s: k=%u, DST_Y_PER_PTE_ROW_NOM_L = %f\n", __func__, k, p->DST_Y_PER_PTE_ROW_NOM_L[k]); - dml2_printf("DML::%s: k=%u, DST_Y_PER_PTE_ROW_NOM_C = %f\n", __func__, k, p->DST_Y_PER_PTE_ROW_NOM_C[k]); - dml2_printf("DML::%s: k=%u, time_per_pte_group_nom_luma = %f\n", __func__, k, p->time_per_pte_group_nom_luma[k]); - dml2_printf("DML::%s: k=%u, time_per_pte_group_vblank_luma = %f\n", __func__, k, p->time_per_pte_group_vblank_luma[k]); - dml2_printf("DML::%s: k=%u, time_per_pte_group_flip_luma = %f\n", __func__, k, p->time_per_pte_group_flip_luma[k]); - dml2_printf("DML::%s: k=%u, time_per_pte_group_nom_chroma = %f\n", __func__, k, p->time_per_pte_group_nom_chroma[k]); - dml2_printf("DML::%s: k=%u, time_per_pte_group_vblank_chroma = %f\n", __func__, k, p->time_per_pte_group_vblank_chroma[k]); - dml2_printf("DML::%s: k=%u, time_per_pte_group_flip_chroma = %f\n", __func__, k, p->time_per_pte_group_flip_chroma[k]); -#endif - } -} // CalculateMetaAndPTETimes - -static void CalculateVMGroupAndRequestTimes( - const struct dml2_display_cfg *display_cfg, - unsigned int NumberOfActiveSurfaces, - unsigned int BytePerPixelC[], - double dst_y_per_vm_vblank[], - double dst_y_per_vm_flip[], - unsigned int dpte_row_width_luma_ub[], - unsigned int dpte_row_width_chroma_ub[], - unsigned int vm_group_bytes[], - unsigned int dpde0_bytes_per_frame_ub_l[], - unsigned int dpde0_bytes_per_frame_ub_c[], - unsigned int tdlut_pte_bytes_per_frame[], - unsigned int meta_pte_bytes_per_frame_ub_l[], - unsigned int meta_pte_bytes_per_frame_ub_c[], - bool mrq_present, - - // Output - double TimePerVMGroupVBlank[], - double TimePerVMGroupFlip[], - double TimePerVMRequestVBlank[], - double TimePerVMRequestFlip[]) -{ - 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); -#endif - for (unsigned int k = 0; k < NumberOfActiveSurfaces; ++k) { - double pixel_clock_mhz = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000); - bool dcc_mrq_enable = display_cfg->plane_descriptors[k].surface.dcc.enable && mrq_present; -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, dcc_mrq_enable = %u\n", __func__, k, dcc_mrq_enable); - dml2_printf("DML::%s: k=%u, vm_group_bytes = %u\n", __func__, k, vm_group_bytes[k]); - dml2_printf("DML::%s: k=%u, dpde0_bytes_per_frame_ub_l = %u\n", __func__, k, dpde0_bytes_per_frame_ub_l[k]); - dml2_printf("DML::%s: k=%u, dpde0_bytes_per_frame_ub_c = %u\n", __func__, k, dpde0_bytes_per_frame_ub_c[k]); - dml2_printf("DML::%s: k=%d, meta_pte_bytes_per_frame_ub_l = %d\n", __func__, k, meta_pte_bytes_per_frame_ub_l[k]); - dml2_printf("DML::%s: k=%d, meta_pte_bytes_per_frame_ub_c = %d\n", __func__, k, meta_pte_bytes_per_frame_ub_c[k]); -#endif - - if (display_cfg->gpuvm_enable) { - if (display_cfg->gpuvm_max_page_table_levels >= 2) { - num_group_per_lower_vm_stage += (unsigned int)math_ceil2((double)(dpde0_bytes_per_frame_ub_l[k]) / (double)(vm_group_bytes[k]), 1); - - if (BytePerPixelC[k] > 0) - num_group_per_lower_vm_stage += (unsigned int)math_ceil2((double)(dpde0_bytes_per_frame_ub_c[k]) / (double)(vm_group_bytes[k]), 1); - } - - if (dcc_mrq_enable) { - if (BytePerPixelC[k] > 0) { - num_group_per_lower_vm_stage += (unsigned int)(2.0 /*for each mpde0 group*/ + math_ceil2((double)(meta_pte_bytes_per_frame_ub_l[k]) / (double)(vm_group_bytes[k]), 1) + - math_ceil2((double)(meta_pte_bytes_per_frame_ub_c[k]) / (double)(vm_group_bytes[k]), 1)); - } else { - num_group_per_lower_vm_stage += (unsigned int)(1.0 + math_ceil2((double)(meta_pte_bytes_per_frame_ub_l[k]) / (double)(vm_group_bytes[k]), 1)); - } - } - - unsigned int num_group_per_lower_vm_stage_flip = num_group_per_lower_vm_stage; - unsigned int num_group_per_lower_vm_stage_pref = num_group_per_lower_vm_stage; - - if (display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut && display_cfg->gpuvm_enable) { - num_group_per_lower_vm_stage_pref += (unsigned int)math_ceil2(tdlut_pte_bytes_per_frame[k] / vm_group_bytes[k], 1); - if (display_cfg->gpuvm_max_page_table_levels >= 2) - num_group_per_lower_vm_stage_pref += 1; // tdpe0 group - } - - if (display_cfg->gpuvm_max_page_table_levels >= 2) { - num_req_per_lower_vm_stage += dpde0_bytes_per_frame_ub_l[k] / 64; - if (BytePerPixelC[k] > 0) - num_req_per_lower_vm_stage += dpde0_bytes_per_frame_ub_c[k]; - } - - if (dcc_mrq_enable) { - num_req_per_lower_vm_stage += meta_pte_bytes_per_frame_ub_l[k] / 64; - if (BytePerPixelC[k] > 0) - num_req_per_lower_vm_stage += meta_pte_bytes_per_frame_ub_c[k] / 64; - } - - unsigned int num_req_per_lower_vm_stage_flip = num_req_per_lower_vm_stage; - unsigned int num_req_per_lower_vm_stage_pref = num_req_per_lower_vm_stage; - - if (display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut && display_cfg->gpuvm_enable) { - num_req_per_lower_vm_stage_pref += tdlut_pte_bytes_per_frame[k] / 64; - } - - 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; - TimePerVMRequestFlip[k] = dst_y_per_vm_flip[k] * line_time / num_req_per_lower_vm_stage_flip; - - dml2_printf("DML::%s: k=%u, dst_y_per_vm_vblank = %f\n", __func__, k, dst_y_per_vm_vblank[k]); - dml2_printf("DML::%s: k=%u, dst_y_per_vm_flip = %f\n", __func__, k, dst_y_per_vm_flip[k]); - dml2_printf("DML::%s: k=%u, line_time = %f\n", __func__, k, line_time); - dml2_printf("DML::%s: k=%u, num_group_per_lower_vm_stage_pref = %f\n", __func__, k, num_group_per_lower_vm_stage_pref); - dml2_printf("DML::%s: k=%u, num_group_per_lower_vm_stage_flip = %f\n", __func__, k, num_group_per_lower_vm_stage_flip); - dml2_printf("DML::%s: k=%u, num_req_per_lower_vm_stage_pref = %f\n", __func__, k, num_req_per_lower_vm_stage_pref); - dml2_printf("DML::%s: k=%u, num_req_per_lower_vm_stage_flip = %f\n", __func__, k, num_req_per_lower_vm_stage_flip); - - if (display_cfg->gpuvm_max_page_table_levels > 2) { - TimePerVMGroupVBlank[k] = TimePerVMGroupVBlank[k] / 2; - TimePerVMGroupFlip[k] = TimePerVMGroupFlip[k] / 2; - TimePerVMRequestVBlank[k] = TimePerVMRequestVBlank[k] / 2; - TimePerVMRequestFlip[k] = TimePerVMRequestFlip[k] / 2; - } - - } else { - TimePerVMGroupVBlank[k] = 0; - TimePerVMGroupFlip[k] = 0; - TimePerVMRequestVBlank[k] = 0; - TimePerVMRequestFlip[k] = 0; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, TimePerVMGroupVBlank = %f\n", __func__, k, TimePerVMGroupVBlank[k]); - dml2_printf("DML::%s: k=%u, TimePerVMGroupFlip = %f\n", __func__, k, TimePerVMGroupFlip[k]); - dml2_printf("DML::%s: k=%u, TimePerVMRequestVBlank = %f\n", __func__, k, TimePerVMRequestVBlank[k]); - dml2_printf("DML::%s: k=%u, TimePerVMRequestFlip = %f\n", __func__, k, TimePerVMRequestFlip[k]); -#endif - } -} - -static void CalculateStutterEfficiency(struct dml2_core_internal_scratch *scratch, - struct dml2_core_calcs_CalculateStutterEfficiency_params *p) -{ - struct dml2_core_calcs_CalculateStutterEfficiency_locals *l = &scratch->CalculateStutterEfficiency_locals; - - memset(l, 0, sizeof(struct dml2_core_calcs_CalculateStutterEfficiency_locals)); - - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - if (!dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k])) { - if (p->display_cfg->plane_descriptors[k].surface.dcc.enable == true) { - if ((dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle) && p->BlockWidth256BytesY[k] > p->SwathHeightY[k]) || (!dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle) && p->BlockHeight256BytesY[k] > p->SwathHeightY[k]) || p->DCCYMaxUncompressedBlock[k] < 256) { - l->MaximumEffectiveCompressionLuma = 2; - } else { - l->MaximumEffectiveCompressionLuma = 4; - } - l->TotalCompressedReadBandwidth = l->TotalCompressedReadBandwidth + p->ReadBandwidthSurfaceLuma[k] / math_min2(p->display_cfg->plane_descriptors[k].surface.dcc.informative.dcc_rate_plane0, l->MaximumEffectiveCompressionLuma); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, ReadBandwidthSurfaceLuma = %f\n", __func__, k, p->ReadBandwidthSurfaceLuma[k]); - dml2_printf("DML::%s: k=%u, NetDCCRateLuma = %f\n", __func__, k, p->display_cfg->plane_descriptors[k].surface.dcc.informative.dcc_rate_plane0); - dml2_printf("DML::%s: k=%u, MaximumEffectiveCompressionLuma = %f\n", __func__, k, l->MaximumEffectiveCompressionLuma); -#endif - l->TotalZeroSizeRequestReadBandwidth = l->TotalZeroSizeRequestReadBandwidth + p->ReadBandwidthSurfaceLuma[k] * p->display_cfg->plane_descriptors[k].surface.dcc.informative.fraction_of_zero_size_request_plane0; - l->TotalZeroSizeCompressedReadBandwidth = l->TotalZeroSizeCompressedReadBandwidth + p->ReadBandwidthSurfaceLuma[k] * p->display_cfg->plane_descriptors[k].surface.dcc.informative.fraction_of_zero_size_request_plane0 / l->MaximumEffectiveCompressionLuma; - - if (p->ReadBandwidthSurfaceChroma[k] > 0) { - if ((dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle) && p->BlockWidth256BytesC[k] > p->SwathHeightC[k]) || (!dml_is_vertical_rotation(p->display_cfg->plane_descriptors[k].composition.rotation_angle) && p->BlockHeight256BytesC[k] > p->SwathHeightC[k]) || p->DCCCMaxUncompressedBlock[k] < 256) { - l->MaximumEffectiveCompressionChroma = 2; - } else { - l->MaximumEffectiveCompressionChroma = 4; - } - l->TotalCompressedReadBandwidth = l->TotalCompressedReadBandwidth + p->ReadBandwidthSurfaceChroma[k] / math_min2(p->display_cfg->plane_descriptors[k].surface.dcc.informative.dcc_rate_plane1, l->MaximumEffectiveCompressionChroma); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, ReadBandwidthSurfaceChroma = %f\n", __func__, k, p->ReadBandwidthSurfaceChroma[k]); - dml2_printf("DML::%s: k=%u, NetDCCRateChroma = %f\n", __func__, k, p->display_cfg->plane_descriptors[k].surface.dcc.informative.dcc_rate_plane1); - dml2_printf("DML::%s: k=%u, MaximumEffectiveCompressionChroma = %f\n", __func__, k, l->MaximumEffectiveCompressionChroma); -#endif - l->TotalZeroSizeRequestReadBandwidth = l->TotalZeroSizeRequestReadBandwidth + p->ReadBandwidthSurfaceChroma[k] * p->display_cfg->plane_descriptors[k].surface.dcc.informative.fraction_of_zero_size_request_plane1; - l->TotalZeroSizeCompressedReadBandwidth = l->TotalZeroSizeCompressedReadBandwidth + p->ReadBandwidthSurfaceChroma[k] * p->display_cfg->plane_descriptors[k].surface.dcc.informative.fraction_of_zero_size_request_plane1 / l->MaximumEffectiveCompressionChroma; - } - } else { - l->TotalCompressedReadBandwidth = l->TotalCompressedReadBandwidth + p->ReadBandwidthSurfaceLuma[k] + p->ReadBandwidthSurfaceChroma[k]; - } - l->TotalRowReadBandwidth = l->TotalRowReadBandwidth + p->DPPPerSurface[k] * (p->meta_row_bw[k] + p->dpte_row_bw[k]); - } - } - - l->AverageDCCCompressionRate = p->TotalDataReadBandwidth / l->TotalCompressedReadBandwidth; - l->AverageDCCZeroSizeFraction = l->TotalZeroSizeRequestReadBandwidth / p->TotalDataReadBandwidth; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: UnboundedRequestEnabled = %u\n", __func__, p->UnboundedRequestEnabled); - dml2_printf("DML::%s: TotalCompressedReadBandwidth = %f\n", __func__, l->TotalCompressedReadBandwidth); - dml2_printf("DML::%s: TotalZeroSizeRequestReadBandwidth = %f\n", __func__, l->TotalZeroSizeRequestReadBandwidth); - dml2_printf("DML::%s: TotalZeroSizeCompressedReadBandwidth = %f\n", __func__, l->TotalZeroSizeCompressedReadBandwidth); - dml2_printf("DML::%s: MaximumEffectiveCompressionLuma = %f\n", __func__, l->MaximumEffectiveCompressionLuma); - dml2_printf("DML::%s: MaximumEffectiveCompressionChroma = %f\n", __func__, l->MaximumEffectiveCompressionChroma); - dml2_printf("DML::%s: AverageDCCCompressionRate = %f\n", __func__, l->AverageDCCCompressionRate); - dml2_printf("DML::%s: AverageDCCZeroSizeFraction = %f\n", __func__, l->AverageDCCZeroSizeFraction); - - dml2_printf("DML::%s: CompbufReservedSpace64B = %u (%f kbytes)\n", __func__, p->CompbufReservedSpace64B, p->CompbufReservedSpace64B * 64 / 1024.0); - dml2_printf("DML::%s: CompbufReservedSpaceZs = %u\n", __func__, p->CompbufReservedSpaceZs); - dml2_printf("DML::%s: CompressedBufferSizeInkByte = %u kbytes\n", __func__, p->CompressedBufferSizeInkByte); - dml2_printf("DML::%s: ROBBufferSizeInKByte = %u kbytes\n", __func__, p->ROBBufferSizeInKByte); -#endif - if (l->AverageDCCZeroSizeFraction == 1) { - l->AverageZeroSizeCompressionRate = l->TotalZeroSizeRequestReadBandwidth / l->TotalZeroSizeCompressedReadBandwidth; - l->EffectiveCompressedBufferSize = (double)p->MetaFIFOSizeInKEntries * 1024 * 64 * l->AverageZeroSizeCompressionRate + ((double)p->ZeroSizeBufferEntries - p->CompbufReservedSpaceZs) * 64 * l->AverageZeroSizeCompressionRate; - - - } else if (l->AverageDCCZeroSizeFraction > 0) { - l->AverageZeroSizeCompressionRate = l->TotalZeroSizeRequestReadBandwidth / l->TotalZeroSizeCompressedReadBandwidth; - l->EffectiveCompressedBufferSize = math_min2((double)p->CompressedBufferSizeInkByte * 1024 * l->AverageDCCCompressionRate, - (double)p->MetaFIFOSizeInKEntries * 1024 * 64 / (l->AverageDCCZeroSizeFraction / l->AverageZeroSizeCompressionRate + 1 / l->AverageDCCCompressionRate)) + - (p->rob_alloc_compressed ? math_min2(((double)p->ROBBufferSizeInKByte * 1024 - p->CompbufReservedSpace64B * 64) * l->AverageDCCCompressionRate, - ((double)p->ZeroSizeBufferEntries - p->CompbufReservedSpaceZs) * 64 / (l->AverageDCCZeroSizeFraction / l->AverageZeroSizeCompressionRate)) - : ((double)p->ROBBufferSizeInKByte * 1024 - p->CompbufReservedSpace64B * 64)); - - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: min 1 = %f\n", __func__, p->CompressedBufferSizeInkByte * 1024 * l->AverageDCCCompressionRate); - dml2_printf("DML::%s: min 2 = %f\n", __func__, p->MetaFIFOSizeInKEntries * 1024 * 64 / (l->AverageDCCZeroSizeFraction / l->AverageZeroSizeCompressionRate + 1 / l->AverageDCCCompressionRate)); - dml2_printf("DML::%s: min 3 = %d\n", __func__, (p->ROBBufferSizeInKByte * 1024 - p->CompbufReservedSpace64B * 64)); - dml2_printf("DML::%s: min 4 = %f\n", __func__, (p->ZeroSizeBufferEntries - p->CompbufReservedSpaceZs) * 64 / (l->AverageDCCZeroSizeFraction / l->AverageZeroSizeCompressionRate)); -#endif - } else { - l->EffectiveCompressedBufferSize = math_min2((double)p->CompressedBufferSizeInkByte * 1024 * l->AverageDCCCompressionRate, - (double)p->MetaFIFOSizeInKEntries * 1024 * 64 * l->AverageDCCCompressionRate) + - ((double)p->ROBBufferSizeInKByte * 1024 - p->CompbufReservedSpace64B * 64) * (p->rob_alloc_compressed ? l->AverageDCCCompressionRate : 1.0); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: min 1 = %f\n", __func__, p->CompressedBufferSizeInkByte * 1024 * l->AverageDCCCompressionRate); - dml2_printf("DML::%s: min 2 = %f\n", __func__, p->MetaFIFOSizeInKEntries * 1024 * 64 * l->AverageDCCCompressionRate); -#endif - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: MetaFIFOSizeInKEntries = %u\n", __func__, p->MetaFIFOSizeInKEntries); - dml2_printf("DML::%s: AverageZeroSizeCompressionRate = %f\n", __func__, l->AverageZeroSizeCompressionRate); - dml2_printf("DML::%s: EffectiveCompressedBufferSize = %f (%f kbytes)\n", __func__, l->EffectiveCompressedBufferSize, l->EffectiveCompressedBufferSize / 1024.0); -#endif - - bool FoundCriticalSurface = false; - *p->StutterPeriod = 0; - - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - if (!dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k])) { - l->LinesInDETY = ((double)p->DETBufferSizeY[k] + (p->UnboundedRequestEnabled == true ? l->EffectiveCompressedBufferSize : 0) * p->ReadBandwidthSurfaceLuma[k] / p->TotalDataReadBandwidth) / p->BytePerPixelDETY[k] / p->SwathWidthY[k]; - l->LinesInDETYRoundedDownToSwath = math_floor2(l->LinesInDETY, p->SwathHeightY[k]); - l->DETBufferingTimeY = l->LinesInDETYRoundedDownToSwath * ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000)) / p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio; -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, DETBufferSizeY = %u (%u kbytes)\n", __func__, k, p->DETBufferSizeY[k], p->DETBufferSizeY[k] / 1024); - dml2_printf("DML::%s: k=%u, BytePerPixelDETY = %f\n", __func__, k, p->BytePerPixelDETY[k]); - dml2_printf("DML::%s: k=%u, SwathWidthY = %u\n", __func__, k, p->SwathWidthY[k]); - dml2_printf("DML::%s: k=%u, ReadBandwidthSurfaceLuma = %f\n", __func__, k, p->ReadBandwidthSurfaceLuma[k]); - dml2_printf("DML::%s: k=%u, TotalDataReadBandwidth = %f\n", __func__, k, p->TotalDataReadBandwidth); - dml2_printf("DML::%s: k=%u, LinesInDETY = %f\n", __func__, k, l->LinesInDETY); - dml2_printf("DML::%s: k=%u, LinesInDETYRoundedDownToSwath = %f\n", __func__, k, l->LinesInDETYRoundedDownToSwath); - dml2_printf("DML::%s: k=%u, VRatio = %f\n", __func__, k, p->display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio); - dml2_printf("DML::%s: k=%u, DETBufferingTimeY = %f\n", __func__, k, l->DETBufferingTimeY); -#endif - - if (!FoundCriticalSurface || l->DETBufferingTimeY < *p->StutterPeriod) { - bool isInterlaceTiming = p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.interlaced && !p->ProgressiveToInterlaceUnitInOPP; - - FoundCriticalSurface = true; - *p->StutterPeriod = l->DETBufferingTimeY; - l->FrameTimeCriticalSurface = (isInterlaceTiming ? math_floor2((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.v_total / 2.0, 1.0) : p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.v_total) * (double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000); - l->VActiveTimeCriticalSurface = (isInterlaceTiming ? math_floor2((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.v_active / 2.0, 1.0) : p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.v_active) * (double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000); - l->BytePerPixelYCriticalSurface = p->BytePerPixelY[k]; - l->SwathWidthYCriticalSurface = p->SwathWidthY[k]; - l->SwathHeightYCriticalSurface = p->SwathHeightY[k]; - l->BlockWidth256BytesYCriticalSurface = p->BlockWidth256BytesY[k]; - l->DETBufferSizeYCriticalSurface = p->DETBufferSizeY[k]; - l->MinTTUVBlankCriticalSurface = p->MinTTUVBlank[k]; - l->SinglePlaneCriticalSurface = (p->ReadBandwidthSurfaceChroma[k] == 0); - l->SinglePipeCriticalSurface = (p->DPPPerSurface[k] == 1); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, FoundCriticalSurface = %u\n", __func__, k, FoundCriticalSurface); - dml2_printf("DML::%s: k=%u, StutterPeriod = %f\n", __func__, k, *p->StutterPeriod); - dml2_printf("DML::%s: k=%u, MinTTUVBlankCriticalSurface = %f\n", __func__, k, l->MinTTUVBlankCriticalSurface); - dml2_printf("DML::%s: k=%u, FrameTimeCriticalSurface= %f\n", __func__, k, l->FrameTimeCriticalSurface); - dml2_printf("DML::%s: k=%u, VActiveTimeCriticalSurface = %f\n", __func__, k, l->VActiveTimeCriticalSurface); - dml2_printf("DML::%s: k=%u, BytePerPixelYCriticalSurface = %u\n", __func__, k, l->BytePerPixelYCriticalSurface); - dml2_printf("DML::%s: k=%u, SwathWidthYCriticalSurface = %f\n", __func__, k, l->SwathWidthYCriticalSurface); - dml2_printf("DML::%s: k=%u, SwathHeightYCriticalSurface = %f\n", __func__, k, l->SwathHeightYCriticalSurface); - dml2_printf("DML::%s: k=%u, BlockWidth256BytesYCriticalSurface = %u\n", __func__, k, l->BlockWidth256BytesYCriticalSurface); - dml2_printf("DML::%s: k=%u, SinglePlaneCriticalSurface = %u\n", __func__, k, l->SinglePlaneCriticalSurface); - dml2_printf("DML::%s: k=%u, SinglePipeCriticalSurface = %u\n", __func__, k, l->SinglePipeCriticalSurface); -#endif - } - } - } - - // for bounded req, the stutter period is calculated only based on DET size, but during burst there can be some return inside ROB/compressed buffer - // stutter period is calculated only on the det sizing - // if (cdb + rob >= det) the stutter burst will be absorbed by the cdb + rob which is before decompress - // else - // the cdb + rob part will be in compressed rate with urg bw (idea bw) - // the det part will be return at uncompressed rate with 64B/dcfclk - // - // for unbounded req, the stutter period should be calculated as total of CDB+ROB+DET, so the term "PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer" - // should be == EffectiveCompressedBufferSize which will returned a compressed rate, the rest of stutter period is from the DET will be returned at uncompressed rate with 64B/dcfclk - - l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer = math_min2(*p->StutterPeriod * p->TotalDataReadBandwidth, l->EffectiveCompressedBufferSize); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: AverageDCCCompressionRate = %f\n", __func__, l->AverageDCCCompressionRate); - dml2_printf("DML::%s: StutterPeriod*TotalDataReadBandwidth = %f (%f kbytes)\n", __func__, *p->StutterPeriod * p->TotalDataReadBandwidth, (*p->StutterPeriod * p->TotalDataReadBandwidth) / 1024.0); - dml2_printf("DML::%s: EffectiveCompressedBufferSize = %f (%f kbytes)\n", __func__, l->EffectiveCompressedBufferSize, l->EffectiveCompressedBufferSize / 1024.0); - dml2_printf("DML::%s: PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer = %f (%f kbytes)\n", __func__, l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer, l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer / 1024); - dml2_printf("DML::%s: ReturnBW = %f\n", __func__, p->ReturnBW); - dml2_printf("DML::%s: TotalDataReadBandwidth = %f\n", __func__, p->TotalDataReadBandwidth); - dml2_printf("DML::%s: TotalRowReadBandwidth = %f\n", __func__, l->TotalRowReadBandwidth); - dml2_printf("DML::%s: DCFCLK = %f\n", __func__, p->DCFCLK); -#endif - - 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)) + - *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)); - dml2_printf("DML::%s: Part 2 = %f\n", __func__, (*p->StutterPeriod * p->TotalDataReadBandwidth - l->PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer) / (p->DCFCLK * 64)); - dml2_printf("DML::%s: Part 3 = %f\n", __func__, *p->StutterPeriod * l->TotalRowReadBandwidth / p->ReturnBW); - dml2_printf("DML::%s: StutterBurstTime = %f\n", __func__, l->StutterBurstTime); -#endif - - l->TotalActiveWriteback = 0; - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - if (p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.enable) { - l->TotalActiveWriteback = l->TotalActiveWriteback + 1; - } - } - - if (l->TotalActiveWriteback == 0) { -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: SRExitTime = %f\n", __func__, p->SRExitTime); - dml2_printf("DML::%s: SRExitZ8Time = %f\n", __func__, p->SRExitZ8Time); - dml2_printf("DML::%s: StutterPeriod = %f\n", __func__, *p->StutterPeriod); -#endif - *p->StutterEfficiencyNotIncludingVBlank = math_max2(0., 1 - (p->SRExitTime + l->StutterBurstTime) / *p->StutterPeriod) * 100; - *p->Z8StutterEfficiencyNotIncludingVBlank = math_max2(0., 1 - (p->SRExitZ8Time + l->StutterBurstTime) / *p->StutterPeriod) * 100; - *p->NumberOfStutterBurstsPerFrame = (*p->StutterEfficiencyNotIncludingVBlank > 0 ? (unsigned int)(math_ceil2(l->VActiveTimeCriticalSurface / *p->StutterPeriod, 1)) : 0); - *p->Z8NumberOfStutterBurstsPerFrame = (*p->Z8StutterEfficiencyNotIncludingVBlank > 0 ? (unsigned int)(math_ceil2(l->VActiveTimeCriticalSurface / *p->StutterPeriod, 1)) : 0); - } else { - *p->StutterEfficiencyNotIncludingVBlank = 0.; - *p->Z8StutterEfficiencyNotIncludingVBlank = 0.; - *p->NumberOfStutterBurstsPerFrame = 0; - *p->Z8NumberOfStutterBurstsPerFrame = 0; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: VActiveTimeCriticalSurface = %f\n", __func__, l->VActiveTimeCriticalSurface); - dml2_printf("DML::%s: StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *p->StutterEfficiencyNotIncludingVBlank); - dml2_printf("DML::%s: Z8StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *p->Z8StutterEfficiencyNotIncludingVBlank); - dml2_printf("DML::%s: NumberOfStutterBurstsPerFrame = %u\n", __func__, *p->NumberOfStutterBurstsPerFrame); - dml2_printf("DML::%s: Z8NumberOfStutterBurstsPerFrame = %u\n", __func__, *p->Z8NumberOfStutterBurstsPerFrame); -#endif - - unsigned int TotalNumberOfActiveOTG = 0; - double SinglePixelClock = 0; - unsigned int SingleHTotal = 0; - unsigned int SingleVTotal = 0; - bool SameTiming = true; - for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { - if (!dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k])) { - if (p->display_cfg->plane_descriptors[k].stream_index == k) { - if (TotalNumberOfActiveOTG == 0) { - SinglePixelClock = ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000); - SingleHTotal = p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total; - SingleVTotal = p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.v_total; - } else if (SinglePixelClock != ((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) || SingleHTotal != p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total || SingleVTotal != p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.v_total) { - SameTiming = false; - } - TotalNumberOfActiveOTG = TotalNumberOfActiveOTG + 1; - } - } - } - - if (*p->StutterEfficiencyNotIncludingVBlank > 0) { - if (!((p->SynchronizeTimings || TotalNumberOfActiveOTG == 1) && SameTiming)) { - *p->StutterEfficiency = *p->StutterEfficiencyNotIncludingVBlank; - } else { - *p->StutterEfficiency = (1 - (*p->NumberOfStutterBurstsPerFrame * p->SRExitTime + l->StutterBurstTime * l->VActiveTimeCriticalSurface / *p->StutterPeriod) / l->FrameTimeCriticalSurface) * 100; - } - } else { - *p->StutterEfficiency = 0; - *p->NumberOfStutterBurstsPerFrame = 0; - } - - double LastZ8StutterPeriod = 0.0; - - if (*p->Z8StutterEfficiencyNotIncludingVBlank > 0) { - LastZ8StutterPeriod = l->VActiveTimeCriticalSurface - (*p->Z8NumberOfStutterBurstsPerFrame - 1) * *p->StutterPeriod; - if (!((p->SynchronizeTimings || TotalNumberOfActiveOTG == 1) && SameTiming)) { - *p->Z8StutterEfficiency = *p->Z8StutterEfficiencyNotIncludingVBlank; - } else { - *p->Z8StutterEfficiency = (1 - (*p->Z8NumberOfStutterBurstsPerFrame * p->SRExitZ8Time + l->StutterBurstTime * l->VActiveTimeCriticalSurface / *p->StutterPeriod) / l->FrameTimeCriticalSurface) * 100; - } - } else { - *p->Z8StutterEfficiency = 0.; - *p->Z8NumberOfStutterBurstsPerFrame = 0; - } - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: LastZ8StutterPeriod = %f\n", __func__, LastZ8StutterPeriod); - dml2_printf("DML::%s: Z8StutterEnterPlusExitWatermark = %f\n", __func__, p->Z8StutterEnterPlusExitWatermark); - dml2_printf("DML::%s: StutterBurstTime = %f\n", __func__, l->StutterBurstTime); - dml2_printf("DML::%s: StutterPeriod = %f\n", __func__, *p->StutterPeriod); - dml2_printf("DML::%s: StutterEfficiency = %f\n", __func__, *p->StutterEfficiency); - dml2_printf("DML::%s: Z8StutterEfficiency = %f\n", __func__, *p->Z8StutterEfficiency); - dml2_printf("DML::%s: StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *p->StutterEfficiencyNotIncludingVBlank); - dml2_printf("DML::%s: Z8NumberOfStutterBurstsPerFrame = %u\n", __func__, *p->Z8NumberOfStutterBurstsPerFrame); -#endif - - - unsigned int SwathSizeCriticalSurface; - unsigned int LastChunkOfSwathSize; - unsigned int MissingPartOfLastSwathOfDETSize; - - 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)); - -#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 -} - -bool dml2_core_shared_mode_programming(struct dml2_core_calcs_mode_programming_ex *in_out_params) -{ - const struct dml2_display_cfg *display_cfg = in_out_params->in_display_cfg; - const struct dml2_mcg_min_clock_table *min_clk_table = in_out_params->min_clk_table; - const struct core_display_cfg_support_info *cfg_support_info = in_out_params->cfg_support_info; - struct dml2_core_internal_display_mode_lib *mode_lib = in_out_params->mode_lib; - struct dml2_display_cfg_programming *programming = in_out_params->programming; - - struct dml2_core_calcs_mode_programming_locals *s = &mode_lib->scratch.dml_core_mode_programming_locals; - struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params *CalculateWatermarks_params = &mode_lib->scratch.CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params; - struct dml2_core_calcs_CalculateVMRowAndSwath_params *CalculateVMRowAndSwath_params = &mode_lib->scratch.CalculateVMRowAndSwath_params; - struct dml2_core_calcs_CalculateSwathAndDETConfiguration_params *CalculateSwathAndDETConfiguration_params = &mode_lib->scratch.CalculateSwathAndDETConfiguration_params; - struct dml2_core_calcs_CalculateStutterEfficiency_params *CalculateStutterEfficiency_params = &mode_lib->scratch.CalculateStutterEfficiency_params; - struct dml2_core_calcs_CalculatePrefetchSchedule_params *CalculatePrefetchSchedule_params = &mode_lib->scratch.CalculatePrefetchSchedule_params; - struct dml2_core_calcs_calculate_mcache_setting_params *calculate_mcache_setting_params = &mode_lib->scratch.calculate_mcache_setting_params; - struct dml2_core_calcs_calculate_tdlut_setting_params *calculate_tdlut_setting_params = &mode_lib->scratch.calculate_tdlut_setting_params; - struct dml2_core_shared_CalculateMetaAndPTETimes_params *CalculateMetaAndPTETimes_params = &mode_lib->scratch.CalculateMetaAndPTETimes_params; - - unsigned int j, k; - - dml2_printf("DML::%s: --- START --- \n", __func__); - - memset(&mode_lib->mp, 0, sizeof(struct dml2_core_internal_mode_program)); - - s->num_active_planes = display_cfg->num_planes; - get_stream_output_bpp(s->OutputBpp, display_cfg); - - 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.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; - dml2_assert(cfg_support_info->stream_support_info[stream_index].odms_used <= 4); - dml2_assert(cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 4 || - cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 2 || - cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 1); - - if (cfg_support_info->stream_support_info[stream_index].odms_used > 1) - dml2_assert(cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 1); - - switch (cfg_support_info->stream_support_info[stream_index].odms_used) { - case (4): - mode_lib->mp.ODMMode[k] = dml2_odm_mode_combine_4to1; - break; - case (3): - mode_lib->mp.ODMMode[k] = dml2_odm_mode_combine_3to1; - break; - case (2): - mode_lib->mp.ODMMode[k] = dml2_odm_mode_combine_2to1; - break; - default: - if (cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 4) - mode_lib->mp.ODMMode[k] = dml2_odm_mode_mso_1to4; - else if (cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 2) - mode_lib->mp.ODMMode[k] = dml2_odm_mode_mso_1to2; - else - mode_lib->mp.ODMMode[k] = dml2_odm_mode_bypass; - break; - } - } - - 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.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.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.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); - dml2_assert(mode_lib->mp.dram_bw_mbps > 0); - dml2_assert(mode_lib->mp.uclk_freq_mhz > 0); - dml2_assert(mode_lib->mp.GlobalDPPCLK > 0); - dml2_assert(mode_lib->mp.Dispclk > 0); - dml2_assert(mode_lib->mp.DCFCLKDeepSleep > 0); - dml2_assert(s->SOCCLK > 0); - -#ifdef __DML_VBA_DEBUG__ - // dml2_printf_dml_display_cfg_timing(&display_cfg->timing, s->num_active_planes); - // dml2_printf_dml_display_cfg_plane(&display_cfg->plane, s->num_active_planes); - // dml2_printf_dml_display_cfg_surface(&display_cfg->surface, s->num_active_planes); - // dml2_printf_dml_display_cfg_output(&display_cfg->output, s->num_active_planes); - // dml2_printf_dml_display_cfg_hw_resource(&display_cfg->hw, s->num_active_planes); - - dml2_printf("DML::%s: num_active_planes = %u\n", __func__, s->num_active_planes); - dml2_printf("DML::%s: num_active_pipes = %u\n", __func__, mode_lib->mp.num_active_pipes); - dml2_printf("DML::%s: Dcfclk = %f\n", __func__, mode_lib->mp.Dcfclk); - dml2_printf("DML::%s: FabricClock = %f\n", __func__, mode_lib->mp.FabricClock); - dml2_printf("DML::%s: dram_bw_mbps = %f\n", __func__, mode_lib->mp.dram_bw_mbps); - dml2_printf("DML::%s: uclk_freq_mhz = %f\n", __func__, mode_lib->mp.uclk_freq_mhz); - dml2_printf("DML::%s: Dispclk = %f\n", __func__, mode_lib->mp.Dispclk); - for (k = 0; k < s->num_active_planes; ++k) { - dml2_printf("DML::%s: Dppclk[%0d] = %f\n", __func__, k, mode_lib->mp.Dppclk[k]); - } - dml2_printf("DML::%s: GlobalDPPCLK = %f\n", __func__, mode_lib->mp.GlobalDPPCLK); - dml2_printf("DML::%s: DCFCLKDeepSleep = %f\n", __func__, mode_lib->mp.DCFCLKDeepSleep); - dml2_printf("DML::%s: SOCCLK = %f\n", __func__, s->SOCCLK); - dml2_printf("DML::%s: min_clk_index = %0d\n", __func__, in_out_params->min_clk_index); - dml2_printf("DML::%s: min_clk_table min_fclk_khz = %d\n", __func__, min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].min_fclk_khz); - dml2_printf("DML::%s: min_clk_table uclk_mhz = %f\n", __func__, 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)); - for (k = 0; k < mode_lib->mp.num_active_pipes; ++k) { - dml2_printf("DML::%s: pipe=%d is in plane=%d\n", __func__, k, mode_lib->mp.pipe_plane[k]); - dml2_printf("DML::%s: Per-plane DPPPerSurface[%0d] = %d\n", __func__, k, mode_lib->mp.NoOfDPP[k]); - } - - for (k = 0; k < s->num_active_planes; k++) - dml2_printf("DML::%s: plane_%d: reserved_vblank_time_ns = %u\n", __func__, k, display_cfg->plane_descriptors[k].overrides.reserved_vblank_time_ns); -#endif - - CalculateMaxDETAndMinCompressedBufferSize( - mode_lib->ip.config_return_buffer_size_in_kbytes, - mode_lib->ip.config_return_buffer_segment_size_in_kbytes, - mode_lib->ip.rob_buffer_size_kbytes, - mode_lib->ip.max_num_dpp, - display_cfg->overrides.hw.force_nom_det_size_kbytes.enable, - display_cfg->overrides.hw.force_nom_det_size_kbytes.value, - mode_lib->ip.dcn_mrq_present, - - /* Output */ - &s->MaxTotalDETInKByte, - &s->NomDETInKByte, - &s->MinCompressedBufferSizeInKByte); - - - PixelClockAdjustmentForProgressiveToInterlaceUnit(display_cfg, mode_lib->ip.ptoi_supported, s->PixelClockBackEnd); - - for (k = 0; k < s->num_active_planes; ++k) { - CalculateSinglePipeDPPCLKAndSCLThroughput( - display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio, - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio, - display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio, - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio, - mode_lib->ip.max_dchub_pscl_bw_pix_per_clk, - mode_lib->ip.max_pscl_lb_bw_pix_per_clk, - ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000), - display_cfg->plane_descriptors[k].pixel_format, - display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_taps, - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps, - display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps, - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_taps, - - /* Output */ - &mode_lib->mp.PSCL_THROUGHPUT[k], - &mode_lib->mp.PSCL_THROUGHPUT_CHROMA[k], - &mode_lib->mp.DPPCLKUsingSingleDPP[k]); - } - - for (k = 0; k < s->num_active_planes; ++k) { - CalculateBytePerPixelAndBlockSizes( - display_cfg->plane_descriptors[k].pixel_format, - display_cfg->plane_descriptors[k].surface.tiling, - display_cfg->plane_descriptors[k].surface.plane0.pitch, - display_cfg->plane_descriptors[k].surface.plane1.pitch, - - // Output - &mode_lib->mp.BytePerPixelY[k], - &mode_lib->mp.BytePerPixelC[k], - &mode_lib->mp.BytePerPixelInDETY[k], - &mode_lib->mp.BytePerPixelInDETC[k], - &mode_lib->mp.Read256BlockHeightY[k], - &mode_lib->mp.Read256BlockHeightC[k], - &mode_lib->mp.Read256BlockWidthY[k], - &mode_lib->mp.Read256BlockWidthC[k], - &mode_lib->mp.MacroTileHeightY[k], - &mode_lib->mp.MacroTileHeightC[k], - &mode_lib->mp.MacroTileWidthY[k], - &mode_lib->mp.MacroTileWidthC[k], - &mode_lib->mp.surf_linear128_l[k], - &mode_lib->mp.surf_linear128_c[k]); - } - - CalculateSwathWidth( - display_cfg, - false, // ForceSingleDPP - s->num_active_planes, - mode_lib->mp.ODMMode, - mode_lib->mp.BytePerPixelY, - mode_lib->mp.BytePerPixelC, - mode_lib->mp.Read256BlockHeightY, - mode_lib->mp.Read256BlockHeightC, - mode_lib->mp.Read256BlockWidthY, - mode_lib->mp.Read256BlockWidthC, - mode_lib->mp.surf_linear128_l, - mode_lib->mp.surf_linear128_c, - mode_lib->mp.NoOfDPP, - - /* Output */ - mode_lib->mp.req_per_swath_ub_l, - mode_lib->mp.req_per_swath_ub_c, - mode_lib->mp.SwathWidthSingleDPPY, - mode_lib->mp.SwathWidthSingleDPPC, - mode_lib->mp.SwathWidthY, - mode_lib->mp.SwathWidthC, - s->dummy_integer_array[0], // unsigned int MaximumSwathHeightY[] - s->dummy_integer_array[1], // unsigned int MaximumSwathHeightC[] - mode_lib->mp.swath_width_luma_ub, - mode_lib->mp.swath_width_chroma_ub); - - for (k = 0; k < s->num_active_planes; ++k) { - mode_lib->mp.cursor_bw[k] = display_cfg->plane_descriptors[k].cursor.num_cursors * display_cfg->plane_descriptors[k].cursor.cursor_width * display_cfg->plane_descriptors[k].cursor.cursor_bpp / 8.0 / - ((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)); - mode_lib->mp.SurfaceReadBandwidthLuma[k] = mode_lib->mp.SwathWidthSingleDPPY[k] * mode_lib->mp.BytePerPixelY[k] / (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)) * display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio; - mode_lib->mp.SurfaceReadBandwidthChroma[k] = mode_lib->mp.SwathWidthSingleDPPC[k] * mode_lib->mp.BytePerPixelC[k] / (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)) * display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio; - dml2_printf("DML::%s: ReadBandwidthSurfaceLuma[%i] = %fBps\n", __func__, k, mode_lib->mp.SurfaceReadBandwidthLuma[k]); - dml2_printf("DML::%s: ReadBandwidthSurfaceChroma[%i] = %fBps\n", __func__, k, mode_lib->mp.SurfaceReadBandwidthChroma[k]); - } - - CalculateSwathAndDETConfiguration_params->display_cfg = display_cfg; - CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSizeInKByte = mode_lib->ip.config_return_buffer_size_in_kbytes; - CalculateSwathAndDETConfiguration_params->MaxTotalDETInKByte = s->MaxTotalDETInKByte; - CalculateSwathAndDETConfiguration_params->MinCompressedBufferSizeInKByte = s->MinCompressedBufferSizeInKByte; - CalculateSwathAndDETConfiguration_params->rob_buffer_size_kbytes = mode_lib->ip.rob_buffer_size_kbytes; - CalculateSwathAndDETConfiguration_params->pixel_chunk_size_kbytes = mode_lib->ip.pixel_chunk_size_kbytes; - CalculateSwathAndDETConfiguration_params->rob_buffer_size_kbytes = mode_lib->ip.rob_buffer_size_kbytes; - CalculateSwathAndDETConfiguration_params->pixel_chunk_size_kbytes = mode_lib->ip.pixel_chunk_size_kbytes; - - CalculateSwathAndDETConfiguration_params->ForceSingleDPP = false; - CalculateSwathAndDETConfiguration_params->NumberOfActiveSurfaces = s->num_active_planes; - CalculateSwathAndDETConfiguration_params->nomDETInKByte = s->NomDETInKByte; - CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSegmentSizeInkByte = mode_lib->ip.config_return_buffer_segment_size_in_kbytes; - CalculateSwathAndDETConfiguration_params->CompressedBufferSegmentSizeInkByte = mode_lib->ip.compressed_buffer_segment_size_in_kbytes; - CalculateSwathAndDETConfiguration_params->ReadBandwidthLuma = mode_lib->mp.SurfaceReadBandwidthLuma; - CalculateSwathAndDETConfiguration_params->ReadBandwidthChroma = mode_lib->mp.SurfaceReadBandwidthChroma; - CalculateSwathAndDETConfiguration_params->MaximumSwathWidthLuma = s->dummy_single_array[0]; - CalculateSwathAndDETConfiguration_params->MaximumSwathWidthChroma = s->dummy_single_array[1]; - CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightY = mode_lib->mp.Read256BlockHeightY; - CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightC = mode_lib->mp.Read256BlockHeightC; - CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthY = mode_lib->mp.Read256BlockWidthY; - CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthC = mode_lib->mp.Read256BlockWidthC; - CalculateSwathAndDETConfiguration_params->surf_linear128_l = mode_lib->mp.surf_linear128_l; - CalculateSwathAndDETConfiguration_params->surf_linear128_c = mode_lib->mp.surf_linear128_c; - CalculateSwathAndDETConfiguration_params->ODMMode = mode_lib->mp.ODMMode; - CalculateSwathAndDETConfiguration_params->DPPPerSurface = mode_lib->mp.NoOfDPP; - CalculateSwathAndDETConfiguration_params->BytePerPixY = mode_lib->mp.BytePerPixelY; - CalculateSwathAndDETConfiguration_params->BytePerPixC = mode_lib->mp.BytePerPixelC; - CalculateSwathAndDETConfiguration_params->BytePerPixDETY = mode_lib->mp.BytePerPixelInDETY; - CalculateSwathAndDETConfiguration_params->BytePerPixDETC = mode_lib->mp.BytePerPixelInDETC; - - // output - CalculateSwathAndDETConfiguration_params->req_per_swath_ub_l = mode_lib->mp.req_per_swath_ub_l; - CalculateSwathAndDETConfiguration_params->req_per_swath_ub_c = mode_lib->mp.req_per_swath_ub_c; - CalculateSwathAndDETConfiguration_params->swath_width_luma_ub = s->dummy_long_array[0]; - CalculateSwathAndDETConfiguration_params->swath_width_chroma_ub = s->dummy_long_array[1]; - CalculateSwathAndDETConfiguration_params->SwathWidth = s->dummy_long_array[2]; - CalculateSwathAndDETConfiguration_params->SwathWidthChroma = s->dummy_long_array[3]; - CalculateSwathAndDETConfiguration_params->SwathHeightY = mode_lib->mp.SwathHeightY; - CalculateSwathAndDETConfiguration_params->SwathHeightC = mode_lib->mp.SwathHeightC; - CalculateSwathAndDETConfiguration_params->request_size_bytes_luma = mode_lib->mp.request_size_bytes_luma; - CalculateSwathAndDETConfiguration_params->request_size_bytes_chroma = mode_lib->mp.request_size_bytes_chroma; - CalculateSwathAndDETConfiguration_params->DETBufferSizeInKByte = mode_lib->mp.DETBufferSizeInKByte; - CalculateSwathAndDETConfiguration_params->DETBufferSizeY = mode_lib->mp.DETBufferSizeY; - CalculateSwathAndDETConfiguration_params->DETBufferSizeC = mode_lib->mp.DETBufferSizeC; - CalculateSwathAndDETConfiguration_params->full_swath_bytes_l = s->full_swath_bytes_l; - CalculateSwathAndDETConfiguration_params->full_swath_bytes_c = s->full_swath_bytes_c; - CalculateSwathAndDETConfiguration_params->UnboundedRequestEnabled = &mode_lib->mp.UnboundedRequestEnabled; - CalculateSwathAndDETConfiguration_params->compbuf_reserved_space_64b = &mode_lib->mp.compbuf_reserved_space_64b; - CalculateSwathAndDETConfiguration_params->hw_debug5 = &mode_lib->mp.hw_debug5; - CalculateSwathAndDETConfiguration_params->CompressedBufferSizeInkByte = &mode_lib->mp.CompressedBufferSizeInkByte; - CalculateSwathAndDETConfiguration_params->ViewportSizeSupportPerSurface = &s->dummy_boolean_array[0][0]; - CalculateSwathAndDETConfiguration_params->ViewportSizeSupport = &s->dummy_boolean[0]; - CalculateSwathAndDETConfiguration_params->funcs = &mode_lib->funcs; - - // VBA_DELTA - // Calculate DET size, swath height here. In VBA, they are calculated in mode check stage - CalculateSwathAndDETConfiguration(&mode_lib->scratch, CalculateSwathAndDETConfiguration_params); - - // DSCCLK - /* - s->DSCFormatFactor = 0; - for (k = 0; k < s->num_active_planes; ++k) { - if ((display_cfg->plane_descriptors[k].stream_index != k) || !cfg_support_info->stream_support_info[display_cfg->plane_descriptors[k].stream_index].dsc_enable) { - } else { - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format == dml2_420) - s->DSCFormatFactor = 2; - else if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format == dml2_444) - s->DSCFormatFactor = 1; - else if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format == dml2_n422 || - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder == dml2_hdmifrl) - s->DSCFormatFactor = 2; - else - s->DSCFormatFactor = 1; - - s->PixelClockBackEndFactor = 3.0; - - if (mode_lib->mp.ODMMode[k] == dml2_odm_mode_combine_4to1) - s->PixelClockBackEndFactor = 12.0; - else if (mode_lib->mp.ODMMode[k] == dml2_odm_mode_combine_3to1) - s->PixelClockBackEndFactor = 9.0; - else if (mode_lib->mp.ODMMode[k] == dml2_odm_mode_combine_2to1) - s->PixelClockBackEndFactor = 6.0; - - } - #ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, DSCEnabled = %u\n", __func__, k, cfg_support_info->stream_support_info[display_cfg->plane_descriptors[k].stream_index].dsc_enable); - dml2_printf("DML::%s: k=%u, BlendingAndTiming = %u\n", __func__, k, display_cfg->plane_descriptors[k].stream_index); - dml2_printf("DML::%s: k=%u, PixelClockBackEndFactor = %f\n", __func__, k, s->PixelClockBackEndFactor); - dml2_printf("DML::%s: k=%u, PixelClockBackEnd = %f\n", __func__, k, s->PixelClockBackEnd[k]); - dml2_printf("DML::%s: k=%u, DSCFormatFactor = %u\n", __func__, k, s->DSCFormatFactor); - dml2_printf("DML::%s: k=%u, DSCCLK = %f\n", __func__, k, mode_lib->mp.DSCCLK[k]); - #endif - } - */ - - // DSC Delay - for (k = 0; k < s->num_active_planes; ++k) { - mode_lib->mp.DSCDelay[k] = DSCDelayRequirement(cfg_support_info->stream_support_info[display_cfg->plane_descriptors[k].stream_index].dsc_enable, - mode_lib->mp.ODMMode[k], - mode_lib->ip.maximum_dsc_bits_per_component, - 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, - cfg_support_info->stream_support_info[display_cfg->plane_descriptors[k].stream_index].num_dsc_slices, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder, - ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000), - s->PixelClockBackEnd[k]); - } - - for (k = 0; k < s->num_active_planes; ++k) - for (j = 0; j < s->num_active_planes; ++j) // NumberOfSurfaces - if (j != k && display_cfg->plane_descriptors[k].stream_index == j && cfg_support_info->stream_support_info[display_cfg->plane_descriptors[j].stream_index].dsc_enable) - mode_lib->mp.DSCDelay[k] = mode_lib->mp.DSCDelay[j]; - - // Prefetch - if (mode_lib->soc.mall_allocated_for_dcn_mbytes == 0) { - for (k = 0; k < s->num_active_planes; ++k) - mode_lib->mp.SurfaceSizeInTheMALL[k] = 0; - } else { - CalculateSurfaceSizeInMall( - display_cfg, - s->num_active_planes, - mode_lib->soc.mall_allocated_for_dcn_mbytes, - mode_lib->mp.BytePerPixelY, - mode_lib->mp.BytePerPixelC, - mode_lib->mp.Read256BlockWidthY, - mode_lib->mp.Read256BlockWidthC, - mode_lib->mp.Read256BlockHeightY, - mode_lib->mp.Read256BlockHeightC, - mode_lib->mp.MacroTileWidthY, - mode_lib->mp.MacroTileWidthC, - mode_lib->mp.MacroTileHeightY, - mode_lib->mp.MacroTileHeightC, - - /* Output */ - mode_lib->mp.SurfaceSizeInTheMALL, - &s->dummy_boolean[0]); /* bool *ExceededMALLSize */ - } - - for (k = 0; k < s->num_active_planes; ++k) { - s->SurfaceParameters[k].PixelClock = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000); - s->SurfaceParameters[k].DPPPerSurface = mode_lib->mp.NoOfDPP[k]; - s->SurfaceParameters[k].RotationAngle = display_cfg->plane_descriptors[k].composition.rotation_angle; - s->SurfaceParameters[k].ViewportHeight = display_cfg->plane_descriptors[k].composition.viewport.plane0.height; - s->SurfaceParameters[k].ViewportHeightC = display_cfg->plane_descriptors[k].composition.viewport.plane1.height; - s->SurfaceParameters[k].BlockWidth256BytesY = mode_lib->mp.Read256BlockWidthY[k]; - s->SurfaceParameters[k].BlockHeight256BytesY = mode_lib->mp.Read256BlockHeightY[k]; - s->SurfaceParameters[k].BlockWidth256BytesC = mode_lib->mp.Read256BlockWidthC[k]; - s->SurfaceParameters[k].BlockHeight256BytesC = mode_lib->mp.Read256BlockHeightC[k]; - s->SurfaceParameters[k].BlockWidthY = mode_lib->mp.MacroTileWidthY[k]; - s->SurfaceParameters[k].BlockHeightY = mode_lib->mp.MacroTileHeightY[k]; - s->SurfaceParameters[k].BlockWidthC = mode_lib->mp.MacroTileWidthC[k]; - s->SurfaceParameters[k].BlockHeightC = mode_lib->mp.MacroTileHeightC[k]; - s->SurfaceParameters[k].InterlaceEnable = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced; - s->SurfaceParameters[k].HTotal = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total; - s->SurfaceParameters[k].DCCEnable = display_cfg->plane_descriptors[k].surface.dcc.enable; - s->SurfaceParameters[k].SourcePixelFormat = display_cfg->plane_descriptors[k].pixel_format; - s->SurfaceParameters[k].SurfaceTiling = display_cfg->plane_descriptors[k].surface.tiling; - s->SurfaceParameters[k].BytePerPixelY = mode_lib->mp.BytePerPixelY[k]; - s->SurfaceParameters[k].BytePerPixelC = mode_lib->mp.BytePerPixelC[k]; - s->SurfaceParameters[k].ProgressiveToInterlaceUnitInOPP = mode_lib->ip.ptoi_supported; - s->SurfaceParameters[k].VRatio = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio; - s->SurfaceParameters[k].VRatioChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio; - s->SurfaceParameters[k].VTaps = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps; - s->SurfaceParameters[k].VTapsChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps; - s->SurfaceParameters[k].PitchY = display_cfg->plane_descriptors[k].surface.plane0.pitch; - s->SurfaceParameters[k].PitchC = display_cfg->plane_descriptors[k].surface.plane1.pitch; - s->SurfaceParameters[k].ViewportStationary = display_cfg->plane_descriptors[k].composition.viewport.stationary; - s->SurfaceParameters[k].ViewportXStart = display_cfg->plane_descriptors[k].composition.viewport.plane0.x_start; - s->SurfaceParameters[k].ViewportYStart = display_cfg->plane_descriptors[k].composition.viewport.plane0.y_start; - s->SurfaceParameters[k].ViewportXStartC = display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start; - s->SurfaceParameters[k].ViewportYStartC = display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start; - s->SurfaceParameters[k].FORCE_ONE_ROW_FOR_FRAME = display_cfg->plane_descriptors[k].overrides.hw.force_one_row_for_frame; - s->SurfaceParameters[k].SwathHeightY = mode_lib->mp.SwathHeightY[k]; - s->SurfaceParameters[k].SwathHeightC = mode_lib->mp.SwathHeightC[k]; - s->SurfaceParameters[k].DCCMetaPitchY = display_cfg->plane_descriptors[k].surface.dcc.plane0.pitch; - s->SurfaceParameters[k].DCCMetaPitchC = display_cfg->plane_descriptors[k].surface.dcc.plane1.pitch; - } - - CalculateVMRowAndSwath_params->display_cfg = display_cfg; - CalculateVMRowAndSwath_params->NumberOfActiveSurfaces = s->num_active_planes; - CalculateVMRowAndSwath_params->myPipe = s->SurfaceParameters; - CalculateVMRowAndSwath_params->SurfaceSizeInMALL = mode_lib->mp.SurfaceSizeInTheMALL; - CalculateVMRowAndSwath_params->PTEBufferSizeInRequestsLuma = mode_lib->ip.dpte_buffer_size_in_pte_reqs_luma; - CalculateVMRowAndSwath_params->PTEBufferSizeInRequestsChroma = mode_lib->ip.dpte_buffer_size_in_pte_reqs_chroma; - CalculateVMRowAndSwath_params->MALLAllocatedForDCN = mode_lib->soc.mall_allocated_for_dcn_mbytes; - CalculateVMRowAndSwath_params->SwathWidthY = mode_lib->mp.SwathWidthY; - CalculateVMRowAndSwath_params->SwathWidthC = mode_lib->mp.SwathWidthC; - CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->soc.hostvm_min_page_size_kbytes; - CalculateVMRowAndSwath_params->DCCMetaBufferSizeBytes = mode_lib->ip.dcc_meta_buffer_size_bytes; - CalculateVMRowAndSwath_params->mrq_present = mode_lib->ip.dcn_mrq_present; - - // output - CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = s->dummy_boolean_array[0]; - CalculateVMRowAndSwath_params->dpte_row_width_luma_ub = mode_lib->mp.dpte_row_width_luma_ub; - CalculateVMRowAndSwath_params->dpte_row_width_chroma_ub = mode_lib->mp.dpte_row_width_chroma_ub; - CalculateVMRowAndSwath_params->dpte_row_height_luma = mode_lib->mp.dpte_row_height; - CalculateVMRowAndSwath_params->dpte_row_height_chroma = mode_lib->mp.dpte_row_height_chroma; - CalculateVMRowAndSwath_params->dpte_row_height_linear_luma = mode_lib->mp.dpte_row_height_linear; - CalculateVMRowAndSwath_params->dpte_row_height_linear_chroma = mode_lib->mp.dpte_row_height_linear_chroma; - CalculateVMRowAndSwath_params->vm_group_bytes = mode_lib->mp.vm_group_bytes; - CalculateVMRowAndSwath_params->dpte_group_bytes = mode_lib->mp.dpte_group_bytes; - CalculateVMRowAndSwath_params->PixelPTEReqWidthY = mode_lib->mp.PixelPTEReqWidthY; - CalculateVMRowAndSwath_params->PixelPTEReqHeightY = mode_lib->mp.PixelPTEReqHeightY; - CalculateVMRowAndSwath_params->PTERequestSizeY = mode_lib->mp.PTERequestSizeY; - CalculateVMRowAndSwath_params->PixelPTEReqWidthC = mode_lib->mp.PixelPTEReqWidthC; - CalculateVMRowAndSwath_params->PixelPTEReqHeightC = mode_lib->mp.PixelPTEReqHeightC; - CalculateVMRowAndSwath_params->PTERequestSizeC = mode_lib->mp.PTERequestSizeC; - CalculateVMRowAndSwath_params->vmpg_width_y = s->vmpg_width_y; - CalculateVMRowAndSwath_params->vmpg_height_y = s->vmpg_height_y; - CalculateVMRowAndSwath_params->vmpg_width_c = s->vmpg_width_c; - CalculateVMRowAndSwath_params->vmpg_height_c = s->vmpg_height_c; - CalculateVMRowAndSwath_params->dpde0_bytes_per_frame_ub_l = mode_lib->mp.dpde0_bytes_per_frame_ub_l; - CalculateVMRowAndSwath_params->dpde0_bytes_per_frame_ub_c = mode_lib->mp.dpde0_bytes_per_frame_ub_c; - CalculateVMRowAndSwath_params->PrefetchSourceLinesY = mode_lib->mp.PrefetchSourceLinesY; - CalculateVMRowAndSwath_params->PrefetchSourceLinesC = mode_lib->mp.PrefetchSourceLinesC; - CalculateVMRowAndSwath_params->VInitPreFillY = mode_lib->mp.VInitPreFillY; - CalculateVMRowAndSwath_params->VInitPreFillC = mode_lib->mp.VInitPreFillC; - CalculateVMRowAndSwath_params->MaxNumSwathY = mode_lib->mp.MaxNumSwathY; - CalculateVMRowAndSwath_params->MaxNumSwathC = mode_lib->mp.MaxNumSwathC; - CalculateVMRowAndSwath_params->dpte_row_bw = mode_lib->mp.dpte_row_bw; - CalculateVMRowAndSwath_params->PixelPTEBytesPerRow = mode_lib->mp.PixelPTEBytesPerRow; - CalculateVMRowAndSwath_params->vm_bytes = mode_lib->mp.vm_bytes; - CalculateVMRowAndSwath_params->use_one_row_for_frame = mode_lib->mp.use_one_row_for_frame; - CalculateVMRowAndSwath_params->use_one_row_for_frame_flip = mode_lib->mp.use_one_row_for_frame_flip; - CalculateVMRowAndSwath_params->is_using_mall_for_ss = mode_lib->mp.is_using_mall_for_ss; - CalculateVMRowAndSwath_params->PTE_BUFFER_MODE = mode_lib->mp.PTE_BUFFER_MODE; - CalculateVMRowAndSwath_params->BIGK_FRAGMENT_SIZE = mode_lib->mp.BIGK_FRAGMENT_SIZE; - CalculateVMRowAndSwath_params->DCCMetaBufferSizeNotExceeded = s->dummy_boolean_array[1]; - CalculateVMRowAndSwath_params->meta_row_bw = mode_lib->mp.meta_row_bw; - CalculateVMRowAndSwath_params->meta_row_bytes = mode_lib->mp.meta_row_bytes; - CalculateVMRowAndSwath_params->meta_req_width_luma = mode_lib->mp.meta_req_width; - CalculateVMRowAndSwath_params->meta_req_height_luma = mode_lib->mp.meta_req_height; - CalculateVMRowAndSwath_params->meta_row_width_luma = mode_lib->mp.meta_row_width; - CalculateVMRowAndSwath_params->meta_row_height_luma = mode_lib->mp.meta_row_height; - CalculateVMRowAndSwath_params->meta_pte_bytes_per_frame_ub_l = mode_lib->mp.meta_pte_bytes_per_frame_ub_l; - CalculateVMRowAndSwath_params->meta_req_width_chroma = mode_lib->mp.meta_req_width_chroma; - CalculateVMRowAndSwath_params->meta_row_height_chroma = mode_lib->mp.meta_row_height_chroma; - CalculateVMRowAndSwath_params->meta_row_width_chroma = mode_lib->mp.meta_row_width_chroma; - CalculateVMRowAndSwath_params->meta_req_height_chroma = mode_lib->mp.meta_req_height_chroma; - CalculateVMRowAndSwath_params->meta_pte_bytes_per_frame_ub_c = mode_lib->mp.meta_pte_bytes_per_frame_ub_c; - - CalculateVMRowAndSwath(&mode_lib->scratch, CalculateVMRowAndSwath_params); - - memset(calculate_mcache_setting_params, 0, sizeof(struct dml2_core_calcs_calculate_mcache_setting_params)); - if (mode_lib->soc.mall_allocated_for_dcn_mbytes == 0 || mode_lib->ip.dcn_mrq_present) { - for (k = 0; k < s->num_active_planes; k++) { - mode_lib->mp.mall_prefetch_sdp_overhead_factor[k] = 1.0; - mode_lib->mp.mall_prefetch_dram_overhead_factor[k] = 1.0; - mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p0[k] = 1.0; - mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p0[k] = 1.0; - mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p1[k] = 1.0; - mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p1[k] = 1.0; - } - } else { - for (k = 0; k < s->num_active_planes; k++) { - calculate_mcache_setting_params->dcc_enable = display_cfg->plane_descriptors[k].surface.dcc.enable; - calculate_mcache_setting_params->num_chans = mode_lib->soc.clk_table.dram_config.channel_count; - calculate_mcache_setting_params->mem_word_bytes = mode_lib->soc.mem_word_bytes; - calculate_mcache_setting_params->mcache_size_bytes = mode_lib->soc.mcache_size_bytes; - calculate_mcache_setting_params->mcache_line_size_bytes = mode_lib->soc.mcache_line_size_bytes; - calculate_mcache_setting_params->gpuvm_enable = display_cfg->gpuvm_enable; - calculate_mcache_setting_params->gpuvm_page_size_kbytes = display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes; - - calculate_mcache_setting_params->source_format = display_cfg->plane_descriptors[k].pixel_format; - calculate_mcache_setting_params->surf_vert = dml_is_vertical_rotation(display_cfg->plane_descriptors[k].composition.rotation_angle); - calculate_mcache_setting_params->vp_stationary = display_cfg->plane_descriptors[k].composition.viewport.stationary; - calculate_mcache_setting_params->tiling_mode = display_cfg->plane_descriptors[k].surface.tiling; - calculate_mcache_setting_params->imall_enable = mode_lib->ip.imall_supported && display_cfg->plane_descriptors[k].overrides.legacy_svp_config == dml2_svp_mode_override_imall; - - calculate_mcache_setting_params->vp_start_x_l = display_cfg->plane_descriptors[k].composition.viewport.plane0.x_start; - calculate_mcache_setting_params->vp_start_y_l = display_cfg->plane_descriptors[k].composition.viewport.plane0.y_start; - calculate_mcache_setting_params->full_vp_width_l = display_cfg->plane_descriptors[k].composition.viewport.plane0.width; - calculate_mcache_setting_params->full_vp_height_l = display_cfg->plane_descriptors[k].composition.viewport.plane0.height; - calculate_mcache_setting_params->blk_width_l = mode_lib->mp.MacroTileWidthY[k]; - calculate_mcache_setting_params->blk_height_l = mode_lib->mp.MacroTileHeightY[k]; - calculate_mcache_setting_params->vmpg_width_l = s->vmpg_width_y[k]; - calculate_mcache_setting_params->vmpg_height_l = s->vmpg_height_y[k]; - calculate_mcache_setting_params->full_swath_bytes_l = s->full_swath_bytes_l[k]; - calculate_mcache_setting_params->bytes_per_pixel_l = mode_lib->mp.BytePerPixelY[k]; - - calculate_mcache_setting_params->vp_start_x_c = display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start; - calculate_mcache_setting_params->vp_start_y_c = display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start; - calculate_mcache_setting_params->full_vp_width_c = display_cfg->plane_descriptors[k].composition.viewport.plane1.width; - calculate_mcache_setting_params->full_vp_height_c = display_cfg->plane_descriptors[k].composition.viewport.plane1.height; - calculate_mcache_setting_params->blk_width_c = mode_lib->mp.MacroTileWidthC[k]; - calculate_mcache_setting_params->blk_height_c = mode_lib->mp.MacroTileHeightC[k]; - calculate_mcache_setting_params->vmpg_width_c = s->vmpg_width_c[k]; - calculate_mcache_setting_params->vmpg_height_c = s->vmpg_height_c[k]; - calculate_mcache_setting_params->full_swath_bytes_c = s->full_swath_bytes_c[k]; - calculate_mcache_setting_params->bytes_per_pixel_c = mode_lib->mp.BytePerPixelC[k]; - - // output - calculate_mcache_setting_params->dcc_dram_bw_nom_overhead_factor_l = &mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p0[k]; - calculate_mcache_setting_params->dcc_dram_bw_pref_overhead_factor_l = &mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p0[k]; - calculate_mcache_setting_params->dcc_dram_bw_nom_overhead_factor_c = &mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p1[k]; - calculate_mcache_setting_params->dcc_dram_bw_pref_overhead_factor_c = &mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p1[k]; - - calculate_mcache_setting_params->num_mcaches_l = &mode_lib->mp.num_mcaches_l[k]; - calculate_mcache_setting_params->mcache_row_bytes_l = &mode_lib->mp.mcache_row_bytes_l[k]; - calculate_mcache_setting_params->mcache_offsets_l = mode_lib->mp.mcache_offsets_l[k]; - calculate_mcache_setting_params->mcache_shift_granularity_l = &mode_lib->mp.mcache_shift_granularity_l[k]; - - calculate_mcache_setting_params->num_mcaches_c = &mode_lib->mp.num_mcaches_c[k]; - calculate_mcache_setting_params->mcache_row_bytes_c = &mode_lib->mp.mcache_row_bytes_c[k]; - calculate_mcache_setting_params->mcache_offsets_c = mode_lib->mp.mcache_offsets_c[k]; - calculate_mcache_setting_params->mcache_shift_granularity_c = &mode_lib->mp.mcache_shift_granularity_c[k]; - - calculate_mcache_setting_params->mall_comb_mcache_l = &mode_lib->mp.mall_comb_mcache_l[k]; - calculate_mcache_setting_params->mall_comb_mcache_c = &mode_lib->mp.mall_comb_mcache_c[k]; - calculate_mcache_setting_params->lc_comb_mcache = &mode_lib->mp.lc_comb_mcache[k]; - calculate_mcache_setting(&mode_lib->scratch, calculate_mcache_setting_params); - } - - calculate_mall_bw_overhead_factor( - mode_lib->mp.mall_prefetch_sdp_overhead_factor, - mode_lib->mp.mall_prefetch_dram_overhead_factor, - - // input - display_cfg, - s->num_active_planes); - } - - // Calculate all the bandwidth availabe - calculate_bandwidth_available( - mode_lib->mp.avg_bandwidth_available_min, - mode_lib->mp.avg_bandwidth_available, - mode_lib->mp.urg_bandwidth_available_min, - mode_lib->mp.urg_bandwidth_available, - mode_lib->mp.urg_bandwidth_available_vm_only, - mode_lib->mp.urg_bandwidth_available_pixel_and_vm, - - &mode_lib->soc, - display_cfg->hostvm_enable, - mode_lib->mp.Dcfclk, - mode_lib->mp.FabricClock, - mode_lib->mp.dram_bw_mbps); - - - calculate_hostvm_inefficiency_factor( - &s->HostVMInefficiencyFactor, - &s->HostVMInefficiencyFactorPrefetch, - - display_cfg->gpuvm_enable, - display_cfg->hostvm_enable, - mode_lib->ip.remote_iommu_outstanding_translations, - mode_lib->soc.max_outstanding_reqs, - mode_lib->mp.urg_bandwidth_available_pixel_and_vm[dml2_core_internal_soc_state_sys_active], - mode_lib->mp.urg_bandwidth_available_vm_only[dml2_core_internal_soc_state_sys_active]); - - s->TotalDCCActiveDPP = 0; - s->TotalActiveDPP = 0; - for (k = 0; k < s->num_active_planes; ++k) { - s->TotalActiveDPP = s->TotalActiveDPP + mode_lib->mp.NoOfDPP[k]; - if (display_cfg->plane_descriptors[k].surface.dcc.enable) - s->TotalDCCActiveDPP = s->TotalDCCActiveDPP + mode_lib->mp.NoOfDPP[k]; - } - // Calculate tdlut schedule related terms - for (k = 0; k <= s->num_active_planes - 1; k++) { - calculate_tdlut_setting_params->dispclk_mhz = mode_lib->mp.Dispclk; - calculate_tdlut_setting_params->setup_for_tdlut = display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut; - calculate_tdlut_setting_params->tdlut_width_mode = display_cfg->plane_descriptors[k].tdlut.tdlut_width_mode; - calculate_tdlut_setting_params->tdlut_addressing_mode = display_cfg->plane_descriptors[k].tdlut.tdlut_addressing_mode; - calculate_tdlut_setting_params->cursor_buffer_size = mode_lib->ip.cursor_buffer_size; - calculate_tdlut_setting_params->gpuvm_enable = display_cfg->gpuvm_enable; - calculate_tdlut_setting_params->gpuvm_page_size_kbytes = display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes; - - // output - calculate_tdlut_setting_params->tdlut_pte_bytes_per_frame = &s->tdlut_pte_bytes_per_frame[k]; - calculate_tdlut_setting_params->tdlut_bytes_per_frame = &s->tdlut_bytes_per_frame[k]; - calculate_tdlut_setting_params->tdlut_groups_per_2row_ub = &s->tdlut_groups_per_2row_ub[k]; - calculate_tdlut_setting_params->tdlut_opt_time = &s->tdlut_opt_time[k]; - calculate_tdlut_setting_params->tdlut_drain_time = &s->tdlut_drain_time[k]; - calculate_tdlut_setting_params->tdlut_bytes_per_group = &s->tdlut_bytes_per_group[k]; - - 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, - 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, - mode_lib->mp.urg_bandwidth_available_min[dml2_core_internal_soc_state_sys_active], - s->num_active_planes, - mode_lib->mp.NoOfDPP, - mode_lib->mp.dpte_group_bytes, - s->tdlut_bytes_per_group, - s->HostVMInefficiencyFactor, - s->HostVMInefficiencyFactorPrefetch, - mode_lib->soc.hostvm_min_page_size_kbytes, - mode_lib->soc.qos_parameters.qos_type, - !(display_cfg->overrides.max_outstanding_when_urgent_expected_disable), - mode_lib->soc.max_outstanding_reqs, - mode_lib->mp.request_size_bytes_luma, - mode_lib->mp.request_size_bytes_chroma, - mode_lib->ip.meta_chunk_size_kbytes, - mode_lib->ip.dchub_arb_to_ret_delay, - mode_lib->mp.TripToMemory, - mode_lib->ip.hostvm_mode, - - // output - &mode_lib->mp.ExtraLatency, - &mode_lib->mp.ExtraLatency_sr, - &mode_lib->mp.ExtraLatencyPrefetch); - - mode_lib->mp.TCalc = 24.0 / mode_lib->mp.DCFCLKDeepSleep; - - for (k = 0; k < s->num_active_planes; ++k) { - if (display_cfg->plane_descriptors[k].stream_index == k) { - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.enable == true) { - mode_lib->mp.WritebackDelay[k] = - mode_lib->soc.qos_parameters.writeback.base_latency_us - + CalculateWriteBackDelay( - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.pixel_format, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.h_ratio, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.v_ratio, - 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.output_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.input_height, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total) / mode_lib->mp.Dispclk; - } else - mode_lib->mp.WritebackDelay[k] = 0; - - for (j = 0; j < s->num_active_planes; ++j) { - if (display_cfg->plane_descriptors[j].stream_index == k - && display_cfg->stream_descriptors[display_cfg->plane_descriptors[j].stream_index].writeback.enable == true) { - mode_lib->mp.WritebackDelay[k] = - math_max2( - mode_lib->mp.WritebackDelay[k], - mode_lib->soc.qos_parameters.writeback.base_latency_us - + CalculateWriteBackDelay( - display_cfg->stream_descriptors[display_cfg->plane_descriptors[j].stream_index].writeback.pixel_format, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[j].stream_index].writeback.scaling_info.h_ratio, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[j].stream_index].writeback.scaling_info.v_ratio, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[j].stream_index].writeback.scaling_info.v_taps, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[j].stream_index].writeback.scaling_info.output_width, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[j].stream_index].writeback.scaling_info.output_height, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[j].stream_index].writeback.scaling_info.input_height, - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total) / mode_lib->mp.Dispclk); - } - } - } - } - - for (k = 0; k < s->num_active_planes; ++k) - for (j = 0; j < s->num_active_planes; ++j) - if (display_cfg->plane_descriptors[k].stream_index == j) - mode_lib->mp.WritebackDelay[k] = mode_lib->mp.WritebackDelay[j]; - - mode_lib->mp.UrgentLatency = CalculateUrgentLatency( - 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.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.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.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); - - mode_lib->mp.MetaTripToMemory = CalculateMetaTripToMemory( - 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.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( - 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]); - - bool cursor_not_enough_urgent_latency_hiding = 0; - double 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 - &mode_lib->mp.UrgentBurstFactorCursor[k], - &cursor_not_enough_urgent_latency_hiding); - mode_lib->mp.UrgentBurstFactorCursorPre[k] = mode_lib->mp.UrgentBurstFactorCursor[k]; - - CalculateUrgentBurstFactor( - &display_cfg->plane_descriptors[k], - mode_lib->mp.swath_width_luma_ub[k], - mode_lib->mp.swath_width_chroma_ub[k], - mode_lib->mp.SwathHeightY[k], - mode_lib->mp.SwathHeightC[k], - line_time_us, - mode_lib->mp.UrgentLatency, - display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio, - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio, - mode_lib->mp.BytePerPixelInDETY[k], - mode_lib->mp.BytePerPixelInDETC[k], - mode_lib->mp.DETBufferSizeY[k], - mode_lib->mp.DETBufferSizeC[k], - - /* output */ - &mode_lib->mp.UrgentBurstFactorLuma[k], - &mode_lib->mp.UrgentBurstFactorChroma[k], - &mode_lib->mp.NotEnoughUrgentLatencyHiding[k]); - - mode_lib->mp.NotEnoughUrgentLatencyHiding[k] = mode_lib->mp.NotEnoughUrgentLatencyHiding[k] || cursor_not_enough_urgent_latency_hiding; - } - - for (k = 0; k < s->num_active_planes; ++k) { - s->MaxVStartupLines[k] = CalculateMaxVStartup( - mode_lib->ip.ptoi_supported, - mode_lib->ip.vblank_nom_default_us, - &display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing, - mode_lib->mp.WritebackDelay[k]); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u MaxVStartupLines = %u\n", __func__, k, s->MaxVStartupLines[k]); - dml2_printf("DML::%s: k=%u WritebackDelay = %f\n", __func__, k, mode_lib->mp.WritebackDelay[k]); -#endif - } - - s->immediate_flip_required = false; - for (k = 0; k < s->num_active_planes; ++k) { - s->immediate_flip_required = s->immediate_flip_required || display_cfg->plane_descriptors[k].immediate_flip; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: immediate_flip_required = %u\n", __func__, s->immediate_flip_required); -#endif - - { - s->DestinationLineTimesForPrefetchLessThan2 = false; - s->VRatioPrefetchMoreThanMax = false; - - dml2_printf("DML::%s: Start one iteration of prefetch schedule evaluation\n", __func__); - - for (k = 0; k < s->num_active_planes; ++k) { - dml2_printf("DML::%s: k=%d MaxVStartupLines = %u\n", __func__, k, s->MaxVStartupLines[k]); - - mode_lib->mp.TWait[k] = CalculateTWait( - display_cfg->plane_descriptors[k].overrides.reserved_vblank_time_ns, - mode_lib->mp.UrgentLatency, - mode_lib->mp.TripToMemory); - - struct dml2_core_internal_DmlPipe *myPipe = &s->myPipe; - myPipe->Dppclk = mode_lib->mp.Dppclk[k]; - myPipe->Dispclk = mode_lib->mp.Dispclk; - myPipe->PixelClock = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000); - myPipe->DCFClkDeepSleep = mode_lib->mp.DCFCLKDeepSleep; - myPipe->DPPPerSurface = mode_lib->mp.NoOfDPP[k]; - myPipe->ScalerEnabled = display_cfg->plane_descriptors[k].composition.scaler_info.enabled; - myPipe->VRatio = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio; - myPipe->VRatioChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio; - myPipe->VTaps = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps; - myPipe->VTapsChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps; - myPipe->RotationAngle = display_cfg->plane_descriptors[k].composition.rotation_angle; - myPipe->mirrored = display_cfg->plane_descriptors[k].composition.mirrored; - myPipe->BlockWidth256BytesY = mode_lib->mp.Read256BlockWidthY[k]; - myPipe->BlockHeight256BytesY = mode_lib->mp.Read256BlockHeightY[k]; - myPipe->BlockWidth256BytesC = mode_lib->mp.Read256BlockWidthC[k]; - myPipe->BlockHeight256BytesC = mode_lib->mp.Read256BlockHeightC[k]; - myPipe->InterlaceEnable = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced; - myPipe->NumberOfCursors = display_cfg->plane_descriptors[k].cursor.num_cursors; - myPipe->VBlank = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active; - myPipe->HTotal = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total; - myPipe->HActive = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_active; - myPipe->DCCEnable = display_cfg->plane_descriptors[k].surface.dcc.enable; - myPipe->ODMMode = mode_lib->mp.ODMMode[k]; - myPipe->SourcePixelFormat = display_cfg->plane_descriptors[k].pixel_format; - myPipe->BytePerPixelY = mode_lib->mp.BytePerPixelY[k]; - myPipe->BytePerPixelC = mode_lib->mp.BytePerPixelC[k]; - myPipe->ProgressiveToInterlaceUnitInOPP = mode_lib->ip.ptoi_supported; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: Calling CalculatePrefetchSchedule for k=%u\n", __func__, k); -#endif - CalculatePrefetchSchedule_params->display_cfg = display_cfg; - CalculatePrefetchSchedule_params->HostVMInefficiencyFactor = s->HostVMInefficiencyFactorPrefetch; - CalculatePrefetchSchedule_params->myPipe = myPipe; - CalculatePrefetchSchedule_params->DSCDelay = mode_lib->mp.DSCDelay[k]; - CalculatePrefetchSchedule_params->DPPCLKDelaySubtotalPlusCNVCFormater = mode_lib->ip.dppclk_delay_subtotal + mode_lib->ip.dppclk_delay_cnvc_formatter; - CalculatePrefetchSchedule_params->DPPCLKDelaySCL = mode_lib->ip.dppclk_delay_scl; - CalculatePrefetchSchedule_params->DPPCLKDelaySCLLBOnly = mode_lib->ip.dppclk_delay_scl_lb_only; - CalculatePrefetchSchedule_params->DPPCLKDelayCNVCCursor = mode_lib->ip.dppclk_delay_cnvc_cursor; - CalculatePrefetchSchedule_params->DISPCLKDelaySubtotal = mode_lib->ip.dispclk_delay_subtotal; - CalculatePrefetchSchedule_params->DPP_RECOUT_WIDTH = (unsigned int)(mode_lib->mp.SwathWidthY[k] / display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio); - 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; - CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = display_cfg->plane_descriptors[k].dynamic_meta_data.lines_before_active_required; - CalculatePrefetchSchedule_params->DynamicMetadataTransmittedBytes = display_cfg->plane_descriptors[k].dynamic_meta_data.transmitted_bytes; - CalculatePrefetchSchedule_params->UrgentLatency = mode_lib->mp.UrgentLatency; - CalculatePrefetchSchedule_params->ExtraLatencyPrefetch = mode_lib->mp.ExtraLatencyPrefetch; - CalculatePrefetchSchedule_params->TCalc = mode_lib->mp.TCalc; - CalculatePrefetchSchedule_params->vm_bytes = mode_lib->mp.vm_bytes[k]; - CalculatePrefetchSchedule_params->PixelPTEBytesPerRow = mode_lib->mp.PixelPTEBytesPerRow[k]; - CalculatePrefetchSchedule_params->PrefetchSourceLinesY = mode_lib->mp.PrefetchSourceLinesY[k]; - CalculatePrefetchSchedule_params->VInitPreFillY = mode_lib->mp.VInitPreFillY[k]; - CalculatePrefetchSchedule_params->MaxNumSwathY = mode_lib->mp.MaxNumSwathY[k]; - CalculatePrefetchSchedule_params->PrefetchSourceLinesC = mode_lib->mp.PrefetchSourceLinesC[k]; - CalculatePrefetchSchedule_params->VInitPreFillC = mode_lib->mp.VInitPreFillC[k]; - CalculatePrefetchSchedule_params->MaxNumSwathC = mode_lib->mp.MaxNumSwathC[k]; - CalculatePrefetchSchedule_params->swath_width_luma_ub = mode_lib->mp.swath_width_luma_ub[k]; - CalculatePrefetchSchedule_params->swath_width_chroma_ub = mode_lib->mp.swath_width_chroma_ub[k]; - CalculatePrefetchSchedule_params->SwathHeightY = mode_lib->mp.SwathHeightY[k]; - CalculatePrefetchSchedule_params->SwathHeightC = mode_lib->mp.SwathHeightC[k]; - CalculatePrefetchSchedule_params->TWait = mode_lib->mp.TWait[k]; - CalculatePrefetchSchedule_params->Ttrip = mode_lib->mp.TripToMemory; - CalculatePrefetchSchedule_params->setup_for_tdlut = display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut; - CalculatePrefetchSchedule_params->tdlut_pte_bytes_per_frame = s->tdlut_pte_bytes_per_frame[k]; - CalculatePrefetchSchedule_params->tdlut_bytes_per_frame = s->tdlut_bytes_per_frame[k]; - CalculatePrefetchSchedule_params->tdlut_opt_time = s->tdlut_opt_time[k]; - CalculatePrefetchSchedule_params->tdlut_drain_time = s->tdlut_drain_time[k]; - CalculatePrefetchSchedule_params->num_cursors = (display_cfg->plane_descriptors[k].cursor.cursor_width > 0); - CalculatePrefetchSchedule_params->cursor_bytes_per_chunk = s->cursor_bytes_per_chunk[k]; - CalculatePrefetchSchedule_params->cursor_bytes_per_line = s->cursor_bytes_per_line[k]; - CalculatePrefetchSchedule_params->dcc_enable = display_cfg->plane_descriptors[k].surface.dcc.enable; - CalculatePrefetchSchedule_params->mrq_present = mode_lib->ip.dcn_mrq_present; - CalculatePrefetchSchedule_params->meta_row_bytes = mode_lib->mp.meta_row_bytes[k]; - CalculatePrefetchSchedule_params->mall_prefetch_sdp_overhead_factor = mode_lib->mp.mall_prefetch_sdp_overhead_factor[k]; - - // output - CalculatePrefetchSchedule_params->DSTXAfterScaler = &mode_lib->mp.DSTXAfterScaler[k]; - CalculatePrefetchSchedule_params->DSTYAfterScaler = &mode_lib->mp.DSTYAfterScaler[k]; - CalculatePrefetchSchedule_params->dst_y_prefetch = &mode_lib->mp.dst_y_prefetch[k]; - CalculatePrefetchSchedule_params->dst_y_per_vm_vblank = &mode_lib->mp.dst_y_per_vm_vblank[k]; - CalculatePrefetchSchedule_params->dst_y_per_row_vblank = &mode_lib->mp.dst_y_per_row_vblank[k]; - CalculatePrefetchSchedule_params->VRatioPrefetchY = &mode_lib->mp.VRatioPrefetchY[k]; - CalculatePrefetchSchedule_params->VRatioPrefetchC = &mode_lib->mp.VRatioPrefetchC[k]; - CalculatePrefetchSchedule_params->RequiredPrefetchPixelDataBWLuma = &mode_lib->mp.RequiredPrefetchPixelDataBWLuma[k]; - CalculatePrefetchSchedule_params->RequiredPrefetchPixelDataBWChroma = &mode_lib->mp.RequiredPrefetchPixelDataBWChroma[k]; - CalculatePrefetchSchedule_params->NotEnoughTimeForDynamicMetadata = &mode_lib->mp.NotEnoughTimeForDynamicMetadata[k]; - CalculatePrefetchSchedule_params->Tno_bw = &mode_lib->mp.Tno_bw[k]; - CalculatePrefetchSchedule_params->Tno_bw_flip = &mode_lib->mp.Tno_bw_flip[k]; - CalculatePrefetchSchedule_params->prefetch_vmrow_bw = &mode_lib->mp.prefetch_vmrow_bw[k]; - CalculatePrefetchSchedule_params->Tdmdl_vm = &mode_lib->mp.Tdmdl_vm[k]; - CalculatePrefetchSchedule_params->Tdmdl = &mode_lib->mp.Tdmdl[k]; - CalculatePrefetchSchedule_params->TSetup = &mode_lib->mp.TSetup[k]; - CalculatePrefetchSchedule_params->Tvm_trips = &s->Tvm_trips[k]; - CalculatePrefetchSchedule_params->Tr0_trips = &s->Tr0_trips[k]; - CalculatePrefetchSchedule_params->Tvm_trips_flip = &s->Tvm_trips_flip[k]; - CalculatePrefetchSchedule_params->Tr0_trips_flip = &s->Tr0_trips_flip[k]; - CalculatePrefetchSchedule_params->Tvm_trips_flip_rounded = &s->Tvm_trips_flip_rounded[k]; - CalculatePrefetchSchedule_params->Tr0_trips_flip_rounded = &s->Tr0_trips_flip_rounded[k]; - CalculatePrefetchSchedule_params->VUpdateOffsetPix = &mode_lib->mp.VUpdateOffsetPix[k]; - CalculatePrefetchSchedule_params->VUpdateWidthPix = &mode_lib->mp.VUpdateWidthPix[k]; - CalculatePrefetchSchedule_params->VReadyOffsetPix = &mode_lib->mp.VReadyOffsetPix[k]; - CalculatePrefetchSchedule_params->prefetch_cursor_bw = &mode_lib->mp.prefetch_cursor_bw[k]; - - mode_lib->mp.NoTimeToPrefetch[k] = CalculatePrefetchSchedule(&mode_lib->scratch, CalculatePrefetchSchedule_params); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%0u NoTimeToPrefetch=%0d\n", __func__, k, mode_lib->mp.NoTimeToPrefetch[k]); -#endif - mode_lib->mp.VStartupMin[k] = s->MaxVStartupLines[k]; - } // for k - - mode_lib->mp.PrefetchModeSupported = true; - for (k = 0; k < s->num_active_planes; ++k) { - if (mode_lib->mp.NoTimeToPrefetch[k] == true || - mode_lib->mp.NotEnoughTimeForDynamicMetadata[k] || - mode_lib->mp.DSTYAfterScaler[k] > 8) { - dml2_printf("DML::%s: k=%u, NoTimeToPrefetch = %0d\n", __func__, k, mode_lib->mp.NoTimeToPrefetch[k]); - dml2_printf("DML::%s: k=%u, NotEnoughTimeForDynamicMetadata=%u\n", __func__, k, mode_lib->mp.NotEnoughTimeForDynamicMetadata[k]); - dml2_printf("DML::%s: k=%u, DSTYAfterScaler=%u (should be <= 0)\n", __func__, k, mode_lib->mp.DSTYAfterScaler[k]); - mode_lib->mp.PrefetchModeSupported = false; - } - 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__) - s->VRatioPrefetchMoreThanMax = true; - - if (mode_lib->mp.NotEnoughUrgentLatencyHiding[k]) { - dml2_printf("DML::%s: k=%u, NotEnoughUrgentLatencyHiding = %u\n", __func__, k, mode_lib->mp.NotEnoughUrgentLatencyHiding[k]); - mode_lib->mp.PrefetchModeSupported = false; - } - } - - if (s->VRatioPrefetchMoreThanMax == true || s->DestinationLineTimesForPrefetchLessThan2 == true) { - dml2_printf("DML::%s: VRatioPrefetchMoreThanMax = %u\n", __func__, s->VRatioPrefetchMoreThanMax); - dml2_printf("DML::%s: DestinationLineTimesForPrefetchLessThan2 = %u\n", __func__, s->DestinationLineTimesForPrefetchLessThan2); - mode_lib->mp.PrefetchModeSupported = false; - } - - dml2_printf("DML::%s: Prefetch schedule is %sOK at vstartup = %u\n", __func__, - mode_lib->mp.PrefetchModeSupported ? "" : "NOT ", CalculatePrefetchSchedule_params->VStartup); - - // Prefetch schedule OK, now check prefetch bw - if (mode_lib->mp.PrefetchModeSupported == true) { - for (k = 0; k < s->num_active_planes; ++k) { - double 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); - CalculateUrgentBurstFactor( - &display_cfg->plane_descriptors[k], - mode_lib->mp.swath_width_luma_ub[k], - mode_lib->mp.swath_width_chroma_ub[k], - mode_lib->mp.SwathHeightY[k], - mode_lib->mp.SwathHeightC[k], - line_time_us, - mode_lib->mp.UrgentLatency, - mode_lib->mp.VRatioPrefetchY[k], - mode_lib->mp.VRatioPrefetchC[k], - mode_lib->mp.BytePerPixelInDETY[k], - mode_lib->mp.BytePerPixelInDETC[k], - mode_lib->mp.DETBufferSizeY[k], - mode_lib->mp.DETBufferSizeC[k], - /* Output */ - &mode_lib->mp.UrgentBurstFactorLumaPre[k], - &mode_lib->mp.UrgentBurstFactorChromaPre[k], - &mode_lib->mp.NotEnoughUrgentLatencyHidingPre[k]); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%0u DPPPerSurface=%u\n", __func__, k, mode_lib->mp.NoOfDPP[k]); - dml2_printf("DML::%s: k=%0u UrgentBurstFactorLuma=%f\n", __func__, k, mode_lib->mp.UrgentBurstFactorLuma[k]); - dml2_printf("DML::%s: k=%0u UrgentBurstFactorChroma=%f\n", __func__, k, mode_lib->mp.UrgentBurstFactorChroma[k]); - dml2_printf("DML::%s: k=%0u UrgentBurstFactorLumaPre=%f\n", __func__, k, mode_lib->mp.UrgentBurstFactorLumaPre[k]); - dml2_printf("DML::%s: k=%0u UrgentBurstFactorChromaPre=%f\n", __func__, k, mode_lib->mp.UrgentBurstFactorChromaPre[k]); - - dml2_printf("DML::%s: k=%0u VRatioPrefetchY=%f\n", __func__, k, mode_lib->mp.VRatioPrefetchY[k]); - dml2_printf("DML::%s: k=%0u VRatioY=%f\n", __func__, k, display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio); - - dml2_printf("DML::%s: k=%0u prefetch_vmrow_bw=%f\n", __func__, k, mode_lib->mp.prefetch_vmrow_bw[k]); - dml2_printf("DML::%s: k=%0u ReadBandwidthSurfaceLuma=%f\n", __func__, k, mode_lib->mp.SurfaceReadBandwidthLuma[k]); - dml2_printf("DML::%s: k=%0u ReadBandwidthSurfaceChroma=%f\n", __func__, k, mode_lib->mp.SurfaceReadBandwidthChroma[k]); - dml2_printf("DML::%s: k=%0u cursor_bw=%f\n", __func__, k, mode_lib->mp.cursor_bw[k]); - dml2_printf("DML::%s: k=%0u dpte_row_bw=%f\n", __func__, k, mode_lib->mp.dpte_row_bw[k]); - dml2_printf("DML::%s: k=%0u meta_row_bw=%f\n", __func__, k, mode_lib->mp.meta_row_bw[k]); - dml2_printf("DML::%s: k=%0u RequiredPrefetchPixelDataBWLuma=%f\n", __func__, k, mode_lib->mp.RequiredPrefetchPixelDataBWLuma[k]); - dml2_printf("DML::%s: k=%0u RequiredPrefetchPixelDataBWChroma=%f\n", __func__, k, mode_lib->mp.RequiredPrefetchPixelDataBWChroma[k]); - dml2_printf("DML::%s: k=%0u prefetch_cursor_bw=%f\n", __func__, k, mode_lib->mp.prefetch_cursor_bw[k]); -#endif - } - - for (k = 0; k <= s->num_active_planes - 1; k++) - mode_lib->mp.final_flip_bw[k] = 0; - - calculate_peak_bandwidth_required( - &mode_lib->scratch, - mode_lib->mp.urg_vactive_bandwidth_required, - mode_lib->mp.urg_bandwidth_required, - mode_lib->mp.non_urg_bandwidth_required, - - // Input - display_cfg, - 0, // inc_flip_bw - s->num_active_planes, - mode_lib->mp.NoOfDPP, - mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p0, - mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p1, - mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p0, - mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p1, - mode_lib->mp.mall_prefetch_sdp_overhead_factor, - mode_lib->mp.mall_prefetch_dram_overhead_factor, - mode_lib->mp.SurfaceReadBandwidthLuma, - mode_lib->mp.SurfaceReadBandwidthChroma, - mode_lib->mp.RequiredPrefetchPixelDataBWLuma, - mode_lib->mp.RequiredPrefetchPixelDataBWChroma, - mode_lib->mp.cursor_bw, - mode_lib->mp.dpte_row_bw, - mode_lib->mp.meta_row_bw, - mode_lib->mp.prefetch_cursor_bw, - mode_lib->mp.prefetch_vmrow_bw, - mode_lib->mp.final_flip_bw, - mode_lib->mp.UrgentBurstFactorLuma, - mode_lib->mp.UrgentBurstFactorChroma, - mode_lib->mp.UrgentBurstFactorCursor, - mode_lib->mp.UrgentBurstFactorLumaPre, - mode_lib->mp.UrgentBurstFactorChromaPre, - mode_lib->mp.UrgentBurstFactorCursorPre); - - // Check urg peak bandwidth against available urg bw - // check at SDP and DRAM, for all soc states (SVP prefetch an Sys Active) - check_urgent_bandwidth_support( - &mode_lib->mp.FractionOfUrgentBandwidth, // double* frac_urg_bandwidth - &mode_lib->mp.FractionOfUrgentBandwidthMALL, // double* frac_urg_bandwidth_mall - &s->dummy_boolean[1], // vactive bw ok - &mode_lib->mp.PrefetchModeSupported, // prefetch bw ok - - mode_lib->soc.mall_allocated_for_dcn_mbytes, - mode_lib->mp.non_urg_bandwidth_required, - mode_lib->mp.urg_vactive_bandwidth_required, - mode_lib->mp.urg_bandwidth_required, - mode_lib->mp.urg_bandwidth_available); - - for (k = 0; k < s->num_active_planes; ++k) { - if (mode_lib->mp.NotEnoughUrgentLatencyHidingPre[k]) { - dml2_printf("DML::%s: k=%u, NotEnoughUrgentLatencyHidingPre = %u\n", __func__, k, mode_lib->mp.NotEnoughUrgentLatencyHidingPre[k]); - mode_lib->mp.PrefetchModeSupported = false; - } - } - } // prefetch schedule ok - - // Prefetch schedule and prefetch bw ok, now check flip bw - if (mode_lib->mp.PrefetchModeSupported == true) { // prefetch schedule and prefetch bw ok, now check flip bw - - mode_lib->mp.BandwidthAvailableForImmediateFlip = - get_bandwidth_available_for_immediate_flip(dml2_core_internal_soc_state_sys_active, - mode_lib->mp.urg_bandwidth_required, // no flip - mode_lib->mp.urg_bandwidth_available); - mode_lib->mp.TotImmediateFlipBytes = 0; - for (k = 0; k < s->num_active_planes; ++k) { - if (display_cfg->plane_descriptors[k].immediate_flip) { - s->per_pipe_flip_bytes[k] = get_pipe_flip_bytes( - s->HostVMInefficiencyFactor, - mode_lib->mp.vm_bytes[k], - mode_lib->mp.PixelPTEBytesPerRow[k], - mode_lib->mp.meta_row_bytes[k]); - } else { - s->per_pipe_flip_bytes[k] = 0; - } - mode_lib->mp.TotImmediateFlipBytes += s->per_pipe_flip_bytes[k] * mode_lib->mp.NoOfDPP[k]; -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k = %u\n", __func__, k); - dml2_printf("DML::%s: DPPPerSurface = %u\n", __func__, mode_lib->mp.NoOfDPP[k]); - dml2_printf("DML::%s: vm_bytes = %u\n", __func__, mode_lib->mp.vm_bytes[k]); - dml2_printf("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, mode_lib->mp.PixelPTEBytesPerRow[k]); - dml2_printf("DML::%s: meta_row_bytes = %u\n", __func__, mode_lib->mp.meta_row_bytes[k]); - dml2_printf("DML::%s: TotImmediateFlipBytes = %u\n", __func__, mode_lib->mp.TotImmediateFlipBytes); -#endif - } - for (k = 0; k < s->num_active_planes; ++k) { - CalculateFlipSchedule( - &mode_lib->scratch, - display_cfg->plane_descriptors[k].immediate_flip, - 0, // use_lb_flip_bw - s->HostVMInefficiencyFactor, - s->Tvm_trips_flip[k], - s->Tr0_trips_flip[k], - s->Tvm_trips_flip_rounded[k], - s->Tr0_trips_flip_rounded[k], - display_cfg->gpuvm_enable, - mode_lib->mp.vm_bytes[k], - mode_lib->mp.PixelPTEBytesPerRow[k], - mode_lib->mp.BandwidthAvailableForImmediateFlip, - mode_lib->mp.TotImmediateFlipBytes, - display_cfg->plane_descriptors[k].pixel_format, - 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), - display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio, - display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio, - mode_lib->mp.Tno_bw[k], - mode_lib->mp.dpte_row_height[k], - 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, - s->per_pipe_flip_bytes[k], - mode_lib->mp.meta_row_bytes[k], - mode_lib->mp.meta_row_height[k], - mode_lib->mp.meta_row_height_chroma[k], - mode_lib->ip.dcn_mrq_present && display_cfg->plane_descriptors[k].surface.dcc.enable, - - // Output - &mode_lib->mp.dst_y_per_vm_flip[k], - &mode_lib->mp.dst_y_per_row_flip[k], - &mode_lib->mp.final_flip_bw[k], - &mode_lib->mp.ImmediateFlipSupportedForPipe[k]); - } - - calculate_peak_bandwidth_required( - &mode_lib->scratch, - s->dummy_bw, - mode_lib->mp.urg_bandwidth_required_flip, - mode_lib->mp.non_urg_bandwidth_required_flip, - - // Input - display_cfg, - 1, // inc_flip_bw - s->num_active_planes, - mode_lib->mp.NoOfDPP, - mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p0, - mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p1, - mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p0, - mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p1, - mode_lib->mp.mall_prefetch_sdp_overhead_factor, - mode_lib->mp.mall_prefetch_dram_overhead_factor, - mode_lib->mp.SurfaceReadBandwidthLuma, - mode_lib->mp.SurfaceReadBandwidthChroma, - mode_lib->mp.RequiredPrefetchPixelDataBWLuma, - mode_lib->mp.RequiredPrefetchPixelDataBWChroma, - mode_lib->mp.cursor_bw, - mode_lib->mp.dpte_row_bw, - mode_lib->mp.meta_row_bw, - mode_lib->mp.prefetch_cursor_bw, - mode_lib->mp.prefetch_vmrow_bw, - mode_lib->mp.final_flip_bw, - mode_lib->mp.UrgentBurstFactorLuma, - mode_lib->mp.UrgentBurstFactorChroma, - mode_lib->mp.UrgentBurstFactorCursor, - mode_lib->mp.UrgentBurstFactorLumaPre, - mode_lib->mp.UrgentBurstFactorChromaPre, - mode_lib->mp.UrgentBurstFactorCursorPre); - - calculate_immediate_flip_bandwidth_support( - &mode_lib->mp.FractionOfUrgentBandwidthImmediateFlip, // double* frac_urg_bandwidth_flip - &mode_lib->mp.ImmediateFlipSupported, // bool* flip_bandwidth_support_ok - - dml2_core_internal_soc_state_sys_active, - mode_lib->mp.urg_bandwidth_required_flip, - mode_lib->mp.non_urg_bandwidth_required_flip, - mode_lib->mp.urg_bandwidth_available); - - for (k = 0; k < s->num_active_planes; ++k) { - if (display_cfg->plane_descriptors[k].immediate_flip && mode_lib->mp.ImmediateFlipSupportedForPipe[k] == false) { - mode_lib->mp.ImmediateFlipSupported = false; -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: Pipe %0d not supporting iflip!\n", __func__, k); -#endif - } - } - } else { // flip or prefetch not support - mode_lib->mp.ImmediateFlipSupported = false; - } - - // consider flip support is okay if the flip bw is ok or (when user does't require a iflip and there is no host vm) - bool must_support_iflip = display_cfg->hostvm_enable || s->immediate_flip_required; - mode_lib->mp.PrefetchAndImmediateFlipSupported = (mode_lib->mp.PrefetchModeSupported == true && (!must_support_iflip || mode_lib->mp.ImmediateFlipSupported)); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: PrefetchModeSupported = %u\n", __func__, mode_lib->mp.PrefetchModeSupported); - for (k = 0; k < s->num_active_planes; ++k) - dml2_printf("DML::%s: immediate_flip_required[%u] = %u\n", __func__, k, display_cfg->plane_descriptors[k].immediate_flip); - dml2_printf("DML::%s: HostVMEnable = %u\n", __func__, display_cfg->hostvm_enable); - dml2_printf("DML::%s: ImmediateFlipSupported = %u\n", __func__, mode_lib->mp.ImmediateFlipSupported); - dml2_printf("DML::%s: PrefetchAndImmediateFlipSupported = %u\n", __func__, mode_lib->mp.PrefetchAndImmediateFlipSupported); -#endif - dml2_printf("DML::%s: Done one iteration: k=%d, MaxVStartupLines=%u\n", __func__, k, s->MaxVStartupLines[k]); - } - - for (k = 0; k < s->num_active_planes; ++k) - dml2_printf("DML::%s: k=%d MaxVStartupLines = %u\n", __func__, k, s->MaxVStartupLines[k]); - - if (!mode_lib->mp.PrefetchAndImmediateFlipSupported) { - dml2_printf("DML::%s: Bad, Prefetch and flip scheduling solution NOT found!\n", __func__); - } else { - dml2_printf("DML::%s: Good, Prefetch and flip scheduling solution found\n", __func__); - - // DCC Configuration - for (k = 0; k < s->num_active_planes; ++k) { -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: Calculate DCC configuration for surface k=%u\n", __func__, k); -#endif - CalculateDCCConfiguration( - display_cfg->plane_descriptors[k].surface.dcc.enable, - display_cfg->overrides.dcc_programming_assumes_scan_direction_unknown, - display_cfg->plane_descriptors[k].pixel_format, - display_cfg->plane_descriptors[k].surface.plane0.width, - display_cfg->plane_descriptors[k].surface.plane1.width, - display_cfg->plane_descriptors[k].surface.plane0.height, - display_cfg->plane_descriptors[k].surface.plane1.height, - s->NomDETInKByte, - mode_lib->mp.Read256BlockHeightY[k], - mode_lib->mp.Read256BlockHeightC[k], - display_cfg->plane_descriptors[k].surface.tiling, - mode_lib->mp.BytePerPixelY[k], - mode_lib->mp.BytePerPixelC[k], - mode_lib->mp.BytePerPixelInDETY[k], - mode_lib->mp.BytePerPixelInDETC[k], - display_cfg->plane_descriptors[k].composition.rotation_angle, - - /* Output */ - &mode_lib->mp.RequestLuma[k], - &mode_lib->mp.RequestChroma[k], - &mode_lib->mp.DCCYMaxUncompressedBlock[k], - &mode_lib->mp.DCCCMaxUncompressedBlock[k], - &mode_lib->mp.DCCYMaxCompressedBlock[k], - &mode_lib->mp.DCCCMaxCompressedBlock[k], - &mode_lib->mp.DCCYIndependentBlock[k], - &mode_lib->mp.DCCCIndependentBlock[k]); - } - - //Watermarks and NB P-State/DRAM Clock Change Support - s->mmSOCParameters.UrgentLatency = mode_lib->mp.UrgentLatency; - s->mmSOCParameters.ExtraLatency = mode_lib->mp.ExtraLatency; - s->mmSOCParameters.ExtraLatency_sr = mode_lib->mp.ExtraLatency_sr; - s->mmSOCParameters.WritebackLatency = mode_lib->soc.qos_parameters.writeback.base_latency_us; - s->mmSOCParameters.DRAMClockChangeLatency = mode_lib->soc.power_management_parameters.dram_clk_change_blackout_us; - s->mmSOCParameters.FCLKChangeLatency = mode_lib->soc.power_management_parameters.fclk_change_blackout_us; - s->mmSOCParameters.SRExitTime = mode_lib->soc.power_management_parameters.stutter_exit_latency_us; - s->mmSOCParameters.SREnterPlusExitTime = mode_lib->soc.power_management_parameters.stutter_enter_plus_exit_latency_us; - s->mmSOCParameters.SRExitZ8Time = mode_lib->soc.power_management_parameters.z8_stutter_exit_latency_us; - s->mmSOCParameters.SREnterPlusExitZ8Time = mode_lib->soc.power_management_parameters.z8_stutter_enter_plus_exit_latency_us; - s->mmSOCParameters.USRRetrainingLatency = 0; //0; //FIXME_STAGE2 - s->mmSOCParameters.SMNLatency = 0; //mode_lib->soc.smn_latency_us; //FIXME_STAGE2 - - CalculateWatermarks_params->display_cfg = display_cfg; - CalculateWatermarks_params->USRRetrainingRequired = false/*FIXME_STAGE2 was: mode_lib->ms.policy.USRRetrainingRequired, no new dml2 replacement*/; - CalculateWatermarks_params->NumberOfActiveSurfaces = s->num_active_planes; - CalculateWatermarks_params->MaxLineBufferLines = mode_lib->ip.max_line_buffer_lines; - CalculateWatermarks_params->LineBufferSize = mode_lib->ip.line_buffer_size_bits; - CalculateWatermarks_params->WritebackInterfaceBufferSize = mode_lib->ip.writeback_interface_buffer_size_kbytes; - CalculateWatermarks_params->DCFCLK = mode_lib->mp.Dcfclk; - CalculateWatermarks_params->SynchronizeTimings = display_cfg->overrides.synchronize_timings; - CalculateWatermarks_params->SynchronizeDRRDisplaysForUCLKPStateChange = display_cfg->overrides.synchronize_ddr_displays_for_uclk_pstate_change; - CalculateWatermarks_params->dpte_group_bytes = mode_lib->mp.dpte_group_bytes; - CalculateWatermarks_params->mmSOCParameters = s->mmSOCParameters; - CalculateWatermarks_params->WritebackChunkSize = mode_lib->ip.writeback_chunk_size_kbytes; - CalculateWatermarks_params->SOCCLK = s->SOCCLK; - CalculateWatermarks_params->DCFClkDeepSleep = mode_lib->mp.DCFCLKDeepSleep; - CalculateWatermarks_params->DETBufferSizeY = mode_lib->mp.DETBufferSizeY; - 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; - CalculateWatermarks_params->BytePerPixelDETC = mode_lib->mp.BytePerPixelInDETC; - CalculateWatermarks_params->DSTXAfterScaler = mode_lib->mp.DSTXAfterScaler; - CalculateWatermarks_params->DSTYAfterScaler = mode_lib->mp.DSTYAfterScaler; - CalculateWatermarks_params->UnboundedRequestEnabled = mode_lib->mp.UnboundedRequestEnabled; - CalculateWatermarks_params->CompressedBufferSizeInkByte = mode_lib->mp.CompressedBufferSizeInkByte; - CalculateWatermarks_params->meta_row_height_l = mode_lib->mp.meta_row_height; - CalculateWatermarks_params->meta_row_height_c = mode_lib->mp.meta_row_height_chroma; - - // Output - CalculateWatermarks_params->Watermark = &mode_lib->mp.Watermark; - CalculateWatermarks_params->DRAMClockChangeSupport = mode_lib->mp.DRAMClockChangeSupport; - CalculateWatermarks_params->global_dram_clock_change_supported = &mode_lib->mp.global_dram_clock_change_supported; - CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = mode_lib->mp.MaxActiveDRAMClockChangeLatencySupported; - CalculateWatermarks_params->SubViewportLinesNeededInMALL = mode_lib->mp.SubViewportLinesNeededInMALL; - CalculateWatermarks_params->FCLKChangeSupport = mode_lib->mp.FCLKChangeSupport; - CalculateWatermarks_params->global_fclk_change_supported = &mode_lib->mp.global_fclk_change_supported; - CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &mode_lib->mp.MaxActiveFCLKChangeLatencySupported; - CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->mp.USRRetrainingSupport; - CalculateWatermarks_params->VActiveLatencyHidingMargin = 0; - - CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(&mode_lib->scratch, CalculateWatermarks_params); - - for (k = 0; k < s->num_active_planes; ++k) { - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.enable == true) { - mode_lib->mp.WritebackAllowDRAMClockChangeEndPosition[k] = math_max2(0, mode_lib->mp.VStartupMin[k] * 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) - mode_lib->mp.Watermark.WritebackDRAMClockChangeWatermark); - mode_lib->mp.WritebackAllowFCLKChangeEndPosition[k] = math_max2(0, mode_lib->mp.VStartupMin[k] * 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) - mode_lib->mp.Watermark.WritebackFCLKChangeWatermark); - } else { - mode_lib->mp.WritebackAllowDRAMClockChangeEndPosition[k] = 0; - mode_lib->mp.WritebackAllowFCLKChangeEndPosition[k] = 0; - } - } - - 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)); - - //Display Pipeline Delivery Time in Prefetch, Groups - CalculatePixelDeliveryTimes( - display_cfg, - cfg_support_info, - s->num_active_planes, - mode_lib->mp.VRatioPrefetchY, - mode_lib->mp.VRatioPrefetchC, - mode_lib->mp.swath_width_luma_ub, - mode_lib->mp.swath_width_chroma_ub, - mode_lib->mp.PSCL_THROUGHPUT, - mode_lib->mp.PSCL_THROUGHPUT_CHROMA, - mode_lib->mp.Dppclk, - mode_lib->mp.BytePerPixelC, - mode_lib->mp.req_per_swath_ub_l, - mode_lib->mp.req_per_swath_ub_c, - - /* Output */ - mode_lib->mp.DisplayPipeLineDeliveryTimeLuma, - mode_lib->mp.DisplayPipeLineDeliveryTimeChroma, - mode_lib->mp.DisplayPipeLineDeliveryTimeLumaPrefetch, - mode_lib->mp.DisplayPipeLineDeliveryTimeChromaPrefetch, - mode_lib->mp.DisplayPipeRequestDeliveryTimeLuma, - mode_lib->mp.DisplayPipeRequestDeliveryTimeChroma, - mode_lib->mp.DisplayPipeRequestDeliveryTimeLumaPrefetch, - mode_lib->mp.DisplayPipeRequestDeliveryTimeChromaPrefetch); - - CalculateMetaAndPTETimes_params->scratch = &mode_lib->scratch; - CalculateMetaAndPTETimes_params->display_cfg = display_cfg; - CalculateMetaAndPTETimes_params->NumberOfActiveSurfaces = s->num_active_planes; - CalculateMetaAndPTETimes_params->use_one_row_for_frame = mode_lib->mp.use_one_row_for_frame; - CalculateMetaAndPTETimes_params->dst_y_per_row_vblank = mode_lib->mp.dst_y_per_row_vblank; - CalculateMetaAndPTETimes_params->dst_y_per_row_flip = mode_lib->mp.dst_y_per_row_flip; - CalculateMetaAndPTETimes_params->BytePerPixelY = mode_lib->mp.BytePerPixelY; - CalculateMetaAndPTETimes_params->BytePerPixelC = mode_lib->mp.BytePerPixelC; - CalculateMetaAndPTETimes_params->dpte_row_height = mode_lib->mp.dpte_row_height; - CalculateMetaAndPTETimes_params->dpte_row_height_chroma = mode_lib->mp.dpte_row_height_chroma; - CalculateMetaAndPTETimes_params->dpte_group_bytes = mode_lib->mp.dpte_group_bytes; - CalculateMetaAndPTETimes_params->PTERequestSizeY = mode_lib->mp.PTERequestSizeY; - CalculateMetaAndPTETimes_params->PTERequestSizeC = mode_lib->mp.PTERequestSizeC; - CalculateMetaAndPTETimes_params->PixelPTEReqWidthY = mode_lib->mp.PixelPTEReqWidthY; - CalculateMetaAndPTETimes_params->PixelPTEReqHeightY = mode_lib->mp.PixelPTEReqHeightY; - CalculateMetaAndPTETimes_params->PixelPTEReqWidthC = mode_lib->mp.PixelPTEReqWidthC; - CalculateMetaAndPTETimes_params->PixelPTEReqHeightC = mode_lib->mp.PixelPTEReqHeightC; - CalculateMetaAndPTETimes_params->dpte_row_width_luma_ub = mode_lib->mp.dpte_row_width_luma_ub; - CalculateMetaAndPTETimes_params->dpte_row_width_chroma_ub = mode_lib->mp.dpte_row_width_chroma_ub; - CalculateMetaAndPTETimes_params->tdlut_groups_per_2row_ub = s->tdlut_groups_per_2row_ub; - CalculateMetaAndPTETimes_params->mrq_present = mode_lib->ip.dcn_mrq_present; - - CalculateMetaAndPTETimes_params->MetaChunkSize = mode_lib->ip.meta_chunk_size_kbytes; - CalculateMetaAndPTETimes_params->MinMetaChunkSizeBytes = mode_lib->ip.min_meta_chunk_size_bytes; - CalculateMetaAndPTETimes_params->meta_row_width = mode_lib->mp.meta_row_width; - CalculateMetaAndPTETimes_params->meta_row_width_chroma = mode_lib->mp.meta_row_width_chroma; - CalculateMetaAndPTETimes_params->meta_row_height = mode_lib->mp.meta_row_height; - CalculateMetaAndPTETimes_params->meta_row_height_chroma = mode_lib->mp.meta_row_height_chroma; - CalculateMetaAndPTETimes_params->meta_req_width = mode_lib->mp.meta_req_width; - CalculateMetaAndPTETimes_params->meta_req_width_chroma = mode_lib->mp.meta_req_width_chroma; - CalculateMetaAndPTETimes_params->meta_req_height = mode_lib->mp.meta_req_height; - CalculateMetaAndPTETimes_params->meta_req_height_chroma = mode_lib->mp.meta_req_height_chroma; - - CalculateMetaAndPTETimes_params->time_per_tdlut_group = mode_lib->mp.time_per_tdlut_group; - CalculateMetaAndPTETimes_params->DST_Y_PER_PTE_ROW_NOM_L = mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_L; - CalculateMetaAndPTETimes_params->DST_Y_PER_PTE_ROW_NOM_C = mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_C; - CalculateMetaAndPTETimes_params->time_per_pte_group_nom_luma = mode_lib->mp.time_per_pte_group_nom_luma; - CalculateMetaAndPTETimes_params->time_per_pte_group_vblank_luma = mode_lib->mp.time_per_pte_group_vblank_luma; - CalculateMetaAndPTETimes_params->time_per_pte_group_flip_luma = mode_lib->mp.time_per_pte_group_flip_luma; - CalculateMetaAndPTETimes_params->time_per_pte_group_nom_chroma = mode_lib->mp.time_per_pte_group_nom_chroma; - CalculateMetaAndPTETimes_params->time_per_pte_group_vblank_chroma = mode_lib->mp.time_per_pte_group_vblank_chroma; - CalculateMetaAndPTETimes_params->time_per_pte_group_flip_chroma = mode_lib->mp.time_per_pte_group_flip_chroma; - CalculateMetaAndPTETimes_params->DST_Y_PER_META_ROW_NOM_L = mode_lib->mp.DST_Y_PER_META_ROW_NOM_L; - CalculateMetaAndPTETimes_params->DST_Y_PER_META_ROW_NOM_C = mode_lib->mp.DST_Y_PER_META_ROW_NOM_C; - CalculateMetaAndPTETimes_params->TimePerMetaChunkNominal = mode_lib->mp.TimePerMetaChunkNominal; - CalculateMetaAndPTETimes_params->TimePerChromaMetaChunkNominal = mode_lib->mp.TimePerChromaMetaChunkNominal; - CalculateMetaAndPTETimes_params->TimePerMetaChunkVBlank = mode_lib->mp.TimePerMetaChunkVBlank; - CalculateMetaAndPTETimes_params->TimePerChromaMetaChunkVBlank = mode_lib->mp.TimePerChromaMetaChunkVBlank; - CalculateMetaAndPTETimes_params->TimePerMetaChunkFlip = mode_lib->mp.TimePerMetaChunkFlip; - CalculateMetaAndPTETimes_params->TimePerChromaMetaChunkFlip = mode_lib->mp.TimePerChromaMetaChunkFlip; - - CalculateMetaAndPTETimes(CalculateMetaAndPTETimes_params); - - CalculateVMGroupAndRequestTimes( - display_cfg, - s->num_active_planes, - mode_lib->mp.BytePerPixelC, - mode_lib->mp.dst_y_per_vm_vblank, - mode_lib->mp.dst_y_per_vm_flip, - mode_lib->mp.dpte_row_width_luma_ub, - mode_lib->mp.dpte_row_width_chroma_ub, - mode_lib->mp.vm_group_bytes, - mode_lib->mp.dpde0_bytes_per_frame_ub_l, - mode_lib->mp.dpde0_bytes_per_frame_ub_c, - s->tdlut_pte_bytes_per_frame, - mode_lib->mp.meta_pte_bytes_per_frame_ub_l, - mode_lib->mp.meta_pte_bytes_per_frame_ub_c, - mode_lib->ip.dcn_mrq_present, - - /* Output */ - mode_lib->mp.TimePerVMGroupVBlank, - mode_lib->mp.TimePerVMGroupFlip, - mode_lib->mp.TimePerVMRequestVBlank, - mode_lib->mp.TimePerVMRequestFlip); - - // VStartup Adjustment - for (k = 0; k < s->num_active_planes; ++k) { - - mode_lib->mp.MinTTUVBlank[k] = mode_lib->mp.TWait[k] + mode_lib->mp.ExtraLatency; - if (!display_cfg->plane_descriptors[k].dynamic_meta_data.enable) - mode_lib->mp.MinTTUVBlank[k] = mode_lib->mp.TCalc + mode_lib->mp.MinTTUVBlank[k]; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, MinTTUVBlank = %f (before vstartup margin)\n", __func__, k, mode_lib->mp.MinTTUVBlank[k]); -#endif - s->Tvstartup_margin = (s->MaxVStartupLines[k] - mode_lib->mp.VStartupMin[k]) * 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); - mode_lib->mp.MinTTUVBlank[k] = mode_lib->mp.MinTTUVBlank[k] + s->Tvstartup_margin; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, Tvstartup_margin = %f\n", __func__, k, s->Tvstartup_margin); - dml2_printf("DML::%s: k=%u, MaxVStartupLines = %u\n", __func__, k, s->MaxVStartupLines[k]); - dml2_printf("DML::%s: k=%u, MinTTUVBlank = %f\n", __func__, k, mode_lib->mp.MinTTUVBlank[k]); -#endif - - mode_lib->mp.Tdmdl[k] = mode_lib->mp.Tdmdl[k] + s->Tvstartup_margin; - if (display_cfg->plane_descriptors[k].dynamic_meta_data.enable && mode_lib->ip.dynamic_metadata_vm_enabled) { - mode_lib->mp.Tdmdl_vm[k] = mode_lib->mp.Tdmdl_vm[k] + s->Tvstartup_margin; - } - - bool isInterlaceTiming = (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced && !mode_lib->ip.ptoi_supported); - - // The actual positioning of the vstartup - mode_lib->mp.VStartup[k] = (isInterlaceTiming ? (2 * s->MaxVStartupLines[k]) : s->MaxVStartupLines[k]); - - s->dlg_vblank_start = ((isInterlaceTiming ? math_floor2((display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch) / 2.0, 1.0) : - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total) - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch); - s->LSetup = math_floor2(4.0 * mode_lib->mp.TSetup[k] / ((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)), 1.0) / 4.0; - s->blank_lines_remaining = (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active) - mode_lib->mp.VStartup[k]; - - if (s->blank_lines_remaining < 0) { - dml2_printf("ERROR: Vstartup is larger than vblank!?\n"); - s->blank_lines_remaining = 0; - DML2_ASSERT(0); - } - mode_lib->mp.MIN_DST_Y_NEXT_START[k] = s->dlg_vblank_start + s->blank_lines_remaining + s->LSetup; - - // debug only - if (((mode_lib->mp.VUpdateOffsetPix[k] + mode_lib->mp.VUpdateWidthPix[k] + (double) mode_lib->mp.VReadyOffsetPix[k]) / display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total) <= - (isInterlaceTiming ? - math_floor2((display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch - mode_lib->mp.VStartup[k]) / 2.0, 1.0) : - (int)(display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch - mode_lib->mp.VStartup[k]))) { - mode_lib->mp.VREADY_AT_OR_AFTER_VSYNC[k] = true; - } else { - mode_lib->mp.VREADY_AT_OR_AFTER_VSYNC[k] = false; - } -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, VStartup = %u (max)\n", __func__, k, mode_lib->mp.VStartup[k]); - dml2_printf("DML::%s: k=%u, VStartupMin = %u (max)\n", __func__, k, mode_lib->mp.VStartupMin[k]); - dml2_printf("DML::%s: k=%u, VUpdateOffsetPix = %u\n", __func__, k, mode_lib->mp.VUpdateOffsetPix[k]); - dml2_printf("DML::%s: k=%u, VUpdateWidthPix = %u\n", __func__, k, mode_lib->mp.VUpdateWidthPix[k]); - dml2_printf("DML::%s: k=%u, VReadyOffsetPix = %u\n", __func__, k, mode_lib->mp.VReadyOffsetPix[k]); - dml2_printf("DML::%s: k=%u, HTotal = %u\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total); - dml2_printf("DML::%s: k=%u, VTotal = %u\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total); - dml2_printf("DML::%s: k=%u, VActive = %u\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active); - dml2_printf("DML::%s: k=%u, VFrontPorch = %u\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch); - dml2_printf("DML::%s: k=%u, TSetup = %f\n", __func__, k, mode_lib->mp.TSetup[k]); - dml2_printf("DML::%s: k=%u, MIN_DST_Y_NEXT_START = %f\n", __func__, k, mode_lib->mp.MIN_DST_Y_NEXT_START[k]); - dml2_printf("DML::%s: k=%u, VREADY_AT_OR_AFTER_VSYNC = %u\n", __func__, k, mode_lib->mp.VREADY_AT_OR_AFTER_VSYNC[k]); -#endif - } - - //Maximum Bandwidth Used - s->TotalWRBandwidth = 0; - s->WRBandwidth = 0; - for (k = 0; k < s->num_active_planes; ++k) { - if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.enable == true && display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.pixel_format == dml2_444_32) { - s->WRBandwidth = 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 * display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.input_height / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000)) * 4; - } else if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.enable == true) { - s->WRBandwidth = 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 * display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.scaling_info.input_height / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000)) * 8; - } - s->TotalWRBandwidth = s->TotalWRBandwidth + s->WRBandwidth; - } - - mode_lib->mp.TotalDataReadBandwidth = 0; - for (k = 0; k < s->num_active_planes; ++k) { - mode_lib->mp.TotalDataReadBandwidth = mode_lib->mp.TotalDataReadBandwidth + mode_lib->mp.SurfaceReadBandwidthLuma[k] + mode_lib->mp.SurfaceReadBandwidthChroma[k]; -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: k=%u, TotalDataReadBandwidth = %f\n", __func__, k, mode_lib->mp.TotalDataReadBandwidth); - dml2_printf("DML::%s: k=%u, ReadBandwidthSurfaceLuma = %f\n", __func__, k, mode_lib->mp.SurfaceReadBandwidthLuma[k]); - dml2_printf("DML::%s: k=%u, ReadBandwidthSurfaceChroma = %f\n", __func__, k, mode_lib->mp.SurfaceReadBandwidthChroma[k]); -#endif - } - - CalculateStutterEfficiency_params->display_cfg = display_cfg; - CalculateStutterEfficiency_params->CompressedBufferSizeInkByte = mode_lib->mp.CompressedBufferSizeInkByte; - CalculateStutterEfficiency_params->UnboundedRequestEnabled = mode_lib->mp.UnboundedRequestEnabled; - CalculateStutterEfficiency_params->MetaFIFOSizeInKEntries = mode_lib->ip.meta_fifo_size_in_kentries; - CalculateStutterEfficiency_params->ZeroSizeBufferEntries = mode_lib->ip.zero_size_buffer_entries; - CalculateStutterEfficiency_params->PixelChunkSizeInKByte = mode_lib->ip.pixel_chunk_size_kbytes; - CalculateStutterEfficiency_params->NumberOfActiveSurfaces = s->num_active_planes; - CalculateStutterEfficiency_params->ROBBufferSizeInKByte = mode_lib->ip.rob_buffer_size_kbytes; - CalculateStutterEfficiency_params->TotalDataReadBandwidth = mode_lib->mp.TotalDataReadBandwidth; - CalculateStutterEfficiency_params->DCFCLK = mode_lib->mp.Dcfclk; - CalculateStutterEfficiency_params->ReturnBW = mode_lib->mp.urg_bandwidth_available_min[dml2_core_internal_soc_state_sys_active]; - CalculateStutterEfficiency_params->CompbufReservedSpace64B = mode_lib->mp.compbuf_reserved_space_64b; - CalculateStutterEfficiency_params->CompbufReservedSpaceZs = mode_lib->ip.compbuf_reserved_space_zs; - CalculateStutterEfficiency_params->SRExitTime = mode_lib->soc.power_management_parameters.stutter_exit_latency_us; - CalculateStutterEfficiency_params->SRExitZ8Time = mode_lib->soc.power_management_parameters.z8_stutter_exit_latency_us; - CalculateStutterEfficiency_params->SynchronizeTimings = display_cfg->overrides.synchronize_timings; - CalculateStutterEfficiency_params->StutterEnterPlusExitWatermark = mode_lib->mp.Watermark.StutterEnterPlusExitWatermark; - CalculateStutterEfficiency_params->Z8StutterEnterPlusExitWatermark = mode_lib->mp.Watermark.Z8StutterEnterPlusExitWatermark; - CalculateStutterEfficiency_params->ProgressiveToInterlaceUnitInOPP = mode_lib->ip.ptoi_supported; - CalculateStutterEfficiency_params->MinTTUVBlank = mode_lib->mp.MinTTUVBlank; - CalculateStutterEfficiency_params->DPPPerSurface = mode_lib->mp.NoOfDPP; - CalculateStutterEfficiency_params->DETBufferSizeY = mode_lib->mp.DETBufferSizeY; - CalculateStutterEfficiency_params->BytePerPixelY = mode_lib->mp.BytePerPixelY; - CalculateStutterEfficiency_params->BytePerPixelDETY = mode_lib->mp.BytePerPixelInDETY; - CalculateStutterEfficiency_params->SwathWidthY = mode_lib->mp.SwathWidthY; - CalculateStutterEfficiency_params->SwathHeightY = mode_lib->mp.SwathHeightY; - CalculateStutterEfficiency_params->SwathHeightC = mode_lib->mp.SwathHeightC; - CalculateStutterEfficiency_params->BlockHeight256BytesY = mode_lib->mp.Read256BlockHeightY; - CalculateStutterEfficiency_params->BlockWidth256BytesY = mode_lib->mp.Read256BlockWidthY; - CalculateStutterEfficiency_params->BlockHeight256BytesC = mode_lib->mp.Read256BlockHeightC; - CalculateStutterEfficiency_params->BlockWidth256BytesC = mode_lib->mp.Read256BlockWidthC; - CalculateStutterEfficiency_params->DCCYMaxUncompressedBlock = mode_lib->mp.DCCYMaxUncompressedBlock; - CalculateStutterEfficiency_params->DCCCMaxUncompressedBlock = mode_lib->mp.DCCCMaxUncompressedBlock; - CalculateStutterEfficiency_params->ReadBandwidthSurfaceLuma = mode_lib->mp.SurfaceReadBandwidthLuma; - CalculateStutterEfficiency_params->ReadBandwidthSurfaceChroma = mode_lib->mp.SurfaceReadBandwidthChroma; - CalculateStutterEfficiency_params->dpte_row_bw = mode_lib->mp.dpte_row_bw; - CalculateStutterEfficiency_params->meta_row_bw = mode_lib->mp.meta_row_bw; - CalculateStutterEfficiency_params->rob_alloc_compressed = mode_lib->ip.dcn_mrq_present; - - // output - CalculateStutterEfficiency_params->StutterEfficiencyNotIncludingVBlank = &mode_lib->mp.StutterEfficiencyNotIncludingVBlank; - CalculateStutterEfficiency_params->StutterEfficiency = &mode_lib->mp.StutterEfficiency; - CalculateStutterEfficiency_params->NumberOfStutterBurstsPerFrame = &mode_lib->mp.NumberOfStutterBurstsPerFrame; - CalculateStutterEfficiency_params->Z8StutterEfficiencyNotIncludingVBlank = &mode_lib->mp.Z8StutterEfficiencyNotIncludingVBlank; - CalculateStutterEfficiency_params->Z8StutterEfficiency = &mode_lib->mp.Z8StutterEfficiency; - CalculateStutterEfficiency_params->Z8NumberOfStutterBurstsPerFrame = &mode_lib->mp.Z8NumberOfStutterBurstsPerFrame; - CalculateStutterEfficiency_params->StutterPeriod = &mode_lib->mp.StutterPeriod; - CalculateStutterEfficiency_params->DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE = &mode_lib->mp.DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE; - - // Stutter Efficiency - CalculateStutterEfficiency(&mode_lib->scratch, CalculateStutterEfficiency_params); - -#ifdef __DML_VBA_ALLOW_DELTA__ - // Calculate z8 stutter eff assuming 0 reserved space - CalculateStutterEfficiency_params->CompbufReservedSpace64B = 0; - CalculateStutterEfficiency_params->CompbufReservedSpaceZs = 0; - - CalculateStutterEfficiency_params->Z8StutterEfficiencyNotIncludingVBlank = &mode_lib->mp.Z8StutterEfficiencyNotIncludingVBlankBestCase; - CalculateStutterEfficiency_params->Z8StutterEfficiency = &mode_lib->mp.Z8StutterEfficiencyBestCase; - CalculateStutterEfficiency_params->Z8NumberOfStutterBurstsPerFrame = &mode_lib->mp.Z8NumberOfStutterBurstsPerFrameBestCase; - CalculateStutterEfficiency_params->StutterPeriod = &mode_lib->mp.StutterPeriodBestCase; - - // Stutter Efficiency - CalculateStutterEfficiency(&mode_lib->scratch, CalculateStutterEfficiency_params); -#else - mode_lib->mp.Z8StutterEfficiencyNotIncludingVBlankBestCase = mode_lib->mp.Z8StutterEfficiencyNotIncludingVBlank; - mode_lib->mp.Z8StutterEfficiencyBestCase = mode_lib->mp.Z8StutterEfficiency; - mode_lib->mp.Z8NumberOfStutterBurstsPerFrameBestCase = mode_lib->mp.Z8NumberOfStutterBurstsPerFrame; - mode_lib->mp.StutterPeriodBestCase = mode_lib->mp.StutterPeriod; -#endif - } // PrefetchAndImmediateFlipSupported - - const long min_return_uclk_cycles = 83; - const long min_return_fclk_cycles = 75; - double max_fclk_mhz = min_clk_table->max_clocks_khz.fclk / 1000.0; - double max_uclk_mhz = mode_lib->soc.clk_table.uclk.clk_values_khz[mode_lib->soc.clk_table.uclk.num_clk_values - 1] / 1000.0; - double hard_minimum_dcfclk_mhz = (double)min_clk_table->dram_bw_table.entries[0].min_dcfclk_khz / 1000.0; - double min_return_latency_in_DCFCLK_cycles = (min_return_uclk_cycles / max_uclk_mhz + min_return_fclk_cycles / max_fclk_mhz) * hard_minimum_dcfclk_mhz; - mode_lib->mp.min_return_latency_in_dcfclk = (unsigned int)min_return_latency_in_DCFCLK_cycles; - mode_lib->mp.dcfclk_deep_sleep_hysteresis = (unsigned int)math_max2(32, (double)mode_lib->ip.pixel_chunk_size_kbytes * 1024 * 3 / 4 / 64 - min_return_latency_in_DCFCLK_cycles); - mode_lib->mp.dcfclk_deep_sleep_hysteresis = 255; - DML2_ASSERT(mode_lib->mp.dcfclk_deep_sleep_hysteresis < 256); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: max_fclk_mhz = %f\n", __func__, max_fclk_mhz); - dml2_printf("DML::%s: max_uclk_mhz = %f\n", __func__, max_uclk_mhz); - dml2_printf("DML::%s: hard_minimum_dcfclk_mhz = %f\n", __func__, hard_minimum_dcfclk_mhz); - dml2_printf("DML::%s: min_return_uclk_cycles = %d\n", __func__, min_return_uclk_cycles); - dml2_printf("DML::%s: min_return_fclk_cycles = %d\n", __func__, min_return_fclk_cycles); - dml2_printf("DML::%s: min_return_latency_in_DCFCLK_cycles = %f\n", __func__, min_return_latency_in_DCFCLK_cycles); - dml2_printf("DML::%s: dcfclk_deep_sleep_hysteresis = %d \n", __func__, mode_lib->mp.dcfclk_deep_sleep_hysteresis); - dml2_printf("DML::%s: --- END --- \n", __func__); -#endif - - return (in_out_params->mode_lib->mp.PrefetchAndImmediateFlipSupported); -} - -static bool dml_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; -} - -static unsigned int dml_get_plane_idx(const struct dml2_core_internal_display_mode_lib *mode_lib, unsigned int pipe_idx) -{ - unsigned int plane_idx = mode_lib->mp.pipe_plane[pipe_idx]; - return plane_idx; -} - -static void rq_dlg_get_wm_regs(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_dchub_watermark_regs *wm_regs) -{ - double refclk_freq_in_mhz = (display_cfg->overrides.hw.dlg_ref_clk_mhz > 0) ? (double)display_cfg->overrides.hw.dlg_ref_clk_mhz : mode_lib->soc.dchub_refclk_mhz; - - wm_regs->fclk_pstate = (int unsigned)(mode_lib->mp.Watermark.FCLKChangeWatermark * refclk_freq_in_mhz); - wm_regs->sr_enter = (int unsigned)(mode_lib->mp.Watermark.StutterEnterPlusExitWatermark * refclk_freq_in_mhz); - wm_regs->sr_exit = (int unsigned)(mode_lib->mp.Watermark.StutterExitWatermark * refclk_freq_in_mhz); - wm_regs->temp_read_or_ppt = 0; - wm_regs->uclk_pstate = (int unsigned)(mode_lib->mp.Watermark.DRAMClockChangeWatermark * refclk_freq_in_mhz); - wm_regs->urgent = (int unsigned)(mode_lib->mp.Watermark.UrgentWatermark * refclk_freq_in_mhz); -} - -static unsigned int log_and_substract_if_non_zero(unsigned int a, unsigned int subtrahend) -{ - if (a == 0) - return 0; - - return (math_log2_approx(a) - subtrahend); -} - -void dml2_core_shared_cursor_dlg_reg(struct dml2_cursor_dlg_regs *cursor_dlg_regs, const struct dml2_get_cursor_dlg_reg *p) -{ - int dst_x_offset = (int)((p->cursor_x_position + (p->cursor_stereo_en == 0 ? 0 : math_max2(p->cursor_primary_offset, p->cursor_secondary_offset)) - - (p->cursor_hotspot_x * (p->cursor_2x_magnify == 0 ? 1 : 2))) * p->dlg_refclk_mhz / p->pixel_rate_mhz / p->hratio); - cursor_dlg_regs->dst_x_offset = (unsigned int)((dst_x_offset > 0) ? dst_x_offset : 0); - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML_DLG::%s: cursor_x_position=%d\n", __func__, p->cursor_x_position); - dml2_printf("DML_DLG::%s: dlg_refclk_mhz=%f\n", __func__, p->dlg_refclk_mhz); - dml2_printf("DML_DLG::%s: pixel_rate_mhz=%f\n", __func__, p->pixel_rate_mhz); - dml2_printf("DML_DLG::%s: dst_x_offset=%d\n", __func__, dst_x_offset); - dml2_printf("DML_DLG::%s: dst_x_offset=%d (reg)\n", __func__, cursor_dlg_regs->dst_x_offset); -#endif - - cursor_dlg_regs->chunk_hdl_adjust = 3; - cursor_dlg_regs->dst_y_offset = 0; - - cursor_dlg_regs->qos_level_fixed = 8; - cursor_dlg_regs->qos_ramp_disable = 0; -} - -static void rq_dlg_get_rq_reg(struct dml2_display_rq_regs *rq_regs, - const struct dml2_display_cfg *display_cfg, - const struct dml2_core_internal_display_mode_lib *mode_lib, - unsigned int pipe_idx) -{ - dml2_printf("DML_DLG::%s: Calculation for pipe[%d] start\n", __func__, pipe_idx); - - unsigned int plane_idx = dml_get_plane_idx(mode_lib, pipe_idx); - enum dml2_source_format_class source_format = display_cfg->plane_descriptors[plane_idx].pixel_format; - enum dml2_swizzle_mode sw_mode = display_cfg->plane_descriptors[plane_idx].surface.tiling; - bool dual_plane = dml_is_dual_plane((enum dml2_source_format_class)(source_format)); - - unsigned int pixel_chunk_bytes = 0; - unsigned int min_pixel_chunk_bytes = 0; - unsigned int dpte_group_bytes = 0; - unsigned int mpte_group_bytes = 0; - - unsigned int p1_pixel_chunk_bytes = 0; - unsigned int p1_min_pixel_chunk_bytes = 0; - unsigned int p1_dpte_group_bytes = 0; - unsigned int p1_mpte_group_bytes = 0; - - pixel_chunk_bytes = (unsigned int)(mode_lib->ip.pixel_chunk_size_kbytes * 1024); - min_pixel_chunk_bytes = (unsigned int)(mode_lib->ip.min_pixel_chunk_size_bytes); - - if (pixel_chunk_bytes == 64 * 1024) - min_pixel_chunk_bytes = 0; - - dpte_group_bytes = (unsigned int)(mode_lib->mp.dpte_group_bytes[mode_lib->mp.pipe_plane[pipe_idx]]); - mpte_group_bytes = (unsigned int)(mode_lib->mp.vm_group_bytes[mode_lib->mp.pipe_plane[pipe_idx]]); - - p1_pixel_chunk_bytes = pixel_chunk_bytes; - p1_min_pixel_chunk_bytes = min_pixel_chunk_bytes; - p1_dpte_group_bytes = dpte_group_bytes; - p1_mpte_group_bytes = mpte_group_bytes; - - if (source_format == dml2_rgbe_alpha) - p1_pixel_chunk_bytes = (unsigned int)(mode_lib->ip.alpha_pixel_chunk_size_kbytes * 1024); - - rq_regs->unbounded_request_enabled = mode_lib->mp.UnboundedRequestEnabled; - rq_regs->rq_regs_l.chunk_size = log_and_substract_if_non_zero(pixel_chunk_bytes, 10); - rq_regs->rq_regs_c.chunk_size = log_and_substract_if_non_zero(p1_pixel_chunk_bytes, 10); - - if (min_pixel_chunk_bytes == 0) - rq_regs->rq_regs_l.min_chunk_size = 0; - else - rq_regs->rq_regs_l.min_chunk_size = log_and_substract_if_non_zero(min_pixel_chunk_bytes, 8 - 1); - - if (p1_min_pixel_chunk_bytes == 0) - rq_regs->rq_regs_c.min_chunk_size = 0; - else - rq_regs->rq_regs_c.min_chunk_size = log_and_substract_if_non_zero(p1_min_pixel_chunk_bytes, 8 - 1); - - rq_regs->rq_regs_l.dpte_group_size = log_and_substract_if_non_zero(dpte_group_bytes, 6); - rq_regs->rq_regs_l.mpte_group_size = log_and_substract_if_non_zero(mpte_group_bytes, 6); - rq_regs->rq_regs_c.dpte_group_size = log_and_substract_if_non_zero(p1_dpte_group_bytes, 6); - rq_regs->rq_regs_c.mpte_group_size = log_and_substract_if_non_zero(p1_mpte_group_bytes, 6); - - unsigned int detile_buf_size_in_bytes = (unsigned int)(mode_lib->mp.DETBufferSizeInKByte[mode_lib->mp.pipe_plane[pipe_idx]] * 1024); - unsigned int detile_buf_plane1_addr = 0; - - if (sw_mode == dml2_sw_linear && display_cfg->gpuvm_enable) { - unsigned int p0_pte_row_height_linear = (unsigned int)(mode_lib->mp.dpte_row_height_linear[mode_lib->mp.pipe_plane[pipe_idx]]); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML_DLG: %s: p0_pte_row_height_linear = %u\n", __func__, p0_pte_row_height_linear); -#endif - DML2_ASSERT(p0_pte_row_height_linear >= 8); - - rq_regs->rq_regs_l.pte_row_height_linear = math_log2_approx(p0_pte_row_height_linear) - 3; - if (dual_plane) { - unsigned int p1_pte_row_height_linear = (unsigned int)(mode_lib->mp.dpte_row_height_linear_chroma[mode_lib->mp.pipe_plane[pipe_idx]]); -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML_DLG: %s: p1_pte_row_height_linear = %u\n", __func__, p1_pte_row_height_linear); -#endif - if (sw_mode == dml2_sw_linear) { - DML2_ASSERT(p1_pte_row_height_linear >= 8); - } - - rq_regs->rq_regs_c.pte_row_height_linear = math_log2_approx(p1_pte_row_height_linear) - 3; - } - } else { - rq_regs->rq_regs_l.pte_row_height_linear = 0; - rq_regs->rq_regs_c.pte_row_height_linear = 0; - } - - rq_regs->rq_regs_l.swath_height = log_and_substract_if_non_zero(mode_lib->mp.SwathHeightY[mode_lib->mp.pipe_plane[pipe_idx]], 0); - rq_regs->rq_regs_c.swath_height = log_and_substract_if_non_zero(mode_lib->mp.SwathHeightC[mode_lib->mp.pipe_plane[pipe_idx]], 0); - - // FIXME_DCN4, programming guide has dGPU condition - if (pixel_chunk_bytes >= 32 * 1024 || (dual_plane && p1_pixel_chunk_bytes >= 32 * 1024)) { //32kb - rq_regs->drq_expansion_mode = 0; - } else { - rq_regs->drq_expansion_mode = 2; - } - rq_regs->prq_expansion_mode = 1; - rq_regs->crq_expansion_mode = 1; - rq_regs->mrq_expansion_mode = 1; - - double stored_swath_l_bytes = mode_lib->mp.DETBufferSizeY[mode_lib->mp.pipe_plane[pipe_idx]]; - double stored_swath_c_bytes = mode_lib->mp.DETBufferSizeC[mode_lib->mp.pipe_plane[pipe_idx]]; - bool is_phantom_pipe = dml_get_is_phantom_pipe(display_cfg, mode_lib, pipe_idx); - - // Note: detile_buf_plane1_addr is in unit of 1KB - if (dual_plane) { - if (is_phantom_pipe) { - detile_buf_plane1_addr = (unsigned int)((1024.0 * 1024.0) / 2.0 / 1024.0); // half to chroma - } else { - if (stored_swath_l_bytes / stored_swath_c_bytes <= 1.5) { - detile_buf_plane1_addr = (unsigned int)(detile_buf_size_in_bytes / 2.0 / 1024.0); // half to chroma -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML_DLG: %s: detile_buf_plane1_addr = %d (1/2 to chroma)\n", __func__, detile_buf_plane1_addr); -#endif - } else { - detile_buf_plane1_addr = (unsigned int)(dml_round_to_multiple((unsigned int)((2.0 * detile_buf_size_in_bytes) / 3.0), 1024, 0) / 1024.0); // 2/3 to luma -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML_DLG: %s: detile_buf_plane1_addr = %d (1/3 chroma)\n", __func__, detile_buf_plane1_addr); -#endif - } - } - } - rq_regs->plane1_base_address = detile_buf_plane1_addr; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML_DLG: %s: is_phantom_pipe = %d\n", __func__, is_phantom_pipe); - dml2_printf("DML_DLG: %s: stored_swath_l_bytes = %f\n", __func__, stored_swath_l_bytes); - dml2_printf("DML_DLG: %s: stored_swath_c_bytes = %f\n", __func__, stored_swath_c_bytes); - dml2_printf("DML_DLG: %s: detile_buf_size_in_bytes = %d\n", __func__, detile_buf_size_in_bytes); - dml2_printf("DML_DLG: %s: detile_buf_plane1_addr = %d\n", __func__, detile_buf_plane1_addr); - dml2_printf("DML_DLG: %s: plane1_base_address = %d\n", __func__, rq_regs->plane1_base_address); -#endif - //dml2_printf_rq_regs_st(rq_regs); - dml2_printf("DML_DLG::%s: Calculation for pipe[%d] done\n", __func__, pipe_idx); -} - -static void rq_dlg_get_dlg_reg( - struct dml2_core_internal_scratch *s, - struct dml2_display_dlg_regs *disp_dlg_regs, - struct dml2_display_ttu_regs *disp_ttu_regs, - const struct dml2_display_cfg *display_cfg, - const struct dml2_core_internal_display_mode_lib *mode_lib, - const unsigned int pipe_idx) -{ - struct dml2_core_shared_rq_dlg_get_dlg_reg_locals *l = &s->rq_dlg_get_dlg_reg_locals; - - memset(l, 0, sizeof(struct dml2_core_shared_rq_dlg_get_dlg_reg_locals)); - - dml2_printf("DML_DLG::%s: Calculation for pipe_idx=%d\n", __func__, pipe_idx); - - l->plane_idx = dml_get_plane_idx(mode_lib, pipe_idx); - dml2_assert(l->plane_idx < DML2_MAX_PLANES); - - l->source_format = dml2_444_8; - l->dual_plane = dml_is_dual_plane(l->source_format); - l->odm_mode = dml2_odm_mode_bypass; - - l->htotal = 0; - l->hactive = 0; - l->hblank_end = 0; - l->vblank_end = 0; - l->interlaced = false; - l->pclk_freq_in_mhz = 0.0; - l->refclk_freq_in_mhz = (display_cfg->overrides.hw.dlg_ref_clk_mhz > 0) ? (double)display_cfg->overrides.hw.dlg_ref_clk_mhz : mode_lib->soc.dchub_refclk_mhz; - l->ref_freq_to_pix_freq = 0.0; - - if (l->plane_idx < DML2_MAX_PLANES) { - - l->timing = &display_cfg->stream_descriptors[display_cfg->plane_descriptors[l->plane_idx].stream_index].timing; - l->source_format = display_cfg->plane_descriptors[l->plane_idx].pixel_format; - l->odm_mode = mode_lib->mp.ODMMode[l->plane_idx]; - - l->htotal = l->timing->h_total; - l->hactive = l->timing->h_active; - l->hblank_end = l->timing->h_blank_end; - l->vblank_end = l->timing->v_blank_end; - l->interlaced = l->timing->interlaced; - l->pclk_freq_in_mhz = (double)l->timing->pixel_clock_khz / 1000; - l->ref_freq_to_pix_freq = l->refclk_freq_in_mhz / l->pclk_freq_in_mhz; - - dml2_printf("DML_DLG::%s: plane_idx = %d\n", __func__, l->plane_idx); - dml2_printf("DML_DLG: %s: htotal = %d\n", __func__, l->htotal); - dml2_printf("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, l->refclk_freq_in_mhz); - dml2_printf("DML_DLG: %s: dlg_ref_clk_mhz = %3.2f\n", __func__, display_cfg->overrides.hw.dlg_ref_clk_mhz); - dml2_printf("DML_DLG: %s: soc.refclk_mhz = %3.2f\n", __func__, mode_lib->soc.dchub_refclk_mhz); - dml2_printf("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, l->pclk_freq_in_mhz); - dml2_printf("DML_DLG: %s: ref_freq_to_pix_freq = %3.2f\n", __func__, l->ref_freq_to_pix_freq); - dml2_printf("DML_DLG: %s: interlaced = %d\n", __func__, l->interlaced); - - DML2_ASSERT(l->refclk_freq_in_mhz != 0); - DML2_ASSERT(l->pclk_freq_in_mhz != 0); - DML2_ASSERT(l->ref_freq_to_pix_freq < 4.0); - - // Need to figure out which side of odm combine we're in - // Assume the pipe instance under the same plane is in order - - if (l->odm_mode == dml2_odm_mode_bypass) { - disp_dlg_regs->refcyc_h_blank_end = (unsigned int)((double)l->hblank_end * l->ref_freq_to_pix_freq); - } else if (l->odm_mode == dml2_odm_mode_combine_2to1 || l->odm_mode == dml2_odm_mode_combine_3to1 || l->odm_mode == dml2_odm_mode_combine_4to1) { - // find out how many pipe are in this plane - l->num_active_pipes = mode_lib->mp.num_active_pipes; - l->first_pipe_idx_in_plane = DML2_MAX_PLANES; - l->pipe_idx_in_combine = 0; // pipe index within the plane - l->odm_combine_factor = 2; - - if (l->odm_mode == dml2_odm_mode_combine_3to1) - l->odm_combine_factor = 3; - else if (l->odm_mode == dml2_odm_mode_combine_4to1) - l->odm_combine_factor = 4; - - for (unsigned int i = 0; i < l->num_active_pipes; i++) { - if (dml_get_plane_idx(mode_lib, i) == l->plane_idx) { - if (i < l->first_pipe_idx_in_plane) { - l->first_pipe_idx_in_plane = i; - } - } - } - l->pipe_idx_in_combine = pipe_idx - l->first_pipe_idx_in_plane; // DML assumes the pipes in the same plane will have continuous indexing (i.e. plane 0 use pipe 0, 1, and plane 1 uses pipe 2, 3, etc.) - - disp_dlg_regs->refcyc_h_blank_end = (unsigned int)(((double)l->hblank_end + (double)l->pipe_idx_in_combine * (double)l->hactive / (double)l->odm_combine_factor) * l->ref_freq_to_pix_freq); - dml2_printf("DML_DLG: %s: pipe_idx = %d\n", __func__, pipe_idx); - dml2_printf("DML_DLG: %s: first_pipe_idx_in_plane = %d\n", __func__, l->first_pipe_idx_in_plane); - dml2_printf("DML_DLG: %s: pipe_idx_in_combine = %d\n", __func__, l->pipe_idx_in_combine); - dml2_printf("DML_DLG: %s: odm_combine_factor = %d\n", __func__, l->odm_combine_factor); - } - dml2_printf("DML_DLG: %s: refcyc_h_blank_end = %d\n", __func__, disp_dlg_regs->refcyc_h_blank_end); - - DML2_ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int)math_pow(2, 13)); - - disp_dlg_regs->ref_freq_to_pix_freq = (unsigned int)(l->ref_freq_to_pix_freq * math_pow(2, 19)); - disp_dlg_regs->refcyc_per_htotal = (unsigned int)(l->ref_freq_to_pix_freq * (double)l->htotal * math_pow(2, 8)); - disp_dlg_regs->dlg_vblank_end = l->interlaced ? (l->vblank_end / 2) : l->vblank_end; // 15 bits - - l->min_ttu_vblank = mode_lib->mp.MinTTUVBlank[mode_lib->mp.pipe_plane[pipe_idx]]; - l->min_dst_y_next_start = (unsigned int)(mode_lib->mp.MIN_DST_Y_NEXT_START[mode_lib->mp.pipe_plane[pipe_idx]]); - - dml2_printf("DML_DLG: %s: min_ttu_vblank (us) = %3.2f\n", __func__, l->min_ttu_vblank); - dml2_printf("DML_DLG: %s: min_dst_y_next_start = %d\n", __func__, l->min_dst_y_next_start); - dml2_printf("DML_DLG: %s: ref_freq_to_pix_freq = %3.2f\n", __func__, l->ref_freq_to_pix_freq); - - l->vready_after_vcount0 = (unsigned int)(mode_lib->mp.VREADY_AT_OR_AFTER_VSYNC[mode_lib->mp.pipe_plane[pipe_idx]]); - disp_dlg_regs->vready_after_vcount0 = l->vready_after_vcount0; - - dml2_printf("DML_DLG: %s: vready_after_vcount0 = %d\n", __func__, disp_dlg_regs->vready_after_vcount0); - - l->dst_x_after_scaler = (unsigned int)(mode_lib->mp.DSTXAfterScaler[mode_lib->mp.pipe_plane[pipe_idx]]); - l->dst_y_after_scaler = (unsigned int)(mode_lib->mp.DSTYAfterScaler[mode_lib->mp.pipe_plane[pipe_idx]]); - - dml2_printf("DML_DLG: %s: dst_x_after_scaler = %d\n", __func__, l->dst_x_after_scaler); - dml2_printf("DML_DLG: %s: dst_y_after_scaler = %d\n", __func__, l->dst_y_after_scaler); - - l->dst_y_prefetch = mode_lib->mp.dst_y_prefetch[mode_lib->mp.pipe_plane[pipe_idx]]; - l->dst_y_per_vm_vblank = mode_lib->mp.dst_y_per_vm_vblank[mode_lib->mp.pipe_plane[pipe_idx]]; - l->dst_y_per_row_vblank = mode_lib->mp.dst_y_per_row_vblank[mode_lib->mp.pipe_plane[pipe_idx]]; - l->dst_y_per_vm_flip = mode_lib->mp.dst_y_per_vm_flip[mode_lib->mp.pipe_plane[pipe_idx]]; - l->dst_y_per_row_flip = mode_lib->mp.dst_y_per_row_flip[mode_lib->mp.pipe_plane[pipe_idx]]; - - l->max_dst_y_per_vm_vblank = 32.0; //U5.2 - l->max_dst_y_per_row_vblank = 16.0; //U4.2 - - // magic! - if (l->htotal <= 75) { - l->max_dst_y_per_vm_vblank = 100.0; - l->max_dst_y_per_row_vblank = 100.0; - } - - dml2_printf("DML_DLG: %s: dst_y_prefetch (after rnd) = %3.2f\n", __func__, l->dst_y_prefetch); - dml2_printf("DML_DLG: %s: dst_y_per_vm_flip = %3.2f\n", __func__, l->dst_y_per_vm_flip); - dml2_printf("DML_DLG: %s: dst_y_per_row_flip = %3.2f\n", __func__, l->dst_y_per_row_flip); - dml2_printf("DML_DLG: %s: dst_y_per_vm_vblank = %3.2f\n", __func__, l->dst_y_per_vm_vblank); - dml2_printf("DML_DLG: %s: dst_y_per_row_vblank = %3.2f\n", __func__, l->dst_y_per_row_vblank); - - DML2_ASSERT(l->dst_y_per_vm_vblank < l->max_dst_y_per_vm_vblank); - DML2_ASSERT(l->dst_y_per_row_vblank < l->max_dst_y_per_row_vblank); - if (l->dst_y_prefetch > 0 && l->dst_y_per_vm_vblank > 0 && l->dst_y_per_row_vblank > 0) { - DML2_ASSERT(l->dst_y_prefetch > (l->dst_y_per_vm_vblank + l->dst_y_per_row_vblank)); - } - - l->vratio_pre_l = mode_lib->mp.VRatioPrefetchY[mode_lib->mp.pipe_plane[pipe_idx]]; - l->vratio_pre_c = mode_lib->mp.VRatioPrefetchC[mode_lib->mp.pipe_plane[pipe_idx]]; - - dml2_printf("DML_DLG: %s: vratio_pre_l = %3.2f\n", __func__, l->vratio_pre_l); - dml2_printf("DML_DLG: %s: vratio_pre_c = %3.2f\n", __func__, l->vratio_pre_c); - - // Active - l->refcyc_per_line_delivery_pre_l = mode_lib->mp.DisplayPipeLineDeliveryTimeLumaPrefetch[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_line_delivery_l = mode_lib->mp.DisplayPipeLineDeliveryTimeLuma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - - dml2_printf("DML_DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f\n", __func__, l->refcyc_per_line_delivery_pre_l); - dml2_printf("DML_DLG: %s: refcyc_per_line_delivery_l = %3.2f\n", __func__, l->refcyc_per_line_delivery_l); - - l->refcyc_per_line_delivery_pre_c = 0.0; - l->refcyc_per_line_delivery_c = 0.0; - - if (l->dual_plane) { - l->refcyc_per_line_delivery_pre_c = mode_lib->mp.DisplayPipeLineDeliveryTimeChromaPrefetch[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_line_delivery_c = mode_lib->mp.DisplayPipeLineDeliveryTimeChroma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - - dml2_printf("DML_DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f\n", __func__, l->refcyc_per_line_delivery_pre_c); - dml2_printf("DML_DLG: %s: refcyc_per_line_delivery_c = %3.2f\n", __func__, l->refcyc_per_line_delivery_c); - } - - disp_dlg_regs->refcyc_per_vm_dmdata = (unsigned int)(mode_lib->mp.Tdmdl_vm[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz); - disp_dlg_regs->dmdata_dl_delta = (unsigned int)(mode_lib->mp.Tdmdl[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz); - - l->refcyc_per_req_delivery_pre_l = mode_lib->mp.DisplayPipeRequestDeliveryTimeLumaPrefetch[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_req_delivery_l = mode_lib->mp.DisplayPipeRequestDeliveryTimeLuma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - - dml2_printf("DML_DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f\n", __func__, l->refcyc_per_req_delivery_pre_l); - dml2_printf("DML_DLG: %s: refcyc_per_req_delivery_l = %3.2f\n", __func__, l->refcyc_per_req_delivery_l); - - l->refcyc_per_req_delivery_pre_c = 0.0; - l->refcyc_per_req_delivery_c = 0.0; - if (l->dual_plane) { - l->refcyc_per_req_delivery_pre_c = mode_lib->mp.DisplayPipeRequestDeliveryTimeChromaPrefetch[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_req_delivery_c = mode_lib->mp.DisplayPipeRequestDeliveryTimeChroma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - - dml2_printf("DML_DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f\n", __func__, l->refcyc_per_req_delivery_pre_c); - dml2_printf("DML_DLG: %s: refcyc_per_req_delivery_c = %3.2f\n", __func__, l->refcyc_per_req_delivery_c); - } - - // TTU - Cursor - DML2_ASSERT(display_cfg->plane_descriptors[l->plane_idx].cursor.num_cursors <= 1); - - // Assign to register structures - disp_dlg_regs->min_dst_y_next_start = (unsigned int)((double)l->min_dst_y_next_start * math_pow(2, 2)); - DML2_ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int)math_pow(2, 18)); - - disp_dlg_regs->dst_y_after_scaler = l->dst_y_after_scaler; // in terms of line - disp_dlg_regs->refcyc_x_after_scaler = (unsigned int)((double)l->dst_x_after_scaler * l->ref_freq_to_pix_freq); // in terms of refclk - disp_dlg_regs->dst_y_prefetch = (unsigned int)(l->dst_y_prefetch * math_pow(2, 2)); - disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int)(l->dst_y_per_vm_vblank * math_pow(2, 2)); - disp_dlg_regs->dst_y_per_row_vblank = (unsigned int)(l->dst_y_per_row_vblank * math_pow(2, 2)); - disp_dlg_regs->dst_y_per_vm_flip = (unsigned int)(l->dst_y_per_vm_flip * math_pow(2, 2)); - disp_dlg_regs->dst_y_per_row_flip = (unsigned int)(l->dst_y_per_row_flip * math_pow(2, 2)); - - disp_dlg_regs->vratio_prefetch = (unsigned int)(l->vratio_pre_l * math_pow(2, 19)); - disp_dlg_regs->vratio_prefetch_c = (unsigned int)(l->vratio_pre_c * math_pow(2, 19)); - - dml2_printf("DML_DLG: %s: disp_dlg_regs->dst_y_per_vm_vblank = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_vm_vblank); - dml2_printf("DML_DLG: %s: disp_dlg_regs->dst_y_per_row_vblank = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_row_vblank); - dml2_printf("DML_DLG: %s: disp_dlg_regs->dst_y_per_vm_flip = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_vm_flip); - dml2_printf("DML_DLG: %s: disp_dlg_regs->dst_y_per_row_flip = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_row_flip); - - disp_dlg_regs->refcyc_per_vm_group_vblank = (unsigned int)(mode_lib->mp.TimePerVMGroupVBlank[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz); - disp_dlg_regs->refcyc_per_vm_group_flip = (unsigned int)(mode_lib->mp.TimePerVMGroupFlip[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz); - disp_dlg_regs->refcyc_per_vm_req_vblank = (unsigned int)(mode_lib->mp.TimePerVMRequestVBlank[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz * math_pow(2, 10)); - disp_dlg_regs->refcyc_per_vm_req_flip = (unsigned int)(mode_lib->mp.TimePerVMRequestFlip[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz * math_pow(2, 10)); - - l->dst_y_per_pte_row_nom_l = mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_L[mode_lib->mp.pipe_plane[pipe_idx]]; - l->dst_y_per_pte_row_nom_c = mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_C[mode_lib->mp.pipe_plane[pipe_idx]]; - l->refcyc_per_pte_group_nom_l = mode_lib->mp.time_per_pte_group_nom_luma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_pte_group_nom_c = mode_lib->mp.time_per_pte_group_nom_chroma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_pte_group_vblank_l = mode_lib->mp.time_per_pte_group_vblank_luma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_pte_group_vblank_c = mode_lib->mp.time_per_pte_group_vblank_chroma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_pte_group_flip_l = mode_lib->mp.time_per_pte_group_flip_luma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_pte_group_flip_c = mode_lib->mp.time_per_pte_group_flip_chroma[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_tdlut_group = mode_lib->mp.time_per_tdlut_group[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - - disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int)(l->dst_y_per_pte_row_nom_l * math_pow(2, 2)); - disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int)(l->dst_y_per_pte_row_nom_c * math_pow(2, 2)); - - disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int)(l->refcyc_per_pte_group_nom_l); - disp_dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int)(l->refcyc_per_pte_group_nom_c); - disp_dlg_regs->refcyc_per_pte_group_vblank_l = (unsigned int)(l->refcyc_per_pte_group_vblank_l); - disp_dlg_regs->refcyc_per_pte_group_vblank_c = (unsigned int)(l->refcyc_per_pte_group_vblank_c); - disp_dlg_regs->refcyc_per_pte_group_flip_l = (unsigned int)(l->refcyc_per_pte_group_flip_l); - disp_dlg_regs->refcyc_per_pte_group_flip_c = (unsigned int)(l->refcyc_per_pte_group_flip_c); - disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int)math_floor2(l->refcyc_per_line_delivery_pre_l, 1); - disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int)math_floor2(l->refcyc_per_line_delivery_l, 1); - disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int)math_floor2(l->refcyc_per_line_delivery_pre_c, 1); - disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int)math_floor2(l->refcyc_per_line_delivery_c, 1); - - l->dst_y_per_meta_row_nom_l = mode_lib->mp.DST_Y_PER_META_ROW_NOM_L[mode_lib->mp.pipe_plane[pipe_idx]]; - l->dst_y_per_meta_row_nom_c = mode_lib->mp.DST_Y_PER_META_ROW_NOM_C[mode_lib->mp.pipe_plane[pipe_idx]]; - l->refcyc_per_meta_chunk_nom_l = mode_lib->mp.TimePerMetaChunkNominal[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_meta_chunk_nom_c = mode_lib->mp.TimePerChromaMetaChunkNominal[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_meta_chunk_vblank_l = mode_lib->mp.TimePerMetaChunkVBlank[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_meta_chunk_vblank_c = mode_lib->mp.TimePerChromaMetaChunkVBlank[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_meta_chunk_flip_l = mode_lib->mp.TimePerMetaChunkFlip[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - l->refcyc_per_meta_chunk_flip_c = mode_lib->mp.TimePerChromaMetaChunkFlip[mode_lib->mp.pipe_plane[pipe_idx]] * l->refclk_freq_in_mhz; - - disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int)(l->dst_y_per_meta_row_nom_l * math_pow(2, 2)); - disp_dlg_regs->dst_y_per_meta_row_nom_c = (unsigned int)(l->dst_y_per_meta_row_nom_c * math_pow(2, 2)); - disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int)(l->refcyc_per_meta_chunk_nom_l); - disp_dlg_regs->refcyc_per_meta_chunk_nom_c = (unsigned int)(l->refcyc_per_meta_chunk_nom_c); - disp_dlg_regs->refcyc_per_meta_chunk_vblank_l = (unsigned int)(l->refcyc_per_meta_chunk_vblank_l); - disp_dlg_regs->refcyc_per_meta_chunk_vblank_c = (unsigned int)(l->refcyc_per_meta_chunk_vblank_c); - disp_dlg_regs->refcyc_per_meta_chunk_flip_l = (unsigned int)(l->refcyc_per_meta_chunk_flip_l); - disp_dlg_regs->refcyc_per_meta_chunk_flip_c = (unsigned int)(l->refcyc_per_meta_chunk_flip_c); - - disp_dlg_regs->refcyc_per_tdlut_group = (unsigned int)(l->refcyc_per_tdlut_group); - disp_dlg_regs->dst_y_delta_drq_limit = 0x7fff; // off - - disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int)(l->refcyc_per_req_delivery_pre_l * math_pow(2, 10)); - disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int)(l->refcyc_per_req_delivery_l * math_pow(2, 10)); - disp_ttu_regs->refcyc_per_req_delivery_pre_c = (unsigned int)(l->refcyc_per_req_delivery_pre_c * math_pow(2, 10)); - disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int)(l->refcyc_per_req_delivery_c * math_pow(2, 10)); - disp_ttu_regs->qos_level_low_wm = 0; - - disp_ttu_regs->qos_level_high_wm = (unsigned int)(4.0 * (double)l->htotal * l->ref_freq_to_pix_freq); - - disp_ttu_regs->qos_level_flip = 14; - disp_ttu_regs->qos_level_fixed_l = 8; - disp_ttu_regs->qos_level_fixed_c = 8; - disp_ttu_regs->qos_ramp_disable_l = 0; - disp_ttu_regs->qos_ramp_disable_c = 0; - disp_ttu_regs->min_ttu_vblank = (unsigned int)(l->min_ttu_vblank * l->refclk_freq_in_mhz); - - // CHECK for HW registers' range, DML2_ASSERT or clamp - DML2_ASSERT(l->refcyc_per_req_delivery_pre_l < math_pow(2, 13)); - DML2_ASSERT(l->refcyc_per_req_delivery_l < math_pow(2, 13)); - DML2_ASSERT(l->refcyc_per_req_delivery_pre_c < math_pow(2, 13)); - DML2_ASSERT(l->refcyc_per_req_delivery_c < math_pow(2, 13)); - if (disp_dlg_regs->refcyc_per_vm_group_vblank >= (unsigned int)math_pow(2, 23)) - disp_dlg_regs->refcyc_per_vm_group_vblank = (unsigned int)(math_pow(2, 23) - 1); - - if (disp_dlg_regs->refcyc_per_vm_group_flip >= (unsigned int)math_pow(2, 23)) - disp_dlg_regs->refcyc_per_vm_group_flip = (unsigned int)(math_pow(2, 23) - 1); - - if (disp_dlg_regs->refcyc_per_vm_req_vblank >= (unsigned int)math_pow(2, 23)) - disp_dlg_regs->refcyc_per_vm_req_vblank = (unsigned int)(math_pow(2, 23) - 1); - - if (disp_dlg_regs->refcyc_per_vm_req_flip >= (unsigned int)math_pow(2, 23)) - disp_dlg_regs->refcyc_per_vm_req_flip = (unsigned int)(math_pow(2, 23) - 1); - - - DML2_ASSERT(disp_dlg_regs->dst_y_after_scaler < (unsigned int)8); - DML2_ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int)math_pow(2, 13)); - - if (disp_dlg_regs->dst_y_per_pte_row_nom_l >= (unsigned int)math_pow(2, 17)) { - dml2_printf("DML_DLG: %s: Warning DST_Y_PER_PTE_ROW_NOM_L %u > register max U15.2 %u, clamp to max\n", __func__, disp_dlg_regs->dst_y_per_pte_row_nom_l, (unsigned int)math_pow(2, 17) - 1); - l->dst_y_per_pte_row_nom_l = (unsigned int)math_pow(2, 17) - 1; - } - if (l->dual_plane) { - if (disp_dlg_regs->dst_y_per_pte_row_nom_c >= (unsigned int)math_pow(2, 17)) { - dml2_printf("DML_DLG: %s: Warning DST_Y_PER_PTE_ROW_NOM_C %u > register max U15.2 %u, clamp to max\n", __func__, disp_dlg_regs->dst_y_per_pte_row_nom_c, (unsigned int)math_pow(2, 17) - 1); - l->dst_y_per_pte_row_nom_c = (unsigned int)math_pow(2, 17) - 1; - } - } - - if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int)math_pow(2, 23)) - disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int)(math_pow(2, 23) - 1); - if (l->dual_plane) { - if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int)math_pow(2, 23)) - disp_dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int)(math_pow(2, 23) - 1); - } - DML2_ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int)math_pow(2, 13)); - if (l->dual_plane) { - DML2_ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c < (unsigned int)math_pow(2, 13)); - } - - DML2_ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int)math_pow(2, 13)); - DML2_ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int)math_pow(2, 13)); - DML2_ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int)math_pow(2, 13)); - DML2_ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int)math_pow(2, 13)); - DML2_ASSERT(disp_ttu_regs->qos_level_low_wm < (unsigned int)math_pow(2, 14)); - DML2_ASSERT(disp_ttu_regs->qos_level_high_wm < (unsigned int)math_pow(2, 14)); - DML2_ASSERT(disp_ttu_regs->min_ttu_vblank < (unsigned int)math_pow(2, 24)); - - dml2_printf("DML_DLG::%s: Calculation for pipe[%d] done\n", __func__, pipe_idx); - - } -} - -static void rq_dlg_get_arb_params(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_display_arb_regs *arb_param) -{ - arb_param->max_req_outstanding = mode_lib->soc.max_outstanding_reqs; - arb_param->min_req_outstanding = mode_lib->soc.max_outstanding_reqs; // turn off the sat level feature if this set to max - arb_param->sdpif_request_rate_limit = (3 * mode_lib->ip.words_per_channel * mode_lib->soc.clk_table.dram_config.channel_count) / 4; - arb_param->sdpif_request_rate_limit = arb_param->sdpif_request_rate_limit < 96 ? 96 : arb_param->sdpif_request_rate_limit; - arb_param->sat_level_us = 60; - arb_param->hvm_max_qos_commit_threshold = 0xf; - arb_param->hvm_min_req_outstand_commit_threshold = 0xa; - arb_param->compbuf_reserved_space_kbytes = mode_lib->mp.compbuf_reserved_space_64b * 64 / 1024; - arb_param->allow_sdpif_rate_limit_when_cstate_req = mode_lib->mp.hw_debug5; - arb_param->dcfclk_deep_sleep_hysteresis = mode_lib->mp.dcfclk_deep_sleep_hysteresis; - -#ifdef __DML_VBA_DEBUG__ - dml2_printf("DML::%s: max_req_outstanding = %d\n", __func__, arb_param->max_req_outstanding); - dml2_printf("DML::%s: sdpif_request_rate_limit = %d\n", __func__, arb_param->sdpif_request_rate_limit); - dml2_printf("DML::%s: compbuf_reserved_space_kbytes = %d\n", __func__, arb_param->compbuf_reserved_space_kbytes); - dml2_printf("DML::%s: allow_sdpif_rate_limit_when_cstate_req = %d\n", __func__, arb_param->allow_sdpif_rate_limit_when_cstate_req); - dml2_printf("DML::%s: dcfclk_deep_sleep_hysteresis = %d\n", __func__, arb_param->dcfclk_deep_sleep_hysteresis); -#endif - -} - -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) -{ - rq_dlg_get_wm_regs(display_cfg, mode_lib, out); -} - -void dml2_core_shared_get_arb_params(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_display_arb_regs *out) -{ - rq_dlg_get_arb_params(mode_lib, 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) -{ - rq_dlg_get_rq_reg(&out->rq_regs, display_cfg, mode_lib, pipe_index); - rq_dlg_get_dlg_reg(&mode_lib->scratch, &out->dlg_regs, &out->ttu_regs, display_cfg, mode_lib, pipe_index); - out->det_size = mode_lib->mp.DETBufferSizeInKByte[mode_lib->mp.pipe_plane[pipe_index]] / mode_lib->ip.config_return_buffer_segment_size_in_kbytes; -} - -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.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) -{ - unsigned int n; - - out->num_mcaches_plane0 = mode_lib->ms.num_mcaches_l[plane_idx]; - out->num_mcaches_plane1 = mode_lib->ms.num_mcaches_c[plane_idx]; - out->shift_granularity.p0 = mode_lib->ms.mcache_shift_granularity_l[plane_idx]; - out->shift_granularity.p1 = mode_lib->ms.mcache_shift_granularity_c[plane_idx]; - - for (n = 0; n < out->num_mcaches_plane0; n++) - out->mcache_x_offsets_plane0[n] = mode_lib->ms.mcache_offsets_l[plane_idx][n]; - - for (n = 0; n < out->num_mcaches_plane1; n++) - out->mcache_x_offsets_plane1[n] = mode_lib->ms.mcache_offsets_l[plane_idx][n]; - - out->last_slice_sharing.mall_comb_mcache_p0 = mode_lib->ms.mall_comb_mcache_l[plane_idx]; - out->last_slice_sharing.mall_comb_mcache_p1 = mode_lib->ms.mall_comb_mcache_c[plane_idx]; - out->last_slice_sharing.plane0_plane1 = mode_lib->ms.lc_comb_mcache[plane_idx]; - out->informative.meta_row_bytes_plane0 = mode_lib->ms.mcache_row_bytes_l[plane_idx]; - out->informative.meta_row_bytes_plane1 = mode_lib->ms.mcache_row_bytes_c[plane_idx]; - - out->valid = true; -} - -void dml2_core_shared_get_mall_allocation(struct dml2_core_internal_display_mode_lib *mode_lib, unsigned int *out, int pipe_index) -{ - *out = mode_lib->mp.SurfaceSizeInTheMALL[mode_lib->mp.pipe_plane[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) -{ - out->mall_svp_size_requirement_ways = 0; - - out->nominal_vblank_pstate_latency_hiding_us = - (int)(display_cfg->stream_descriptors[display_cfg->plane_descriptors[plane_idx].stream_index].timing.h_total / - ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[plane_idx].stream_index].timing.pixel_clock_khz / 1000) * mode_lib->ms.TWait[plane_idx]); - - out->dram_change_latency_hiding_margin_in_active = (int)mode_lib->ms.VActiveLatencyHidingMargin[plane_idx]; - - out->active_latency_hiding_us = (int)mode_lib->ms.VActiveLatencyHidingUs[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) -{ - double phantom_processing_delay_pix; - unsigned int phantom_processing_delay_lines; - unsigned int phantom_v_active_lines; - unsigned int phantom_v_startup_lines; - unsigned int phantom_v_blank_lines; - unsigned int main_v_blank_lines; - unsigned int rem; - - 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, 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 = mode_lib->ms.MaxVStartupLines[plane_index]; - phantom_v_active_lines = phantom_processing_delay_lines + mode_lib->ms.SubViewportLinesNeededInMALL[plane_index] + 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; - main_v_blank_lines = display_cfg->stream_descriptors[display_cfg->plane_descriptors[plane_index].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[plane_index].stream_index].timing.v_active; - if (phantom_v_blank_lines > main_v_blank_lines) - phantom_v_blank_lines = main_v_blank_lines; - - out->phantom_v_active = phantom_v_active_lines; - // phantom_vtotal = vactive + vblank - out->phantom_v_total = phantom_v_active_lines + phantom_v_blank_lines; - - out->phantom_min_v_active = mode_lib->ms.SubViewportLinesNeededInMALL[plane_index]; - out->phantom_v_startup = mode_lib->ms.MaxVStartupLines[plane_index]; - - out->vblank_reserved_time_us = display_cfg->plane_descriptors[plane_index].overrides.reserved_vblank_time_ns / 1000; -#if defined(__DML_VBA_DEBUG__) - dml2_printf("DML::%s: subvp_fw_processing_delay_us = %d\n", __func__, mode_lib->ip.subvp_fw_processing_delay_us); - dml2_printf("DML::%s: subvp_pstate_allow_width_us = %d\n", __func__, mode_lib->ip.subvp_pstate_allow_width_us); - dml2_printf("DML::%s: subvp_swath_height_margin_lines = %d\n", __func__, mode_lib->ip.subvp_swath_height_margin_lines); - dml2_printf("DML::%s: vblank_reserved_time_us = %f\n", __func__, out->vblank_reserved_time_us); -#endif -} - -void dml2_core_shared_get_informative(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_display_cfg_programming *out) -{ - unsigned int k, n; - - out->informative.mode_support_info.ModeIsSupported = mode_lib->ms.support.ModeSupport; - out->informative.mode_support_info.ImmediateFlipSupport = mode_lib->ms.support.ImmediateFlipSupport; - out->informative.mode_support_info.WritebackLatencySupport = mode_lib->ms.support.WritebackLatencySupport; - 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.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; - out->informative.mode_support_info.BPPForMultistreamNotIndicated = mode_lib->ms.support.BPPForMultistreamNotIndicated; - out->informative.mode_support_info.MultistreamWithHDMIOreDP = mode_lib->ms.support.MultistreamWithHDMIOreDP; - out->informative.mode_support_info.MSOOrODMSplitWithNonDPLink = mode_lib->ms.support.MSOOrODMSplitWithNonDPLink; - out->informative.mode_support_info.NotEnoughLanesForMSO = mode_lib->ms.support.NotEnoughLanesForMSO; - out->informative.mode_support_info.NumberOfOTGSupport = mode_lib->ms.support.NumberOfOTGSupport; - out->informative.mode_support_info.NumberOfHDMIFRLSupport = mode_lib->ms.support.NumberOfHDMIFRLSupport; - out->informative.mode_support_info.NumberOfDP2p0Support = mode_lib->ms.support.NumberOfDP2p0Support; - out->informative.mode_support_info.WritebackScaleRatioAndTapsSupport = mode_lib->ms.support.WritebackScaleRatioAndTapsSupport; - out->informative.mode_support_info.CursorSupport = mode_lib->ms.support.CursorSupport; - out->informative.mode_support_info.PitchSupport = mode_lib->ms.support.PitchSupport; - out->informative.mode_support_info.ViewportExceedsSurface = mode_lib->ms.support.ViewportExceedsSurface; - out->informative.mode_support_info.ImmediateFlipRequiredButTheRequirementForEachSurfaceIsNotSpecified = false; - out->informative.mode_support_info.ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe = mode_lib->ms.support.ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe; - out->informative.mode_support_info.InvalidCombinationOfMALLUseForPStateAndStaticScreen = mode_lib->ms.support.InvalidCombinationOfMALLUseForPStateAndStaticScreen; - out->informative.mode_support_info.InvalidCombinationOfMALLUseForPState = mode_lib->ms.support.InvalidCombinationOfMALLUseForPState; - out->informative.mode_support_info.ExceededMALLSize = mode_lib->ms.support.ExceededMALLSize; - out->informative.mode_support_info.EnoughWritebackUnits = mode_lib->ms.support.EnoughWritebackUnits; - - out->informative.mode_support_info.ExceededMultistreamSlots = mode_lib->ms.support.ExceededMultistreamSlots; - out->informative.mode_support_info.NotEnoughDSCUnits = mode_lib->ms.support.NotEnoughDSCUnits; - out->informative.mode_support_info.NotEnoughDSCSlices = mode_lib->ms.support.NotEnoughDSCSlices; - out->informative.mode_support_info.PixelsPerLinePerDSCUnitSupport = mode_lib->ms.support.PixelsPerLinePerDSCUnitSupport; - out->informative.mode_support_info.DSCCLKRequiredMoreThanSupported = mode_lib->ms.support.DSCCLKRequiredMoreThanSupported; - out->informative.mode_support_info.DTBCLKRequiredMoreThanSupported = mode_lib->ms.support.DTBCLKRequiredMoreThanSupported; - out->informative.mode_support_info.LinkCapacitySupport = mode_lib->ms.support.LinkCapacitySupport; - - out->informative.mode_support_info.ROBSupport = mode_lib->ms.support.ROBSupport; - out->informative.mode_support_info.OutstandingRequestsSupport = mode_lib->ms.support.OutstandingRequestsSupport; - out->informative.mode_support_info.OutstandingRequestsUrgencyAvoidance = mode_lib->ms.support.OutstandingRequestsUrgencyAvoidance; - out->informative.mode_support_info.PTEBufferSizeNotExceeded = mode_lib->ms.support.PTEBufferSizeNotExceeded; - out->informative.mode_support_info.DCCMetaBufferSizeNotExceeded = mode_lib->ms.support.DCCMetaBufferSizeNotExceeded; - - out->informative.mode_support_info.TotalVerticalActiveBandwidthSupport = mode_lib->ms.support.AvgBandwidthSupport; - out->informative.mode_support_info.VActiveBandwidthSupport = mode_lib->ms.support.UrgVactiveBandwidthSupport; - out->informative.mode_support_info.USRRetrainingSupport = mode_lib->ms.support.USRRetrainingSupport; - - out->informative.mode_support_info.PrefetchSupported = mode_lib->ms.support.PrefetchSupported; - out->informative.mode_support_info.DynamicMetadataSupported = mode_lib->ms.support.DynamicMetadataSupported; - out->informative.mode_support_info.VRatioInPrefetchSupported = mode_lib->ms.support.VRatioInPrefetchSupported; - out->informative.mode_support_info.DISPCLK_DPPCLK_Support = mode_lib->ms.support.DISPCLK_DPPCLK_Support; - out->informative.mode_support_info.TotalAvailablePipesSupport = mode_lib->ms.support.TotalAvailablePipesSupport; - out->informative.mode_support_info.ViewportSizeSupport = mode_lib->ms.support.ViewportSizeSupport; - - for (k = 0; k < out->display_config.num_planes; k++) { - - out->informative.mode_support_info.FCLKChangeSupport[k] = mode_lib->ms.support.FCLKChangeSupport[k]; - out->informative.mode_support_info.MPCCombineEnable[k] = mode_lib->ms.support.MPCCombineEnable[k]; - out->informative.mode_support_info.ODMMode[k] = mode_lib->ms.support.ODMMode[k]; - out->informative.mode_support_info.DPPPerSurface[k] = mode_lib->ms.support.DPPPerSurface[k]; - out->informative.mode_support_info.DSCEnabled[k] = mode_lib->ms.support.DSCEnabled[k]; - out->informative.mode_support_info.FECEnabled[k] = mode_lib->ms.support.FECEnabled[k]; - out->informative.mode_support_info.NumberOfDSCSlices[k] = mode_lib->ms.support.NumberOfDSCSlices[k]; - out->informative.mode_support_info.OutputBpp[k] = mode_lib->ms.support.OutputBpp[k]; - - if (mode_lib->ms.support.OutputType[k] == dml2_core_internal_output_type_unknown) - out->informative.mode_support_info.OutputType[k] = dml2_output_type_unknown; - else if (mode_lib->ms.support.OutputType[k] == dml2_core_internal_output_type_dp) - out->informative.mode_support_info.OutputType[k] = dml2_output_type_dp; - else if (mode_lib->ms.support.OutputType[k] == dml2_core_internal_output_type_edp) - out->informative.mode_support_info.OutputType[k] = dml2_output_type_edp; - else if (mode_lib->ms.support.OutputType[k] == dml2_core_internal_output_type_dp2p0) - out->informative.mode_support_info.OutputType[k] = dml2_output_type_dp2p0; - else if (mode_lib->ms.support.OutputType[k] == dml2_core_internal_output_type_hdmi) - out->informative.mode_support_info.OutputType[k] = dml2_output_type_hdmi; - else if (mode_lib->ms.support.OutputType[k] == dml2_core_internal_output_type_hdmifrl) - out->informative.mode_support_info.OutputType[k] = dml2_output_type_hdmifrl; - - if (mode_lib->ms.support.OutputRate[k] == dml2_core_internal_output_rate_unknown) - out->informative.mode_support_info.OutputRate[k] = dml2_output_rate_unknown; - else if (mode_lib->ms.support.OutputRate[k] == dml2_core_internal_output_rate_dp_rate_hbr) - out->informative.mode_support_info.OutputRate[k] = dml2_output_rate_dp_rate_hbr; - else if (mode_lib->ms.support.OutputRate[k] == dml2_core_internal_output_rate_dp_rate_hbr2) - out->informative.mode_support_info.OutputRate[k] = dml2_output_rate_dp_rate_hbr2; - else if (mode_lib->ms.support.OutputRate[k] == dml2_core_internal_output_rate_dp_rate_hbr3) - out->informative.mode_support_info.OutputRate[k] = dml2_output_rate_dp_rate_hbr3; - else if (mode_lib->ms.support.OutputRate[k] == dml2_core_internal_output_rate_dp_rate_uhbr10) - out->informative.mode_support_info.OutputRate[k] = dml2_output_rate_dp_rate_uhbr10; - else if (mode_lib->ms.support.OutputRate[k] == dml2_core_internal_output_rate_dp_rate_uhbr13p5) - out->informative.mode_support_info.OutputRate[k] = dml2_output_rate_dp_rate_uhbr13p5; - else if (mode_lib->ms.support.OutputRate[k] == dml2_core_internal_output_rate_dp_rate_uhbr20) - out->informative.mode_support_info.OutputRate[k] = dml2_output_rate_dp_rate_uhbr20; - else if (mode_lib->ms.support.OutputRate[k] == dml2_core_internal_output_rate_hdmi_rate_3x3) - out->informative.mode_support_info.OutputRate[k] = dml2_output_rate_hdmi_rate_3x3; - else if (mode_lib->ms.support.OutputRate[k] == dml2_core_internal_output_rate_hdmi_rate_6x3) - out->informative.mode_support_info.OutputRate[k] = dml2_output_rate_hdmi_rate_6x3; - else if (mode_lib->ms.support.OutputRate[k] == dml2_core_internal_output_rate_hdmi_rate_6x4) - out->informative.mode_support_info.OutputRate[k] = dml2_output_rate_hdmi_rate_6x4; - else if (mode_lib->ms.support.OutputRate[k] == dml2_core_internal_output_rate_hdmi_rate_8x4) - out->informative.mode_support_info.OutputRate[k] = dml2_output_rate_hdmi_rate_8x4; - else if (mode_lib->ms.support.OutputRate[k] == dml2_core_internal_output_rate_hdmi_rate_10x4) - out->informative.mode_support_info.OutputRate[k] = dml2_output_rate_hdmi_rate_10x4; - else if (mode_lib->ms.support.OutputRate[k] == dml2_core_internal_output_rate_hdmi_rate_12x4) - out->informative.mode_support_info.OutputRate[k] = dml2_output_rate_hdmi_rate_12x4; - - out->informative.mode_support_info.AlignedYPitch[k] = mode_lib->ms.support.AlignedYPitch[k]; - out->informative.mode_support_info.AlignedCPitch[k] = mode_lib->ms.support.AlignedCPitch[k]; - } - - out->informative.watermarks.urgent_us = mode_lib->mp.Watermark.UrgentWatermark; - out->informative.watermarks.writeback_urgent_us = mode_lib->mp.Watermark.WritebackUrgentWatermark; - out->informative.watermarks.writeback_pstate_us = mode_lib->mp.Watermark.WritebackDRAMClockChangeWatermark; - out->informative.watermarks.writeback_fclk_pstate_us = mode_lib->mp.Watermark.WritebackFCLKChangeWatermark; - - out->informative.watermarks.cstate_exit_us = mode_lib->mp.Watermark.StutterExitWatermark; - out->informative.watermarks.cstate_enter_plus_exit_us = mode_lib->mp.Watermark.StutterEnterPlusExitWatermark; - out->informative.watermarks.z8_cstate_exit_us = mode_lib->mp.Watermark.Z8StutterExitWatermark; - out->informative.watermarks.z8_cstate_enter_plus_exit_us = mode_lib->mp.Watermark.Z8StutterEnterPlusExitWatermark; - out->informative.watermarks.pstate_change_us = mode_lib->mp.Watermark.DRAMClockChangeWatermark; - out->informative.watermarks.fclk_pstate_change_us = mode_lib->mp.Watermark.FCLKChangeWatermark; - out->informative.watermarks.usr_retraining_us = mode_lib->mp.Watermark.USRRetrainingWatermark; - - out->informative.mall.total_surface_size_in_mall_bytes = 0; - for (k = 0; k < out->display_config.num_planes; ++k) - out->informative.mall.total_surface_size_in_mall_bytes += mode_lib->mp.SurfaceSizeInTheMALL[k]; - - out->informative.qos.min_return_latency_in_dcfclk = mode_lib->mp.min_return_latency_in_dcfclk; - out->informative.qos.urgent_latency_us = mode_lib->mp.UrgentLatency; - - out->informative.qos.max_urgent_latency_us = mode_lib->ms.support.max_urgent_latency_us; - out->informative.qos.avg_non_urgent_latency_us = mode_lib->ms.support.avg_non_urgent_latency_us; - out->informative.qos.avg_urgent_latency_us = mode_lib->ms.support.avg_urgent_latency_us; - - out->informative.qos.wm_memory_trip_us = mode_lib->mp.UrgentLatency; - out->informative.qos.meta_trip_memory_us = mode_lib->mp.MetaTripToMemory; - out->informative.qos.fraction_of_urgent_bandwidth = mode_lib->mp.FractionOfUrgentBandwidth; - out->informative.qos.fraction_of_urgent_bandwidth_immediate_flip = mode_lib->mp.FractionOfUrgentBandwidthImmediateFlip; - out->informative.qos.fraction_of_urgent_bandwidth_mall = mode_lib->mp.FractionOfUrgentBandwidthMALL; - - out->informative.qos.avg_bw_required.sys_active.sdp_bw_mbps = - mode_lib->ms.support.avg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]; - out->informative.qos.avg_bw_required.sys_active.dram_bw_mbps = - mode_lib->ms.support.avg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram]; - out->informative.qos.avg_bw_required.svp_prefetch.sdp_bw_mbps = - mode_lib->ms.support.avg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp]; - out->informative.qos.avg_bw_required.svp_prefetch.dram_bw_mbps = - mode_lib->ms.support.avg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram]; - - out->informative.qos.avg_bw_available.sys_active.sdp_bw_mbps = - mode_lib->mp.avg_bandwidth_available[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]; - out->informative.qos.avg_bw_available.sys_active.dram_bw_mbps = - mode_lib->mp.avg_bandwidth_available[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram]; - out->informative.qos.avg_bw_available.svp_prefetch.sdp_bw_mbps = - mode_lib->mp.avg_bandwidth_available[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp]; - out->informative.qos.avg_bw_available.svp_prefetch.dram_bw_mbps = - mode_lib->mp.avg_bandwidth_available[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram]; - - out->informative.qos.urg_bw_available.sys_active.sdp_bw_mbps = - mode_lib->mp.urg_bandwidth_available[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]; - out->informative.qos.urg_bw_available.sys_active.dram_bw_mbps = - mode_lib->mp.urg_bandwidth_available[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram]; - out->informative.qos.urg_bw_available.sys_active.dram_vm_only_bw_mbps = - mode_lib->mp.urg_bandwidth_available_vm_only[dml2_core_internal_soc_state_sys_active]; - - out->informative.qos.urg_bw_available.svp_prefetch.sdp_bw_mbps = - mode_lib->mp.urg_bandwidth_available[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp]; - out->informative.qos.urg_bw_available.svp_prefetch.dram_bw_mbps = - mode_lib->mp.urg_bandwidth_available[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram]; - out->informative.qos.urg_bw_available.svp_prefetch.dram_vm_only_bw_mbps = - mode_lib->mp.urg_bandwidth_available_vm_only[dml2_core_internal_soc_state_svp_prefetch]; - - out->informative.qos.urg_bw_required.sys_active.sdp_bw_mbps = mode_lib->mp.urg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]; - out->informative.qos.urg_bw_required.sys_active.dram_bw_mbps = mode_lib->mp.urg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram]; - out->informative.qos.urg_bw_required.svp_prefetch.sdp_bw_mbps = mode_lib->mp.urg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp]; - out->informative.qos.urg_bw_required.svp_prefetch.dram_bw_mbps = mode_lib->mp.urg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram]; - - out->informative.qos.non_urg_bw_required.sys_active.sdp_bw_mbps = mode_lib->mp.non_urg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]; - out->informative.qos.non_urg_bw_required.sys_active.dram_bw_mbps = mode_lib->mp.non_urg_bandwidth_required[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram]; - out->informative.qos.non_urg_bw_required.svp_prefetch.sdp_bw_mbps = mode_lib->mp.non_urg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp]; - out->informative.qos.non_urg_bw_required.svp_prefetch.dram_bw_mbps = mode_lib->mp.non_urg_bandwidth_required[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram]; - - out->informative.qos.urg_bw_required_with_flip.sys_active.sdp_bw_mbps = mode_lib->mp.urg_bandwidth_required_flip[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]; - out->informative.qos.urg_bw_required_with_flip.sys_active.dram_bw_mbps = mode_lib->mp.urg_bandwidth_required_flip[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram]; - out->informative.qos.urg_bw_required_with_flip.svp_prefetch.sdp_bw_mbps = mode_lib->mp.urg_bandwidth_required_flip[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp]; - out->informative.qos.urg_bw_required_with_flip.svp_prefetch.dram_bw_mbps = mode_lib->mp.urg_bandwidth_required_flip[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram]; - - out->informative.qos.non_urg_bw_required_with_flip.sys_active.sdp_bw_mbps = mode_lib->mp.non_urg_bandwidth_required_flip[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_sdp]; - out->informative.qos.non_urg_bw_required_with_flip.sys_active.dram_bw_mbps = mode_lib->mp.non_urg_bandwidth_required_flip[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram]; - out->informative.qos.non_urg_bw_required_with_flip.svp_prefetch.sdp_bw_mbps = mode_lib->mp.non_urg_bandwidth_required_flip[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_sdp]; - out->informative.qos.non_urg_bw_required_with_flip.svp_prefetch.dram_bw_mbps = mode_lib->mp.non_urg_bandwidth_required_flip[dml2_core_internal_soc_state_svp_prefetch][dml2_core_internal_bw_dram]; - - out->informative.crb.comp_buffer_size_kbytes = mode_lib->mp.CompressedBufferSizeInkByte; - out->informative.crb.UnboundedRequestEnabled = mode_lib->mp.UnboundedRequestEnabled; - - out->informative.crb.compbuf_reserved_space_64b = mode_lib->mp.compbuf_reserved_space_64b; - out->informative.misc.hw_debug5 = mode_lib->mp.hw_debug5; - out->informative.misc.dcfclk_deep_sleep_hysteresis = mode_lib->mp.dcfclk_deep_sleep_hysteresis; - - out->informative.power_management.stutter_efficiency = mode_lib->mp.StutterEfficiencyNotIncludingVBlank; - out->informative.power_management.stutter_efficiency_with_vblank = mode_lib->mp.StutterEfficiency; - out->informative.power_management.stutter_num_bursts = mode_lib->mp.NumberOfStutterBurstsPerFrame; - - out->informative.power_management.z8.stutter_efficiency = mode_lib->mp.Z8StutterEfficiency; - out->informative.power_management.z8.stutter_efficiency_with_vblank = mode_lib->mp.StutterEfficiency; - out->informative.power_management.z8.stutter_num_bursts = mode_lib->mp.Z8NumberOfStutterBurstsPerFrame; - out->informative.power_management.z8.stutter_period = mode_lib->mp.StutterPeriod; - - out->informative.power_management.z8.bestcase.stutter_efficiency = mode_lib->mp.Z8StutterEfficiencyBestCase; - out->informative.power_management.z8.bestcase.stutter_num_bursts = mode_lib->mp.Z8NumberOfStutterBurstsPerFrameBestCase; - out->informative.power_management.z8.bestcase.stutter_period = mode_lib->mp.StutterPeriodBestCase; - - out->informative.misc.cstate_max_cap_mode = mode_lib->mp.DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE; - - 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; - - for (k = 0; k < out->display_config.num_planes; k++) { - - if ((out->display_config.plane_descriptors->overrides.reserved_vblank_time_ns >= 1000.0 * mode_lib->soc.power_management_parameters.dram_clk_change_blackout_us) - && (out->display_config.plane_descriptors->overrides.reserved_vblank_time_ns >= 1000.0 * mode_lib->soc.power_management_parameters.fclk_change_blackout_us) - && (out->display_config.plane_descriptors->overrides.reserved_vblank_time_ns >= 1000.0 * mode_lib->soc.power_management_parameters.stutter_enter_plus_exit_latency_us)) - out->informative.misc.PrefetchMode[k] = 0; - else if ((out->display_config.plane_descriptors->overrides.reserved_vblank_time_ns >= 1000.0 * mode_lib->soc.power_management_parameters.fclk_change_blackout_us) - && (out->display_config.plane_descriptors->overrides.reserved_vblank_time_ns >= 1000.0 * mode_lib->soc.power_management_parameters.stutter_enter_plus_exit_latency_us)) - out->informative.misc.PrefetchMode[k] = 1; - else if (out->display_config.plane_descriptors->overrides.reserved_vblank_time_ns >= 1000.0 * mode_lib->soc.power_management_parameters.stutter_enter_plus_exit_latency_us) - out->informative.misc.PrefetchMode[k] = 2; - else - out->informative.misc.PrefetchMode[k] = 3; - - out->informative.misc.min_ttu_vblank_us[k] = mode_lib->mp.MinTTUVBlank[k]; - out->informative.mall.subviewport_lines_needed_in_mall[k] = mode_lib->mp.SubViewportLinesNeededInMALL[k]; - out->informative.crb.det_size_in_kbytes[k] = mode_lib->mp.DETBufferSizeInKByte[k]; - out->informative.crb.DETBufferSizeY[k] = mode_lib->mp.DETBufferSizeY[k]; - out->informative.misc.ImmediateFlipSupportedForPipe[k] = mode_lib->mp.ImmediateFlipSupportedForPipe[k]; - out->informative.misc.UsesMALLForStaticScreen[k] = mode_lib->mp.is_using_mall_for_ss[k]; - out->informative.plane_info[k].dpte_row_height_plane0 = mode_lib->mp.dpte_row_height[k]; - out->informative.plane_info[k].dpte_row_height_plane1 = mode_lib->mp.dpte_row_height_chroma[k]; - out->informative.plane_info[k].meta_row_height_plane0 = mode_lib->mp.meta_row_height[k]; - out->informative.plane_info[k].meta_row_height_plane1 = mode_lib->mp.meta_row_height_chroma[k]; - out->informative.dcc_control[k].max_uncompressed_block_plane0 = mode_lib->mp.DCCYMaxUncompressedBlock[k]; - out->informative.dcc_control[k].max_compressed_block_plane0 = mode_lib->mp.DCCYMaxCompressedBlock[k]; - out->informative.dcc_control[k].independent_block_plane0 = mode_lib->mp.DCCYIndependentBlock[k]; - out->informative.dcc_control[k].max_uncompressed_block_plane1 = mode_lib->mp.DCCCMaxUncompressedBlock[k]; - out->informative.dcc_control[k].max_compressed_block_plane1 = mode_lib->mp.DCCCMaxCompressedBlock[k]; - out->informative.dcc_control[k].independent_block_plane1 = mode_lib->mp.DCCCIndependentBlock[k]; - out->informative.misc.dst_x_after_scaler[k] = mode_lib->mp.DSTXAfterScaler[k]; - out->informative.misc.dst_y_after_scaler[k] = mode_lib->mp.DSTYAfterScaler[k]; - out->informative.misc.prefetch_source_lines_plane0[k] = mode_lib->mp.PrefetchSourceLinesY[k]; - out->informative.misc.prefetch_source_lines_plane1[k] = mode_lib->mp.PrefetchSourceLinesC[k]; - out->informative.misc.vready_at_or_after_vsync[k] = mode_lib->mp.VREADY_AT_OR_AFTER_VSYNC[k]; - out->informative.misc.min_dst_y_next_start[k] = mode_lib->mp.MIN_DST_Y_NEXT_START[k]; - out->informative.plane_info[k].swath_width_plane0 = mode_lib->mp.SwathWidthY[k]; - out->informative.plane_info[k].swath_height_plane0 = mode_lib->mp.SwathHeightY[k]; - out->informative.plane_info[k].swath_height_plane1 = mode_lib->mp.SwathHeightC[k]; - out->informative.misc.CursorDstXOffset[k] = mode_lib->mp.CursorDstXOffset[k]; - out->informative.misc.CursorDstYOffset[k] = mode_lib->mp.CursorDstYOffset[k]; - out->informative.misc.CursorChunkHDLAdjust[k] = mode_lib->mp.CursorChunkHDLAdjust[k]; - out->informative.misc.dpte_group_bytes[k] = mode_lib->mp.dpte_group_bytes[k]; - out->informative.misc.vm_group_bytes[k] = mode_lib->mp.vm_group_bytes[k]; - out->informative.misc.DisplayPipeRequestDeliveryTimeLuma[k] = mode_lib->mp.DisplayPipeRequestDeliveryTimeLuma[k]; - out->informative.misc.DisplayPipeRequestDeliveryTimeChroma[k] = mode_lib->mp.DisplayPipeRequestDeliveryTimeChroma[k]; - out->informative.misc.DisplayPipeRequestDeliveryTimeLumaPrefetch[k] = mode_lib->mp.DisplayPipeRequestDeliveryTimeLumaPrefetch[k]; - out->informative.misc.DisplayPipeRequestDeliveryTimeChromaPrefetch[k] = mode_lib->mp.DisplayPipeRequestDeliveryTimeChromaPrefetch[k]; - out->informative.misc.TimePerVMGroupVBlank[k] = mode_lib->mp.TimePerVMGroupVBlank[k]; - out->informative.misc.TimePerVMGroupFlip[k] = mode_lib->mp.TimePerVMGroupFlip[k]; - out->informative.misc.TimePerVMRequestVBlank[k] = mode_lib->mp.TimePerVMRequestVBlank[k]; - out->informative.misc.TimePerVMRequestFlip[k] = mode_lib->mp.TimePerVMRequestFlip[k]; - out->informative.misc.Tdmdl_vm[k] = mode_lib->mp.Tdmdl_vm[k]; - out->informative.misc.Tdmdl[k] = mode_lib->mp.Tdmdl[k]; - out->informative.misc.VStartup[k] = mode_lib->mp.VStartup[k]; - out->informative.misc.VUpdateOffsetPix[k] = mode_lib->mp.VUpdateOffsetPix[k]; - out->informative.misc.VUpdateWidthPix[k] = mode_lib->mp.VUpdateWidthPix[k]; - out->informative.misc.VReadyOffsetPix[k] = mode_lib->mp.VReadyOffsetPix[k]; - - out->informative.misc.DST_Y_PER_PTE_ROW_NOM_L[k] = mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_L[k]; - out->informative.misc.DST_Y_PER_PTE_ROW_NOM_C[k] = mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_C[k]; - out->informative.misc.time_per_pte_group_nom_luma[k] = mode_lib->mp.time_per_pte_group_nom_luma[k]; - out->informative.misc.time_per_pte_group_nom_chroma[k] = mode_lib->mp.time_per_pte_group_nom_chroma[k]; - out->informative.misc.time_per_pte_group_vblank_luma[k] = mode_lib->mp.time_per_pte_group_vblank_luma[k]; - out->informative.misc.time_per_pte_group_vblank_chroma[k] = mode_lib->mp.time_per_pte_group_vblank_chroma[k]; - out->informative.misc.time_per_pte_group_flip_luma[k] = mode_lib->mp.time_per_pte_group_flip_luma[k]; - out->informative.misc.time_per_pte_group_flip_chroma[k] = mode_lib->mp.time_per_pte_group_flip_chroma[k]; - out->informative.misc.VRatioPrefetchY[k] = mode_lib->mp.VRatioPrefetchY[k]; - out->informative.misc.VRatioPrefetchC[k] = mode_lib->mp.VRatioPrefetchC[k]; - out->informative.misc.DestinationLinesForPrefetch[k] = mode_lib->mp.dst_y_prefetch[k]; - out->informative.misc.DestinationLinesToRequestVMInVBlank[k] = mode_lib->mp.dst_y_per_vm_vblank[k]; - out->informative.misc.DestinationLinesToRequestRowInVBlank[k] = mode_lib->mp.dst_y_per_row_vblank[k]; - out->informative.misc.DestinationLinesToRequestVMInImmediateFlip[k] = mode_lib->mp.dst_y_per_vm_flip[k]; - out->informative.misc.DestinationLinesToRequestRowInImmediateFlip[k] = mode_lib->mp.dst_y_per_row_flip[k]; - out->informative.misc.DisplayPipeLineDeliveryTimeLuma[k] = mode_lib->mp.DisplayPipeLineDeliveryTimeLuma[k]; - out->informative.misc.DisplayPipeLineDeliveryTimeChroma[k] = mode_lib->mp.DisplayPipeLineDeliveryTimeChroma[k]; - out->informative.misc.DisplayPipeLineDeliveryTimeLumaPrefetch[k] = mode_lib->mp.DisplayPipeLineDeliveryTimeLumaPrefetch[k]; - out->informative.misc.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = mode_lib->mp.DisplayPipeLineDeliveryTimeChromaPrefetch[k]; - - out->informative.misc.WritebackAllowDRAMClockChangeEndPosition[k] = mode_lib->mp.WritebackAllowDRAMClockChangeEndPosition[k]; - out->informative.misc.WritebackAllowFCLKChangeEndPosition[k] = mode_lib->mp.WritebackAllowFCLKChangeEndPosition[k]; - out->informative.misc.DSCCLK_calculated[k] = mode_lib->mp.DSCCLK[k]; - out->informative.misc.BIGK_FRAGMENT_SIZE[k] = mode_lib->mp.BIGK_FRAGMENT_SIZE[k]; - out->informative.misc.PTE_BUFFER_MODE[k] = mode_lib->mp.PTE_BUFFER_MODE[k]; - out->informative.misc.DSCDelay[k] = mode_lib->mp.DSCDelay[k]; - out->informative.misc.MaxActiveDRAMClockChangeLatencySupported[k] = mode_lib->mp.MaxActiveDRAMClockChangeLatencySupported[k]; - } - - // For this DV informative layer, all pipes in the same planes will just use the same id - // will have the optimization and helper layer later on - // only work when we can have high "mcache" that fit everything without thrashing the cache - for (k = 0; k < out->display_config.num_planes; k++) { - out->informative.non_optimized_mcache_allocation[k].num_mcaches_plane0 = mode_lib->ms.num_mcaches_l[k]; - out->informative.non_optimized_mcache_allocation[k].informative.meta_row_bytes_plane0 = mode_lib->ms.mcache_row_bytes_l[k]; - - for (n = 0; n < out->informative.non_optimized_mcache_allocation[k].num_mcaches_plane0; n++) { - out->informative.non_optimized_mcache_allocation[k].mcache_x_offsets_plane0[n] = mode_lib->ms.mcache_offsets_l[k][n]; - out->informative.non_optimized_mcache_allocation[k].global_mcache_ids_plane0[n] = k; - } - - out->informative.non_optimized_mcache_allocation[k].num_mcaches_plane1 = mode_lib->ms.num_mcaches_c[k]; - out->informative.non_optimized_mcache_allocation[k].informative.meta_row_bytes_plane1 = mode_lib->ms.mcache_row_bytes_c[k]; - - for (n = 0; n < out->informative.non_optimized_mcache_allocation[k].num_mcaches_plane1; n++) { - out->informative.non_optimized_mcache_allocation[k].mcache_x_offsets_plane1[n] = mode_lib->ms.mcache_offsets_c[k][n]; - out->informative.non_optimized_mcache_allocation[k].global_mcache_ids_plane1[n] = k; - } - } - - 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_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; - } else { - out->informative.misc.ROBUrgencyAvoidance = false; - } - } else { - out->informative.misc.ROBUrgencyAvoidance = true; - } -} 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 b7cb017b59ba..dfe54112a9c6 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 @@ -484,7 +484,7 @@ struct dml2_core_internal_mode_support { double WriteBandwidth[DML2_MAX_PLANES][DML2_MAX_WRITEBACK]; double RequiredPrefetchPixelDataBWLuma[DML2_MAX_PLANES]; double RequiredPrefetchPixelDataBWChroma[DML2_MAX_PLANES]; - /* oto bw should also be considered when calculating urgent bw to avoid situations oto/equ mismatches between ms and mp */ + /* oto bw should also be considered when calculating peak urgent bw to avoid situations oto/equ mismatches between ms and mp */ double RequiredPrefetchBWOTO[DML2_MAX_PLANES]; double cursor_bw[DML2_MAX_PLANES]; double prefetch_cursor_bw[DML2_MAX_PLANES]; @@ -524,11 +524,13 @@ struct dml2_core_internal_mode_support { unsigned int num_mcaches_l[DML2_MAX_PLANES]; unsigned int mcache_row_bytes_l[DML2_MAX_PLANES]; + unsigned int mcache_row_bytes_per_channel_l[DML2_MAX_PLANES]; unsigned int mcache_offsets_l[DML2_MAX_PLANES][DML2_MAX_MCACHES + 1]; unsigned int mcache_shift_granularity_l[DML2_MAX_PLANES]; unsigned int num_mcaches_c[DML2_MAX_PLANES]; unsigned int mcache_row_bytes_c[DML2_MAX_PLANES]; + unsigned int mcache_row_bytes_per_channel_c[DML2_MAX_PLANES]; unsigned int mcache_offsets_c[DML2_MAX_PLANES][DML2_MAX_MCACHES + 1]; unsigned int mcache_shift_granularity_c[DML2_MAX_PLANES]; @@ -841,11 +843,13 @@ struct dml2_core_internal_mode_program { unsigned int num_mcaches_l[DML2_MAX_PLANES]; unsigned int mcache_row_bytes_l[DML2_MAX_PLANES]; + unsigned int mcache_row_bytes_per_channel_l[DML2_MAX_PLANES]; unsigned int mcache_offsets_l[DML2_MAX_PLANES][DML2_MAX_MCACHES + 1]; unsigned int mcache_shift_granularity_l[DML2_MAX_PLANES]; unsigned int num_mcaches_c[DML2_MAX_PLANES]; unsigned int mcache_row_bytes_c[DML2_MAX_PLANES]; + unsigned int mcache_row_bytes_per_channel_c[DML2_MAX_PLANES]; unsigned int mcache_offsets_c[DML2_MAX_PLANES][DML2_MAX_MCACHES + 1]; unsigned int mcache_shift_granularity_c[DML2_MAX_PLANES]; @@ -1887,6 +1891,7 @@ struct dml2_core_calcs_calculate_mcache_row_bytes_params { // output unsigned int *num_mcaches; unsigned int *mcache_row_bytes; + unsigned int *mcache_row_bytes_per_channel; unsigned int *meta_row_width_ub; double *dcc_dram_bw_nom_overhead_factor; double *dcc_dram_bw_pref_overhead_factor; @@ -1966,6 +1971,7 @@ struct dml2_core_calcs_calculate_mcache_setting_params { // output unsigned int *num_mcaches_l; unsigned int *mcache_row_bytes_l; + unsigned int *mcache_row_bytes_per_channel_l; unsigned int *mcache_offsets_l; unsigned int *mcache_shift_granularity_l; double *dcc_dram_bw_nom_overhead_factor_l; @@ -1973,6 +1979,7 @@ struct dml2_core_calcs_calculate_mcache_setting_params { unsigned int *num_mcaches_c; unsigned int *mcache_row_bytes_c; + unsigned int *mcache_row_bytes_per_channel_c; unsigned int *mcache_offsets_c; unsigned int *mcache_shift_granularity_c; double *dcc_dram_bw_nom_overhead_factor_c; 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 index 456b3f8a6d38..2504d9c2ec34 100644 --- 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 @@ -544,7 +544,8 @@ unsigned int dml2_core_utils_get_active_min_uclk_dpm_index(unsigned long uclk_fr } } - dml2_assert(clk_entry_found); + if (!clk_entry_found) + 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); 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 fc77fb34a19a..02004b7efa8c 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 @@ -212,7 +212,7 @@ static bool add_margin_and_round_to_dfs_grainularity(double clock_khz, double ma clock_khz *= 1.0 + margin; - divider = (unsigned int)((int)DFS_DIVIDER_RANGE_SCALE_FACTOR * (vco_freq_khz / clock_khz)); + divider = (unsigned int)(DFS_DIVIDER_RANGE_SCALE_FACTOR * (vco_freq_khz / clock_khz)); /* we want to floor here to get higher clock than required rather than lower */ if (divider < DFS_DIVIDER_RANGE_2_START) { @@ -307,8 +307,8 @@ static bool map_soc_min_clocks_to_dpm_fine_grained(struct dml2_display_cfg_progr /* these clocks are optional, so they can fail to map, in which case map all to 0 */ if (result) { if (!round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.svp_prefetch_no_throttle.dcfclk_khz, &state_table->dcfclk) || - !round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.svp_prefetch_no_throttle.fclk_khz, &state_table->fclk) || - !round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.svp_prefetch_no_throttle.uclk_khz, &state_table->uclk)) { + !round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.svp_prefetch_no_throttle.fclk_khz, &state_table->fclk) || + !round_up_to_next_dpm(&display_cfg->min_clocks.dcn4x.svp_prefetch_no_throttle.uclk_khz, &state_table->uclk)) { display_cfg->min_clocks.dcn4x.svp_prefetch_no_throttle.dcfclk_khz = 0; display_cfg->min_clocks.dcn4x.svp_prefetch_no_throttle.fclk_khz = 0; display_cfg->min_clocks.dcn4x.svp_prefetch_no_throttle.uclk_khz = 0; 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 b165c58dfd11..e7b58f2efda4 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 @@ -11,6 +11,4 @@ bool dpmm_dcn3_map_mode_to_soc_dpm(struct dml2_dpmm_map_mode_to_soc_dpm_params_i bool dpmm_dcn4_map_mode_to_soc_dpm(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out); bool dpmm_dcn4_map_watermarks(struct dml2_dpmm_map_watermarks_params_in_out *in_out); -bool dpmm_dcn4_unit_test(void); - #endif 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 c60b8fe90819..cd3fbc0591d8 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 @@ -15,7 +15,7 @@ bool dml2_mcg_create(enum dml2_project_id project_id, struct dml2_mcg_instance * { bool result = false; - if (!out) + if (out == 0) return false; memset(out, 0, sizeof(struct dml2_mcg_instance)); 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 15c906c42ec4..f50662b83296 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 @@ -1094,8 +1094,8 @@ static bool all_timings_support_svp(const struct dml2_pmo_instance *pmo, if (plane_descriptor->surface.dcc.enable) { mcaches_per_plane += display_config->stage2.mcache_allocations[i].num_mcaches_plane0 + - display_config->stage2.mcache_allocations[i].num_mcaches_plane1 - - (display_config->stage2.mcache_allocations[i].last_slice_sharing.plane0_plane1 ? 1 : 0); + display_config->stage2.mcache_allocations[i].num_mcaches_plane1 - + (display_config->stage2.mcache_allocations[i].last_slice_sharing.plane0_plane1 ? 1 : 0); } if (is_bit_set_in_bitfield(mask, (unsigned char)plane_descriptor->stream_index)) { @@ -1113,7 +1113,6 @@ static bool all_timings_support_svp(const struct dml2_pmo_instance *pmo, mcaches_per_plane *= 2; } } - total_mcaches_required += mcaches_per_plane; } diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_interfaces.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_interfaces.c index f88931ccbc5e..5a33e2f357f4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_interfaces.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_interfaces.c @@ -47,4 +47,3 @@ bool dml2_build_mcache_programming(struct dml2_build_mcache_programming_in_out * return in_out->dml2_instance->funcs.build_mcache_programming(in_out); } - 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 deleted file mode 100644 index f9f8869cd8b8..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c +++ /dev/null @@ -1,354 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright 2024 Advanced Micro Devices, Inc. - -#include "dml2_internal_shared_types.h" -#include "dml_top.h" -#include "dml2_mcg_factory.h" -#include "dml2_core_factory.h" -#include "dml2_dpmm_factory.h" -#include "dml2_pmo_factory.h" -#include "dml_top_mcache.h" -#include "dml2_top_optimization.h" -#include "dml2_external_lib_deps.h" - -unsigned int dml2_get_instance_size_bytes(void) -{ - return sizeof(struct dml2_instance); -} - -bool dml2_initialize_instance(struct dml2_initialize_instance_in_out *in_out) -{ - struct dml2_instance *dml = (struct dml2_instance *)in_out->dml2_instance; - struct dml2_initialize_instance_locals *l = &dml->scratch.initialize_instance_locals; - struct dml2_core_initialize_in_out core_init_params = { 0 }; - struct dml2_mcg_build_min_clock_table_params_in_out mcg_build_min_clk_params = { 0 }; - struct dml2_pmo_initialize_in_out pmo_init_params = { 0 }; - 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)); - - dml->project_id = in_out->options.project_id; - dml->pmo_options = in_out->options.pmo_options; - - // Initialize All Components - result = dml2_mcg_create(in_out->options.project_id, &dml->mcg_instance); - - if (result) - result = dml2_dpmm_create(in_out->options.project_id, &dml->dpmm_instance); - - if (result) - result = dml2_core_create(in_out->options.project_id, &dml->core_instance); - - if (result) { - mcg_build_min_clk_params.soc_bb = &in_out->soc_bb; - mcg_build_min_clk_params.min_clk_table = &dml->min_clk_table; - result = dml->mcg_instance.build_min_clock_table(&mcg_build_min_clk_params); - } - - if (result) { - core_init_params.project_id = in_out->options.project_id; - core_init_params.instance = &dml->core_instance; - core_init_params.minimum_clock_table = &dml->min_clk_table; - core_init_params.explicit_ip_bb = in_out->overrides.explicit_ip_bb; - core_init_params.explicit_ip_bb_size = in_out->overrides.explicit_ip_bb_size; - core_init_params.ip_caps = &in_out->ip_caps; - core_init_params.soc_bb = &in_out->soc_bb; - result = dml->core_instance.initialize(&core_init_params); - - if (core_init_params.explicit_ip_bb && core_init_params.explicit_ip_bb_size > 0) { - memcpy(&dml->ip_caps, &in_out->ip_caps, sizeof(struct dml2_ip_capabilities)); - } - } - - if (result) - result = dml2_pmo_create(in_out->options.project_id, &dml->pmo_instance); - - if (result) { - pmo_init_params.instance = &dml->pmo_instance; - pmo_init_params.soc_bb = &dml->soc_bbox; - pmo_init_params.ip_caps = &dml->ip_caps; - pmo_init_params.mcg_clock_table_size = dml->min_clk_table.dram_bw_table.num_entries; - pmo_init_params.options = &dml->pmo_options; - dml->pmo_instance.initialize(&pmo_init_params); - } - - return result; -} - -static void setup_unoptimized_display_config_with_meta(const struct dml2_instance *dml, struct display_configuation_with_meta *out, const struct dml2_display_cfg *display_config) -{ - memcpy(&out->display_config, display_config, sizeof(struct dml2_display_cfg)); - out->stage1.min_clk_index_for_latency = dml->min_clk_table.dram_bw_table.num_entries - 1; //dml->min_clk_table.clean_me_up.soc_bb.num_states - 1; -} - -static void setup_speculative_display_config_with_meta(const struct dml2_instance *dml, struct display_configuation_with_meta *out, const struct dml2_display_cfg *display_config) -{ - memcpy(&out->display_config, display_config, sizeof(struct dml2_display_cfg)); - out->stage1.min_clk_index_for_latency = 0; -} - -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; - struct dml2_display_cfg_programming *dpmm_programming = &dml->dpmm_instance.dpmm_scratch.programming; - - bool result = false; - bool mcache_success = false; - - 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); - - l->mode_support_params.instance = &dml->core_instance; - l->mode_support_params.display_cfg = &l->base_display_config_with_meta; - l->mode_support_params.min_clk_table = &dml->min_clk_table; - l->mode_support_params.min_clk_index = l->base_display_config_with_meta.stage1.min_clk_index_for_latency; - - result = dml->core_instance.mode_support(&l->mode_support_params); - l->base_display_config_with_meta.mode_support_result = l->mode_support_params.mode_support_result; - - if (result) { - struct optimization_phase_params mcache_phase = { - .dml = dml, - .display_config = &l->base_display_config_with_meta, - .test_function = dml2_top_optimization_test_function_mcache, - .optimize_function = dml2_top_optimization_optimize_function_mcache, - .optimized_display_config = &l->optimized_display_config_with_meta, - .all_or_nothing = false, - }; - mcache_success = dml2_top_optimization_perform_optimization_phase(&l->optimization_phase_locals, &mcache_phase); - } - - /* - * Call DPMM to map all requirements to minimum clock state - */ - 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; - l->dppm_map_mode_params.soc_bb = &dml->soc_bbox; - l->dppm_map_mode_params.ip = &dml->core_instance.clean_me_up.mode_lib.ip; - result = dml->dpmm_instance.map_mode_to_soc_dpm(&l->dppm_map_mode_params); - } - - in_out->is_supported = mcache_success; - result = result && in_out->is_supported; - - return result; -} - -bool dml2_build_mode_programming(struct dml2_build_mode_programming_in_out *in_out) -{ - struct dml2_instance *dml = (struct dml2_instance *)in_out->dml2_instance; - struct dml2_build_mode_programming_locals *l = &dml->scratch.build_mode_programming_locals; - - bool result = false; - bool mcache_success = false; - bool uclk_pstate_success = false; - bool vmin_success = false; - bool stutter_success = false; - unsigned int i; - - memset(l, 0, sizeof(struct dml2_build_mode_programming_locals)); - memset(in_out->programming, 0, sizeof(struct dml2_display_cfg_programming)); - - memcpy(&in_out->programming->display_config, in_out->display_config, sizeof(struct dml2_display_cfg)); - - setup_speculative_display_config_with_meta(dml, &l->base_display_config_with_meta, in_out->display_config); - - l->mode_support_params.instance = &dml->core_instance; - l->mode_support_params.display_cfg = &l->base_display_config_with_meta; - l->mode_support_params.min_clk_table = &dml->min_clk_table; - l->mode_support_params.min_clk_index = l->base_display_config_with_meta.stage1.min_clk_index_for_latency; - - result = dml->core_instance.mode_support(&l->mode_support_params); - l->base_display_config_with_meta.mode_support_result = l->mode_support_params.mode_support_result; - - if (!result) { - setup_unoptimized_display_config_with_meta(dml, &l->base_display_config_with_meta, in_out->display_config); - - l->mode_support_params.instance = &dml->core_instance; - l->mode_support_params.display_cfg = &l->base_display_config_with_meta; - l->mode_support_params.min_clk_table = &dml->min_clk_table; - l->mode_support_params.min_clk_index = l->base_display_config_with_meta.stage1.min_clk_index_for_latency; - - result = dml->core_instance.mode_support(&l->mode_support_params); - l->base_display_config_with_meta.mode_support_result = l->mode_support_params.mode_support_result; - - if (!result) { - l->informative_params.instance = &dml->core_instance; - l->informative_params.programming = in_out->programming; - l->informative_params.mode_is_supported = false; - dml->core_instance.populate_informative(&l->informative_params); - - return false; - } - - /* - * Phase 1: Determine minimum clocks to satisfy latency requirements for this mode - */ - memset(&l->min_clock_for_latency_phase, 0, sizeof(struct optimization_phase_params)); - l->min_clock_for_latency_phase.dml = dml; - l->min_clock_for_latency_phase.display_config = &l->base_display_config_with_meta; - l->min_clock_for_latency_phase.init_function = dml2_top_optimization_init_function_min_clk_for_latency; - l->min_clock_for_latency_phase.test_function = dml2_top_optimization_test_function_min_clk_for_latency; - l->min_clock_for_latency_phase.optimize_function = dml2_top_optimization_optimize_function_min_clk_for_latency; - l->min_clock_for_latency_phase.optimized_display_config = &l->optimized_display_config_with_meta; - l->min_clock_for_latency_phase.all_or_nothing = false; - - dml2_top_optimization_perform_optimization_phase_1(&l->optimization_phase_locals, &l->min_clock_for_latency_phase); - - memcpy(&l->base_display_config_with_meta, &l->optimized_display_config_with_meta, sizeof(struct display_configuation_with_meta)); - } - - /* - * Phase 2: Satisfy DCC mcache requirements - */ - memset(&l->mcache_phase, 0, sizeof(struct optimization_phase_params)); - l->mcache_phase.dml = dml; - l->mcache_phase.display_config = &l->base_display_config_with_meta; - l->mcache_phase.test_function = dml2_top_optimization_test_function_mcache; - l->mcache_phase.optimize_function = dml2_top_optimization_optimize_function_mcache; - l->mcache_phase.optimized_display_config = &l->optimized_display_config_with_meta; - l->mcache_phase.all_or_nothing = true; - - mcache_success = dml2_top_optimization_perform_optimization_phase(&l->optimization_phase_locals, &l->mcache_phase); - - if (!mcache_success) { - l->informative_params.instance = &dml->core_instance; - l->informative_params.programming = in_out->programming; - l->informative_params.mode_is_supported = false; - - dml->core_instance.populate_informative(&l->informative_params); - - in_out->programming->informative.failed_mcache_validation = true; - return false; - } - - memcpy(&l->base_display_config_with_meta, &l->optimized_display_config_with_meta, sizeof(struct display_configuation_with_meta)); - - /* - * Phase 3: Optimize for Pstate - */ - memset(&l->uclk_pstate_phase, 0, sizeof(struct optimization_phase_params)); - l->uclk_pstate_phase.dml = dml; - l->uclk_pstate_phase.display_config = &l->base_display_config_with_meta; - l->uclk_pstate_phase.init_function = dml2_top_optimization_init_function_uclk_pstate; - l->uclk_pstate_phase.test_function = dml2_top_optimization_test_function_uclk_pstate; - l->uclk_pstate_phase.optimize_function = dml2_top_optimization_optimize_function_uclk_pstate; - l->uclk_pstate_phase.optimized_display_config = &l->optimized_display_config_with_meta; - l->uclk_pstate_phase.all_or_nothing = true; - - uclk_pstate_success = dml2_top_optimization_perform_optimization_phase(&l->optimization_phase_locals, &l->uclk_pstate_phase); - - if (uclk_pstate_success) { - 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.stage3.success = true; - } - - /* - * Phase 4: Optimize for Vmin - */ - memset(&l->vmin_phase, 0, sizeof(struct optimization_phase_params)); - l->vmin_phase.dml = dml; - l->vmin_phase.display_config = &l->base_display_config_with_meta; - l->vmin_phase.init_function = dml2_top_optimization_init_function_vmin; - l->vmin_phase.test_function = dml2_top_optimization_test_function_vmin; - l->vmin_phase.optimize_function = dml2_top_optimization_optimize_function_vmin; - l->vmin_phase.optimized_display_config = &l->optimized_display_config_with_meta; - l->vmin_phase.all_or_nothing = false; - - vmin_success = dml2_top_optimization_perform_optimization_phase(&l->optimization_phase_locals, &l->vmin_phase); - - 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 = vmin_success; - } - - /* - * Phase 5: Optimize for Stutter - */ - memset(&l->stutter_phase, 0, sizeof(struct optimization_phase_params)); - l->stutter_phase.dml = dml; - l->stutter_phase.display_config = &l->base_display_config_with_meta; - l->stutter_phase.init_function = dml2_top_optimization_init_function_stutter; - l->stutter_phase.test_function = dml2_top_optimization_test_function_stutter; - l->stutter_phase.optimize_function = dml2_top_optimization_optimize_function_stutter; - l->stutter_phase.optimized_display_config = &l->optimized_display_config_with_meta; - l->stutter_phase.all_or_nothing = true; - - stutter_success = dml2_top_optimization_perform_optimization_phase(&l->optimization_phase_locals, &l->stutter_phase); - - if (stutter_success) { - 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.stage5.success = true; - } - - /* - * Populate mcache programming - */ - for (i = 0; i < in_out->display_config->num_planes; i++) { - in_out->programming->plane_programming[i].mcache_allocation = l->base_display_config_with_meta.stage2.mcache_allocations[i]; - } - - /* - * Call DPMM to map all requirements to minimum clock state - */ - 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 = in_out->programming; - l->dppm_map_mode_params.soc_bb = &dml->soc_bbox; - l->dppm_map_mode_params.ip = &dml->core_instance.clean_me_up.mode_lib.ip; - result = dml->dpmm_instance.map_mode_to_soc_dpm(&l->dppm_map_mode_params); - if (!result) - in_out->programming->informative.failed_dpmm = true; - } - - if (result) { - l->mode_programming_params.instance = &dml->core_instance; - l->mode_programming_params.display_cfg = &l->base_display_config_with_meta; - l->mode_programming_params.cfg_support_info = &l->base_display_config_with_meta.mode_support_result.cfg_support_info; - l->mode_programming_params.programming = in_out->programming; - - result = dml->core_instance.mode_programming(&l->mode_programming_params); - if (!result) - in_out->programming->informative.failed_mode_programming = true; - } - - if (result) { - l->dppm_map_watermarks_params.core = &dml->core_instance; - l->dppm_map_watermarks_params.display_cfg = &l->base_display_config_with_meta; - l->dppm_map_watermarks_params.programming = in_out->programming; - result = dml->dpmm_instance.map_watermarks(&l->dppm_map_watermarks_params); - } - - l->informative_params.instance = &dml->core_instance; - l->informative_params.programming = in_out->programming; - l->informative_params.mode_is_supported = result; - - dml->core_instance.populate_informative(&l->informative_params); - - return result; -} - -bool dml2_build_mcache_programming(struct dml2_build_mcache_programming_in_out *in_out) -{ - return dml2_top_mcache_build_mcache_programming(in_out); -} - 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 f95c7ff56f15..c506667897c4 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 @@ -29,8 +29,3 @@ int dml2_printf(const char *format, ...) return 0; #endif } - -void dml2_assert(int condition) -{ - //ASSERT(condition); -} 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 a27792b56f7e..bfe6f236d2e4 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 @@ -5,11 +5,10 @@ #ifndef __DML2_DEBUG_H__ #define __DML2_DEBUG_H__ -#ifdef _DEBUG -#define DML2_ASSERT(condition) dml2_assert(condition) -#else +#ifndef DML2_ASSERT #define DML2_ASSERT(condition) ((void)0) #endif + /* * DML_LOG_FATAL - fatal errors for unrecoverable DML states until a restart. * DML_LOG_ERROR - unexpected but recoverable failures inside DML @@ -56,6 +55,5 @@ int dml2_log_internal(const char *format, ...); int dml2_printf(const char *format, ...); -void dml2_assert(int condition); #endif 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 7fb6026bcb49..d8d01dceacdd 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 @@ -64,7 +64,6 @@ struct dml2_mcg_build_min_clock_table_params_in_out { }; struct dml2_mcg_instance { bool (*build_min_clock_table)(struct dml2_mcg_build_min_clock_table_params_in_out *in_out); - bool (*unit_test)(void); }; /* @@ -110,7 +109,6 @@ struct dml2_dpmm_scratch { 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; }; @@ -473,7 +471,6 @@ struct dml2_core_instance { bool (*mode_programming)(struct dml2_core_mode_programming_in_out *in_out); bool (*populate_informative)(struct dml2_core_populate_informative_in_out *in_out); bool (*calculate_mcache_allocation)(struct dml2_calculate_mcache_allocation_in_out *in_out); - bool (*unit_test)(void); struct { struct dml2_core_internal_display_mode_lib mode_lib; @@ -721,8 +718,6 @@ struct dml2_pmo_instance { bool (*test_for_stutter)(struct dml2_pmo_test_for_stutter_in_out *in_out); bool (*optimize_for_stutter)(struct dml2_pmo_optimize_for_stutter_in_out *in_out); - bool (*unit_test)(void); - struct dml2_pmo_init_data init_data; struct dml2_pmo_scratch scratch; }; @@ -947,7 +942,6 @@ struct dml2_top_funcs { bool (*check_mode_supported)(struct dml2_check_mode_supported_in_out *in_out); bool (*build_mode_programming)(struct dml2_build_mode_programming_in_out *in_out); bool (*build_mcache_programming)(struct dml2_build_mcache_programming_in_out *in_out); - bool (*unit_test)(void); }; struct dml2_instance { -- cgit v1.2.3 From 8e539d2dd2afbf5a8755b373bf29082b58f912ad Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Mon, 27 Jan 2025 18:44:56 -0500 Subject: drm/amd/display: use s1_12 filter tables in SPL [Why & How] Instead of converting tables from s1_10 to s1_12, added s1_12 tables instead in SPL Remove init calls that do the conversion Reviewed-by: Alvin Lee Signed-off-by: Samson Tam Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 6ab194a86cb9..64f2153310df 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,9 +76,6 @@ #include "dml2/dml2_wrapper.h" -#include "sspl/dc_spl_scl_easf_filters.h" -#include "sspl/dc_spl_isharp_filters.h" - #define DC_LOGGER_INIT(logger) enum dcn401_clk_src_array_id { @@ -2189,8 +2186,6 @@ static bool dcn401_resource_construct( dc->dml2_options.det_segment_size = DCN4_01_CRB_SEGMENT_SIZE_KB; /* SPL */ - spl_init_easf_filter_coeffs(); - spl_init_blur_scale_coeffs(); dc->caps.scl_caps.sharpener_support = true; return true; -- cgit v1.2.3 From 2a4519c4e9b2e1f622ab4c5f5841abdb9760cb0b Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Mon, 27 Jan 2025 18:27:06 -0500 Subject: drm/amd/display: remove TF check for LLS policy [Why & How] LLS policy not affected by TF. Remove check in don't care case and use pixel format only. Reviewed-by: Navid Assadian Signed-off-by: Samson Tam Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c | 31 +++++++--------------------- 1 file changed, 7 insertions(+), 24 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c index 38a9a0d68058..31495c9978b0 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c @@ -767,25 +767,13 @@ static enum scl_mode spl_get_dscl_mode(const struct spl_in *spl_in, 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, +static void spl_choose_lls_policy(enum spl_pixel_format format, enum linear_light_scaling *lls_pref) { - if (spl_is_video_format(format)) { + if (spl_is_subsampled_format(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; + else /* RGB or YUV444 */ + *lls_pref = LLS_PREF_YES; } /* Enable EASF ?*/ @@ -794,7 +782,6 @@ 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; @@ -810,17 +797,13 @@ static bool enable_easf(struct spl_in *spl_in, struct spl_scratch *spl_scratch) 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 lls_pref is LLS_PREF_DONT_CARE, then use pixel format + * 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_choose_lls_policy(spl_in->basic_in.format, &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; -- cgit v1.2.3 From b474a6e11f3be9e1c45df56bb6579a7bc8468dbd Mon Sep 17 00:00:00 2001 From: Leo Zeng Date: Tue, 28 Jan 2025 15:47:27 -0500 Subject: drm/amd/display: add new IRQ enum for underflows [WHY & HOW] needed in certain scenarios for debugging and logging Reviewed-by: Joshua Aberback Reviewed-by: Martin Leung Signed-off-by: Leo Zeng Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/irq_types.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/irq_types.h b/drivers/gpu/drm/amd/display/dc/irq_types.h index e962c426beda..110f656d43ae 100644 --- a/drivers/gpu/drm/amd/display/dc/irq_types.h +++ b/drivers/gpu/drm/amd/display/dc/irq_types.h @@ -170,6 +170,7 @@ enum irq_type IRQ_TYPE_VUPDATE = DC_IRQ_SOURCE_VUPDATE1, IRQ_TYPE_VBLANK = DC_IRQ_SOURCE_VBLANK1, IRQ_TYPE_VLINE0 = DC_IRQ_SOURCE_DC1_VLINE0, + IRQ_TYPE_DCUNDERFLOW = DC_IRQ_SOURCE_DC1UNDERFLOW, }; #define DAL_VALID_IRQ_SRC_NUM(src) \ -- cgit v1.2.3 From c36d7948bb460f27f7ad77d35ad1d96cf848cd73 Mon Sep 17 00:00:00 2001 From: Ausef Yousof Date: Thu, 30 Jan 2025 12:30:10 -0500 Subject: drm/amd/display: limit coverage of optimization skip [why&how] causing some regression on dgpu which still needs the pre-emptive return, limit this to reporter asic version it is simple to include different dcn versions from this point forward, each dcn resource is initialized with the flag and can be enabled at will Reviewed-by: Chris Park Signed-off-by: Ausef Yousof Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 1 + drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 1 + drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c | 1 + 3 files changed, 3 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') 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 6d163dcecde6..ffd2b816cd02 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 @@ -1909,6 +1909,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 */ { diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c index 4a03df5d760f..98f5bc1b929e 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c @@ -1877,6 +1877,7 @@ static bool dcn351_resource_construct( /* Use pipe context based otg sync logic */ dc->config.use_pipe_ctx_sync_logic = true; + /* Use psp mailbox to enable assr */ dc->config.use_assr_psp_message = true; 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 64f2153310df..4e842f29d4c4 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 @@ -1923,6 +1923,7 @@ static bool dcn401_resource_construct( dc->config.dc_mode_clk_limit_support = true; dc->config.enable_windowed_mpo_odm = true; dc->config.set_pipe_unlock_order = true; /* Need to ensure DET gets freed before allocating */ + /* read VBIOS LTTPR caps */ { if (ctx->dc_bios->funcs->get_lttpr_caps) { -- cgit v1.2.3 From 5a20ca32a2a1bca469b238f1cab8ca05f06a7a08 Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Tue, 28 Jan 2025 15:12:43 -0500 Subject: drm/amd/display: add s1_12 filter tables [Why & How] Instead of converting tables from s1_10 to s1_12, add s1_12 tables instead. Remove init calls that do the conversion. Add APIs to read s1_10 tables Reviewed-by: Navid Assadian Signed-off-by: Samson Tam Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/dc/sspl/dc_spl_isharp_filters.c | 143 ++- .../amd/display/dc/sspl/dc_spl_isharp_filters.h | 10 +- .../amd/display/dc/sspl/dc_spl_scl_easf_filters.c | 1025 ++++++++++++++++++-- .../amd/display/dc/sspl/dc_spl_scl_easf_filters.h | 10 +- 4 files changed, 1079 insertions(+), 109 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c index e0572252c640..060451bf90d1 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c @@ -456,9 +456,113 @@ static const uint16_t filter_isharp_bs_3tap_64p[99] = { }; /* 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]; +static const uint16_t filter_isharp_bs_4tap_in_6_64p_s1_12[198] = { +0x0000, 0x0394, 0x08dc, 0x0390, 0x0000, 0x0000, +0x0000, 0x0378, 0x08dc, 0x03ac, 0x0000, 0x0000, +0x0000, 0x035c, 0x08d8, 0x03c8, 0x0004, 0x0000, +0x0000, 0x0340, 0x08d4, 0x03e8, 0x0004, 0x0000, +0x0000, 0x0324, 0x08d0, 0x0404, 0x0008, 0x0000, +0x0000, 0x0308, 0x08cc, 0x0420, 0x000c, 0x0000, +0x0000, 0x02ec, 0x08c8, 0x0440, 0x000c, 0x0000, +0x0000, 0x02d4, 0x08c0, 0x045c, 0x0010, 0x0000, +0x0000, 0x02b8, 0x08b8, 0x047c, 0x0014, 0x0000, +0x0000, 0x02a0, 0x08b0, 0x0498, 0x0018, 0x0000, +0x0000, 0x0288, 0x08a8, 0x04b4, 0x001c, 0x0000, +0x0000, 0x0270, 0x08a0, 0x04d0, 0x0020, 0x0000, +0x0000, 0x0258, 0x0894, 0x04f0, 0x0024, 0x0000, +0x0000, 0x0240, 0x0888, 0x050c, 0x002c, 0x0000, +0x0000, 0x0228, 0x087c, 0x052c, 0x0030, 0x0000, +0x0000, 0x0214, 0x0870, 0x0544, 0x0038, 0x0000, +0x0000, 0x01fc, 0x0860, 0x0568, 0x003c, 0x0000, +0x0000, 0x01e8, 0x0854, 0x0580, 0x0044, 0x0000, +0x0000, 0x01d0, 0x0844, 0x05a0, 0x004c, 0x0000, +0x0000, 0x01bc, 0x0834, 0x05bc, 0x0054, 0x0000, +0x0000, 0x01a8, 0x0824, 0x05d8, 0x005c, 0x0000, +0x0000, 0x0194, 0x0810, 0x05f8, 0x0064, 0x0000, +0x0000, 0x0180, 0x0800, 0x0614, 0x006c, 0x0000, +0x0000, 0x0170, 0x07ec, 0x0630, 0x0074, 0x0000, +0x0000, 0x015c, 0x07d8, 0x064c, 0x0080, 0x0000, +0x0000, 0x014c, 0x07c4, 0x0668, 0x0088, 0x0000, +0x0000, 0x0138, 0x07b0, 0x0684, 0x0094, 0x0000, +0x0000, 0x0128, 0x0798, 0x06a0, 0x00a0, 0x0000, +0x0000, 0x0118, 0x0784, 0x06bc, 0x00a8, 0x0000, +0x0000, 0x0108, 0x076c, 0x06d8, 0x00b4, 0x0000, +0x0000, 0x00fc, 0x0754, 0x06ec, 0x00c4, 0x0000, +0x0000, 0x00ec, 0x073c, 0x0708, 0x00d0, 0x0000, +0x0000, 0x00dc, 0x0724, 0x0724, 0x00dc, 0x0000, +}; + +static const uint16_t filter_isharp_bs_4tap_64p_s1_12[132] = { +0x0394, 0x08dc, 0x0390, 0x0000, +0x0378, 0x08dc, 0x03ac, 0x0000, +0x035c, 0x08d8, 0x03c8, 0x0004, +0x0340, 0x08d4, 0x03e8, 0x0004, +0x0324, 0x08d0, 0x0404, 0x0008, +0x0308, 0x08cc, 0x0420, 0x000c, +0x02ec, 0x08c8, 0x0440, 0x000c, +0x02d4, 0x08c0, 0x045c, 0x0010, +0x02b8, 0x08b8, 0x047c, 0x0014, +0x02a0, 0x08b0, 0x0498, 0x0018, +0x0288, 0x08a8, 0x04b4, 0x001c, +0x0270, 0x08a0, 0x04d0, 0x0020, +0x0258, 0x0894, 0x04f0, 0x0024, +0x0240, 0x0888, 0x050c, 0x002c, +0x0228, 0x087c, 0x052c, 0x0030, +0x0214, 0x0870, 0x0544, 0x0038, +0x01fc, 0x0860, 0x0568, 0x003c, +0x01e8, 0x0854, 0x0580, 0x0044, +0x01d0, 0x0844, 0x05a0, 0x004c, +0x01bc, 0x0834, 0x05bc, 0x0054, +0x01a8, 0x0824, 0x05d8, 0x005c, +0x0194, 0x0810, 0x05f8, 0x0064, +0x0180, 0x0800, 0x0614, 0x006c, +0x0170, 0x07ec, 0x0630, 0x0074, +0x015c, 0x07d8, 0x064c, 0x0080, +0x014c, 0x07c4, 0x0668, 0x0088, +0x0138, 0x07b0, 0x0684, 0x0094, +0x0128, 0x0798, 0x06a0, 0x00a0, +0x0118, 0x0784, 0x06bc, 0x00a8, +0x0108, 0x076c, 0x06d8, 0x00b4, +0x00fc, 0x0754, 0x06ec, 0x00c4, +0x00ec, 0x073c, 0x0708, 0x00d0, +0x00dc, 0x0724, 0x0724, 0x00dc, +}; + +static const uint16_t filter_isharp_bs_3tap_64p_s1_12[99] = { +0x0800, 0x0800, 0x0000, +0x07d8, 0x0818, 0x0010, +0x07b0, 0x082c, 0x0024, +0x0788, 0x0844, 0x0034, +0x0760, 0x0858, 0x0048, +0x0738, 0x0870, 0x0058, +0x0710, 0x0884, 0x006c, +0x06e8, 0x0898, 0x0080, +0x06c0, 0x08a8, 0x0098, +0x0698, 0x08bc, 0x00ac, +0x0670, 0x08cc, 0x00c4, +0x0648, 0x08e0, 0x00d8, +0x0620, 0x08f0, 0x00f0, +0x05f8, 0x0900, 0x0108, +0x05d0, 0x0910, 0x0120, +0x05a8, 0x0920, 0x0138, +0x0584, 0x0928, 0x0154, +0x055c, 0x0938, 0x016c, +0x0534, 0x0944, 0x0188, +0x0510, 0x094c, 0x01a4, +0x04e8, 0x0958, 0x01c0, +0x04c4, 0x0960, 0x01dc, +0x049c, 0x096c, 0x01f8, +0x0478, 0x0970, 0x0218, +0x0454, 0x0978, 0x0234, +0x042c, 0x0980, 0x0254, +0x0408, 0x0988, 0x0270, +0x03e4, 0x098c, 0x0290, +0x03c0, 0x0990, 0x02b0, +0x039c, 0x0994, 0x02d0, +0x037c, 0x0990, 0x02f4, +0x0358, 0x0994, 0x0314, +0x0334, 0x0998, 0x0334, +}; /* Pre-generated 1DLUT for given setup and sharpness level */ struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] = { @@ -537,15 +641,15 @@ const uint16_t *spl_get_filter_isharp_wide_6tap_64p(void) { return filter_isharp_wide_6tap_64p; } -uint16_t *spl_get_filter_isharp_bs_4tap_in_6_64p(void) +const uint16_t *spl_get_filter_isharp_bs_4tap_in_6_64p(void) { return filter_isharp_bs_4tap_in_6_64p_s1_12; } -uint16_t *spl_get_filter_isharp_bs_4tap_64p(void) +const 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) +const uint16_t *spl_get_filter_isharp_bs_3tap_64p(void) { return filter_isharp_bs_3tap_64p_s1_12; } @@ -720,17 +824,7 @@ 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) +const uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps) { if (taps == 3) return spl_get_filter_isharp_bs_3tap_64p(); @@ -745,6 +839,21 @@ uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps) } } +const uint16_t *spl_dscl_get_blur_scale_coeffs_64p_s1_10(int taps) +{ + if (taps == 3) + return filter_isharp_bs_3tap_64p; + else if (taps == 4) + return filter_isharp_bs_4tap_64p; + else if (taps == 6) + return 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) { diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.h index 89af91e19b6c..7d0be2fc2d00 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.h +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.h @@ -13,11 +13,12 @@ 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 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_bs_4tap_in_6_64p(void); +const uint16_t *spl_get_filter_isharp_bs_4tap_64p(void); +const 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); +const uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps); +const uint16_t *spl_dscl_get_blur_scale_coeffs_64p_s1_10(int taps); #define NUM_SHARPNESS_ADJ_LEVELS 6 struct scale_ratio_to_sharpness_level_adj { @@ -40,7 +41,6 @@ enum system_setup { 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); diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.c index 09bf82f7d468..5f4e2e36c91f 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.c +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.c @@ -1136,30 +1136,870 @@ static const uint16_t easf_filter_6tap_64p_ratio_1_00[198] = { }; /* 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]; + +static const uint16_t easf_filter_3tap_64p_ratio_0_30_s1_12[99] = { +0x0800, 0x0800, 0x0000, +0x07d8, 0x0818, 0x0010, +0x07b0, 0x082c, 0x0024, +0x0788, 0x0844, 0x0034, +0x0760, 0x0858, 0x0048, +0x0738, 0x0870, 0x0058, +0x0710, 0x0884, 0x006c, +0x06e8, 0x0898, 0x0080, +0x06c0, 0x08a8, 0x0098, +0x0698, 0x08bc, 0x00ac, +0x0670, 0x08cc, 0x00c4, +0x0648, 0x08e0, 0x00d8, +0x0620, 0x08f0, 0x00f0, +0x05f8, 0x0900, 0x0108, +0x05d0, 0x0910, 0x0120, +0x05a8, 0x0920, 0x0138, +0x0584, 0x0928, 0x0154, +0x055c, 0x0938, 0x016c, +0x0534, 0x0944, 0x0188, +0x0510, 0x094c, 0x01a4, +0x04e8, 0x0958, 0x01c0, +0x04c4, 0x0960, 0x01dc, +0x049c, 0x096c, 0x01f8, +0x0478, 0x0970, 0x0218, +0x0454, 0x0978, 0x0234, +0x042c, 0x0980, 0x0254, +0x0408, 0x0988, 0x0270, +0x03e4, 0x098c, 0x0290, +0x03c0, 0x0990, 0x02b0, +0x039c, 0x0994, 0x02d0, +0x037c, 0x0990, 0x02f4, +0x0358, 0x0994, 0x0314, +0x0334, 0x0998, 0x0334, +}; + +static const uint16_t easf_filter_3tap_64p_ratio_0_40_s1_12[99] = { +0x0800, 0x0800, 0x0000, +0x07d8, 0x0818, 0x0010, +0x07ac, 0x0838, 0x001c, +0x0784, 0x0850, 0x002c, +0x075c, 0x0868, 0x003c, +0x0734, 0x0880, 0x004c, +0x0708, 0x0898, 0x0060, +0x06e0, 0x08b0, 0x0070, +0x06b8, 0x08c4, 0x0084, +0x068c, 0x08dc, 0x0098, +0x0664, 0x08f0, 0x00ac, +0x063c, 0x0900, 0x00c4, +0x0614, 0x0914, 0x00d8, +0x05e8, 0x0928, 0x00f0, +0x05c0, 0x093c, 0x0104, +0x0598, 0x094c, 0x011c, +0x0570, 0x095c, 0x0134, +0x0548, 0x0968, 0x0150, +0x0520, 0x0978, 0x0168, +0x04f8, 0x0984, 0x0184, +0x04d0, 0x0990, 0x01a0, +0x04ac, 0x0998, 0x01bc, +0x0484, 0x09a4, 0x01d8, +0x045c, 0x09b0, 0x01f4, +0x0438, 0x09b8, 0x0210, +0x0410, 0x09c0, 0x0230, +0x03ec, 0x09c4, 0x0250, +0x03c8, 0x09c8, 0x0270, +0x03a4, 0x09cc, 0x0290, +0x0380, 0x09d0, 0x02b0, +0x035c, 0x09d4, 0x02d0, +0x0338, 0x09d4, 0x02f4, +0x0314, 0x09d8, 0x0314, +}; + +static const uint16_t easf_filter_3tap_64p_ratio_0_50_s1_12[99] = { +0x0800, 0x0800, 0x0000, +0x07d4, 0x0824, 0x0008, +0x07a8, 0x0844, 0x0014, +0x077c, 0x0868, 0x001c, +0x0750, 0x0888, 0x0028, +0x0724, 0x08a8, 0x0034, +0x06f8, 0x08c8, 0x0040, +0x06cc, 0x08e4, 0x0050, +0x06a0, 0x0904, 0x005c, +0x0674, 0x0920, 0x006c, +0x0648, 0x093c, 0x007c, +0x061c, 0x0954, 0x0090, +0x05f0, 0x0970, 0x00a0, +0x05c4, 0x0988, 0x00b4, +0x0598, 0x09a0, 0x00c8, +0x056c, 0x09b8, 0x00dc, +0x0540, 0x09cc, 0x00f4, +0x0518, 0x09e0, 0x0108, +0x04ec, 0x09f4, 0x0120, +0x04c0, 0x0a08, 0x0138, +0x0498, 0x0a18, 0x0150, +0x046c, 0x0a28, 0x016c, +0x0444, 0x0a34, 0x0188, +0x041c, 0x0a40, 0x01a4, +0x03f4, 0x0a4c, 0x01c0, +0x03cc, 0x0a58, 0x01dc, +0x03a4, 0x0a60, 0x01fc, +0x037c, 0x0a68, 0x021c, +0x0354, 0x0a70, 0x023c, +0x0330, 0x0a74, 0x025c, +0x030c, 0x0a78, 0x027c, +0x02e8, 0x0a78, 0x02a0, +0x02c4, 0x0a78, 0x02c4, +}; + +static const uint16_t easf_filter_3tap_64p_ratio_0_60_s1_12[99] = { +0x0800, 0x0800, 0x0000, +0x07d0, 0x082c, 0x0004, +0x07a0, 0x0858, 0x0008, +0x0770, 0x0884, 0x000c, +0x0740, 0x08ac, 0x0014, +0x0710, 0x08d4, 0x001c, +0x06e0, 0x0900, 0x0020, +0x06b0, 0x0924, 0x002c, +0x0680, 0x094c, 0x0034, +0x0650, 0x0970, 0x0040, +0x0620, 0x0994, 0x004c, +0x05f0, 0x09b8, 0x0058, +0x05c0, 0x09dc, 0x0064, +0x0590, 0x09fc, 0x0074, +0x0560, 0x0a1c, 0x0084, +0x0530, 0x0a3c, 0x0094, +0x0500, 0x0a5c, 0x00a4, +0x04d4, 0x0a74, 0x00b8, +0x04a4, 0x0a90, 0x00cc, +0x0474, 0x0aac, 0x00e0, +0x0448, 0x0ac0, 0x00f8, +0x041c, 0x0ad4, 0x0110, +0x03f0, 0x0ae8, 0x0128, +0x03c4, 0x0afc, 0x0140, +0x0398, 0x0b0c, 0x015c, +0x036c, 0x0b1c, 0x0178, +0x0344, 0x0b28, 0x0194, +0x031c, 0x0b30, 0x01b4, +0x02f4, 0x0b38, 0x01d4, +0x02cc, 0x0b40, 0x01f4, +0x02a4, 0x0b48, 0x0214, +0x0280, 0x0b48, 0x0238, +0x025c, 0x0b48, 0x025c, +}; + +static const uint16_t easf_filter_3tap_64p_ratio_0_70_s1_12[99] = { +0x0800, 0x0800, 0x0000, +0x07cc, 0x0834, 0x0000, +0x0794, 0x086c, 0x0000, +0x0760, 0x08a0, 0x0000, +0x072c, 0x08d4, 0x0000, +0x06f4, 0x090c, 0x0000, +0x06c0, 0x093c, 0x0004, +0x0688, 0x0970, 0x0008, +0x0654, 0x09a0, 0x000c, +0x061c, 0x09d4, 0x0010, +0x05e8, 0x0a00, 0x0018, +0x05b4, 0x0a30, 0x001c, +0x057c, 0x0a60, 0x0024, +0x0548, 0x0a88, 0x0030, +0x0514, 0x0ab4, 0x0038, +0x04e0, 0x0adc, 0x0044, +0x04ac, 0x0b00, 0x0054, +0x0478, 0x0b28, 0x0060, +0x0444, 0x0b4c, 0x0070, +0x0414, 0x0b6c, 0x0080, +0x03e0, 0x0b8c, 0x0094, +0x03b0, 0x0ba8, 0x00a8, +0x0380, 0x0bc4, 0x00bc, +0x0354, 0x0bd8, 0x00d4, +0x0324, 0x0bf0, 0x00ec, +0x02f8, 0x0c04, 0x0104, +0x02cc, 0x0c14, 0x0120, +0x02a0, 0x0c24, 0x013c, +0x0278, 0x0c30, 0x0158, +0x0250, 0x0c38, 0x0178, +0x0228, 0x0c40, 0x0198, +0x0204, 0x0c40, 0x01bc, +0x01dc, 0x0c48, 0x01dc, +}; + +static const uint16_t easf_filter_3tap_64p_ratio_0_80_s1_12[99] = { +0x0800, 0x0800, 0x0000, +0x07c4, 0x0840, 0x3ffc, +0x0788, 0x0880, 0x3ff8, +0x0748, 0x08c8, 0x3ff0, +0x070c, 0x0904, 0x3ff0, +0x06d0, 0x0944, 0x3fec, +0x0690, 0x0988, 0x3fe8, +0x0654, 0x09c4, 0x3fe8, +0x0618, 0x0a04, 0x3fe4, +0x05d8, 0x0a44, 0x3fe4, +0x059c, 0x0a80, 0x3fe4, +0x0560, 0x0ab8, 0x3fe8, +0x0524, 0x0af4, 0x3fe8, +0x04e8, 0x0b2c, 0x3fec, +0x04b0, 0x0b5c, 0x3ff4, +0x0474, 0x0b94, 0x3ff8, +0x043c, 0x0bc4, 0x0000, +0x0404, 0x0bf4, 0x0008, +0x03cc, 0x0c20, 0x0014, +0x0394, 0x0c4c, 0x0020, +0x0360, 0x0c74, 0x002c, +0x032c, 0x0c98, 0x003c, +0x02f8, 0x0cbc, 0x004c, +0x02c8, 0x0cdc, 0x005c, +0x0298, 0x0cf8, 0x0070, +0x0268, 0x0d14, 0x0084, +0x023c, 0x0d28, 0x009c, +0x0210, 0x0d3c, 0x00b4, +0x01e4, 0x0d4c, 0x00d0, +0x01bc, 0x0d58, 0x00ec, +0x0194, 0x0d60, 0x010c, +0x0170, 0x0d64, 0x012c, +0x014c, 0x0d68, 0x014c, +}; + +static const uint16_t easf_filter_3tap_64p_ratio_0_90_s1_12[99] = { +0x0800, 0x0800, 0x0000, +0x07b8, 0x0850, 0x3ff8, +0x0770, 0x08a0, 0x3ff0, +0x0728, 0x08f0, 0x3fe8, +0x06e4, 0x093c, 0x3fe0, +0x069c, 0x0988, 0x3fdc, +0x0654, 0x09d8, 0x3fd4, +0x060c, 0x0a28, 0x3fcc, +0x05c8, 0x0a70, 0x3fc8, +0x0580, 0x0abc, 0x3fc4, +0x053c, 0x0b08, 0x3fbc, +0x04f8, 0x0b50, 0x3fb8, +0x04b4, 0x0b94, 0x3fb8, +0x0470, 0x0bdc, 0x3fb4, +0x0430, 0x0c1c, 0x3fb4, +0x03ec, 0x0c60, 0x3fb4, +0x03b0, 0x0c9c, 0x3fb4, +0x0370, 0x0cd8, 0x3fb8, +0x0334, 0x0d10, 0x3fbc, +0x02f8, 0x0d48, 0x3fc0, +0x02c0, 0x0d78, 0x3fc8, +0x0288, 0x0da8, 0x3fd0, +0x0254, 0x0dd4, 0x3fd8, +0x0220, 0x0dfc, 0x3fe4, +0x01ec, 0x0e20, 0x3ff4, +0x01bc, 0x0e44, 0x0000, +0x0190, 0x0e5c, 0x0014, +0x0164, 0x0e74, 0x0028, +0x0138, 0x0e8c, 0x003c, +0x0114, 0x0e98, 0x0054, +0x00ec, 0x0ea4, 0x0070, +0x00cc, 0x0ea8, 0x008c, +0x00a8, 0x0eb0, 0x00a8, +}; + +static const uint16_t easf_filter_3tap_64p_ratio_1_00_s1_12[99] = { +0x0800, 0x0800, 0x0000, +0x07ac, 0x085c, 0x3ff8, +0x0754, 0x08bc, 0x3ff0, +0x0700, 0x091c, 0x3fe4, +0x06ac, 0x0978, 0x3fdc, +0x0658, 0x09d8, 0x3fd0, +0x0604, 0x0a34, 0x3fc8, +0x05b0, 0x0a94, 0x3fbc, +0x0560, 0x0aec, 0x3fb4, +0x0510, 0x0b44, 0x3fac, +0x04c0, 0x0ba0, 0x3fa0, +0x0470, 0x0bf8, 0x3f98, +0x0424, 0x0c4c, 0x3f90, +0x03d8, 0x0ca0, 0x3f88, +0x0390, 0x0cf0, 0x3f80, +0x0348, 0x0d3c, 0x3f7c, +0x0300, 0x0d8c, 0x3f74, +0x02c0, 0x0dd0, 0x3f70, +0x027c, 0x0e14, 0x3f70, +0x0240, 0x0e54, 0x3f6c, +0x0204, 0x0e90, 0x3f6c, +0x01c8, 0x0ecc, 0x3f6c, +0x0190, 0x0f00, 0x3f70, +0x015c, 0x0f30, 0x3f74, +0x012c, 0x0f58, 0x3f7c, +0x00fc, 0x0f80, 0x3f84, +0x00d0, 0x0fa0, 0x3f90, +0x00a8, 0x0fbc, 0x3f9c, +0x0080, 0x0fd4, 0x3fac, +0x005c, 0x0fe8, 0x3fbc, +0x003c, 0x0ff4, 0x3fd0, +0x001c, 0x0ffc, 0x3fe8, +0x0000, 0x1000, 0x0000, +}; + +static const uint16_t easf_filter_4tap_64p_ratio_0_30_s1_12[132] = { +0x0410, 0x07e0, 0x0410, 0x0000, +0x03f8, 0x07dc, 0x0428, 0x0004, +0x03e0, 0x07d8, 0x043c, 0x000c, +0x03c8, 0x07d4, 0x0450, 0x0014, +0x03ac, 0x07d0, 0x046c, 0x0018, +0x0394, 0x07cc, 0x0480, 0x0020, +0x037c, 0x07c8, 0x0494, 0x0028, +0x0368, 0x07c0, 0x04a8, 0x0030, +0x0350, 0x07b8, 0x04c0, 0x0038, +0x0338, 0x07b4, 0x04d4, 0x0040, +0x0320, 0x07ac, 0x04e8, 0x004c, +0x0308, 0x07a4, 0x0500, 0x0054, +0x02f4, 0x079c, 0x0514, 0x005c, +0x02dc, 0x0794, 0x0528, 0x0068, +0x02c4, 0x0788, 0x0544, 0x0070, +0x02b0, 0x0780, 0x0554, 0x007c, +0x029c, 0x0774, 0x0568, 0x0088, +0x0284, 0x076c, 0x057c, 0x0094, +0x0270, 0x0760, 0x0594, 0x009c, +0x025c, 0x0754, 0x05a8, 0x00a8, +0x0248, 0x0748, 0x05b8, 0x00b8, +0x0230, 0x073c, 0x05d0, 0x00c4, +0x021c, 0x0730, 0x05e4, 0x00d0, +0x020c, 0x0724, 0x05f4, 0x00dc, +0x01f8, 0x0714, 0x0608, 0x00ec, +0x01e4, 0x0708, 0x061c, 0x00f8, +0x01d0, 0x06f8, 0x0630, 0x0108, +0x01c0, 0x06e8, 0x0640, 0x0118, +0x01ac, 0x06dc, 0x0654, 0x0124, +0x0198, 0x06cc, 0x0668, 0x0134, +0x0188, 0x06bc, 0x0678, 0x0144, +0x0178, 0x06ac, 0x0688, 0x0154, +0x0168, 0x0698, 0x0698, 0x0168, +}; + +static const uint16_t easf_filter_4tap_64p_ratio_0_40_s1_12[132] = { +0x03ec, 0x0824, 0x03f0, 0x0000, +0x03d4, 0x0824, 0x0404, 0x0004, +0x03b8, 0x0820, 0x0420, 0x0008, +0x03a0, 0x081c, 0x0438, 0x000c, +0x0388, 0x0818, 0x0450, 0x0010, +0x036c, 0x0814, 0x0468, 0x0018, +0x0354, 0x0810, 0x0480, 0x001c, +0x033c, 0x080c, 0x0494, 0x0024, +0x0324, 0x0804, 0x04b0, 0x0028, +0x030c, 0x07fc, 0x04c8, 0x0030, +0x02f4, 0x07f4, 0x04e0, 0x0038, +0x02dc, 0x07ec, 0x04f8, 0x0040, +0x02c4, 0x07e4, 0x0510, 0x0048, +0x02b0, 0x07dc, 0x0524, 0x0050, +0x0298, 0x07d0, 0x0540, 0x0058, +0x0280, 0x07c8, 0x0558, 0x0060, +0x026c, 0x07bc, 0x0570, 0x0068, +0x0254, 0x07b0, 0x0588, 0x0074, +0x0240, 0x07a4, 0x05a0, 0x007c, +0x022c, 0x0798, 0x05b4, 0x0088, +0x0214, 0x078c, 0x05cc, 0x0094, +0x0200, 0x077c, 0x05e4, 0x00a0, +0x01ec, 0x0770, 0x05f8, 0x00ac, +0x01d8, 0x0760, 0x0610, 0x00b8, +0x01c4, 0x0750, 0x0628, 0x00c4, +0x01b4, 0x0744, 0x0638, 0x00d0, +0x01a0, 0x0734, 0x064c, 0x00e0, +0x018c, 0x0720, 0x0668, 0x00ec, +0x017c, 0x0710, 0x0678, 0x00fc, +0x016c, 0x0700, 0x068c, 0x0108, +0x0158, 0x06ec, 0x06a4, 0x0118, +0x0148, 0x06dc, 0x06b4, 0x0128, +0x0138, 0x06c8, 0x06c8, 0x0138, +}; + +static const uint16_t easf_filter_4tap_64p_ratio_0_50_s1_12[132] = { +0x0394, 0x08d8, 0x0394, 0x0000, +0x0378, 0x08d4, 0x03b4, 0x0000, +0x035c, 0x08d4, 0x03d0, 0x0000, +0x0340, 0x08d4, 0x03ec, 0x0000, +0x0324, 0x08d0, 0x0408, 0x0004, +0x0308, 0x08cc, 0x0428, 0x0004, +0x02f0, 0x08c8, 0x0444, 0x0004, +0x02d4, 0x08c0, 0x0464, 0x0008, +0x02b8, 0x08bc, 0x0484, 0x0008, +0x02a0, 0x08b4, 0x04a0, 0x000c, +0x0288, 0x08ac, 0x04bc, 0x0010, +0x026c, 0x08a4, 0x04dc, 0x0014, +0x0254, 0x0898, 0x04fc, 0x0018, +0x023c, 0x0890, 0x0518, 0x001c, +0x0224, 0x0884, 0x0538, 0x0020, +0x020c, 0x0878, 0x0554, 0x0028, +0x01f8, 0x086c, 0x0570, 0x002c, +0x01e0, 0x085c, 0x0590, 0x0034, +0x01c8, 0x084c, 0x05b4, 0x0038, +0x01b4, 0x0840, 0x05cc, 0x0040, +0x01a0, 0x0830, 0x05e8, 0x0048, +0x018c, 0x081c, 0x0608, 0x0050, +0x0178, 0x080c, 0x0624, 0x0058, +0x0164, 0x07f8, 0x0644, 0x0060, +0x0150, 0x07e4, 0x0660, 0x006c, +0x0140, 0x07d0, 0x067c, 0x0074, +0x012c, 0x07bc, 0x0698, 0x0080, +0x011c, 0x07a8, 0x06b0, 0x008c, +0x010c, 0x0790, 0x06cc, 0x0098, +0x00fc, 0x077c, 0x06e4, 0x00a4, +0x00ec, 0x0764, 0x0700, 0x00b0, +0x00dc, 0x074c, 0x0718, 0x00c0, +0x00cc, 0x0734, 0x0734, 0x00cc, +}; + +static const uint16_t easf_filter_4tap_64p_ratio_0_60_s1_12[132] = { +0x0320, 0x09bc, 0x0324, 0x0000, +0x0300, 0x09c0, 0x0344, 0x3ffc, +0x02e0, 0x09c0, 0x0364, 0x3ffc, +0x02c4, 0x09c0, 0x0384, 0x3ff8, +0x02a4, 0x09bc, 0x03ac, 0x3ff4, +0x0288, 0x09b8, 0x03cc, 0x3ff4, +0x0268, 0x09b4, 0x03f4, 0x3ff0, +0x024c, 0x09b0, 0x0414, 0x3ff0, +0x0230, 0x09a8, 0x043c, 0x3fec, +0x0214, 0x09a0, 0x0460, 0x3fec, +0x01f8, 0x0994, 0x0488, 0x3fec, +0x01e0, 0x098c, 0x04a8, 0x3fec, +0x01c4, 0x0980, 0x04d0, 0x3fec, +0x01ac, 0x0970, 0x04f8, 0x3fec, +0x0194, 0x0964, 0x051c, 0x3fec, +0x017c, 0x0954, 0x0544, 0x3fec, +0x0164, 0x0944, 0x0568, 0x3ff0, +0x0150, 0x0934, 0x058c, 0x3ff0, +0x0138, 0x0920, 0x05b4, 0x3ff4, +0x0124, 0x090c, 0x05d8, 0x3ff8, +0x0110, 0x08f8, 0x05fc, 0x3ffc, +0x00fc, 0x08e0, 0x0624, 0x0000, +0x00e8, 0x08c8, 0x064c, 0x0004, +0x00d8, 0x08b0, 0x0670, 0x0008, +0x00c4, 0x0898, 0x0694, 0x0010, +0x00b4, 0x087c, 0x06bc, 0x0014, +0x00a4, 0x0860, 0x06e0, 0x001c, +0x0094, 0x0844, 0x0704, 0x0024, +0x0088, 0x0828, 0x0724, 0x002c, +0x0078, 0x080c, 0x0748, 0x0034, +0x006c, 0x07ec, 0x0768, 0x0040, +0x0060, 0x07cc, 0x078c, 0x0048, +0x0054, 0x07ac, 0x07ac, 0x0054, +}; + +static const uint16_t easf_filter_4tap_64p_ratio_0_70_s1_12[132] = { +0x028c, 0x0ae4, 0x0290, 0x0000, +0x0268, 0x0ae8, 0x02b4, 0x3ffc, +0x0248, 0x0ae8, 0x02d8, 0x3ff8, +0x0224, 0x0ae8, 0x0304, 0x3ff0, +0x0204, 0x0ae4, 0x032c, 0x3fec, +0x01e4, 0x0ae0, 0x0354, 0x3fe8, +0x01c4, 0x0adc, 0x037c, 0x3fe4, +0x01a4, 0x0ad4, 0x03a8, 0x3fe0, +0x0188, 0x0acc, 0x03d0, 0x3fdc, +0x016c, 0x0ac0, 0x03fc, 0x3fd8, +0x0150, 0x0ab4, 0x042c, 0x3fd0, +0x0134, 0x0aa4, 0x045c, 0x3fcc, +0x0118, 0x0a94, 0x048c, 0x3fc8, +0x0100, 0x0a84, 0x04b4, 0x3fc8, +0x00e8, 0x0a70, 0x04e4, 0x3fc4, +0x00d0, 0x0a5c, 0x0514, 0x3fc0, +0x00bc, 0x0a48, 0x0540, 0x3fbc, +0x00a4, 0x0a30, 0x0570, 0x3fbc, +0x0090, 0x0a14, 0x05a4, 0x3fb8, +0x007c, 0x09fc, 0x05d0, 0x3fb8, +0x006c, 0x09e0, 0x05fc, 0x3fb8, +0x0058, 0x09c0, 0x0634, 0x3fb4, +0x0048, 0x09a0, 0x0664, 0x3fb4, +0x0038, 0x0980, 0x0690, 0x3fb8, +0x002c, 0x0960, 0x06bc, 0x3fb8, +0x001c, 0x093c, 0x06f0, 0x3fb8, +0x0010, 0x0918, 0x071c, 0x3fbc, +0x0004, 0x08f4, 0x074c, 0x3fbc, +0x3ff8, 0x08cc, 0x077c, 0x3fc0, +0x3ff0, 0x08a4, 0x07a8, 0x3fc4, +0x3fe8, 0x087c, 0x07d0, 0x3fcc, +0x3fe0, 0x0854, 0x07fc, 0x3fd0, +0x3fd8, 0x0828, 0x0828, 0x3fd8, +}; + +static const uint16_t easf_filter_4tap_64p_ratio_0_80_s1_12[132] = { +0x01d4, 0x0c54, 0x01d8, 0x0000, +0x01b0, 0x0c58, 0x01fc, 0x3ffc, +0x0188, 0x0c58, 0x0228, 0x3ff8, +0x0164, 0x0c54, 0x0258, 0x3ff0, +0x0140, 0x0c50, 0x0284, 0x3fec, +0x0120, 0x0c48, 0x02b4, 0x3fe4, +0x0100, 0x0c40, 0x02e0, 0x3fe0, +0x00e0, 0x0c34, 0x0314, 0x3fd8, +0x00c0, 0x0c28, 0x0344, 0x3fd4, +0x00a4, 0x0c18, 0x0378, 0x3fcc, +0x0088, 0x0c04, 0x03ac, 0x3fc8, +0x0070, 0x0bf0, 0x03e0, 0x3fc0, +0x0054, 0x0bdc, 0x0418, 0x3fb8, +0x0040, 0x0bc4, 0x0448, 0x3fb4, +0x0028, 0x0ba8, 0x0484, 0x3fac, +0x0014, 0x0b8c, 0x04bc, 0x3fa4, +0x0000, 0x0b6c, 0x04f4, 0x3fa0, +0x3fec, 0x0b4c, 0x0530, 0x3f98, +0x3fdc, 0x0b28, 0x0568, 0x3f94, +0x3fcc, 0x0b04, 0x05a4, 0x3f8c, +0x3fc0, 0x0adc, 0x05dc, 0x3f88, +0x3fb0, 0x0ab4, 0x0618, 0x3f84, +0x3fa4, 0x0a88, 0x0658, 0x3f7c, +0x3f9c, 0x0a5c, 0x0690, 0x3f78, +0x3f90, 0x0a30, 0x06cc, 0x3f74, +0x3f88, 0x0a00, 0x0708, 0x3f70, +0x3f80, 0x09d0, 0x0740, 0x3f70, +0x3f7c, 0x09a0, 0x0778, 0x3f6c, +0x3f74, 0x096c, 0x07b8, 0x3f68, +0x3f70, 0x0938, 0x07f0, 0x3f68, +0x3f6c, 0x0904, 0x0828, 0x3f68, +0x3f6c, 0x08cc, 0x0860, 0x3f68, +0x3f68, 0x0898, 0x0898, 0x3f68, +}; + +static const uint16_t easf_filter_4tap_64p_ratio_0_90_s1_12[132] = { +0x00fc, 0x0e0c, 0x00f8, 0x0000, +0x00d0, 0x0e0c, 0x0128, 0x3ffc, +0x00ac, 0x0e0c, 0x0150, 0x3ff8, +0x0084, 0x0e04, 0x0184, 0x3ff4, +0x0064, 0x0dfc, 0x01b0, 0x3ff0, +0x0040, 0x0df0, 0x01e4, 0x3fec, +0x0020, 0x0de0, 0x0218, 0x3fe8, +0x0004, 0x0dd0, 0x024c, 0x3fe0, +0x3fe8, 0x0db8, 0x0284, 0x3fdc, +0x3fcc, 0x0da0, 0x02c0, 0x3fd4, +0x3fb4, 0x0d84, 0x02fc, 0x3fcc, +0x3fa0, 0x0d68, 0x0334, 0x3fc4, +0x3f88, 0x0d48, 0x0370, 0x3fc0, +0x3f78, 0x0d24, 0x03ac, 0x3fb8, +0x3f64, 0x0cfc, 0x03f0, 0x3fb0, +0x3f54, 0x0cd4, 0x0434, 0x3fa4, +0x3f48, 0x0ca8, 0x0474, 0x3f9c, +0x3f3c, 0x0c78, 0x04b8, 0x3f94, +0x3f30, 0x0c48, 0x04fc, 0x3f8c, +0x3f28, 0x0c14, 0x0540, 0x3f84, +0x3f20, 0x0be0, 0x0588, 0x3f78, +0x3f18, 0x0ba8, 0x05d0, 0x3f70, +0x3f14, 0x0b70, 0x0614, 0x3f68, +0x3f10, 0x0b34, 0x065c, 0x3f60, +0x3f0c, 0x0af8, 0x06a8, 0x3f54, +0x3f0c, 0x0abc, 0x06ec, 0x3f4c, +0x3f0c, 0x0a7c, 0x0734, 0x3f44, +0x3f0c, 0x0a38, 0x0780, 0x3f3c, +0x3f0c, 0x09f8, 0x07c8, 0x3f34, +0x3f10, 0x09b4, 0x080c, 0x3f30, +0x3f14, 0x0970, 0x0854, 0x3f28, +0x3f18, 0x092c, 0x089c, 0x3f20, +0x3f1c, 0x08e4, 0x08e4, 0x3f1c, +}; + +static const uint16_t easf_filter_4tap_64p_ratio_1_00_s1_12[132] = { +0x0000, 0x1000, 0x0000, 0x0000, +0x3fd8, 0x0ffc, 0x002c, 0x0000, +0x3fb4, 0x0ff8, 0x0054, 0x0000, +0x3f90, 0x0fec, 0x0088, 0x3ffc, +0x3f70, 0x0fdc, 0x00b8, 0x3ffc, +0x3f54, 0x0fc8, 0x00ec, 0x3ff8, +0x3f38, 0x0fb0, 0x0120, 0x3ff8, +0x3f20, 0x0f94, 0x0158, 0x3ff4, +0x3f0c, 0x0f70, 0x0194, 0x3ff0, +0x3ef8, 0x0f4c, 0x01d4, 0x3fe8, +0x3ee4, 0x0f24, 0x0214, 0x3fe4, +0x3ed8, 0x0ef8, 0x0250, 0x3fe0, +0x3ec8, 0x0ec8, 0x0298, 0x3fd8, +0x3ec0, 0x0e94, 0x02dc, 0x3fd0, +0x3eb4, 0x0e5c, 0x0328, 0x3fc8, +0x3eac, 0x0e24, 0x0370, 0x3fc0, +0x3ea8, 0x0de4, 0x03bc, 0x3fb8, +0x3ea4, 0x0da4, 0x0408, 0x3fb0, +0x3ea4, 0x0d64, 0x0454, 0x3fa4, +0x3ea4, 0x0d20, 0x04a4, 0x3f98, +0x3ea4, 0x0cd8, 0x04f4, 0x3f90, +0x3ea4, 0x0c8c, 0x054c, 0x3f84, +0x3ea8, 0x0c40, 0x05a0, 0x3f78, +0x3eb0, 0x0bf4, 0x05f0, 0x3f6c, +0x3eb4, 0x0ba4, 0x0648, 0x3f60, +0x3ebc, 0x0b54, 0x069c, 0x3f54, +0x3ec4, 0x0b00, 0x06f4, 0x3f48, +0x3ecc, 0x0ab0, 0x0748, 0x3f3c, +0x3ed4, 0x0a58, 0x07a4, 0x3f30, +0x3ee0, 0x0a04, 0x07f8, 0x3f24, +0x3ee8, 0x09b0, 0x0850, 0x3f18, +0x3ef4, 0x0958, 0x08a8, 0x3f0c, +0x3f00, 0x0900, 0x0900, 0x3f00, +}; + +static const uint16_t easf_filter_6tap_64p_ratio_0_30_s1_12[198] = { +0x012c, 0x0400, 0x05a4, 0x0404, 0x012c, 0x0000, +0x0124, 0x03f4, 0x05a4, 0x040c, 0x0138, 0x0000, +0x011c, 0x03e8, 0x05a4, 0x0418, 0x0140, 0x0000, +0x0114, 0x03dc, 0x05a0, 0x0424, 0x0148, 0x0004, +0x010c, 0x03d4, 0x05a0, 0x042c, 0x0150, 0x0004, +0x0100, 0x03c8, 0x05a0, 0x0438, 0x015c, 0x0004, +0x00f8, 0x03bc, 0x05a0, 0x0440, 0x0164, 0x0008, +0x00f0, 0x03b0, 0x059c, 0x044c, 0x0170, 0x0008, +0x00e8, 0x03a4, 0x059c, 0x0458, 0x0178, 0x0008, +0x00e0, 0x0398, 0x0598, 0x0460, 0x0184, 0x000c, +0x00d8, 0x038c, 0x0594, 0x0470, 0x018c, 0x000c, +0x00d0, 0x0380, 0x0594, 0x0474, 0x0198, 0x0010, +0x00cc, 0x0374, 0x0590, 0x0480, 0x01a0, 0x0010, +0x00c4, 0x0368, 0x058c, 0x0488, 0x01ac, 0x0014, +0x00bc, 0x035c, 0x058c, 0x0494, 0x01b4, 0x0014, +0x00b4, 0x034c, 0x0588, 0x04a0, 0x01c0, 0x0018, +0x00ac, 0x0340, 0x0584, 0x04a8, 0x01cc, 0x001c, +0x00a8, 0x0334, 0x0580, 0x04b4, 0x01d4, 0x001c, +0x00a0, 0x0328, 0x057c, 0x04bc, 0x01e0, 0x0020, +0x0098, 0x031c, 0x0578, 0x04c4, 0x01ec, 0x0024, +0x0094, 0x0310, 0x0574, 0x04cc, 0x01f8, 0x0024, +0x008c, 0x0304, 0x0570, 0x04d8, 0x0200, 0x0028, +0x0088, 0x02f8, 0x0568, 0x04e0, 0x020c, 0x002c, +0x0080, 0x02ec, 0x0564, 0x04e8, 0x0218, 0x0030, +0x007c, 0x02e0, 0x0560, 0x04ec, 0x0224, 0x0034, +0x0078, 0x02d4, 0x0558, 0x04f8, 0x0230, 0x0034, +0x0070, 0x02c8, 0x0554, 0x0500, 0x023c, 0x0038, +0x006c, 0x02bc, 0x054c, 0x050c, 0x0244, 0x003c, +0x0064, 0x02b0, 0x0548, 0x0514, 0x0250, 0x0040, +0x0060, 0x02a4, 0x0540, 0x051c, 0x025c, 0x0044, +0x005c, 0x0298, 0x053c, 0x0520, 0x0268, 0x0048, +0x0058, 0x028c, 0x0534, 0x0524, 0x0274, 0x0050, +0x0054, 0x0280, 0x052c, 0x052c, 0x0280, 0x0054, +}; + +static const uint16_t easf_filter_6tap_64p_ratio_0_40_s1_12[198] = { +0x00a0, 0x0418, 0x068c, 0x041c, 0x00a0, 0x0000, +0x0098, 0x0408, 0x068c, 0x0428, 0x00ac, 0x0000, +0x0090, 0x03f8, 0x068c, 0x043c, 0x00b4, 0x3ffc, +0x0088, 0x03e8, 0x068c, 0x044c, 0x00bc, 0x3ffc, +0x0084, 0x03d8, 0x068c, 0x0458, 0x00c4, 0x3ffc, +0x007c, 0x03c8, 0x0688, 0x046c, 0x00d0, 0x3ff8, +0x0074, 0x03b8, 0x0688, 0x047c, 0x00d8, 0x3ff8, +0x006c, 0x03a8, 0x0684, 0x048c, 0x00e4, 0x3ff8, +0x0064, 0x0398, 0x0684, 0x049c, 0x00ec, 0x3ff8, +0x0060, 0x0388, 0x0680, 0x04a8, 0x00f8, 0x3ff8, +0x0058, 0x0378, 0x0680, 0x04b8, 0x0104, 0x3ff4, +0x0054, 0x0368, 0x067c, 0x04c8, 0x010c, 0x3ff4, +0x004c, 0x0358, 0x0678, 0x04d8, 0x0118, 0x3ff4, +0x0048, 0x0348, 0x0674, 0x04e4, 0x0124, 0x3ff4, +0x0040, 0x0338, 0x0670, 0x04f4, 0x0130, 0x3ff4, +0x003c, 0x0328, 0x0668, 0x0504, 0x013c, 0x3ff4, +0x0038, 0x0318, 0x0664, 0x0510, 0x0148, 0x3ff4, +0x0034, 0x0308, 0x065c, 0x0520, 0x0154, 0x3ff4, +0x002c, 0x02f8, 0x0658, 0x0530, 0x0160, 0x3ff4, +0x0028, 0x02e8, 0x0654, 0x053c, 0x016c, 0x3ff4, +0x0024, 0x02d8, 0x064c, 0x054c, 0x0178, 0x3ff4, +0x0020, 0x02c8, 0x0644, 0x055c, 0x0184, 0x3ff4, +0x001c, 0x02b8, 0x0640, 0x0568, 0x0190, 0x3ff4, +0x0018, 0x02a8, 0x0638, 0x0574, 0x01a0, 0x3ff4, +0x0014, 0x0298, 0x0630, 0x0584, 0x01ac, 0x3ff4, +0x0014, 0x0288, 0x0624, 0x0590, 0x01bc, 0x3ff4, +0x0010, 0x0278, 0x061c, 0x059c, 0x01c8, 0x3ff8, +0x000c, 0x0268, 0x0614, 0x05ac, 0x01d4, 0x3ff8, +0x0008, 0x0258, 0x060c, 0x05b8, 0x01e4, 0x3ff8, +0x0008, 0x024c, 0x0600, 0x05bc, 0x01f4, 0x3ffc, +0x0004, 0x023c, 0x05f8, 0x05cc, 0x0200, 0x3ffc, +0x0004, 0x022c, 0x05ec, 0x05d4, 0x0210, 0x0000, +0x0000, 0x021c, 0x05e4, 0x05e4, 0x021c, 0x0000, +}; + +static const uint16_t easf_filter_6tap_64p_ratio_0_50_s1_12[198] = { +0x0000, 0x041c, 0x07cc, 0x0418, 0x0000, 0x0000, +0x3ff8, 0x0404, 0x07cc, 0x0434, 0x0008, 0x3ffc, +0x3ff4, 0x03ec, 0x07cc, 0x044c, 0x000c, 0x3ffc, +0x3ff0, 0x03d8, 0x07cc, 0x0460, 0x0014, 0x3ff8, +0x3fe8, 0x03c0, 0x07cc, 0x0478, 0x001c, 0x3ff8, +0x3fe4, 0x03ac, 0x07c8, 0x0490, 0x0024, 0x3ff4, +0x3fe0, 0x0394, 0x07c8, 0x04a4, 0x002c, 0x3ff4, +0x3fdc, 0x0380, 0x07c4, 0x04bc, 0x0034, 0x3ff0, +0x3fd8, 0x0368, 0x07c0, 0x04d4, 0x0040, 0x3fec, +0x3fd4, 0x0350, 0x07bc, 0x04ec, 0x0048, 0x3fec, +0x3fd0, 0x033c, 0x07b8, 0x0504, 0x0050, 0x3fe8, +0x3fcc, 0x0324, 0x07b4, 0x051c, 0x005c, 0x3fe4, +0x3fc8, 0x0310, 0x07ac, 0x0530, 0x0068, 0x3fe4, +0x3fc4, 0x02fc, 0x07a8, 0x0548, 0x0070, 0x3fe0, +0x3fc4, 0x02e4, 0x07a0, 0x055c, 0x007c, 0x3fe0, +0x3fc0, 0x02d0, 0x0798, 0x0574, 0x0088, 0x3fdc, +0x3fc0, 0x02b8, 0x0790, 0x058c, 0x0094, 0x3fd8, +0x3fbc, 0x02a4, 0x0788, 0x05a0, 0x00a0, 0x3fd8, +0x3fbc, 0x0290, 0x077c, 0x05b8, 0x00ac, 0x3fd4, +0x3fbc, 0x027c, 0x0774, 0x05c8, 0x00b8, 0x3fd4, +0x3fb8, 0x0268, 0x0768, 0x05e0, 0x00c8, 0x3fd0, +0x3fb8, 0x0250, 0x0760, 0x05f8, 0x00d4, 0x3fcc, +0x3fb8, 0x023c, 0x0754, 0x0608, 0x00e4, 0x3fcc, +0x3fb8, 0x0228, 0x0748, 0x0620, 0x00f0, 0x3fc8, +0x3fb8, 0x0214, 0x073c, 0x0630, 0x0100, 0x3fc8, +0x3fb8, 0x0204, 0x072c, 0x0644, 0x0110, 0x3fc4, +0x3fb8, 0x01f0, 0x0720, 0x0658, 0x011c, 0x3fc4, +0x3fb8, 0x01dc, 0x0710, 0x0670, 0x012c, 0x3fc0, +0x3fb8, 0x01c8, 0x0704, 0x0680, 0x013c, 0x3fc0, +0x3fb8, 0x01b8, 0x06f4, 0x0690, 0x014c, 0x3fc0, +0x3fb8, 0x01a4, 0x06e4, 0x06a4, 0x0160, 0x3fbc, +0x3fb8, 0x0194, 0x06d4, 0x06b4, 0x0170, 0x3fbc, +0x3fbc, 0x0180, 0x06c4, 0x06c4, 0x0180, 0x3fbc, +}; + +static const uint16_t easf_filter_6tap_64p_ratio_0_60_s1_12[198] = { +0x3f64, 0x03ec, 0x0960, 0x03ec, 0x3f64, 0x0000, +0x3f64, 0x03cc, 0x0960, 0x0408, 0x3f68, 0x0000, +0x3f60, 0x03ac, 0x0960, 0x042c, 0x3f6c, 0x3ffc, +0x3f60, 0x038c, 0x0960, 0x0448, 0x3f70, 0x3ffc, +0x3f60, 0x0370, 0x095c, 0x046c, 0x3f70, 0x3ff8, +0x3f5c, 0x0350, 0x0958, 0x048c, 0x3f78, 0x3ff8, +0x3f5c, 0x0334, 0x0954, 0x04ac, 0x3f7c, 0x3ff4, +0x3f5c, 0x0314, 0x0950, 0x04cc, 0x3f80, 0x3ff4, +0x3f5c, 0x02f8, 0x0948, 0x04f0, 0x3f84, 0x3ff0, +0x3f5c, 0x02d8, 0x0944, 0x050c, 0x3f8c, 0x3ff0, +0x3f60, 0x02bc, 0x093c, 0x052c, 0x3f90, 0x3fec, +0x3f60, 0x02a0, 0x0930, 0x0550, 0x3f98, 0x3fe8, +0x3f60, 0x0284, 0x0928, 0x056c, 0x3fa0, 0x3fe8, +0x3f64, 0x0268, 0x091c, 0x058c, 0x3fa8, 0x3fe4, +0x3f64, 0x024c, 0x0910, 0x05b0, 0x3fb0, 0x3fe0, +0x3f64, 0x0230, 0x0904, 0x05d0, 0x3fbc, 0x3fdc, +0x3f68, 0x0214, 0x08f8, 0x05ec, 0x3fc4, 0x3fdc, +0x3f6c, 0x01fc, 0x08e8, 0x060c, 0x3fcc, 0x3fd8, +0x3f6c, 0x01e0, 0x08dc, 0x062c, 0x3fd8, 0x3fd4, +0x3f70, 0x01c8, 0x08cc, 0x0648, 0x3fe4, 0x3fd0, +0x3f74, 0x01b0, 0x08bc, 0x0664, 0x3ff0, 0x3fcc, +0x3f74, 0x0194, 0x08a8, 0x068c, 0x3ffc, 0x3fc8, +0x3f78, 0x017c, 0x0898, 0x06a8, 0x0008, 0x3fc4, +0x3f7c, 0x0168, 0x0884, 0x06c0, 0x0018, 0x3fc0, +0x3f80, 0x0150, 0x0870, 0x06dc, 0x0024, 0x3fc0, +0x3f84, 0x0138, 0x085c, 0x06f8, 0x0034, 0x3fbc, +0x3f88, 0x0120, 0x0848, 0x0718, 0x0040, 0x3fb8, +0x3f8c, 0x010c, 0x0830, 0x0734, 0x0050, 0x3fb4, +0x3f90, 0x00f8, 0x081c, 0x074c, 0x0060, 0x3fb0, +0x3f94, 0x00e4, 0x0800, 0x0768, 0x0074, 0x3fac, +0x3f98, 0x00d0, 0x07e8, 0x0784, 0x0084, 0x3fa8, +0x3f9c, 0x00bc, 0x07d4, 0x079c, 0x0094, 0x3fa4, +0x3fa0, 0x00a8, 0x07b8, 0x07b8, 0x00a8, 0x3fa0, +}; + +static const uint16_t easf_filter_6tap_64p_ratio_0_70_s1_12[198] = { +0x3f00, 0x0368, 0x0b30, 0x0368, 0x3f00, 0x0000, +0x3f04, 0x0340, 0x0b30, 0x0390, 0x3efc, 0x0000, +0x3f08, 0x0318, 0x0b2c, 0x03bc, 0x3ef8, 0x0000, +0x3f0c, 0x02f0, 0x0b28, 0x03e4, 0x3ef8, 0x0000, +0x3f10, 0x02c8, 0x0b24, 0x0410, 0x3ef4, 0x0000, +0x3f14, 0x02a0, 0x0b1c, 0x043c, 0x3ef4, 0x0000, +0x3f1c, 0x027c, 0x0b14, 0x0464, 0x3ef0, 0x0000, +0x3f20, 0x0254, 0x0b0c, 0x0490, 0x3ef0, 0x0000, +0x3f24, 0x0230, 0x0b00, 0x04bc, 0x3ef0, 0x0000, +0x3f2c, 0x020c, 0x0af4, 0x04e4, 0x3ef0, 0x0000, +0x3f30, 0x01e8, 0x0ae8, 0x0510, 0x3ef0, 0x0000, +0x3f38, 0x01c8, 0x0ad8, 0x0534, 0x3ef4, 0x0000, +0x3f40, 0x01a4, 0x0ac8, 0x0564, 0x3ef4, 0x3ffc, +0x3f44, 0x0184, 0x0ab4, 0x0590, 0x3ef8, 0x3ffc, +0x3f4c, 0x0164, 0x0aa4, 0x05b8, 0x3efc, 0x3ff8, +0x3f50, 0x0144, 0x0a90, 0x05e8, 0x3efc, 0x3ff8, +0x3f58, 0x0124, 0x0a78, 0x0610, 0x3f04, 0x3ff8, +0x3f60, 0x0108, 0x0a64, 0x0638, 0x3f08, 0x3ff4, +0x3f64, 0x00e8, 0x0a4c, 0x066c, 0x3f0c, 0x3ff0, +0x3f6c, 0x00cc, 0x0a34, 0x0690, 0x3f14, 0x3ff0, +0x3f70, 0x00b4, 0x0a18, 0x06bc, 0x3f1c, 0x3fec, +0x3f78, 0x0098, 0x0a00, 0x06e8, 0x3f20, 0x3fe8, +0x3f80, 0x007c, 0x09e4, 0x0710, 0x3f2c, 0x3fe4, +0x3f84, 0x0064, 0x09c8, 0x0738, 0x3f34, 0x3fe4, +0x3f8c, 0x004c, 0x09a8, 0x0764, 0x3f3c, 0x3fe0, +0x3f90, 0x0034, 0x098c, 0x078c, 0x3f48, 0x3fdc, +0x3f98, 0x0020, 0x096c, 0x07b0, 0x3f54, 0x3fd8, +0x3f9c, 0x0008, 0x094c, 0x07dc, 0x3f60, 0x3fd4, +0x3fa4, 0x3ff4, 0x0928, 0x0808, 0x3f6c, 0x3fcc, +0x3fa8, 0x3fe0, 0x0908, 0x082c, 0x3f7c, 0x3fc8, +0x3fb0, 0x3fcc, 0x08e4, 0x0854, 0x3f88, 0x3fc4, +0x3fb4, 0x3fbc, 0x08c0, 0x0878, 0x3f98, 0x3fc0, +0x3fbc, 0x3fac, 0x0898, 0x0898, 0x3fac, 0x3fbc, +}; + +static const uint16_t easf_filter_6tap_64p_ratio_0_80_s1_12[198] = { +0x3efc, 0x0284, 0x0d00, 0x0284, 0x3efc, 0x0000, +0x3f04, 0x0254, 0x0d00, 0x02b4, 0x3ef0, 0x0004, +0x3f10, 0x0224, 0x0cf8, 0x02e8, 0x3ee8, 0x0004, +0x3f18, 0x01f4, 0x0cf4, 0x0318, 0x3ee0, 0x0008, +0x3f24, 0x01c8, 0x0ce8, 0x034c, 0x3ed8, 0x0008, +0x3f30, 0x019c, 0x0ce0, 0x037c, 0x3ecc, 0x000c, +0x3f38, 0x0170, 0x0cd0, 0x03b8, 0x3ec4, 0x000c, +0x3f44, 0x0144, 0x0cc4, 0x03e8, 0x3ebc, 0x0010, +0x3f4c, 0x011c, 0x0cb4, 0x0420, 0x3eb4, 0x0010, +0x3f58, 0x00f4, 0x0ca0, 0x0458, 0x3eac, 0x0010, +0x3f60, 0x00cc, 0x0c8c, 0x048c, 0x3ea8, 0x0014, +0x3f6c, 0x00a8, 0x0c74, 0x04c4, 0x3ea0, 0x0014, +0x3f74, 0x0084, 0x0c5c, 0x04fc, 0x3e9c, 0x0014, +0x3f7c, 0x0060, 0x0c44, 0x0534, 0x3e94, 0x0018, +0x3f88, 0x0040, 0x0c28, 0x0568, 0x3e90, 0x0018, +0x3f90, 0x0020, 0x0c08, 0x05a4, 0x3e8c, 0x0018, +0x3f98, 0x0000, 0x0bec, 0x05dc, 0x3e88, 0x0018, +0x3fa0, 0x3fe4, 0x0bcc, 0x0614, 0x3e84, 0x0018, +0x3fac, 0x3fc4, 0x0ba8, 0x064c, 0x3e84, 0x0018, +0x3fb4, 0x3fac, 0x0b84, 0x0684, 0x3e80, 0x0018, +0x3fb8, 0x3f90, 0x0b60, 0x06c0, 0x3e80, 0x0018, +0x3fc0, 0x3f78, 0x0b38, 0x06f8, 0x3e80, 0x0018, +0x3fc8, 0x3f60, 0x0b14, 0x072c, 0x3e80, 0x0018, +0x3fd0, 0x3f4c, 0x0ae8, 0x0760, 0x3e84, 0x0018, +0x3fd8, 0x3f34, 0x0ac0, 0x079c, 0x3e84, 0x0014, +0x3fdc, 0x3f20, 0x0a94, 0x07d4, 0x3e88, 0x0014, +0x3fe4, 0x3f10, 0x0a68, 0x0808, 0x3e8c, 0x0010, +0x3fe8, 0x3f00, 0x0a38, 0x0840, 0x3e90, 0x0010, +0x3fec, 0x3ef0, 0x0a0c, 0x0874, 0x3e98, 0x000c, +0x3ff4, 0x3ee0, 0x09d8, 0x08a8, 0x3ea0, 0x000c, +0x3ff8, 0x3ed0, 0x09ac, 0x08dc, 0x3ea8, 0x0008, +0x3ffc, 0x3ec4, 0x0978, 0x0914, 0x3eb0, 0x0004, +0x0000, 0x3eb8, 0x0948, 0x0948, 0x3eb8, 0x0000, +}; + +static const uint16_t easf_filter_6tap_64p_ratio_0_90_s1_12[198] = { +0x3f60, 0x0154, 0x0e9c, 0x0150, 0x3f60, 0x0000, +0x3f6c, 0x011c, 0x0e9c, 0x018c, 0x3f50, 0x0000, +0x3f7c, 0x00ec, 0x0e94, 0x01bc, 0x3f44, 0x0004, +0x3f88, 0x00b8, 0x0e8c, 0x01f8, 0x3f34, 0x0008, +0x3f94, 0x0088, 0x0e80, 0x0234, 0x3f28, 0x0008, +0x3fa0, 0x005c, 0x0e74, 0x026c, 0x3f18, 0x000c, +0x3fac, 0x0030, 0x0e60, 0x02b0, 0x3f08, 0x000c, +0x3fb8, 0x0004, 0x0e50, 0x02e8, 0x3efc, 0x0010, +0x3fc4, 0x3fdc, 0x0e38, 0x0328, 0x3eec, 0x0014, +0x3fd0, 0x3fb4, 0x0e20, 0x0368, 0x3ee0, 0x0014, +0x3fd8, 0x3f90, 0x0e04, 0x03ac, 0x3ed0, 0x0018, +0x3fe4, 0x3f6c, 0x0de8, 0x03e8, 0x3ec4, 0x001c, +0x3fec, 0x3f4c, 0x0dc8, 0x042c, 0x3eb4, 0x0020, +0x3ff4, 0x3f2c, 0x0da4, 0x0474, 0x3ea8, 0x0020, +0x0000, 0x3f0c, 0x0d80, 0x04b8, 0x3e98, 0x0024, +0x0008, 0x3ef0, 0x0d58, 0x04fc, 0x3e8c, 0x0028, +0x000c, 0x3ed8, 0x0d30, 0x0540, 0x3e80, 0x002c, +0x0014, 0x3ec0, 0x0d04, 0x0588, 0x3e74, 0x002c, +0x001c, 0x3ea8, 0x0cd8, 0x05cc, 0x3e68, 0x0030, +0x0020, 0x3e94, 0x0ca8, 0x0614, 0x3e5c, 0x0034, +0x0028, 0x3e80, 0x0c78, 0x065c, 0x3e50, 0x0034, +0x002c, 0x3e6c, 0x0c44, 0x06a4, 0x3e48, 0x0038, +0x0030, 0x3e5c, 0x0c0c, 0x06f0, 0x3e3c, 0x003c, +0x0034, 0x3e50, 0x0bd8, 0x0734, 0x3e34, 0x003c, +0x0038, 0x3e44, 0x0ba0, 0x0778, 0x3e2c, 0x0040, +0x003c, 0x3e38, 0x0b64, 0x07c4, 0x3e24, 0x0040, +0x0040, 0x3e2c, 0x0b28, 0x0808, 0x3e20, 0x0044, +0x0040, 0x3e24, 0x0aec, 0x0850, 0x3e1c, 0x0044, +0x0044, 0x3e1c, 0x0aac, 0x0898, 0x3e18, 0x0044, +0x0044, 0x3e18, 0x0a70, 0x08d8, 0x3e14, 0x0048, +0x0044, 0x3e14, 0x0a2c, 0x0924, 0x3e10, 0x0048, +0x0048, 0x3e10, 0x09ec, 0x0964, 0x3e10, 0x0048, +0x0048, 0x3e10, 0x09a8, 0x09a8, 0x3e10, 0x0048, +}; + +static const uint16_t easf_filter_6tap_64p_ratio_1_00_s1_12[198] = { +0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, +0x000c, 0x3fcc, 0x1000, 0x0034, 0x3ff4, 0x0000, +0x0018, 0x3f9c, 0x0ff8, 0x0070, 0x3fe4, 0x0000, +0x0024, 0x3f6c, 0x0ff0, 0x00ac, 0x3fd4, 0x0000, +0x0030, 0x3f40, 0x0fe4, 0x00e8, 0x3fc4, 0x0000, +0x0038, 0x3f14, 0x0fd4, 0x0128, 0x3fb4, 0x0004, +0x0044, 0x3eec, 0x0fc0, 0x0168, 0x3fa4, 0x0004, +0x004c, 0x3ec8, 0x0fac, 0x01a8, 0x3f94, 0x0004, +0x0054, 0x3ea4, 0x0f90, 0x01ec, 0x3f84, 0x0008, +0x005c, 0x3e84, 0x0f74, 0x0234, 0x3f70, 0x0008, +0x0060, 0x3e64, 0x0f50, 0x0280, 0x3f60, 0x000c, +0x0068, 0x3e48, 0x0f2c, 0x02c8, 0x3f4c, 0x0010, +0x006c, 0x3e30, 0x0f04, 0x0318, 0x3f38, 0x0010, +0x0070, 0x3e18, 0x0edc, 0x0364, 0x3f24, 0x0014, +0x0074, 0x3e00, 0x0eac, 0x03b8, 0x3f10, 0x0018, +0x0078, 0x3df0, 0x0e7c, 0x0404, 0x3efc, 0x001c, +0x007c, 0x3de0, 0x0e48, 0x0454, 0x3ee8, 0x0020, +0x007c, 0x3dd0, 0x0e14, 0x04ac, 0x3ed4, 0x0020, +0x0080, 0x3dc4, 0x0dd8, 0x0500, 0x3ec0, 0x0024, +0x0080, 0x3db8, 0x0d9c, 0x0554, 0x3eac, 0x002c, +0x0080, 0x3db0, 0x0d5c, 0x05ac, 0x3e98, 0x0030, +0x0080, 0x3da8, 0x0d1c, 0x0600, 0x3e88, 0x0034, +0x0080, 0x3da4, 0x0cd8, 0x0658, 0x3e74, 0x0038, +0x0080, 0x3da4, 0x0c94, 0x06ac, 0x3e60, 0x003c, +0x007c, 0x3da0, 0x0c4c, 0x070c, 0x3e4c, 0x0040, +0x007c, 0x3da4, 0x0c00, 0x0760, 0x3e3c, 0x0044, +0x0078, 0x3da4, 0x0bb4, 0x07bc, 0x3e2c, 0x0048, +0x0074, 0x3da8, 0x0b64, 0x0814, 0x3e1c, 0x0050, +0x0074, 0x3db0, 0x0b14, 0x0868, 0x3e0c, 0x0054, +0x0070, 0x3db8, 0x0ac4, 0x08c0, 0x3dfc, 0x0058, +0x006c, 0x3dc0, 0x0a70, 0x091c, 0x3dec, 0x005c, +0x0068, 0x3dc8, 0x0a1c, 0x0974, 0x3de0, 0x0060, +0x0064, 0x3dd4, 0x09c8, 0x09c8, 0x3dd4, 0x0064, +}; struct scale_ratio_to_reg_value_lookup easf_v_bf3_mode_lookup[] = { {3, 10, 0x0000}, @@ -1353,61 +2193,7 @@ struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt2_offset_lookup[] = { {-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) +const 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; @@ -1427,7 +2213,7 @@ uint16_t *spl_get_easf_filter_3tap_64p(struct spl_fixed31_32 ratio) return easf_filter_3tap_64p_ratio_1_00_s1_12; } -uint16_t *spl_get_easf_filter_4tap_64p(struct spl_fixed31_32 ratio) +const 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; @@ -1447,7 +2233,7 @@ uint16_t *spl_get_easf_filter_4tap_64p(struct spl_fixed31_32 ratio) return easf_filter_4tap_64p_ratio_1_00_s1_12; } -uint16_t *spl_get_easf_filter_6tap_64p(struct spl_fixed31_32 ratio) +const 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; @@ -1467,7 +2253,7 @@ uint16_t *spl_get_easf_filter_6tap_64p(struct spl_fixed31_32 ratio) 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) +const 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); @@ -1482,6 +2268,81 @@ uint16_t *spl_dscl_get_easf_filter_coeffs_64p(int taps, struct spl_fixed31_32 ra } } +static const uint16_t *spl_get_easf_filter_3tap_64p_s1_10(struct spl_fixed31_32 ratio) +{ + if (ratio.value < spl_fixpt_from_fraction(3, 10).value) + return easf_filter_3tap_64p_ratio_0_30; + else if (ratio.value < spl_fixpt_from_fraction(4, 10).value) + return easf_filter_3tap_64p_ratio_0_40; + else if (ratio.value < spl_fixpt_from_fraction(5, 10).value) + return easf_filter_3tap_64p_ratio_0_50; + else if (ratio.value < spl_fixpt_from_fraction(6, 10).value) + return easf_filter_3tap_64p_ratio_0_60; + else if (ratio.value < spl_fixpt_from_fraction(7, 10).value) + return easf_filter_3tap_64p_ratio_0_70; + else if (ratio.value < spl_fixpt_from_fraction(8, 10).value) + return easf_filter_3tap_64p_ratio_0_80; + else if (ratio.value < spl_fixpt_from_fraction(9, 10).value) + return easf_filter_3tap_64p_ratio_0_90; + else + return easf_filter_3tap_64p_ratio_1_00; +} + +static const uint16_t *spl_get_easf_filter_4tap_64p_s1_10(struct spl_fixed31_32 ratio) +{ + if (ratio.value < spl_fixpt_from_fraction(3, 10).value) + return easf_filter_4tap_64p_ratio_0_30; + else if (ratio.value < spl_fixpt_from_fraction(4, 10).value) + return easf_filter_4tap_64p_ratio_0_40; + else if (ratio.value < spl_fixpt_from_fraction(5, 10).value) + return easf_filter_4tap_64p_ratio_0_50; + else if (ratio.value < spl_fixpt_from_fraction(6, 10).value) + return easf_filter_4tap_64p_ratio_0_60; + else if (ratio.value < spl_fixpt_from_fraction(7, 10).value) + return easf_filter_4tap_64p_ratio_0_70; + else if (ratio.value < spl_fixpt_from_fraction(8, 10).value) + return easf_filter_4tap_64p_ratio_0_80; + else if (ratio.value < spl_fixpt_from_fraction(9, 10).value) + return easf_filter_4tap_64p_ratio_0_90; + else + return easf_filter_4tap_64p_ratio_1_00; +} + +static const uint16_t *spl_get_easf_filter_6tap_64p_s1_10(struct spl_fixed31_32 ratio) +{ + if (ratio.value < spl_fixpt_from_fraction(3, 10).value) + return easf_filter_6tap_64p_ratio_0_30; + else if (ratio.value < spl_fixpt_from_fraction(4, 10).value) + return easf_filter_6tap_64p_ratio_0_40; + else if (ratio.value < spl_fixpt_from_fraction(5, 10).value) + return easf_filter_6tap_64p_ratio_0_50; + else if (ratio.value < spl_fixpt_from_fraction(6, 10).value) + return easf_filter_6tap_64p_ratio_0_60; + else if (ratio.value < spl_fixpt_from_fraction(7, 10).value) + return easf_filter_6tap_64p_ratio_0_70; + else if (ratio.value < spl_fixpt_from_fraction(8, 10).value) + return easf_filter_6tap_64p_ratio_0_80; + else if (ratio.value < spl_fixpt_from_fraction(9, 10).value) + return easf_filter_6tap_64p_ratio_0_90; + else + return easf_filter_6tap_64p_ratio_1_00; +} + +const uint16_t *spl_dscl_get_easf_filter_coeffs_64p_s1_10(int taps, struct spl_fixed31_32 ratio) +{ + if (taps == 6) + return spl_get_easf_filter_6tap_64p_s1_10(ratio); + else if (taps == 4) + return spl_get_easf_filter_4tap_64p_s1_10(ratio); + else if (taps == 3) + return spl_get_easf_filter_3tap_64p_s1_10(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) diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.h index 8bb2b8108e38..edc2b5d25c13 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.h +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.h @@ -13,14 +13,14 @@ struct scale_ratio_to_reg_value_lookup { 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); +const uint16_t *spl_get_easf_filter_3tap_64p(struct spl_fixed31_32 ratio); +const uint16_t *spl_get_easf_filter_4tap_64p(struct spl_fixed31_32 ratio); +const uint16_t *spl_get_easf_filter_6tap_64p(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); +const uint16_t *spl_dscl_get_easf_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio); +const uint16_t *spl_dscl_get_easf_filter_coeffs_64p_s1_10(int taps, struct spl_fixed31_32 ratio); uint32_t spl_get_v_bf3_mode(struct spl_fixed31_32 ratio); uint32_t spl_get_h_bf3_mode(struct spl_fixed31_32 ratio); -- cgit v1.2.3 From 51d1b338541dea83fec8e6f95d3e46fa469a73a8 Mon Sep 17 00:00:00 2001 From: Brendan Tam Date: Thu, 23 Jan 2025 11:25:16 -0500 Subject: drm/amd/display: add workaround flag to link to force FFE preset [Why] There have been instances of some monitors being unable to link train on their reported link speed using their selected FFE preset. If a different FFE preset is found that has a higher rate of success during link training this workaround can be used to force its FFE preset. [How] A new link workaround flag is made called force_dp_ffe_preset. The flag is checked in override_training_settings and will set lt_settings->ffe_preset which is null if the flag is not set. The flag is then set in override_lane_settings. Reviewed-by: Wenjing Liu Signed-off-by: Brendan Tam Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 ++ drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index e1f4f643c364..16cd7833e931 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1792,7 +1792,9 @@ struct dc_link { bool dongle_mode_timing_override; bool blank_stream_on_ocs_change; bool read_dpcd204h_on_irq_hpd; + bool force_dp_ffe_preset; } wa_flags; + union dc_dp_ffe_preset forced_dp_ffe_preset; struct link_mst_stream_allocation_table mst_stream_alloc_table; struct dc_link_status link_status; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index 88d4288cde0f..751c18e592ea 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -736,6 +736,8 @@ void override_training_settings( lt_settings->pre_emphasis = overrides->pre_emphasis; if (overrides->post_cursor2 != NULL) lt_settings->post_cursor2 = overrides->post_cursor2; + if (link->wa_flags.force_dp_ffe_preset && !dp_is_lttpr_present(link)) + lt_settings->ffe_preset = &link->forced_dp_ffe_preset; if (overrides->ffe_preset != NULL) lt_settings->ffe_preset = overrides->ffe_preset; /* Override HW lane settings with BIOS forced values if present */ -- cgit v1.2.3 From b40d022ec06ade9f6c809091dc188422a0f0946d Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Mon, 13 Jan 2025 11:57:54 -0500 Subject: drm/amd/display: pass calculated dram_speed_mts to dml2 [why] currently dml2 is using a hard coded 16 to convert memclk to dram_speed_mts. for apu, this depends on wck_ratio. change to pass the already calculated dram_speed_mts from fpu to dml2. v2: use existing calculation of dram_speed_mts for now to avoid regression Signed-off-by: Charlene Liu Signed-off-by: Aurabindo Pillai Reviewed-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c | 2 ++ drivers/gpu/drm/amd/display/dc/dml/dcn351/dcn351_fpu.c | 1 + drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h | 1 + 3 files changed, 4 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c index 47d785204f29..e8efffcc69a1 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c @@ -367,6 +367,8 @@ void dcn35_update_bw_bounding_box_fpu(struct dc *dc, clock_limits[i].socclk_mhz; dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].memclk_mhz = clk_table->entries[i].memclk_mhz * clk_table->entries[i].wck_ratio; + + dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dram_speed_mts = clock_limits[i].dram_speed_mts; dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dtbclk_mhz = clock_limits[i].dtbclk_mhz; dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dcfclk_levels = diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn351/dcn351_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn351/dcn351_fpu.c index d9e63c4fdd95..17d0b4923b0c 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn351/dcn351_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn351/dcn351_fpu.c @@ -401,6 +401,7 @@ void dcn351_update_bw_bounding_box_fpu(struct dc *dc, clock_limits[i].socclk_mhz; dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].memclk_mhz = clk_table->entries[i].memclk_mhz * clk_table->entries[i].wck_ratio; + dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dram_speed_mts = clock_limits[i].dram_speed_mts; dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dtbclk_mhz = clock_limits[i].dtbclk_mhz; dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dcfclk_levels = 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 0f944fcfd5a5..785226945699 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h @@ -159,6 +159,7 @@ struct dml2_clks_table_entry { unsigned int dtbclk_mhz; unsigned int dispclk_mhz; unsigned int dppclk_mhz; + unsigned int dram_speed_mts; /*which is based on wck_ratio*/ }; struct dml2_clks_num_entries { -- cgit v1.2.3 From 8f87447a8e5ea415100c005a4f468b1b7804678f Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Tue, 4 Feb 2025 15:33:13 -0500 Subject: drm/amd/display: Make dcn401_program_pipe non static Allow reuse of code by making dcn401_program_pipe() non static. Fixes: 2739bd123782 ("drm/amd/display: Allow reuse of of DCN4x code") Signed-off-by: Aurabindo Pillai Signed-off-by: Karthi Kandasamy Reviewed-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 2 +- drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 8ad0ff669b7a..c4a37a95e812 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 @@ -1934,7 +1934,7 @@ static void dcn401_program_tg( hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx); } -static void dcn401_program_pipe( +void dcn401_program_pipe( struct dc *dc, struct pipe_ctx *pipe_ctx, struct dc_state *context) 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 dbd69d215b8b..781cf0efccc6 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 @@ -93,6 +93,10 @@ void dcn401_reset_back_end_for_pipe( void dcn401_reset_hw_ctx_wrap( struct dc *dc, struct dc_state *context); +void dcn401_program_pipe( + struct dc *dc, + struct pipe_ctx *pipe_ctx, + struct dc_state *context); void dcn401_perform_3dlut_wa_unlock(struct pipe_ctx *pipe_ctx); void dcn401_program_front_end_for_ctx(struct dc *dc, struct dc_state *context); void dcn401_post_unlock_program_front_end(struct dc *dc, struct dc_state *context); -- cgit v1.2.3 From 53b2e0c24afa4c24a2bf42bc850fe1565d978805 Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Tue, 21 Jan 2025 11:02:34 -0500 Subject: drm/amd/display: sspl: cleanup filter code [Why & How] Remove unused filters and functions Add static to limit scope Signed-off-by: Samson Tam Signed-off-by: Aurabindo Pillai Reviewed-by: Jun Lei Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/dc/sspl/dc_spl_isharp_filters.c | 321 +-------------------- .../amd/display/dc/sspl/dc_spl_isharp_filters.h | 18 +- .../amd/display/dc/sspl/dc_spl_scl_easf_filters.c | 39 ++- .../amd/display/dc/sspl/dc_spl_scl_easf_filters.h | 9 +- .../drm/amd/display/dc/sspl/dc_spl_scl_filters.c | 232 +-------------- .../drm/amd/display/dc/sspl/dc_spl_scl_filters.h | 11 +- 6 files changed, 40 insertions(+), 590 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c index 060451bf90d1..12acdd34e6a6 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c @@ -6,232 +6,6 @@ #include "dc_spl_filters.h" #include "dc_spl_isharp_filters.h" -//======================================== -// Delta Gain 1DLUT -// LUT content is packed as 4-bytes into one DWORD/entry -// A_start = 0.000000 -// A_end = 10.000000 -// A_gain = 2.000000 -// B_start = 11.000000 -// B_end = 86.000000 -// C_start = 40.000000 -// C_end = 64.000000 -//======================================== -static const uint32_t filter_isharp_1D_lut_0[ISHARP_LUT_TABLE_SIZE] = { -0x02010000, -0x0A070503, -0x1614100D, -0x1C1B1918, -0x22211F1E, -0x27262423, -0x2A2A2928, -0x2D2D2C2B, -0x302F2F2E, -0x31313030, -0x31313131, -0x31313131, -0x30303031, -0x292D2F2F, -0x191D2125, -0x050A0F14, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -}; -//======================================== -// Delta Gain 1DLUT -// LUT content is packed as 4-bytes into one DWORD/entry -// A_start = 0.000000 -// A_end = 10.000000 -// A_gain = 0.500000 -// B_start = 11.000000 -// B_end = 127.000000 -// C_start = 96.000000 -// C_end = 127.000000 -//======================================== - -static const uint32_t filter_isharp_1D_lut_0p5x[ISHARP_LUT_TABLE_SIZE] = { -0x00000000, -0x02020101, -0x06050403, -0x07070606, -0x09080808, -0x0A0A0A09, -0x0C0B0B0B, -0x0D0D0C0C, -0x0E0E0D0D, -0x0F0F0E0E, -0x100F0F0F, -0x10101010, -0x11111010, -0x11111111, -0x11111111, -0x11111111, -0x11111111, -0x11111111, -0x11111111, -0x10101111, -0x10101010, -0x0F0F0F10, -0x0E0E0F0F, -0x0D0D0E0E, -0x0C0C0D0D, -0x0B0B0B0C, -0x090A0A0A, -0x08080809, -0x06060707, -0x04050506, -0x02030304, -0x00010102, -}; -//======================================== -// Delta Gain 1DLUT -// LUT content is packed as 4-bytes into one DWORD/entry -// A_start = 0.000000 -// A_end = 10.000000 -// A_gain = 1.000000 -// B_start = 11.000000 -// B_end = 127.000000 -// C_start = 96.000000 -// C_end = 127.000000 -//======================================== -static const uint32_t filter_isharp_1D_lut_1p0x[ISHARP_LUT_TABLE_SIZE] = { -0x01000000, -0x05040302, -0x0B0A0806, -0x0E0E0D0C, -0x1211100F, -0x15141312, -0x17171615, -0x1A191918, -0x1C1B1B1A, -0x1E1D1D1C, -0x1F1F1E1E, -0x2020201F, -0x21212121, -0x22222222, -0x23232222, -0x23232323, -0x23232323, -0x22222323, -0x22222222, -0x21212121, -0x1F202020, -0x1E1E1F1F, -0x1C1D1D1E, -0x1A1B1B1C, -0x1819191A, -0x15161717, -0x12131415, -0x0F101112, -0x0C0D0E0E, -0x08090A0B, -0x04050607, -0x00010203, -}; -//======================================== -// Delta Gain 1DLUT -// LUT content is packed as 4-bytes into one DWORD/entry -// A_start = 0.000000 -// A_end = 10.000000 -// A_gain = 1.500000 -// B_start = 11.000000 -// B_end = 127.000000 -// C_start = 96.000000 -// C_end = 127.000000 -//======================================== -static const uint32_t filter_isharp_1D_lut_1p5x[ISHARP_LUT_TABLE_SIZE] = { -0x01010000, -0x07050402, -0x110F0C0A, -0x16141312, -0x1B191817, -0x1F1E1D1C, -0x23222120, -0x26262524, -0x2A292827, -0x2C2C2B2A, -0x2F2E2E2D, -0x3130302F, -0x32323131, -0x33333332, -0x34343433, -0x34343434, -0x34343434, -0x33343434, -0x32333333, -0x31313232, -0x2F303031, -0x2D2E2E2F, -0x2A2B2C2C, -0x2728292A, -0x24252626, -0x20212223, -0x1C1D1E1F, -0x1718191B, -0x12131416, -0x0C0E0F10, -0x0608090B, -0x00020305 -}; -//======================================== -// Delta Gain 1DLUT -// LUT content is packed as 4-bytes into one DWORD/entry -// A_start = 0.000000 -// A_end = 10.000000 -// A_gain = 2.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_2p0x[ISHARP_LUT_TABLE_SIZE] = { -0x02010000, -0x0A070503, -0x1614100D, -0x1D1B1A18, -0x2322201F, -0x29282625, -0x2F2D2C2B, -0x33323130, -0x38373534, -0x3B3A3938, -0x3E3E3D3C, -0x4140403F, -0x43424241, -0x44444443, -0x45454545, -0x46454545, -0x45454546, -0x45454545, -0x43444444, -0x41424243, -0x3F404041, -0x3C3D3E3E, -0x38393A3B, -0x34353738, -0x30313233, -0x2B2C2D2F, -0x25262829, -0x1F202223, -0x181A1B1D, -0x10121416, -0x080B0D0E, -0x00020406, -}; //======================================== // Delta Gain 1DLUT // LUT content is packed as 4-bytes into one DWORD/entry @@ -278,52 +52,6 @@ static const uint32_t filter_isharp_1D_lut_3p0x[ISHARP_LUT_TABLE_SIZE] = { 0x0003060A, }; -//======================================== -// Wide scaler coefficients -//======================================================== -// gen_scaler_coeffs.m -// 15-Dec-2021 -// 6t_64p_LanczosEd_p_1_p_10qb_ -// 6 -// 64 -// LanczosEd -// S1.10 -//======================================================== -static const uint16_t filter_isharp_wide_6tap_64p[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 -}; // Blur and scale coefficients //======================================================== // gen_BlurScale_coeffs.m @@ -613,47 +341,6 @@ struct scale_ratio_to_sharpness_level_adj sharpness_level_adj[NUM_SHARPNESS_ADJ_ {1, 1, 5}, }; -const uint32_t *spl_get_filter_isharp_1D_lut_0(void) -{ - return filter_isharp_1D_lut_0; -} -const uint32_t *spl_get_filter_isharp_1D_lut_0p5x(void) -{ - return filter_isharp_1D_lut_0p5x; -} -const uint32_t *spl_get_filter_isharp_1D_lut_1p0x(void) -{ - return filter_isharp_1D_lut_1p0x; -} -const uint32_t *spl_get_filter_isharp_1D_lut_1p5x(void) -{ - return filter_isharp_1D_lut_1p5x; -} -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_in_6_64p(void) -{ - return filter_isharp_bs_4tap_in_6_64p_s1_12; -} -const uint16_t *spl_get_filter_isharp_bs_4tap_64p(void) -{ - return filter_isharp_bs_4tap_64p_s1_12; -} -const 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_adj(struct spl_fixed31_32 ratio) { int j; @@ -693,7 +380,7 @@ static unsigned int spl_calculate_sharpness_level_adj(struct spl_fixed31_32 rati } static unsigned int spl_calculate_sharpness_level(struct spl_fixed31_32 ratio, - int discrete_sharpness_level, enum system_setup setup, + unsigned int discrete_sharpness_level, enum system_setup setup, struct spl_sharpness_range sharpness_range, enum scale_to_sharpness_policy scale_to_sharpness_policy) { @@ -827,11 +514,11 @@ uint32_t *spl_get_pregen_filter_isharp_1D_lut(enum system_setup setup) const uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps) { if (taps == 3) - return spl_get_filter_isharp_bs_3tap_64p(); + return filter_isharp_bs_3tap_64p_s1_12; else if (taps == 4) - return spl_get_filter_isharp_bs_4tap_64p(); + return filter_isharp_bs_4tap_64p_s1_12; else if (taps == 6) - return spl_get_filter_isharp_bs_4tap_in_6_64p(); + return filter_isharp_bs_4tap_in_6_64p_s1_12; else { /* should never happen, bug */ SPL_BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.h index 7d0be2fc2d00..f5e3d3ecc913 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.h +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.h @@ -7,19 +7,6 @@ #include "dc_spl_types.h" -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 uint32_t *spl_get_filter_isharp_1D_lut_3p0x(void); -const uint16_t *spl_get_filter_isharp_bs_4tap_in_6_64p(void); -const uint16_t *spl_get_filter_isharp_bs_4tap_64p(void); -const uint16_t *spl_get_filter_isharp_bs_3tap_64p(void); -const uint16_t *spl_get_filter_isharp_wide_6tap_64p(void); -const uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps); -const uint16_t *spl_dscl_get_blur_scale_coeffs_64p_s1_10(int taps); - #define NUM_SHARPNESS_ADJ_LEVELS 6 struct scale_ratio_to_sharpness_level_adj { unsigned int ratio_numer; @@ -47,4 +34,9 @@ void spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data, void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup, struct adaptive_sharpness sharpness, enum scale_to_sharpness_policy scale_to_sharpness_policy); uint32_t *spl_get_pregen_filter_isharp_1D_lut(enum system_setup setup); + +// public API +const uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps); +const uint16_t *spl_dscl_get_blur_scale_coeffs_64p_s1_10(int taps); + #endif /* __DC_SPL_ISHARP_FILTERS_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.c index 5f4e2e36c91f..0d1bd81ff04a 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.c +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.c @@ -1136,7 +1136,6 @@ static const uint16_t easf_filter_6tap_64p_ratio_1_00[198] = { }; /* Converted scaler coeff tables from S1.10 to S1.12 */ - static const uint16_t easf_filter_3tap_64p_ratio_0_30_s1_12[99] = { 0x0800, 0x0800, 0x0000, 0x07d8, 0x0818, 0x0010, @@ -2001,7 +2000,7 @@ static const uint16_t easf_filter_6tap_64p_ratio_1_00_s1_12[198] = { 0x0064, 0x3dd4, 0x09c8, 0x09c8, 0x3dd4, 0x0064, }; -struct scale_ratio_to_reg_value_lookup easf_v_bf3_mode_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_v_bf3_mode_lookup[] = { {3, 10, 0x0000}, {4, 10, 0x0000}, {5, 10, 0x0000}, @@ -2013,7 +2012,7 @@ struct scale_ratio_to_reg_value_lookup easf_v_bf3_mode_lookup[] = { {-1, -1, 0x0002}, }; -struct scale_ratio_to_reg_value_lookup easf_h_bf3_mode_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_h_bf3_mode_lookup[] = { {3, 10, 0x0000}, {4, 10, 0x0000}, {5, 10, 0x0000}, @@ -2025,7 +2024,7 @@ struct scale_ratio_to_reg_value_lookup easf_h_bf3_mode_lookup[] = { {-1, -1, 0x0002}, }; -struct scale_ratio_to_reg_value_lookup easf_reducer_gain6_6tap_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_reducer_gain6_6tap_lookup[] = { {3, 10, 0x4100}, {4, 10, 0x4100}, {5, 10, 0x4100}, @@ -2037,7 +2036,7 @@ struct scale_ratio_to_reg_value_lookup easf_reducer_gain6_6tap_lookup[] = { {-1, -1, 0x4100}, }; -struct scale_ratio_to_reg_value_lookup easf_reducer_gain4_6tap_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_reducer_gain4_6tap_lookup[] = { {3, 10, 0x4000}, {4, 10, 0x4000}, {5, 10, 0x4000}, @@ -2049,7 +2048,7 @@ struct scale_ratio_to_reg_value_lookup easf_reducer_gain4_6tap_lookup[] = { {-1, -1, 0x4000}, }; -struct scale_ratio_to_reg_value_lookup easf_gain_ring6_6tap_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_gain_ring6_6tap_lookup[] = { {3, 10, 0x0000}, {4, 10, 0x251F}, {5, 10, 0x291F}, @@ -2061,7 +2060,7 @@ struct scale_ratio_to_reg_value_lookup easf_gain_ring6_6tap_lookup[] = { {-1, -1, 0xA640}, }; -struct scale_ratio_to_reg_value_lookup easf_gain_ring4_6tap_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_gain_ring4_6tap_lookup[] = { {3, 10, 0x0000}, {4, 10, 0x9600}, {5, 10, 0xA460}, @@ -2073,7 +2072,7 @@ struct scale_ratio_to_reg_value_lookup easf_gain_ring4_6tap_lookup[] = { {-1, -1, 0xB058}, }; -struct scale_ratio_to_reg_value_lookup easf_reducer_gain6_4tap_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_reducer_gain6_4tap_lookup[] = { {3, 10, 0x4100}, {4, 10, 0x4100}, {5, 10, 0x4100}, @@ -2085,7 +2084,7 @@ struct scale_ratio_to_reg_value_lookup easf_reducer_gain6_4tap_lookup[] = { {-1, -1, 0x4100}, }; -struct scale_ratio_to_reg_value_lookup easf_reducer_gain4_4tap_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_reducer_gain4_4tap_lookup[] = { {3, 10, 0x4000}, {4, 10, 0x4000}, {5, 10, 0x4000}, @@ -2097,7 +2096,7 @@ struct scale_ratio_to_reg_value_lookup easf_reducer_gain4_4tap_lookup[] = { {-1, -1, 0x4000}, }; -struct scale_ratio_to_reg_value_lookup easf_gain_ring6_4tap_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_gain_ring6_4tap_lookup[] = { {3, 10, 0x0000}, {4, 10, 0x0000}, {5, 10, 0x0000}, @@ -2109,7 +2108,7 @@ struct scale_ratio_to_reg_value_lookup easf_gain_ring6_4tap_lookup[] = { {-1, -1, 0x0000}, }; -struct scale_ratio_to_reg_value_lookup easf_gain_ring4_4tap_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_gain_ring4_4tap_lookup[] = { {3, 10, 0x0000}, {4, 10, 0x0000}, {5, 10, 0x0000}, @@ -2121,7 +2120,7 @@ struct scale_ratio_to_reg_value_lookup easf_gain_ring4_4tap_lookup[] = { {-1, -1, 0xAC00}, }; -struct scale_ratio_to_reg_value_lookup easf_3tap_dntilt_uptilt_offset_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_3tap_dntilt_uptilt_offset_lookup[] = { {3, 10, 0x0000}, {4, 10, 0x0000}, {5, 10, 0x0000}, @@ -2133,7 +2132,7 @@ struct scale_ratio_to_reg_value_lookup easf_3tap_dntilt_uptilt_offset_lookup[] = {-1, -1, 0xA8D8}, }; -struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt_maxval_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt_maxval_lookup[] = { {3, 10, 0x0000}, {4, 10, 0x0000}, {5, 10, 0x0000}, @@ -2145,7 +2144,7 @@ struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt_maxval_lookup[] = { {-1, -1, 0x3ADB}, }; -struct scale_ratio_to_reg_value_lookup easf_3tap_dntilt_slope_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_3tap_dntilt_slope_lookup[] = { {3, 10, 0x3800}, {4, 10, 0x3800}, {5, 10, 0x3800}, @@ -2157,7 +2156,7 @@ struct scale_ratio_to_reg_value_lookup easf_3tap_dntilt_slope_lookup[] = { {-1, -1, 0x3B66}, }; -struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt1_slope_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt1_slope_lookup[] = { {3, 10, 0x3800}, {4, 10, 0x3800}, {5, 10, 0x3800}, @@ -2169,7 +2168,7 @@ struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt1_slope_lookup[] = { {-1, -1, 0x2F20}, }; -struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt2_slope_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt2_slope_lookup[] = { {3, 10, 0x0000}, {4, 10, 0x0000}, {5, 10, 0x0000}, @@ -2181,7 +2180,7 @@ struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt2_slope_lookup[] = { {-1, -1, 0x1F00}, }; -struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt2_offset_lookup[] = { +static struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt2_offset_lookup[] = { {3, 10, 0x0000}, {4, 10, 0x0000}, {5, 10, 0x0000}, @@ -2193,7 +2192,7 @@ struct scale_ratio_to_reg_value_lookup easf_3tap_uptilt2_offset_lookup[] = { {-1, -1, 0x9E00}, }; -const uint16_t *spl_get_easf_filter_3tap_64p(struct spl_fixed31_32 ratio) +static const 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; @@ -2213,7 +2212,7 @@ const uint16_t *spl_get_easf_filter_3tap_64p(struct spl_fixed31_32 ratio) return easf_filter_3tap_64p_ratio_1_00_s1_12; } -const uint16_t *spl_get_easf_filter_4tap_64p(struct spl_fixed31_32 ratio) +static const 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; @@ -2233,7 +2232,7 @@ const uint16_t *spl_get_easf_filter_4tap_64p(struct spl_fixed31_32 ratio) return easf_filter_4tap_64p_ratio_1_00_s1_12; } -const uint16_t *spl_get_easf_filter_6tap_64p(struct spl_fixed31_32 ratio) +static const 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; diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.h index edc2b5d25c13..321ae22a04d4 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.h +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_easf_filters.h @@ -13,14 +13,9 @@ struct scale_ratio_to_reg_value_lookup { const uint32_t reg_value; }; -const uint16_t *spl_get_easf_filter_3tap_64p(struct spl_fixed31_32 ratio); -const uint16_t *spl_get_easf_filter_4tap_64p(struct spl_fixed31_32 ratio); -const uint16_t *spl_get_easf_filter_6tap_64p(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); -const uint16_t *spl_dscl_get_easf_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio); -const uint16_t *spl_dscl_get_easf_filter_coeffs_64p_s1_10(int taps, struct spl_fixed31_32 ratio); uint32_t spl_get_v_bf3_mode(struct spl_fixed31_32 ratio); uint32_t spl_get_h_bf3_mode(struct spl_fixed31_32 ratio); @@ -35,4 +30,8 @@ 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); +/* public API */ +const uint16_t *spl_dscl_get_easf_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio); +const uint16_t *spl_dscl_get_easf_filter_coeffs_64p_s1_10(int taps, struct spl_fixed31_32 ratio); + #endif /* __DC_SPL_SCL_EASF_FILTERS_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.c index b02c7b0b262b..5e52bdf1ad44 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.c +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.c @@ -4,194 +4,6 @@ #include "spl_debug.h" #include "dc_spl_scl_filters.h" -//========================================= -// = 2 -// = 16 -// = 0.833333 (input/output) -// = 0 -// = ModifiedLanczos -// = s1.10 -// = s1.12 -//========================================= -static const uint16_t filter_2tap_16p[18] = { - 0x1000, 0x0000, - 0x0FF0, 0x0010, - 0x0FB0, 0x0050, - 0x0F34, 0x00CC, - 0x0E68, 0x0198, - 0x0D44, 0x02BC, - 0x0BC4, 0x043C, - 0x09FC, 0x0604, - 0x0800, 0x0800 -}; - -//========================================= -// = 3 -// = 16 -// = 0.83333 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_3tap_16p_upscale[27] = { - 0x0804, 0x07FC, 0x0000, - 0x06AC, 0x0978, 0x3FDC, - 0x055C, 0x0AF0, 0x3FB4, - 0x0420, 0x0C50, 0x3F90, - 0x0300, 0x0D88, 0x3F78, - 0x0200, 0x0E90, 0x3F70, - 0x0128, 0x0F5C, 0x3F7C, - 0x007C, 0x0FD8, 0x3FAC, - 0x0000, 0x1000, 0x0000 -}; - -//========================================= -// = 3 -// = 16 -// = 1.16666 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_3tap_16p_116[27] = { - 0x0804, 0x07FC, 0x0000, - 0x0700, 0x0914, 0x3FEC, - 0x0604, 0x0A1C, 0x3FE0, - 0x050C, 0x0B14, 0x3FE0, - 0x041C, 0x0BF4, 0x3FF0, - 0x0340, 0x0CB0, 0x0010, - 0x0274, 0x0D3C, 0x0050, - 0x01C0, 0x0D94, 0x00AC, - 0x0128, 0x0DB4, 0x0124 -}; - -//========================================= -// = 3 -// = 16 -// = 1.49999 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_3tap_16p_149[27] = { - 0x0804, 0x07FC, 0x0000, - 0x0730, 0x08CC, 0x0004, - 0x0660, 0x098C, 0x0014, - 0x0590, 0x0A3C, 0x0034, - 0x04C4, 0x0AD4, 0x0068, - 0x0400, 0x0B54, 0x00AC, - 0x0348, 0x0BB0, 0x0108, - 0x029C, 0x0BEC, 0x0178, - 0x0200, 0x0C00, 0x0200 -}; - -//========================================= -// = 3 -// = 16 -// = 1.83332 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_3tap_16p_183[27] = { - 0x0804, 0x07FC, 0x0000, - 0x0754, 0x0880, 0x002C, - 0x06A8, 0x08F0, 0x0068, - 0x05FC, 0x0954, 0x00B0, - 0x0550, 0x09AC, 0x0104, - 0x04A8, 0x09F0, 0x0168, - 0x0408, 0x0A20, 0x01D8, - 0x036C, 0x0A40, 0x0254, - 0x02DC, 0x0A48, 0x02DC -}; - -//========================================= -// = 4 -// = 16 -// = 0.83333 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_4tap_16p_upscale[36] = { - 0x0000, 0x1000, 0x0000, 0x0000, - 0x3F74, 0x0FDC, 0x00B4, 0x3FFC, - 0x3F0C, 0x0F70, 0x0194, 0x3FF0, - 0x3ECC, 0x0EC4, 0x0298, 0x3FD8, - 0x3EAC, 0x0DE4, 0x03B8, 0x3FB8, - 0x3EA4, 0x0CD8, 0x04F4, 0x3F90, - 0x3EB8, 0x0BA0, 0x0644, 0x3F64, - 0x3ED8, 0x0A54, 0x07A0, 0x3F34, - 0x3F00, 0x08FC, 0x0900, 0x3F04 -}; - -//========================================= -// = 4 -// = 16 -// = 1.16666 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_4tap_16p_116[36] = { - 0x01A8, 0x0CB4, 0x01A4, 0x0000, - 0x0110, 0x0CB0, 0x0254, 0x3FEC, - 0x0090, 0x0C80, 0x031C, 0x3FD4, - 0x0024, 0x0C2C, 0x03F4, 0x3FBC, - 0x3FD8, 0x0BAC, 0x04DC, 0x3FA0, - 0x3F9C, 0x0B14, 0x05CC, 0x3F84, - 0x3F70, 0x0A60, 0x06C4, 0x3F6C, - 0x3F5C, 0x098C, 0x07BC, 0x3F5C, - 0x3F54, 0x08AC, 0x08AC, 0x3F54 -}; - -//========================================= -// = 4 -// = 16 -// = 1.49999 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_4tap_16p_149[36] = { - 0x02B8, 0x0A90, 0x02B8, 0x0000, - 0x0230, 0x0A90, 0x0350, 0x3FF0, - 0x01B8, 0x0A78, 0x03F0, 0x3FE0, - 0x0148, 0x0A48, 0x049C, 0x3FD4, - 0x00E8, 0x0A00, 0x054C, 0x3FCC, - 0x0098, 0x09A0, 0x0600, 0x3FC8, - 0x0054, 0x0928, 0x06B4, 0x3FD0, - 0x001C, 0x08A4, 0x0760, 0x3FE0, - 0x3FFC, 0x0804, 0x0804, 0x3FFC -}; - -//========================================= -// = 4 -// = 16 -// = 1.83332 (input/output) -// = 0 -// = ModifiedLanczos -// = 1.10 -// = 1.12 -//========================================= -static const uint16_t filter_4tap_16p_183[36] = { - 0x03B0, 0x08A0, 0x03B0, 0x0000, - 0x0348, 0x0898, 0x041C, 0x0004, - 0x02DC, 0x0884, 0x0490, 0x0010, - 0x0278, 0x0864, 0x0500, 0x0024, - 0x021C, 0x0838, 0x0570, 0x003C, - 0x01C8, 0x07FC, 0x05E0, 0x005C, - 0x0178, 0x07B8, 0x064C, 0x0084, - 0x0130, 0x076C, 0x06B0, 0x00B4, - 0x00F0, 0x0714, 0x0710, 0x00EC -}; //========================================= // = 2 @@ -1318,19 +1130,7 @@ 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 spl_fixed31_32 ratio) -{ - if (ratio.value < spl_fixpt_one.value) - return filter_3tap_16p_upscale; - else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) - return filter_3tap_16p_116; - 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 spl_fixed31_32 ratio) +static const uint16_t *spl_get_filter_3tap_64p(struct spl_fixed31_32 ratio) { if (ratio.value < spl_fixpt_one.value) return filter_3tap_64p_upscale; @@ -1342,19 +1142,7 @@ const uint16_t *spl_get_filter_3tap_64p(struct spl_fixed31_32 ratio) return filter_3tap_64p_183; } -const uint16_t *spl_get_filter_4tap_16p(struct spl_fixed31_32 ratio) -{ - if (ratio.value < spl_fixpt_one.value) - return filter_4tap_16p_upscale; - else if (ratio.value < spl_fixpt_from_fraction(4, 3).value) - return filter_4tap_16p_116; - 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 spl_fixed31_32 ratio) +static const uint16_t *spl_get_filter_4tap_64p(struct spl_fixed31_32 ratio) { if (ratio.value < spl_fixpt_one.value) return filter_4tap_64p_upscale; @@ -1366,7 +1154,7 @@ const uint16_t *spl_get_filter_4tap_64p(struct spl_fixed31_32 ratio) return filter_4tap_64p_183; } -const uint16_t *spl_get_filter_5tap_64p(struct spl_fixed31_32 ratio) +static const uint16_t *spl_get_filter_5tap_64p(struct spl_fixed31_32 ratio) { if (ratio.value < spl_fixpt_one.value) return filter_5tap_64p_upscale; @@ -1378,7 +1166,7 @@ const uint16_t *spl_get_filter_5tap_64p(struct spl_fixed31_32 ratio) return filter_5tap_64p_183; } -const uint16_t *spl_get_filter_6tap_64p(struct spl_fixed31_32 ratio) +static const uint16_t *spl_get_filter_6tap_64p(struct spl_fixed31_32 ratio) { if (ratio.value < spl_fixpt_one.value) return filter_6tap_64p_upscale; @@ -1390,7 +1178,7 @@ const uint16_t *spl_get_filter_6tap_64p(struct spl_fixed31_32 ratio) return filter_6tap_64p_183; } -const uint16_t *spl_get_filter_7tap_64p(struct spl_fixed31_32 ratio) +static const uint16_t *spl_get_filter_7tap_64p(struct spl_fixed31_32 ratio) { if (ratio.value < spl_fixpt_one.value) return filter_7tap_64p_upscale; @@ -1402,7 +1190,7 @@ const uint16_t *spl_get_filter_7tap_64p(struct spl_fixed31_32 ratio) return filter_7tap_64p_183; } -const uint16_t *spl_get_filter_8tap_64p(struct spl_fixed31_32 ratio) +static const uint16_t *spl_get_filter_8tap_64p(struct spl_fixed31_32 ratio) { if (ratio.value < spl_fixpt_one.value) return filter_8tap_64p_upscale; @@ -1414,12 +1202,7 @@ const uint16_t *spl_get_filter_8tap_64p(struct spl_fixed31_32 ratio) return filter_8tap_64p_183; } -const uint16_t *spl_get_filter_2tap_16p(void) -{ - return filter_2tap_16p; -} - -const uint16_t *spl_get_filter_2tap_64p(void) +static const uint16_t *spl_get_filter_2tap_64p(void) { return filter_2tap_64p; } @@ -1448,4 +1231,3 @@ const uint16_t *spl_dscl_get_filter_coeffs_64p(int taps, struct spl_fixed31_32 r return NULL; } } - diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.h index 48202bc4f81e..c315a438d064 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.h +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_scl_filters.h @@ -7,16 +7,7 @@ #include "dc_spl_types.h" -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); +/* public API */ const uint16_t *spl_dscl_get_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio); #endif /* __DC_SPL_SCL_FILTERS_H__ */ -- cgit v1.2.3 From 53472eeb22ad5b122a485f73583f8201a8a32401 Mon Sep 17 00:00:00 2001 From: Taimur Hassan Date: Sun, 2 Feb 2025 22:43:49 -0500 Subject: drm/amd/display: 3.2.320 Summary: * Start enabling support for 4-plane MPO * DML21 Updates * SPL Updates * Other minor fixes Signed-off-by: Taimur Hassan Signed-off-by: Aurabindo Pillai Reviewed-by: Aric Cyr Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 16cd7833e931..ab88ce02893e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -53,7 +53,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.319" +#define DC_VER "3.2.320" /** * MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC -- cgit v1.2.3 From 196222dccb3e1f3defe85919ae9f00f6f4a3f4c4 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 24 Jul 2024 08:49:35 -0700 Subject: drm/amd/display: Reapply 2fde4fdddc1f Commit 2563391e57b5 ("drm/amd/display: DML2.1 resynchronization") blew away the compiler warning fix from commit 2fde4fdddc1f ("drm/amd/display: Avoid -Wenum-float-conversion in add_margin_and_round_to_dfs_grainularity()"), causing the warning to reappear. drivers/gpu/drm/amd/amdgpu/../display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c:183:58: error: arithmetic between enumeration type 'enum dentist_divider_range' and floating-point type 'double' [-Werror,-Wenum-float-conversion] 183 | divider = (unsigned int)(DFS_DIVIDER_RANGE_SCALE_FACTOR * (vco_freq_khz / clock_khz)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. Apply the fix again to resolve the warning. Fixes: 1b30456150e5 ("drm/amd/display: DML21 Reintegration") Signed-off-by: Nathan Chancellor Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dml2/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 02004b7efa8c..15507926f3a4 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 @@ -212,7 +212,7 @@ static bool add_margin_and_round_to_dfs_grainularity(double clock_khz, double ma clock_khz *= 1.0 + margin; - divider = (unsigned int)(DFS_DIVIDER_RANGE_SCALE_FACTOR * (vco_freq_khz / clock_khz)); + divider = (unsigned int)((int)DFS_DIVIDER_RANGE_SCALE_FACTOR * (vco_freq_khz / clock_khz)); /* we want to floor here to get higher clock than required rather than lower */ if (divider < DFS_DIVIDER_RANGE_2_START) { -- cgit v1.2.3 From c488967488d7eff7b9c527d5469c424c15377502 Mon Sep 17 00:00:00 2001 From: Ovidiu Bunea Date: Mon, 3 Feb 2025 15:43:32 -0500 Subject: drm/amd/display: Exit idle optimizations before accessing PHY [why & how] By default, DCN HW is in idle optimized state which does not allow access to PHY registers. If BIOS powers up the DCN, it is fine because they will power up everything. Only exit idle optimized state when not taking control from VBIOS. Fixes: be704e5ef4bd ("Revert "drm/amd/display: Exit idle optimizations before attempt to access PHY"") Reviewed-by: Charlene Liu Signed-off-by: Ovidiu Bunea Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') 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 7572448e5b9f..935d08d3a670 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 @@ -1891,6 +1891,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(); @@ -1967,6 +1968,8 @@ 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*/ + 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); @@ -1979,6 +1982,8 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) 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); + 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); } -- cgit v1.2.3 From 8ae6dfc0b61b170cf13832d4cfe2a0c744e621a7 Mon Sep 17 00:00:00 2001 From: Leo Zeng Date: Fri, 31 Jan 2025 11:46:52 -0500 Subject: Revert "drm/amd/display: Request HW cursor on DCN3.2 with SubVP" This reverts commit 13437c91606c9232c747475e202fe3827cd53264. Reason to revert: idle power regression found in testing. Reviewed-by: Dillon Varone Signed-off-by: Leo Zeng Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 56dda686e299..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 @@ -626,7 +626,6 @@ static bool dcn32_assign_subvp_pipe(struct dc *dc, * - Not TMZ surface */ if (pipe->plane_state && !pipe->top_pipe && !pipe->prev_odm_pipe && !dcn32_is_center_timing(pipe) && - !pipe->stream->hw_cursor_req && !(pipe->stream->timing.pix_clk_100hz / 10000 > DCN3_2_MAX_SUBVP_PIXEL_RATE_MHZ) && (!dcn32_is_psr_capable(pipe) || (context->stream_count == 1 && dc->caps.dmub_caps.subvp_psr)) && dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_NONE && -- cgit v1.2.3 From 098c9b58be2267a69d15403f6341e8c2da0d90a4 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Tue, 4 Feb 2025 08:07:21 -0700 Subject: drm/amd/display: Add DCC/Tiling reset helper for DCN and DCE This commit introduces a function helper for resetting DCN/DCE DCC and tiling. Those functions are generic for their respective DCN/DCE, so they were added to the oldest version of each architecture. Reviewed-by: Alvin Lee Signed-off-by: Rodrigo Siqueira Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/hwss/dce100/dce100_hwseq.c | 29 ++++++++++++++++++++++ .../drm/amd/display/dc/hwss/dce100/dce100_hwseq.h | 4 +++ .../drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 29 ++++++++++++++++++++++ .../drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h | 4 +++ 4 files changed, 66 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.c index f1f14796a3da..b76350a9cf5f 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.c @@ -140,3 +140,32 @@ void dce100_hw_sequencer_construct(struct dc *dc) dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth; } +/** + * dce100_reset_surface_dcc_and_tiling - Set DCC and tiling in DCE to their disable mode. + * + * @pipe_ctx: Pointer to the pipe context structure. + * @plane_state: Surface state + * @clear_tiling: If true set tiling to Linear, otherwise does not change tiling + * + * This function is responsible for call the HUBP block to disable DCC and set + * tiling to the linear mode. + */ +void dce100_reset_surface_dcc_and_tiling(struct pipe_ctx *pipe_ctx, + struct dc_plane_state *plane_state, + bool clear_tiling) +{ + struct mem_input *mi = pipe_ctx->plane_res.mi; + + if (!mi) + return; + + /* if framebuffer is tiled, disable tiling */ + if (clear_tiling && mi->funcs->mem_input_clear_tiling) + mi->funcs->mem_input_clear_tiling(mi); + + /* force page flip to see the new content of the framebuffer */ + mi->funcs->mem_input_program_surface_flip_and_addr(mi, + &plane_state->address, + true); +} + diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.h index 34518da20009..fadfa794f96b 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.h @@ -46,5 +46,9 @@ bool dce100_enable_display_power_gating(struct dc *dc, uint8_t controller_id, struct dc_bios *dcb, enum pipe_gating_control power_gating); +void dce100_reset_surface_dcc_and_tiling(struct pipe_ctx *pipe_ctx, + struct dc_plane_state *plane_state, + bool clear_tiling); + #endif /* __DC_HWSS_DCE100_H__ */ 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 35c0d101d7c8..301ef36d3d05 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 @@ -3920,3 +3920,32 @@ void dcn10_get_dcc_en_bits(struct dc *dc, int *dcc_en_bits) dcc_en_bits[i] = s->dcc_en ? 1 : 0; } } + +/** + * dcn10_reset_surface_dcc_and_tiling - Set DCC and tiling in DCN to their disable mode. + * + * @pipe_ctx: Pointer to the pipe context structure. + * @plane_state: Surface state + * @clear_tiling: If true set tiling to Linear, otherwise does not change tiling + * + * This function is responsible for call the HUBP block to disable DCC and set + * tiling to the linear mode. + */ +void dcn10_reset_surface_dcc_and_tiling(struct pipe_ctx *pipe_ctx, + struct dc_plane_state *plane_state, + bool clear_tiling) +{ + struct hubp *hubp = pipe_ctx->plane_res.hubp; + + if (!hubp) + return; + + /* if framebuffer is tiled, disable tiling */ + if (clear_tiling && hubp->funcs->hubp_clear_tiling) + hubp->funcs->hubp_clear_tiling(hubp); + + /* force page flip to see the new content of the framebuffer */ + hubp->funcs->hubp_program_surface_flip_and_addr(hubp, + &plane_state->address, + true); +} diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h index bc5dd68a2408..42ffd1e1299c 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h @@ -207,4 +207,8 @@ void dcn10_update_visual_confirm_color( struct pipe_ctx *pipe_ctx, int mpcc_id); +void dcn10_reset_surface_dcc_and_tiling(struct pipe_ctx *pipe_ctx, + struct dc_plane_state *plane_state, + bool clear_tiling); + #endif /* __DC_HWSS_DCN10_H__ */ -- cgit v1.2.3 From c905aa685655f20db68929c00e1279ba16f30756 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Tue, 4 Feb 2025 08:34:58 -0700 Subject: drm/amd/display: Rename panic function Rename dc_plane_force_update_for_panic to dc_plane_force_dcc_and_tiling_disable to describe the function operation in the name. Also, this function might be used in other contexts, and a more generic name can be helpful for this purpose. Reviewed-by: Alvin Lee Signed-off-by: Rodrigo Siqueira Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 4 ++-- drivers/gpu/drm/amd/display/dc/dc_plane.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c index f3471d45b312..aa4184dd0e53 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c @@ -270,8 +270,8 @@ void dc_3dlut_func_retain(struct dc_3dlut *lut) kref_get(&lut->refcount); } -void dc_plane_force_update_for_panic(struct dc_plane_state *plane_state, - bool clear_tiling) +void dc_plane_force_dcc_and_tiling_disable(struct dc_plane_state *plane_state, + bool clear_tiling) { struct dc *dc; int i; diff --git a/drivers/gpu/drm/amd/display/dc/dc_plane.h b/drivers/gpu/drm/amd/display/dc/dc_plane.h index fabcefeda288..e9413685ed4f 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_plane.h +++ b/drivers/gpu/drm/amd/display/dc/dc_plane.h @@ -34,7 +34,7 @@ const struct dc_plane_status *dc_plane_get_status( void dc_plane_state_retain(struct dc_plane_state *plane_state); void dc_plane_state_release(struct dc_plane_state *plane_state); -void dc_plane_force_update_for_panic(struct dc_plane_state *plane_state, - bool clear_tiling); +void dc_plane_force_dcc_and_tiling_disable(struct dc_plane_state *plane_state, + bool clear_tiling); #endif /* _DC_PLANE_H_ */ -- cgit v1.2.3 From d27a1e93f21c209b8a87c816ae04cc3ae4dcc9b6 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Tue, 4 Feb 2025 08:31:33 -0700 Subject: drm/amd/display: Add clear DCC and Tiling callback for DCN Introduce the DCC and Tiling reset callback to all DCN versions that can call it. Reviewed-by: Alvin Lee Signed-off-by: Rodrigo Siqueira Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 13 ++----------- drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_init.c | 1 + drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_init.c | 1 + drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_init.c | 1 + drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_init.c | 1 + drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c | 1 + drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_init.c | 1 + drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c | 1 + drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c | 1 + drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c | 1 + drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c | 1 + drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c | 1 + drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c | 1 + drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h | 1 + 14 files changed, 15 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c index aa4184dd0e53..691b4a68d8ac 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c @@ -291,17 +291,8 @@ void dc_plane_force_dcc_and_tiling_disable(struct dc_plane_state *plane_state, continue; if (dc->ctx->dce_version >= DCE_VERSION_MAX) { - struct hubp *hubp = pipe_ctx->plane_res.hubp; - if (!hubp) - continue; - /* if framebuffer is tiled, disable tiling */ - if (clear_tiling && hubp->funcs->hubp_clear_tiling) - hubp->funcs->hubp_clear_tiling(hubp); - - /* force page flip to see the new content of the framebuffer */ - hubp->funcs->hubp_program_surface_flip_and_addr(hubp, - &plane_state->address, - true); + if (dc->hwss.clear_surface_dcc_and_tiling) + dc->hwss.clear_surface_dcc_and_tiling(pipe_ctx, plane_state, clear_tiling); } else { struct mem_input *mi = pipe_ctx->plane_res.mi; if (!mi) 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 5e51e1761707..079c226c1097 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 @@ -40,6 +40,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { .update_plane_addr = dcn10_update_plane_addr, .update_dchub = dcn10_update_dchub, .update_pending_status = dcn10_update_pending_status, + .clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling, .program_output_csc = dcn10_program_output_csc, .enable_accelerated_mode = dce110_enable_accelerated_mode, .enable_timing_synchronization = dcn10_enable_timing_synchronization, 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 32707b344f0b..ad253c586ea1 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 @@ -36,6 +36,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, + .clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling, .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, .update_plane_addr = dcn20_update_plane_addr, 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 78351408e864..dec57fb4c05c 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 @@ -36,6 +36,7 @@ static const struct hw_sequencer_funcs dcn201_funcs = { .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, + .clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling, .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, .post_unlock_program_front_end = dcn10_post_unlock_program_front_end, .update_plane_addr = dcn201_update_plane_addr, 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 e044e9e0a3a1..c7701a8b574a 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 @@ -37,6 +37,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, + .clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling, .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, .update_plane_addr = dcn20_update_plane_addr, 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 c32764aef884..2ac5d54d1626 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 @@ -37,6 +37,7 @@ static const struct hw_sequencer_funcs dcn30_funcs = { .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, + .clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling, .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, .update_plane_addr = dcn20_update_plane_addr, 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 dcb27cdbce73..8d7ceb7b32b8 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 @@ -39,6 +39,7 @@ static const struct hw_sequencer_funcs dcn301_funcs = { .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, + .clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling, .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, .update_plane_addr = dcn20_update_plane_addr, 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 fb2ffb637931..556f4fe57eda 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 @@ -40,6 +40,7 @@ static const struct hw_sequencer_funcs dcn31_funcs = { .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, + .clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling, .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, .update_plane_addr = dcn20_update_plane_addr, 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 21ef03a76229..f5112742edf9 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 @@ -42,6 +42,7 @@ static const struct hw_sequencer_funcs dcn314_funcs = { .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, + .clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling, .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, .update_plane_addr = dcn20_update_plane_addr, 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 e4d149eff10f..b971356d30b1 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 @@ -39,6 +39,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = { .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, + .clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling, .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, .update_plane_addr = dcn20_update_plane_addr, 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 c7acaf97974c..6a82a865209c 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 @@ -44,6 +44,7 @@ static const struct hw_sequencer_funcs dcn35_funcs = { .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, + .clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling, .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, .update_plane_addr = dcn20_update_plane_addr, 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 4f73e7f551ac..902a96940a01 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 @@ -43,6 +43,7 @@ static const struct hw_sequencer_funcs dcn351_funcs = { .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, + .clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling, .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, .update_plane_addr = dcn20_update_plane_addr, 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 a4e3501fadbb..fe7aceb2f510 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 @@ -18,6 +18,7 @@ static const struct hw_sequencer_funcs dcn401_funcs = { .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn401_program_front_end_for_ctx, + .clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling, .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, .post_unlock_program_front_end = dcn401_post_unlock_program_front_end, .update_plane_addr = dcn20_update_plane_addr, 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 a7d66cfd93c9..599fa41fd75f 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h @@ -240,6 +240,7 @@ struct hw_sequencer_funcs { struct pipe_ctx *pipe_ctx, bool enableTripleBuffer); void (*update_pending_status)(struct pipe_ctx *pipe_ctx); void (*update_dsc_pg)(struct dc *dc, struct dc_state *context, bool safe_to_disable); + void (*clear_surface_dcc_and_tiling)(struct pipe_ctx *pipe_ctx, struct dc_plane_state *plane_state, bool clear_tiling); /* Pipe Lock Related */ void (*pipe_control_lock)(struct dc *dc, -- cgit v1.2.3 From 5f7e384ab56e1edd6aabe860ebcb2b88ec468cb6 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Tue, 4 Feb 2025 11:51:29 -0700 Subject: drm/amd/display: Print seamless boot message in mark_seamless_boot_stream [WHAT & HOW] Add a message so users know the stream will be used for seamless boot. Reviewed-by: Mario Limonciello Reviewed-by: Rodrigo Siqueira Signed-off-by: Alex Hung Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 bf14fa1e3771..e6bc479497e8 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -3764,6 +3764,8 @@ static void mark_seamless_boot_stream(const struct dc *dc, { struct dc_bios *dcb = dc->ctx->dc_bios; + DC_LOGGER_INIT(dc->ctx->logger); + if (stream->apply_seamless_boot_optimization) return; if (!dc->config.allow_seamless_boot_optimization) @@ -3772,7 +3774,7 @@ static void mark_seamless_boot_stream(const struct dc *dc, return; if (dc_validate_boot_timing(dc, stream->sink, &stream->timing)) { stream->apply_seamless_boot_optimization = true; - DC_LOG_INFO("Marked stream for seamless boot optimization\n"); + DC_LOG_DC("Marked stream for seamless boot optimization\n"); } } -- cgit v1.2.3 From de84d580126eb2214937df755cfec5ef0901479e Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 4 Feb 2025 14:34:02 -0500 Subject: drm/amd/display: Read LTTPR ALPM caps during link cap retrieval [Why] The latest DP spec requires the DP TX to read DPCD F0000h through F0009h when detecting LTTPR capabilities for the first time. [How] Update LTTPR cap retrieval to read up to F0009h (two more bytes than the previous F0007h), and store the LTTPR ALPM capabilities. Reviewed-by: Wenjing Liu Signed-off-by: George Shen Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 12 ++++++++++++ .../drm/amd/display/dc/link/protocols/link_dp_capability.c | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h index 94ce8fe74481..ae6e2d8552ac 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h @@ -959,6 +959,14 @@ union dp_128b_132b_supported_lttpr_link_rates { uint8_t raw; }; +union dp_alpm_lttpr_cap { + struct { + uint8_t AUX_LESS_ALPM_SUPPORTED :1; + uint8_t RESERVED :7; + } bits; + uint8_t raw; +}; + union dp_sink_video_fallback_formats { struct { uint8_t dp_1024x768_60Hz_24bpp_support :1; @@ -1118,6 +1126,7 @@ struct dc_lttpr_caps { uint8_t max_ext_timeout; union dp_main_link_channel_coding_lttpr_cap main_link_channel_coding; union dp_128b_132b_supported_lttpr_link_rates supported_128b_132b_rates; + union dp_alpm_lttpr_cap alpm; uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1]; }; @@ -1370,6 +1379,9 @@ struct dp_trace { #ifndef DPCD_MAX_UNCOMPRESSED_PIXEL_RATE_CAP #define DPCD_MAX_UNCOMPRESSED_PIXEL_RATE_CAP 0x221c #endif +#ifndef DP_LTTPR_ALPM_CAPABILITIES +#define DP_LTTPR_ALPM_CAPABILITIES 0xF0009 +#endif #ifndef DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE #define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50 #endif 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 44c3023a7731..80439224acca 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 @@ -1502,7 +1502,7 @@ static bool dpcd_read_sink_ext_caps(struct dc_link *link) enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link) { - uint8_t lttpr_dpcd_data[8] = {0}; + uint8_t lttpr_dpcd_data[10] = {0}; enum dc_status status; bool is_lttpr_present; @@ -1552,6 +1552,10 @@ enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link) lttpr_dpcd_data[DP_PHY_REPEATER_128B132B_RATES - DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV]; + link->dpcd_caps.lttpr_caps.alpm.raw = + lttpr_dpcd_data[DP_LTTPR_ALPM_CAPABILITIES - + DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV]; + /* If this chip cap is set, at least one retimer must exist in the chain * Override count to 1 if we receive a known bad count (0 or an invalid value) */ if (((link->chip_caps & AMD_EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK) == AMD_EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && -- cgit v1.2.3 From e619ac419174fdb6093b9e78b41bb5d0a97de9dd Mon Sep 17 00:00:00 2001 From: Oleh Kuzhylnyi Date: Tue, 4 Feb 2025 19:33:00 +0100 Subject: drm/amd/display: Add total_num_dpps_required field to informative structure [Why] The informative structure needs to be extended by the total number of DPPs required per each active plane. The new informative field is going to be used as a statistical indicator. [How] The dml2_core_calcs_get_informative() routine must count a total number of DPPs. Reviewed-by: Austin Zheng Signed-off-by: Oleh Kuzhylnyi Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_types.h | 4 ++++ .../amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 19bce4084382..0dbf886d8926 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 @@ -453,6 +453,10 @@ struct dml2_display_cfg_programming { unsigned int meta_row_height_plane1; } plane_info[DML2_MAX_PLANES]; + struct { + unsigned int total_num_dpps_required; + } dpp; + struct { unsigned long long total_surface_size_in_mall_bytes; unsigned int subviewport_lines_needed_in_mall[DML2_MAX_PLANES]; 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 87e53f59cb9f..78c93a502518 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 @@ -13147,8 +13147,11 @@ void dml2_core_calcs_get_informative(const struct dml2_core_internal_display_mod out->informative.watermarks.temp_read_or_ppt_watermark_us = dml_get_wm_temp_read_or_ppt(mode_lib); out->informative.mall.total_surface_size_in_mall_bytes = 0; - for (k = 0; k < out->display_config.num_planes; ++k) + out->informative.dpp.total_num_dpps_required = 0; + for (k = 0; k < out->display_config.num_planes; ++k) { out->informative.mall.total_surface_size_in_mall_bytes += mode_lib->mp.SurfaceSizeInTheMALL[k]; + out->informative.dpp.total_num_dpps_required += mode_lib->mp.NoOfDPP[k]; + } out->informative.qos.min_return_latency_in_dcfclk = mode_lib->mp.min_return_latency_in_dcfclk; out->informative.qos.urgent_latency_us = dml_get_urgent_latency(mode_lib); -- cgit v1.2.3 From 9856893f754435c8f78e0a2e03716bac680b4bf4 Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Fri, 24 Jan 2025 16:10:57 -0500 Subject: drm/amd/display: Add log for MALL entry on DCN32x [Why&How] Add a dyndbg log entry to check whether the driver requested scanout from MALL cache to PMFW via DMCUB Reviewed-by: Zaeem Mohamed Reviewed-by: Roman Li Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/amd/display/dc') 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 dd46db67d033..cd0adf72b223 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 @@ -316,10 +316,12 @@ bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable) cmd.cab.cab_alloc_ways = (uint8_t)ways; dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT); + DC_LOG_MALL("enable scanout from MALL"); return true; } + DC_LOG_MALL("surface cannot fit in CAB, disabling scanout from MALL\n"); return false; } -- cgit v1.2.3 From 07bc2dcbcf403d47d6f305ef7f0d3d489491c5fb Mon Sep 17 00:00:00 2001 From: Ilya Bakoulin Date: Wed, 29 Jan 2025 14:46:27 -0500 Subject: drm/amd/display: Fix BT2020 YCbCr limited/full range input [Why] BT2020 YCbCr input is not handled properly when full range quantization is used and limited range is not supported at all. [How] - Add enums for BT2020 YCbCr limited/full range - Add limited range CSC matrix Reviewed-by: Krunoslav Kovac Signed-off-by: Ilya Bakoulin Signed-off-by: Roman Li Tested-by: Robert Mader Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/basics/dc_common.c | 3 ++- drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 5 +++-- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 4 ++-- drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 4 +++- drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c | 3 ++- drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_stream_encoder.c | 3 ++- .../gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.c | 3 ++- .../gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.c | 3 ++- drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h | 6 +++++- 9 files changed, 23 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/basics/dc_common.c b/drivers/gpu/drm/amd/display/dc/basics/dc_common.c index b2fc4f8e6482..a51c2701da24 100644 --- a/drivers/gpu/drm/amd/display/dc/basics/dc_common.c +++ b/drivers/gpu/drm/amd/display/dc/basics/dc_common.c @@ -40,7 +40,8 @@ bool is_rgb_cspace(enum dc_color_space output_color_space) case COLOR_SPACE_YCBCR709: case COLOR_SPACE_YCBCR601_LIMITED: case COLOR_SPACE_YCBCR709_LIMITED: - case COLOR_SPACE_2020_YCBCR: + case COLOR_SPACE_2020_YCBCR_LIMITED: + case COLOR_SPACE_2020_YCBCR_FULL: return false; default: /* Add a case to switch */ 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 6eb9bae3af91..6b514fd03f16 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 @@ -176,7 +176,7 @@ static bool is_ycbcr2020_type( { bool ret = false; - if (color_space == COLOR_SPACE_2020_YCBCR) + if (color_space == COLOR_SPACE_2020_YCBCR_LIMITED || color_space == COLOR_SPACE_2020_YCBCR_FULL) ret = true; return ret; } @@ -247,7 +247,8 @@ void color_space_to_black_color( case COLOR_SPACE_YCBCR709_BLACK: case COLOR_SPACE_YCBCR601_LIMITED: case COLOR_SPACE_YCBCR709_LIMITED: - case COLOR_SPACE_2020_YCBCR: + case COLOR_SPACE_2020_YCBCR_LIMITED: + case COLOR_SPACE_2020_YCBCR_FULL: *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV]; break; 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 e6bc479497e8..7eb91612b60d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -4488,7 +4488,7 @@ static void set_avi_info_frame( break; case COLOR_SPACE_2020_RGB_FULLRANGE: case COLOR_SPACE_2020_RGB_LIMITEDRANGE: - case COLOR_SPACE_2020_YCBCR: + case COLOR_SPACE_2020_YCBCR_LIMITED: hdmi_info.bits.EC0_EC2 = COLORIMETRYEX_BT2020RGBYCBCR; hdmi_info.bits.C0_C1 = COLORIMETRY_EXTENDED; break; @@ -4502,7 +4502,7 @@ static void set_avi_info_frame( break; } - if (pixel_encoding && color_space == COLOR_SPACE_2020_YCBCR && + if (pixel_encoding && color_space == COLOR_SPACE_2020_YCBCR_LIMITED && stream->out_transfer_func.tf == TRANSFER_FUNCTION_GAMMA22) { hdmi_info.bits.EC0_EC2 = 0; hdmi_info.bits.C0_C1 = COLORIMETRY_ITU709; 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 5ac55601a6da..9f3dd8824ed5 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -653,7 +653,8 @@ enum dc_color_space { COLOR_SPACE_YCBCR709_LIMITED, COLOR_SPACE_2020_RGB_FULLRANGE, COLOR_SPACE_2020_RGB_LIMITEDRANGE, - COLOR_SPACE_2020_YCBCR, + COLOR_SPACE_2020_YCBCR_LIMITED, + COLOR_SPACE_2020_YCBCR_FULL, COLOR_SPACE_ADOBERGB, COLOR_SPACE_DCIP3, COLOR_SPACE_DISPLAYNATIVE, @@ -661,6 +662,7 @@ enum dc_color_space { COLOR_SPACE_APPCTRL, COLOR_SPACE_CUSTOMPOINTS, COLOR_SPACE_YCBCR709_BLACK, + COLOR_SPACE_2020_YCBCR = COLOR_SPACE_2020_YCBCR_LIMITED, }; enum dc_dither_option { diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c index d199e4ed2e59..1130d7619b26 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c @@ -418,7 +418,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute( dynamic_range_rgb = 1; /*limited range*/ break; case COLOR_SPACE_2020_RGB_FULLRANGE: - case COLOR_SPACE_2020_YCBCR: + case COLOR_SPACE_2020_YCBCR_LIMITED: case COLOR_SPACE_XR_RGB: case COLOR_SPACE_MSREF_SCRGB: case COLOR_SPACE_ADOBERGB: @@ -430,6 +430,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute( case COLOR_SPACE_APPCTRL: case COLOR_SPACE_CUSTOMPOINTS: case COLOR_SPACE_UNKNOWN: + default: /* do nothing */ break; } diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_stream_encoder.c index d01a8b8f9595..22e66b375a7f 100644 --- a/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_stream_encoder.c @@ -391,7 +391,7 @@ void enc1_stream_encoder_dp_set_stream_attribute( break; case COLOR_SPACE_2020_RGB_LIMITEDRANGE: case COLOR_SPACE_2020_RGB_FULLRANGE: - case COLOR_SPACE_2020_YCBCR: + case COLOR_SPACE_2020_YCBCR_LIMITED: case COLOR_SPACE_XR_RGB: case COLOR_SPACE_MSREF_SCRGB: case COLOR_SPACE_ADOBERGB: @@ -404,6 +404,7 @@ void enc1_stream_encoder_dp_set_stream_attribute( case COLOR_SPACE_CUSTOMPOINTS: case COLOR_SPACE_UNKNOWN: case COLOR_SPACE_YCBCR709_BLACK: + default: /* do nothing */ break; } diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.c index 334fb5e2c003..4bab180e1938 100644 --- a/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.c @@ -632,7 +632,7 @@ void enc401_stream_encoder_dp_set_stream_attribute( break; case COLOR_SPACE_2020_RGB_LIMITEDRANGE: case COLOR_SPACE_2020_RGB_FULLRANGE: - case COLOR_SPACE_2020_YCBCR: + case COLOR_SPACE_2020_YCBCR_LIMITED: case COLOR_SPACE_XR_RGB: case COLOR_SPACE_MSREF_SCRGB: case COLOR_SPACE_ADOBERGB: @@ -645,6 +645,7 @@ void enc401_stream_encoder_dp_set_stream_attribute( case COLOR_SPACE_CUSTOMPOINTS: case COLOR_SPACE_UNKNOWN: case COLOR_SPACE_YCBCR709_BLACK: + default: /* do nothing */ break; } diff --git a/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.c index 678db949cfe3..759b453385c4 100644 --- a/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.c @@ -323,7 +323,7 @@ static void dcn31_hpo_dp_stream_enc_set_stream_attribute( break; case COLOR_SPACE_2020_RGB_LIMITEDRANGE: case COLOR_SPACE_2020_RGB_FULLRANGE: - case COLOR_SPACE_2020_YCBCR: + case COLOR_SPACE_2020_YCBCR_LIMITED: case COLOR_SPACE_XR_RGB: case COLOR_SPACE_MSREF_SCRGB: case COLOR_SPACE_ADOBERGB: @@ -336,6 +336,7 @@ static void dcn31_hpo_dp_stream_enc_set_stream_attribute( case COLOR_SPACE_CUSTOMPOINTS: case COLOR_SPACE_UNKNOWN: case COLOR_SPACE_YCBCR709_BLACK: + default: /* do nothing */ break; } diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h index 0150f2581ee4..0c5675d1c593 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h @@ -119,10 +119,14 @@ static const struct dpp_input_csc_matrix __maybe_unused dpp_input_csc_matrix[] = { 0x39a6, 0x2568, 0, 0xe0d6, 0xeedd, 0x2568, 0xf925, 0x9a8, 0, 0x2568, 0x43ee, 0xdbb2 } }, - { COLOR_SPACE_2020_YCBCR, + { COLOR_SPACE_2020_YCBCR_FULL, { 0x2F30, 0x2000, 0, 0xE869, 0xEDB7, 0x2000, 0xFABC, 0xBC6, 0, 0x2000, 0x3C34, 0xE1E6 } }, + { COLOR_SPACE_2020_YCBCR_LIMITED, + { 0x35B9, 0x2543, 0, 0xE2B2, + 0xEB2F, 0x2543, 0xFA01, 0x0B1F, + 0, 0x2543, 0x4489, 0xDB42 } }, { COLOR_SPACE_2020_RGB_LIMITEDRANGE, { 0x35E0, 0x255F, 0, 0xE2B3, 0xEB20, 0x255F, 0xF9FD, 0xB1E, -- cgit v1.2.3 From 72d7a7fa1f2404fd31c84a8f808b1b37021a3a9e Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Mon, 3 Feb 2025 09:49:58 -0500 Subject: drm/amd/display: Guard against setting dispclk low when active [Why] We should never apply a minimum dispclk value while in prepare_bandwidth or while displays are active. This is always an optimization for when all displays are disabled. [How] Defer dispclk optimization until safe_to_lower = true and display_count reaches 0. Since 0 has a special value in this logic (ie. no dispclk required) we also need adjust the logic that clamps it for the actual request to PMFW. Reviewed-by: Gabe Teeger Reviewed-by: Leo Chen Reviewed-by: Syed Hassan Signed-off-by: Nicholas Kazlauskas Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 56800c573a71..df29d28d89c9 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 @@ -467,14 +467,19 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base, update_dppclk = true; } - if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { + if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz) && + (new_clocks->dispclk_khz > 0 || (safe_to_lower && display_count == 0))) { + int requested_dispclk_khz = new_clocks->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; + /* Clamp the requested clock to PMFW based on their limit. */ + if (dc->debug.min_disp_clk_khz > 0 && requested_dispclk_khz < dc->debug.min_disp_clk_khz) + requested_dispclk_khz = dc->debug.min_disp_clk_khz; + dcn35_smu_set_dispclk(clk_mgr, requested_dispclk_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); update_dispclk = true; -- cgit v1.2.3 From 73e686939cb9152751791e518172c37eb31668d6 Mon Sep 17 00:00:00 2001 From: Peichen Huang Date: Tue, 4 Feb 2025 16:00:40 +0800 Subject: drm/amd/display: dpia should avoid encoder used by dp2 [WHY] In current HPO DP2 implementation, driver would enable/disable DIG encoder when configuring HPO DP2. Therefore, usb4 dp tunnelling should not use the DIG encoder if the corresponded phy is used by a HPO DP2 stream. [HOW] A DP2 stream is treated as a dig stream. Reviewed-by: Meenakshikumar Somasundaram Signed-off-by: Peichen Huang Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c index 08b4258b0e2f..814f68d76257 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c @@ -44,20 +44,8 @@ static bool is_dig_link_enc_stream(struct dc_stream_state *stream) * yet match. */ if (link_enc && ((uint32_t)stream->link->connector_signal & link_enc->output_signals)) { - if (dc_is_dp_signal(stream->signal)) { - /* DIGs do not support DP2.0 streams with 128b/132b encoding. */ - struct dc_link_settings link_settings = {0}; - - stream->ctx->dc->link_srv->dp_decide_link_settings(stream, &link_settings); - if ((link_settings.link_rate >= LINK_RATE_LOW) && - link_settings.link_rate <= LINK_RATE_HIGH3) { - is_dig_stream = true; - break; - } - } else { - is_dig_stream = true; - break; - } + is_dig_stream = true; + break; } } } -- cgit v1.2.3 From 6571bef25fe48c642f7a69ccf7c3198b317c136a Mon Sep 17 00:00:00 2001 From: Harry VanZyllDeJong Date: Fri, 7 Feb 2025 13:46:53 -0500 Subject: drm/amd/display: Add support for disconnected eDP streams [Why] eDP may not be connected to the GPU on driver start causing fail enumeration. [How] Move the virtual signal type check before the eDP connector signal check. Reviewed-by: Wenjing Liu Signed-off-by: Harry VanZyllDeJong Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') 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 80439224acca..e3e7fcb07f19 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 @@ -945,6 +945,9 @@ bool link_decide_link_settings(struct dc_stream_state *stream, * TODO: add MST specific link training routine */ decide_mst_link_settings(link, link_setting); + } else if (stream->signal == SIGNAL_TYPE_VIRTUAL) { + link_setting->lane_count = LANE_COUNT_FOUR; + link_setting->link_rate = LINK_RATE_HIGH3; } else if (link->connector_signal == SIGNAL_TYPE_EDP) { /* enable edp link optimization for DSC eDP case */ if (stream->timing.flags.DSC) { @@ -967,9 +970,6 @@ bool link_decide_link_settings(struct dc_stream_state *stream, } else { edp_decide_link_settings(link, link_setting, req_bw); } - } else if (stream->signal == SIGNAL_TYPE_VIRTUAL) { - link_setting->lane_count = LANE_COUNT_FOUR; - link_setting->link_rate = LINK_RATE_HIGH3; } else { decide_dp_link_settings(link, link_setting, req_bw); } -- cgit v1.2.3 From 71e59a426845a033cf782652c36cb733296917b8 Mon Sep 17 00:00:00 2001 From: Taimur Hassan Date: Sun, 9 Feb 2025 19:10:14 -0500 Subject: drm/amd/display: 3.2.321 Summary: * Add support for disconnected eDP streams * Add log for MALL entry on DCN32x * Add DCC/Tiling reset helper for DCN and DCE * Guard against setting dispclk low when active * Other minor fixes Reviewed-by: Aurabindo Pillai Signed-off-by: Taimur Hassan Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index ab88ce02893e..5e96913bcab1 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -53,7 +53,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.320" +#define DC_VER "3.2.321" /** * MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC -- cgit v1.2.3 From 3f670b745d6144dc97db8ed65ec6b2eb315b0006 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Tue, 4 Feb 2025 08:59:35 -0700 Subject: drm/amd/display: Add clear DCC and Tiling callback for DCE Introduce the DCC and Tiling reset callback to all DCE versions that can call it. Reviewed-by: Alvin Lee Signed-off-by: Rodrigo Siqueira Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 18 ++---------------- .../gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c | 1 + .../gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.c | 1 + .../gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 2 ++ .../gpu/drm/amd/display/dc/hwss/dce120/dce120_hwseq.c | 2 ++ .../gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.c | 1 + 6 files changed, 9 insertions(+), 16 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c index 691b4a68d8ac..e6fcc21bb9bc 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c @@ -290,21 +290,7 @@ void dc_plane_force_dcc_and_tiling_disable(struct dc_plane_state *plane_state, if (!pipe_ctx) continue; - if (dc->ctx->dce_version >= DCE_VERSION_MAX) { - if (dc->hwss.clear_surface_dcc_and_tiling) - dc->hwss.clear_surface_dcc_and_tiling(pipe_ctx, plane_state, clear_tiling); - } else { - struct mem_input *mi = pipe_ctx->plane_res.mi; - if (!mi) - continue; - /* if framebuffer is tiled, disable tiling */ - if (clear_tiling && mi->funcs->mem_input_clear_tiling) - mi->funcs->mem_input_clear_tiling(mi); - - /* force page flip to see the new content of the framebuffer */ - mi->funcs->mem_input_program_surface_flip_and_addr(mi, - &plane_state->address, - true); - } + if (dc->hwss.clear_surface_dcc_and_tiling) + dc->hwss.clear_surface_dcc_and_tiling(pipe_ctx, plane_state, clear_tiling); } } diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c index 1fdeef47e4dc..44b56490e152 100644 --- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c @@ -428,5 +428,6 @@ void dce60_hw_sequencer_construct(struct dc *dc) dc->hwss.pipe_control_lock = dce60_pipe_control_lock; dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth; dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth; + dc->hwss.clear_surface_dcc_and_tiling = dce100_reset_surface_dcc_and_tiling; } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.c index b76350a9cf5f..0d7e28260db1 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dce100/dce100_hwseq.c @@ -138,6 +138,7 @@ void dce100_hw_sequencer_construct(struct dc *dc) dc->hwseq->funcs.enable_display_power_gating = dce100_enable_display_power_gating; dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth; dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth; + dc->hwss.clear_surface_dcc_and_tiling = dce100_reset_surface_dcc_and_tiling; } /** 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 935d08d3a670..8280e3652171 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 @@ -33,6 +33,7 @@ #include "dce110_hwseq.h" #include "dce110/dce110_timing_generator.h" #include "dce/dce_hwseq.h" +#include "dce100/dce100_hwseq.h" #include "gpio_service_interface.h" #include "dce110/dce110_compressor.h" @@ -3332,6 +3333,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { .post_unlock_program_front_end = dce110_post_unlock_program_front_end, .update_plane_addr = update_plane_addr, .update_pending_status = dce110_update_pending_status, + .clear_surface_dcc_and_tiling = dce100_reset_surface_dcc_and_tiling, .enable_accelerated_mode = dce110_enable_accelerated_mode, .enable_timing_synchronization = dce110_enable_timing_synchronization, .enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset, diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce120/dce120_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce120/dce120_hwseq.c index 22ee304ef9cf..2a62f63d0357 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dce120/dce120_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dce120/dce120_hwseq.c @@ -29,6 +29,7 @@ #include "dce120_hwseq.h" #include "dce/dce_hwseq.h" +#include "dce100/dce100_hwseq.h" #include "dce110/dce110_hwseq.h" #include "dce/dce_12_0_offset.h" @@ -264,5 +265,6 @@ void dce120_hw_sequencer_construct(struct dc *dc) dce110_hw_sequencer_construct(dc); dc->hwseq->funcs.enable_display_power_gating = dce120_enable_display_power_gating; dc->hwss.update_dchub = dce120_update_dchub; + dc->hwss.clear_surface_dcc_and_tiling = dce100_reset_surface_dcc_and_tiling; } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.c index 0a054e880801..76fd45550c5e 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.c @@ -50,5 +50,6 @@ void dce80_hw_sequencer_construct(struct dc *dc) dc->hwss.pipe_control_lock = dce_pipe_control_lock; dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth; dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth; + dc->hwss.clear_surface_dcc_and_tiling = dce100_reset_surface_dcc_and_tiling; } -- cgit v1.2.3