diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2513-drm-amd-display-Restructuring-and-cleaning-up-DML.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2513-drm-amd-display-Restructuring-and-cleaning-up-DML.patch | 15456 |
1 files changed, 15456 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2513-drm-amd-display-Restructuring-and-cleaning-up-DML.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2513-drm-amd-display-Restructuring-and-cleaning-up-DML.patch new file mode 100644 index 00000000..37d95acf --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2513-drm-amd-display-Restructuring-and-cleaning-up-DML.patch @@ -0,0 +1,15456 @@ +From a4b6aa038974d036952e16f7fc2c04e8900e419b Mon Sep 17 00:00:00 2001 +From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Date: Wed, 23 Aug 2017 16:43:17 -0400 +Subject: [PATCH 2513/4131] drm/amd/display: Restructuring and cleaning up DML + +Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> +Acked-by: Harry Wentland <Harry.Wentland@amd.com> +--- + .../gpu/drm/amd/display/dc/calcs/dcn_calc_math.c | 16 + + drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 103 +- + drivers/gpu/drm/amd/display/dc/dc.h | 1 - + .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 5 +- + drivers/gpu/drm/amd/display/dc/dml/Makefile | 8 +- + drivers/gpu/drm/amd/display/dc/dml/dc_features.h | 2 + + .../drm/amd/display/dc/dml/display_mode_enums.h | 52 +- + .../gpu/drm/amd/display/dc/dml/display_mode_lib.c | 7 +- + .../gpu/drm/amd/display/dc/dml/display_mode_lib.h | 8 +- + .../drm/amd/display/dc/dml/display_mode_structs.h | 898 +++--- + .../drm/amd/display/dc/dml/display_mode_support.c | 2326 -------------- + .../drm/amd/display/dc/dml/display_mode_support.h | 199 -- + .../gpu/drm/amd/display/dc/dml/display_mode_vba.c | 3263 ++++++++++++++++++++ + .../gpu/drm/amd/display/dc/dml/display_mode_vba.h | 410 +++ + .../drm/amd/display/dc/dml/display_pipe_clocks.c | 377 +-- + .../drm/amd/display/dc/dml/display_pipe_clocks.h | 8 +- + .../drm/amd/display/dc/dml/display_rq_dlg_calc.c | 2457 ++++++--------- + .../drm/amd/display/dc/dml/display_rq_dlg_calc.h | 151 +- + .../amd/display/dc/dml/display_rq_dlg_helpers.c | 482 +-- + .../amd/display/dc/dml/display_rq_dlg_helpers.h | 41 +- + .../gpu/drm/amd/display/dc/dml/display_watermark.c | 1281 -------- + .../gpu/drm/amd/display/dc/dml/display_watermark.h | 98 - + .../amd/display/dc/dml/dml1_display_rq_dlg_calc.c | 1903 ++++++++++++ + .../amd/display/dc/dml/dml1_display_rq_dlg_calc.h | 67 + + .../gpu/drm/amd/display/dc/dml/dml_common_defs.c | 12 +- + .../gpu/drm/amd/display/dc/dml/dml_common_defs.h | 8 +- + .../gpu/drm/amd/display/dc/dml/soc_bounding_box.c | 48 +- + .../gpu/drm/amd/display/dc/dml/soc_bounding_box.h | 9 +- + 28 files changed, 7658 insertions(+), 6582 deletions(-) + delete mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c + delete mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h + create mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c + create mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h + delete mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_watermark.c + delete mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_watermark.h + create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c + create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h + +diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c +index a184744..b6abe0f 100644 +--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c ++++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c +@@ -27,20 +27,36 @@ + + float dcn_bw_mod(const float arg1, const float arg2) + { ++ if (arg1 != arg1) ++ return arg2; ++ if (arg2 != arg2) ++ return arg1; + return arg1 - arg1 * ((int) (arg1 / arg2)); + } + + float dcn_bw_min2(const float arg1, const float arg2) + { ++ if (arg1 != arg1) ++ return arg2; ++ if (arg2 != arg2) ++ return arg1; + return arg1 < arg2 ? arg1 : arg2; + } + + unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2) + { ++ if (arg1 != arg1) ++ return arg2; ++ if (arg2 != arg2) ++ return arg1; + return arg1 > arg2 ? arg1 : arg2; + } + float dcn_bw_max2(const float arg1, const float arg2) + { ++ if (arg1 != arg1) ++ return arg2; ++ if (arg2 != arg2) ++ return arg1; + return arg1 > arg2 ? arg1 : arg2; + } + +diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +index 6318f9f..fd1db8d 100644 +--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c ++++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +@@ -386,10 +386,6 @@ static void pipe_ctx_to_e2e_pipe_params ( + - pipe->stream->timing.v_addressable + - pipe->stream->timing.v_border_bottom + - pipe->stream->timing.v_border_top; +- +- input->dest.vsync_plus_back_porch = pipe->stream->timing.v_total +- - pipe->stream->timing.v_addressable +- - pipe->stream->timing.v_front_porch; + input->dest.pixel_rate_mhz = pipe->stream->timing.pix_clk_khz/1000.0; + input->dest.vstartup_start = pipe->pipe_dlg_param.vstartup_start; + input->dest.vupdate_offset = pipe->pipe_dlg_param.vupdate_offset; +@@ -459,9 +455,9 @@ static void dcn_bw_calc_rq_dlg_ttu( + /*todo: soc->sr_enter_plus_exit_time??*/ + dlg_sys_param.t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / v->dcf_clk_deep_sleep; + +- dml_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src); +- extract_rq_regs(dml, rq_regs, rq_param); +- dml_rq_dlg_get_dlg_params( ++ dml1_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src); ++ dml1_extract_rq_regs(dml, rq_regs, rq_param); ++ dml1_rq_dlg_get_dlg_params( + dml, + dlg_regs, + ttu_regs, +@@ -474,96 +470,6 @@ static void dcn_bw_calc_rq_dlg_ttu( + pipe->plane_state->flip_immediate); + } + +-static void dcn_dml_wm_override( +- const struct dcn_bw_internal_vars *v, +- struct display_mode_lib *dml, +- struct dc_state *context, +- const struct resource_pool *pool) +-{ +- int i, in_idx, active_count; +- +- struct _vcs_dpi_display_e2e_pipe_params_st *input = kzalloc(pool->pipe_count * sizeof(struct _vcs_dpi_display_e2e_pipe_params_st), +- GFP_KERNEL); +- struct wm { +- double urgent; +- struct _vcs_dpi_cstate_pstate_watermarks_st cpstate; +- double pte_meta_urgent; +- } a; +- +- +- for (i = 0, in_idx = 0; i < pool->pipe_count; i++) { +- struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; +- +- if (!pipe->stream || !pipe->plane_state) +- continue; +- +- input[in_idx].clks_cfg.dcfclk_mhz = v->dcfclk; +- input[in_idx].clks_cfg.dispclk_mhz = v->dispclk; +- input[in_idx].clks_cfg.dppclk_mhz = v->dppclk; +- input[in_idx].clks_cfg.refclk_mhz = pool->ref_clock_inKhz / 1000; +- input[in_idx].clks_cfg.socclk_mhz = v->socclk; +- input[in_idx].clks_cfg.voltage = v->voltage_level; +- input[in_idx].dout.output_format = (v->output_format[in_idx] == dcn_bw_420) ? dm_420 : dm_444; +- input[in_idx].dout.output_type = (v->output[in_idx] == dcn_bw_hdmi) ? dm_hdmi : dm_dp; +- //input[in_idx].dout.output_standard; +- switch (v->output_deep_color[in_idx]) { +- case dcn_bw_encoder_12bpc: +- input[in_idx].dout.output_bpc = dm_out_12; +- break; +- case dcn_bw_encoder_10bpc: +- input[in_idx].dout.output_bpc = dm_out_10; +- break; +- case dcn_bw_encoder_8bpc: +- default: +- input[in_idx].dout.output_bpc = dm_out_8; +- break; +- } +- pipe_ctx_to_e2e_pipe_params(pipe, &input[in_idx].pipe); +- dml_rq_dlg_get_rq_reg( +- dml, +- &pipe->rq_regs, +- input[in_idx].pipe.src); +- in_idx++; +- } +- active_count = in_idx; +- +- a.urgent = dml_wm_urgent_e2e(dml, input, active_count); +- a.cpstate = dml_wm_cstate_pstate_e2e(dml, input, active_count); +- a.pte_meta_urgent = dml_wm_pte_meta_urgent(dml, a.urgent); +- +- context->bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = +- a.cpstate.cstate_exit_us * 1000; +- context->bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = +- a.cpstate.cstate_enter_plus_exit_us * 1000; +- context->bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = +- a.cpstate.pstate_change_us * 1000; +- context->bw.dcn.watermarks.a.pte_meta_urgent_ns = a.pte_meta_urgent * 1000; +- context->bw.dcn.watermarks.a.urgent_ns = a.urgent * 1000; +- context->bw.dcn.watermarks.b = context->bw.dcn.watermarks.a; +- context->bw.dcn.watermarks.c = context->bw.dcn.watermarks.a; +- context->bw.dcn.watermarks.d = context->bw.dcn.watermarks.a; +- +- +- for (i = 0, in_idx = 0; i < pool->pipe_count; i++) { +- struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; +- +- if (!pipe->stream || !pipe->plane_state) +- continue; +- +- dml_rq_dlg_get_dlg_reg(dml, +- &pipe->dlg_regs, +- &pipe->ttu_regs, +- input, active_count, +- in_idx, +- true, +- true, +- v->pte_enable == dcn_bw_yes, +- pipe->plane_state->flip_immediate); +- in_idx++; +- } +- kfree(input); +-} +- + static void split_stream_across_pipes( + struct resource_context *res_ctx, + const struct resource_pool *pool, +@@ -1163,9 +1069,6 @@ bool dcn_validate_bandwidth( + + input_idx++; + } +- if (dc->debug.use_dml_wm) +- dcn_dml_wm_override(v, (struct display_mode_lib *) +- &dc->dml, context, pool); + } + + if (v->voltage_level == 0) { +diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h +index bfa468d..72440e3 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc.h ++++ b/drivers/gpu/drm/amd/display/dc/dc.h +@@ -200,7 +200,6 @@ struct dc_debug { + bool disable_hubp_power_gate; + bool disable_pplib_wm_range; + enum wm_report_mode pplib_wm_report_mode; +- bool use_dml_wm; + unsigned int min_disp_clk_khz; + int sr_exit_time_dpm0_ns; + int sr_enter_plus_exit_time_dpm0_ns; +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +index a9bb927..cf3a283 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +@@ -425,8 +425,6 @@ static const struct dc_debug debug_defaults_drv = { + .disable_pplib_clock_request = true, + .disable_pplib_wm_range = false, + .pplib_wm_report_mode = WM_REPORT_DEFAULT, +- .use_dml_wm = false, +- + .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, + .disable_dcc = DCC_ENABLE, + .voltage_align_fclk = true, +@@ -439,8 +437,7 @@ static const struct dc_debug debug_defaults_diags = { + .clock_trace = true, + .disable_stutter = true, + .disable_pplib_clock_request = true, +- .disable_pplib_wm_range = true, +- .use_dml_wm = false, ++ .disable_pplib_wm_range = true + }; + + static void dcn10_dpp_destroy(struct transform **xfm) +diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile +index 9d7791d..c6d9d95 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile ++++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile +@@ -3,19 +3,19 @@ + # It provides the general basic services required by other DAL + # subcomponents. + ++CFLAGS_display_mode_vba.o := -mhard-float -msse -mpreferred-stack-boundary=4 + CFLAGS_display_mode_lib.o := -mhard-float -msse -mpreferred-stack-boundary=4 + CFLAGS_display_pipe_clocks.o := -mhard-float -msse -mpreferred-stack-boundary=4 + CFLAGS_display_rq_dlg_calc.o := -mhard-float -msse -mpreferred-stack-boundary=4 ++CFLAGS_dml1_display_rq_dlg_calc.o := -mhard-float -msse -mpreferred-stack-boundary=4 + CFLAGS_display_rq_dlg_helpers.o := -mhard-float -msse -mpreferred-stack-boundary=4 +-CFLAGS_display_watermark.o := -mhard-float -msse -mpreferred-stack-boundary=4 + CFLAGS_soc_bounding_box.o := -mhard-float -msse -mpreferred-stack-boundary=4 + CFLAGS_dml_common_defs.o := -mhard-float -msse -mpreferred-stack-boundary=4 +-CFLAGS_display_mode_support.o := -mhard-float -msse -mpreferred-stack-boundary=4 + + + DML = display_mode_lib.o display_pipe_clocks.o display_rq_dlg_calc.o \ +- display_rq_dlg_helpers.o display_watermark.o \ +- soc_bounding_box.o dml_common_defs.o display_mode_support.o ++ display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \ ++ soc_bounding_box.o dml_common_defs.o display_mode_vba.o + + AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML)) + +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h +index 745c04c..ea4cde9 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h ++++ b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h +@@ -25,9 +25,11 @@ + #ifndef __DC_FEATURES_H__ + #define __DC_FEATURES_H__ + ++// local features + #define DC__PRESENT 1 + #define DC__PRESENT__1 1 + #define DC__NUM_DPP 4 ++#define DC__VOLTAGE_STATES 7 + #define DC__NUM_DPP__4 1 + #define DC__NUM_DPP__0_PRESENT 1 + #define DC__NUM_DPP__1_PRESENT 1 +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h +index 143a3d4..eebaeb1 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h ++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h +@@ -24,14 +24,12 @@ + */ + #ifndef __DISPLAY_MODE_ENUMS_H__ + #define __DISPLAY_MODE_ENUMS_H__ ++ + enum output_encoder_class { +- dm_dp = 0, +- dm_hdmi = 1, +- dm_wb = 2 ++ dm_dp = 0, dm_hdmi = 1, dm_wb = 2 + }; + enum output_format_class { +- dm_444 = 0, +- dm_420 = 1 ++ dm_444 = 0, dm_420 = 1, dm_n422, dm_s422 + }; + enum source_format_class { + dm_444_16 = 0, +@@ -40,18 +38,14 @@ enum source_format_class { + dm_420_8 = 3, + dm_420_10 = 4, + dm_422_8 = 5, +- dm_422_10 = 6 ++ dm_422_10 = 6, ++ dm_444_8 = 7 + }; + enum output_bpc_class { +- dm_out_6 = 0, +- dm_out_8 = 1, +- dm_out_10 = 2, +- dm_out_12 = 3, +- dm_out_16 = 4 ++ dm_out_6 = 0, dm_out_8 = 1, dm_out_10 = 2, dm_out_12 = 3, dm_out_16 = 4 + }; + enum scan_direction_class { +- dm_horz = 0, +- dm_vert = 1 ++ dm_horz = 0, dm_vert = 1 + }; + enum dm_swizzle_mode { + dm_sw_linear = 0, +@@ -84,28 +78,30 @@ enum dm_swizzle_mode { + dm_sw_SPARE_14 = 27, + dm_sw_SPARE_15 = 28, + dm_sw_var_s_x = 29, +- dm_sw_var_d_x = 30 ++ dm_sw_var_d_x = 30, ++ dm_sw_64kb_r_x + }; + enum lb_depth { +- dm_lb_10 = 30, +- dm_lb_8 = 24, +- dm_lb_6 = 18, +- dm_lb_12 = 36 ++ dm_lb_10 = 0, dm_lb_8 = 1, dm_lb_6 = 2, dm_lb_12 = 3, dm_lb_16 + }; + enum voltage_state { +- dm_vmin = 0, +- dm_vmid = 1, +- dm_vnom = 2, +- dm_vmax = 3, +- dm_vmax_exceeded = 4 ++ dm_vmin = 0, dm_vmid = 1, dm_vnom = 2, dm_vmax = 3 + }; + enum source_macro_tile_size { +- dm_4k_tile = 0, +- dm_64k_tile = 1, +- dm_256k_tile = 2 ++ dm_4k_tile = 0, dm_64k_tile = 1, dm_256k_tile = 2 + }; + enum cursor_bpp { +- dm_cur_2bit = 0, +- dm_cur_32bit = 1 ++ dm_cur_2bit = 0, dm_cur_32bit = 1, dm_cur_64bit = 2 + }; ++enum clock_change_support { ++ dm_dram_clock_change_uninitialized = 0, ++ dm_dram_clock_change_vactive, ++ dm_dram_clock_change_vblank, ++ dm_dram_clock_change_unsupported ++}; ++ ++enum output_standard { ++ dm_std_uninitialized = 0, dm_std_cvtr2, dm_std_cvt ++}; ++ + #endif +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c +index c02c552..09d2328 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c +@@ -24,6 +24,7 @@ + */ + + #include "display_mode_lib.h" ++#include "dc_features.h" + + static void set_soc_bounding_box(struct _vcs_dpi_soc_bounding_box_st *soc, enum dml_project project) + { +@@ -128,11 +129,7 @@ static void set_ip_params(struct _vcs_dpi_ip_params_st *ip, enum dml_project pro + + static void set_mode_evaluation(struct _vcs_dpi_mode_evaluation_st *me, enum dml_project project) + { +- if (project == DML_PROJECT_RAVEN1) { +- me->voltage_override = dm_vmin; +- } else { +- BREAK_TO_DEBUGGER(); /* Invalid Project Specified */ +- } ++ me->voltage_override = dm_vmin; + } + + void dml_init_instance(struct display_mode_lib *lib, enum dml_project project) +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h +index e2e3111..57f49d2 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h ++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h +@@ -25,12 +25,13 @@ + #ifndef __DISPLAY_MODE_LIB_H__ + #define __DISPLAY_MODE_LIB_H__ + ++ + #include "dml_common_defs.h" + #include "soc_bounding_box.h" +-#include "display_watermark.h" ++#include "display_mode_vba.h" + #include "display_pipe_clocks.h" + #include "display_rq_dlg_calc.h" +-#include "display_mode_support.h" ++#include "dml1_display_rq_dlg_calc.h" + + enum dml_project { + DML_PROJECT_UNDEFINED, +@@ -42,8 +43,7 @@ struct display_mode_lib { + struct _vcs_dpi_soc_bounding_box_st soc; + struct _vcs_dpi_mode_evaluation_st me; + enum dml_project project; +- struct dml_ms_internal_vars vars; +- struct _vcs_dpi_wm_calc_pipe_params_st wm_param[DC__NUM_PIPES__MAX]; ++ struct vba_vars_st vba; + struct dal_logger *logger; + }; + +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +index e589a5e..e5b7f70 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h ++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +@@ -25,405 +25,531 @@ + #ifndef __DISPLAY_MODE_STRUCTS_H__ + #define __DISPLAY_MODE_STRUCTS_H__ + ++typedef struct _vcs_dpi_voltage_scaling_st voltage_scaling_st; ++typedef struct _vcs_dpi_soc_bounding_box_st soc_bounding_box_st; ++typedef struct _vcs_dpi_mode_evaluation_st mode_evaluation_st; ++typedef struct _vcs_dpi_ip_params_st ip_params_st; ++typedef struct _vcs_dpi_display_pipe_source_params_st display_pipe_source_params_st; ++typedef struct _vcs_dpi_display_output_params_st display_output_params_st; ++typedef struct _vcs_dpi_display_bandwidth_st display_bandwidth_st; ++typedef struct _vcs_dpi_scaler_ratio_depth_st scaler_ratio_depth_st; ++typedef struct _vcs_dpi_scaler_taps_st scaler_taps_st; ++typedef struct _vcs_dpi_display_pipe_dest_params_st display_pipe_dest_params_st; ++typedef struct _vcs_dpi_display_pipe_params_st display_pipe_params_st; ++typedef struct _vcs_dpi_display_clocks_and_cfg_st display_clocks_and_cfg_st; ++typedef struct _vcs_dpi_display_e2e_pipe_params_st display_e2e_pipe_params_st; ++typedef struct _vcs_dpi_dchub_buffer_sizing_st dchub_buffer_sizing_st; ++typedef struct _vcs_dpi_watermarks_perf_st watermarks_perf_st; ++typedef struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_watermarks_st; ++typedef struct _vcs_dpi_wm_calc_pipe_params_st wm_calc_pipe_params_st; ++typedef struct _vcs_dpi_vratio_pre_st vratio_pre_st; ++typedef struct _vcs_dpi_display_data_rq_misc_params_st display_data_rq_misc_params_st; ++typedef struct _vcs_dpi_display_data_rq_sizing_params_st display_data_rq_sizing_params_st; ++typedef struct _vcs_dpi_display_data_rq_dlg_params_st display_data_rq_dlg_params_st; ++typedef struct _vcs_dpi_display_cur_rq_dlg_params_st display_cur_rq_dlg_params_st; ++typedef struct _vcs_dpi_display_rq_dlg_params_st display_rq_dlg_params_st; ++typedef struct _vcs_dpi_display_rq_sizing_params_st display_rq_sizing_params_st; ++typedef struct _vcs_dpi_display_rq_misc_params_st display_rq_misc_params_st; ++typedef struct _vcs_dpi_display_rq_params_st display_rq_params_st; ++typedef struct _vcs_dpi_display_dlg_regs_st display_dlg_regs_st; ++typedef struct _vcs_dpi_display_ttu_regs_st display_ttu_regs_st; ++typedef struct _vcs_dpi_display_data_rq_regs_st display_data_rq_regs_st; ++typedef struct _vcs_dpi_display_rq_regs_st display_rq_regs_st; ++typedef struct _vcs_dpi_display_dlg_sys_params_st display_dlg_sys_params_st; ++typedef struct _vcs_dpi_display_dlg_prefetch_param_st display_dlg_prefetch_param_st; ++typedef struct _vcs_dpi_display_pipe_clock_st display_pipe_clock_st; ++typedef struct _vcs_dpi_display_arb_params_st display_arb_params_st; ++ ++struct _vcs_dpi_mode_evaluation_st { ++ int voltage_override; ++}; ++ + struct _vcs_dpi_voltage_scaling_st { ++ int state; + double dcfclk_mhz; ++ double socclk_mhz; ++ double dram_speed_mhz; ++ double fabricclk_mhz; + double dispclk_mhz; +- double dppclk_mhz; + double dram_bw_per_chan_gbps; + double phyclk_mhz; +- double socclk_mhz; ++ double dppclk_mhz; + }; + +-struct _vcs_dpi_soc_bounding_box_st { +- double sr_exit_time_us; +- double sr_enter_plus_exit_time_us; +- double urgent_latency_us; +- double writeback_latency_us; +- double ideal_dram_bw_after_urgent_percent; +- unsigned int max_request_size_bytes; +- struct _vcs_dpi_voltage_scaling_st vmin; +- struct _vcs_dpi_voltage_scaling_st vmid; +- struct _vcs_dpi_voltage_scaling_st vnom; +- struct _vcs_dpi_voltage_scaling_st vmax; +- double downspread_percent; +- double dram_page_open_time_ns; +- double dram_rw_turnaround_time_ns; +- double dram_return_buffer_per_channel_bytes; +- unsigned int round_trip_ping_latency_dcfclk_cycles; +- unsigned int urgent_out_of_order_return_per_channel_bytes; +- unsigned int channel_interleave_bytes; +- unsigned int num_banks; +- unsigned int num_chans; +- unsigned int vmm_page_size_bytes; +- double dram_clock_change_latency_us; +- double writeback_dram_clock_change_latency_us; +- unsigned int return_bus_width_bytes; +-}; +- +-struct _vcs_dpi_ip_params_st { +- unsigned int rob_buffer_size_kbytes; +- unsigned int det_buffer_size_kbytes; +- unsigned int dpte_buffer_size_in_pte_reqs; +- unsigned int dpp_output_buffer_pixels; +- unsigned int opp_output_buffer_lines; +- unsigned int pixel_chunk_size_kbytes; +- unsigned char pte_enable; +- unsigned int pte_chunk_size_kbytes; +- unsigned int meta_chunk_size_kbytes; +- unsigned int writeback_chunk_size_kbytes; +- unsigned int line_buffer_size_bits; +- unsigned int max_line_buffer_lines; ++struct _vcs_dpi_soc_bounding_box_st { ++ double sr_exit_time_us; ++ double sr_enter_plus_exit_time_us; ++ double urgent_latency_us; ++ double writeback_latency_us; ++ double ideal_dram_bw_after_urgent_percent; ++ unsigned int max_request_size_bytes; ++ struct _vcs_dpi_voltage_scaling_st vmin; ++ struct _vcs_dpi_voltage_scaling_st vmid; ++ struct _vcs_dpi_voltage_scaling_st vnom; ++ struct _vcs_dpi_voltage_scaling_st vmax; ++ double downspread_percent; ++ double dram_page_open_time_ns; ++ double dram_rw_turnaround_time_ns; ++ double dram_return_buffer_per_channel_bytes; ++ double dram_channel_width_bytes; ++ double fabric_datapath_to_dcn_data_return_bytes; ++ double dcn_downspread_percent; ++ double dispclk_dppclk_vco_speed_mhz; ++ unsigned int round_trip_ping_latency_dcfclk_cycles; ++ unsigned int urgent_out_of_order_return_per_channel_bytes; ++ unsigned int channel_interleave_bytes; ++ unsigned int num_banks; ++ unsigned int num_chans; ++ unsigned int vmm_page_size_bytes; ++ double dram_clock_change_latency_us; ++ double writeback_dram_clock_change_latency_us; ++ unsigned int return_bus_width_bytes; ++ double xfc_bus_transport_time_us; ++ double xfc_xbuf_latency_tolerance_us; ++ struct _vcs_dpi_voltage_scaling_st clock_limits[7]; ++}; ++ ++struct _vcs_dpi_ip_params_st { ++ unsigned int max_inter_dcn_tile_repeaters; ++ unsigned int num_dsc; ++ unsigned int odm_capable; ++ unsigned int rob_buffer_size_kbytes; ++ unsigned int det_buffer_size_kbytes; ++ unsigned int dpte_buffer_size_in_pte_reqs; ++ unsigned int pde_proc_buffer_size_64k_reqs; ++ unsigned int dpp_output_buffer_pixels; ++ unsigned int opp_output_buffer_lines; ++ unsigned int pixel_chunk_size_kbytes; ++ unsigned char pte_enable; ++ unsigned int pte_chunk_size_kbytes; ++ unsigned int meta_chunk_size_kbytes; ++ unsigned int writeback_chunk_size_kbytes; ++ unsigned int line_buffer_size_bits; ++ unsigned int max_line_buffer_lines; ++ unsigned int writeback_luma_buffer_size_kbytes; ++ unsigned int writeback_chroma_buffer_size_kbytes; ++ unsigned int writeback_chroma_line_buffer_width_pixels; ++ unsigned int max_page_table_levels; ++ unsigned int max_num_dpp; ++ unsigned int max_num_wb; ++ unsigned int max_dchub_pscl_bw_pix_per_clk; ++ unsigned int max_pscl_lb_bw_pix_per_clk; ++ unsigned int max_lb_vscl_bw_pix_per_clk; ++ unsigned int max_vscl_hscl_bw_pix_per_clk; ++ double max_hscl_ratio; ++ double max_vscl_ratio; ++ unsigned int hscl_mults; ++ unsigned int vscl_mults; ++ unsigned int max_hscl_taps; ++ unsigned int max_vscl_taps; ++ unsigned int xfc_supported; ++ unsigned int ptoi_supported; ++ unsigned int xfc_fill_constant_bytes; ++ double dispclk_ramp_margin_percent; ++ double xfc_fill_bw_overhead_percent; ++ double underscan_factor; ++ unsigned int min_vblank_lines; ++ unsigned int dppclk_delay_subtotal; ++ unsigned int dispclk_delay_subtotal; ++ unsigned int dcfclk_cstate_latency; ++ unsigned int dppclk_delay_scl; ++ unsigned int dppclk_delay_scl_lb_only; ++ unsigned int dppclk_delay_cnvc_formatter; ++ unsigned int dppclk_delay_cnvc_cursor; ++ unsigned int is_line_buffer_bpp_fixed; ++ unsigned int line_buffer_fixed_bpp; ++ unsigned int dcc_supported; ++ + unsigned int IsLineBufferBppFixed; + unsigned int LineBufferFixedBpp; +- unsigned int writeback_luma_buffer_size_kbytes; +- unsigned int writeback_chroma_buffer_size_kbytes; +- unsigned int max_num_dpp; +- unsigned int max_num_wb; +- unsigned int max_dchub_pscl_bw_pix_per_clk; +- unsigned int max_pscl_lb_bw_pix_per_clk; +- unsigned int max_lb_vscl_bw_pix_per_clk; +- unsigned int max_vscl_hscl_bw_pix_per_clk; +- double max_hscl_ratio; +- double max_vscl_ratio; +- unsigned int hscl_mults; +- unsigned int vscl_mults; +- unsigned int max_hscl_taps; +- unsigned int max_vscl_taps; +- double dispclk_ramp_margin_percent; +- double underscan_factor; +- unsigned int min_vblank_lines; +- unsigned int dppclk_delay_subtotal; +- unsigned int dispclk_delay_subtotal; +- unsigned int dcfclk_cstate_latency; +- unsigned int max_inter_dcn_tile_repeaters; + unsigned int can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one; + unsigned int bug_forcing_LC_req_same_size_fixed; + }; + +-struct _vcs_dpi_display_pipe_source_params_st { +- int source_format; +- unsigned char dcc; +- unsigned int dcc_rate; +- unsigned char vm; +- int source_scan; +- int sw_mode; +- int macro_tile_size; +- unsigned char is_display_sw; +- unsigned int viewport_width; +- unsigned int viewport_height; +- unsigned int viewport_width_c; +- unsigned int viewport_height_c; +- unsigned int data_pitch; +- unsigned int data_pitch_c; +- unsigned int meta_pitch; +- unsigned int meta_pitch_c; +- unsigned int cur0_src_width; +- int cur0_bpp; +- unsigned char is_hsplit; +- unsigned int hsplit_grp; +-}; +- +-struct _vcs_dpi_display_output_params_st { +- int output_bpc; +- int output_type; +- int output_format; +- int output_standard; +-}; +- +-struct _vcs_dpi_display_bandwidth_st { +- double total_bw_consumed_gbps; +- double guaranteed_urgent_return_bw_gbps; +-}; +- +-struct _vcs_dpi_scaler_ratio_depth_st { +- double hscl_ratio; +- double vscl_ratio; +- double hscl_ratio_c; +- double vscl_ratio_c; +- double vinit; +- double vinit_c; +- double vinit_bot; +- double vinit_bot_c; +- int lb_depth; +-}; +- +-struct _vcs_dpi_scaler_taps_st { +- unsigned int htaps; +- unsigned int vtaps; +- unsigned int htaps_c; +- unsigned int vtaps_c; +-}; +- +-struct _vcs_dpi_display_pipe_dest_params_st { +- unsigned int recout_width; +- unsigned int recout_height; +- unsigned int full_recout_width; +- unsigned int full_recout_height; +- unsigned int hblank_start; +- unsigned int hblank_end; +- unsigned int vblank_start; +- unsigned int vblank_end; +- unsigned int htotal; +- unsigned int vtotal; +- unsigned int vactive; +- unsigned int vstartup_start; +- unsigned int vupdate_offset; +- unsigned int vupdate_width; +- unsigned int vready_offset; +- unsigned int vsync_plus_back_porch; +- unsigned char interlaced; +- unsigned char underscan; +- double pixel_rate_mhz; +- unsigned char syncronized_vblank_all_planes; +-}; +- +-struct _vcs_dpi_display_pipe_params_st { +- struct _vcs_dpi_display_pipe_source_params_st src; +- struct _vcs_dpi_display_pipe_dest_params_st dest; +- struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth; +- struct _vcs_dpi_scaler_taps_st scale_taps; +-}; +- +-struct _vcs_dpi_display_clocks_and_cfg_st { +- int voltage; +- double dppclk_mhz; +- double refclk_mhz; +- double dispclk_mhz; +- double dcfclk_mhz; +- double socclk_mhz; +-}; +- +-struct _vcs_dpi_display_e2e_pipe_params_st { +- struct _vcs_dpi_display_pipe_params_st pipe; +- struct _vcs_dpi_display_output_params_st dout; +- struct _vcs_dpi_display_clocks_and_cfg_st clks_cfg; +-}; +- +-struct _vcs_dpi_dchub_buffer_sizing_st { +- unsigned int swath_width_y; +- unsigned int swath_height_y; +- unsigned int swath_height_c; +- unsigned int detail_buffer_size_y; +-}; +- +-struct _vcs_dpi_watermarks_perf_st { +- double stutter_eff_in_active_region_percent; +- double urgent_latency_supported_us; +- double non_urgent_latency_supported_us; +- double dram_clock_change_margin_us; +- double dram_access_eff_percent; +-}; +- +-struct _vcs_dpi_cstate_pstate_watermarks_st { +- double cstate_exit_us; +- double cstate_enter_plus_exit_us; +- double pstate_change_us; +-}; +- +-struct _vcs_dpi_wm_calc_pipe_params_st { +- unsigned int num_dpp; +- int voltage; +- int output_type; +- double dcfclk_mhz; +- double socclk_mhz; +- double dppclk_mhz; +- double pixclk_mhz; +- unsigned char interlace_en; +- unsigned char pte_enable; +- unsigned char dcc_enable; +- double dcc_rate; +- double bytes_per_pixel_c; +- double bytes_per_pixel_y; +- unsigned int swath_width_y; +- unsigned int swath_height_y; +- unsigned int swath_height_c; +- unsigned int det_buffer_size_y; +- double h_ratio; +- double v_ratio; +- unsigned int h_taps; +- unsigned int h_total; +- unsigned int v_total; +- unsigned int v_active; +- unsigned int e2e_index; +- double display_pipe_line_delivery_time; +- double read_bw; +- unsigned int lines_in_det_y; +- unsigned int lines_in_det_y_rounded_down_to_swath; +- double full_det_buffering_time; +- double dcfclk_deepsleep_mhz_per_plane; +-}; +- +-struct _vcs_dpi_vratio_pre_st { +- double vratio_pre_l; +- double vratio_pre_c; +-}; +- +-struct _vcs_dpi_display_data_rq_misc_params_st { +- unsigned int full_swath_bytes; +- unsigned int stored_swath_bytes; +- unsigned int blk256_height; +- unsigned int blk256_width; +- unsigned int req_height; +- unsigned int req_width; +-}; +- +-struct _vcs_dpi_display_data_rq_sizing_params_st { +- unsigned int chunk_bytes; +- unsigned int min_chunk_bytes; +- unsigned int meta_chunk_bytes; +- unsigned int min_meta_chunk_bytes; +- unsigned int mpte_group_bytes; +- unsigned int dpte_group_bytes; +-}; +- +-struct _vcs_dpi_display_data_rq_dlg_params_st { +- unsigned int swath_width_ub; +- unsigned int swath_height; +- unsigned int req_per_swath_ub; +- unsigned int meta_pte_bytes_per_frame_ub; +- unsigned int dpte_req_per_row_ub; +- unsigned int dpte_groups_per_row_ub; +- unsigned int dpte_row_height; +- unsigned int dpte_bytes_per_row_ub; +- unsigned int meta_chunks_per_row_ub; +- unsigned int meta_req_per_row_ub; +- unsigned int meta_row_height; +- unsigned int meta_bytes_per_row_ub; +-}; +- +-struct _vcs_dpi_display_cur_rq_dlg_params_st { +- unsigned char enable; +- unsigned int swath_height; +- unsigned int req_per_line; +-}; +- +-struct _vcs_dpi_display_rq_dlg_params_st { +- struct _vcs_dpi_display_data_rq_dlg_params_st rq_l; +- struct _vcs_dpi_display_data_rq_dlg_params_st rq_c; +- struct _vcs_dpi_display_cur_rq_dlg_params_st rq_cur0; +-}; +- +-struct _vcs_dpi_display_rq_sizing_params_st { +- struct _vcs_dpi_display_data_rq_sizing_params_st rq_l; +- struct _vcs_dpi_display_data_rq_sizing_params_st rq_c; +-}; +- +-struct _vcs_dpi_display_rq_misc_params_st { +- struct _vcs_dpi_display_data_rq_misc_params_st rq_l; +- struct _vcs_dpi_display_data_rq_misc_params_st rq_c; +-}; +- +-struct _vcs_dpi_display_rq_params_st { +- unsigned char yuv420; +- unsigned char yuv420_10bpc; +- struct _vcs_dpi_display_rq_misc_params_st misc; +- struct _vcs_dpi_display_rq_sizing_params_st sizing; +- struct _vcs_dpi_display_rq_dlg_params_st dlg; +-}; +- +-struct _vcs_dpi_display_dlg_regs_st { +- unsigned int refcyc_h_blank_end; +- unsigned int dlg_vblank_end; +- unsigned int min_dst_y_next_start; +- unsigned int refcyc_per_htotal; +- unsigned int refcyc_x_after_scaler; +- unsigned int dst_y_after_scaler; +- unsigned int dst_y_prefetch; +- unsigned int dst_y_per_vm_vblank; +- unsigned int dst_y_per_row_vblank; +- unsigned int ref_freq_to_pix_freq; +- unsigned int vratio_prefetch; +- unsigned int vratio_prefetch_c; +- unsigned int refcyc_per_pte_group_vblank_l; +- unsigned int refcyc_per_pte_group_vblank_c; +- unsigned int refcyc_per_meta_chunk_vblank_l; +- unsigned int refcyc_per_meta_chunk_vblank_c; +- unsigned int dst_y_per_pte_row_nom_l; +- unsigned int dst_y_per_pte_row_nom_c; +- unsigned int refcyc_per_pte_group_nom_l; +- unsigned int refcyc_per_pte_group_nom_c; +- unsigned int dst_y_per_meta_row_nom_l; +- unsigned int dst_y_per_meta_row_nom_c; +- unsigned int refcyc_per_meta_chunk_nom_l; +- unsigned int refcyc_per_meta_chunk_nom_c; +- unsigned int refcyc_per_line_delivery_pre_l; +- unsigned int refcyc_per_line_delivery_pre_c; +- unsigned int refcyc_per_line_delivery_l; +- unsigned int refcyc_per_line_delivery_c; +- unsigned int chunk_hdl_adjust_cur0; +-}; +- +-struct _vcs_dpi_display_ttu_regs_st { +- unsigned int qos_level_low_wm; +- unsigned int qos_level_high_wm; +- unsigned int min_ttu_vblank; +- unsigned int qos_level_flip; +- unsigned int refcyc_per_req_delivery_l; +- unsigned int refcyc_per_req_delivery_c; +- unsigned int refcyc_per_req_delivery_cur0; +- unsigned int refcyc_per_req_delivery_pre_l; +- unsigned int refcyc_per_req_delivery_pre_c; +- unsigned int refcyc_per_req_delivery_pre_cur0; +- unsigned int qos_level_fixed_l; +- unsigned int qos_level_fixed_c; +- unsigned int qos_level_fixed_cur0; +- unsigned int qos_ramp_disable_l; +- unsigned int qos_ramp_disable_c; +- unsigned int qos_ramp_disable_cur0; +-}; +- +-struct _vcs_dpi_display_data_rq_regs_st { +- unsigned int chunk_size; +- unsigned int min_chunk_size; +- unsigned int meta_chunk_size; +- unsigned int min_meta_chunk_size; +- unsigned int dpte_group_size; +- unsigned int mpte_group_size; +- unsigned int swath_height; +- unsigned int pte_row_height_linear; +-}; +- +-struct _vcs_dpi_display_rq_regs_st { +- struct _vcs_dpi_display_data_rq_regs_st rq_regs_l; +- struct _vcs_dpi_display_data_rq_regs_st rq_regs_c; +- unsigned int drq_expansion_mode; +- unsigned int prq_expansion_mode; +- unsigned int mrq_expansion_mode; +- unsigned int crq_expansion_mode; +- unsigned int plane1_base_address; +-}; +- +-struct _vcs_dpi_display_dlg_sys_params_st { +- double t_mclk_wm_us; +- double t_urg_wm_us; +- double t_sr_wm_us; +- double t_extra_us; +- double t_srx_delay_us; +- double deepsleep_dcfclk_mhz; +- double total_flip_bw; +- unsigned int total_flip_bytes; +-}; +- +-struct _vcs_dpi_display_dlg_prefetch_param_st { +- double prefetch_bw; +- unsigned int flip_bytes; +-}; +- +-struct _vcs_dpi_display_pipe_clock_st { +- double dcfclk_mhz; +- double dispclk_mhz; +- double dppclk_mhz[4]; +- unsigned char dppclk_div[4]; +-}; +- +-struct _vcs_dpi_display_arb_params_st { +- int max_req_outstanding; +- int min_req_outstanding; +- int sat_level_us; +-}; +- +-struct _vcs_dpi_mode_evaluation_st { +- int voltage_override; ++struct _vcs_dpi_display_xfc_params_st { ++ double xfc_tslv_vready_offset_us; ++ double xfc_tslv_vupdate_width_us; ++ double xfc_tslv_vupdate_offset_us; ++ int xfc_slv_chunk_size_bytes; ++}; ++ ++struct _vcs_dpi_display_pipe_source_params_st { ++ int source_format; ++ unsigned char dcc; ++ unsigned int dcc_override; ++ unsigned int dcc_rate; ++ unsigned char dcc_use_global; ++ unsigned char vm; ++ unsigned char vm_levels_force_en; ++ unsigned int vm_levels_force; ++ int source_scan; ++ int sw_mode; ++ int macro_tile_size; ++ unsigned char is_display_sw; ++ unsigned int viewport_width; ++ unsigned int viewport_height; ++ unsigned int viewport_y_y; ++ unsigned int viewport_y_c; ++ unsigned int viewport_width_c; ++ unsigned int viewport_height_c; ++ unsigned int data_pitch; ++ unsigned int data_pitch_c; ++ unsigned int meta_pitch; ++ unsigned int meta_pitch_c; ++ unsigned int cur0_src_width; ++ int cur0_bpp; ++ unsigned int cur1_src_width; ++ int cur1_bpp; ++ int num_cursors; ++ unsigned char is_hsplit; ++ unsigned char dynamic_metadata_enable; ++ unsigned int dynamic_metadata_lines_before_active; ++ unsigned int dynamic_metadata_xmit_bytes; ++ unsigned int hsplit_grp; ++ unsigned char xfc_enable; ++ unsigned char xfc_slave; ++ struct _vcs_dpi_display_xfc_params_st xfc_params; ++}; ++struct writeback_st { ++ int wb_src_height; ++ int wb_dst_width; ++ int wb_dst_height; ++ int wb_pixel_format; ++ int wb_htaps_luma; ++ int wb_vtaps_luma; ++ int wb_htaps_chroma; ++ int wb_vtaps_chroma; ++ int wb_hratio; ++ int wb_vratio; ++}; ++ ++struct _vcs_dpi_display_output_params_st { ++ int output_bpp; ++ int dsc_enable; ++ int wb_enable; ++ int output_bpc; ++ int output_type; ++ int output_format; ++ int output_standard; ++ int dsc_slices; ++ struct writeback_st wb; ++}; ++ ++struct _vcs_dpi_display_bandwidth_st { ++ double total_bw_consumed_gbps; ++ double guaranteed_urgent_return_bw_gbps; ++}; ++ ++struct _vcs_dpi_scaler_ratio_depth_st { ++ double hscl_ratio; ++ double vscl_ratio; ++ double hscl_ratio_c; ++ double vscl_ratio_c; ++ double vinit; ++ double vinit_c; ++ double vinit_bot; ++ double vinit_bot_c; ++ int lb_depth; ++ int scl_enable; ++}; ++ ++struct _vcs_dpi_scaler_taps_st { ++ unsigned int htaps; ++ unsigned int vtaps; ++ unsigned int htaps_c; ++ unsigned int vtaps_c; ++}; ++ ++struct _vcs_dpi_display_pipe_dest_params_st { ++ unsigned int recout_width; ++ unsigned int recout_height; ++ unsigned int full_recout_width; ++ unsigned int full_recout_height; ++ unsigned int hblank_start; ++ unsigned int hblank_end; ++ unsigned int vblank_start; ++ unsigned int vblank_end; ++ unsigned int htotal; ++ unsigned int vtotal; ++ unsigned int vactive; ++ unsigned int hactive; ++ unsigned int vstartup_start; ++ unsigned int vupdate_offset; ++ unsigned int vupdate_width; ++ unsigned int vready_offset; ++ unsigned char interlaced; ++ unsigned char underscan; ++ double pixel_rate_mhz; ++ unsigned char synchronized_vblank_all_planes; ++ unsigned char otg_inst; ++ unsigned char odm_split_cnt; ++ unsigned char odm_combine; ++}; ++ ++struct _vcs_dpi_display_pipe_params_st { ++ display_pipe_source_params_st src; ++ display_pipe_dest_params_st dest; ++ scaler_ratio_depth_st scale_ratio_depth; ++ scaler_taps_st scale_taps; ++}; ++ ++struct _vcs_dpi_display_clocks_and_cfg_st { ++ int voltage; ++ double dppclk_mhz; ++ double refclk_mhz; ++ double dispclk_mhz; ++ double dcfclk_mhz; ++ double socclk_mhz; ++}; ++ ++struct _vcs_dpi_display_e2e_pipe_params_st { ++ display_pipe_params_st pipe; ++ display_output_params_st dout; ++ display_clocks_and_cfg_st clks_cfg; ++}; ++ ++struct _vcs_dpi_dchub_buffer_sizing_st { ++ unsigned int swath_width_y; ++ unsigned int swath_height_y; ++ unsigned int swath_height_c; ++ unsigned int detail_buffer_size_y; ++}; ++ ++struct _vcs_dpi_watermarks_perf_st { ++ double stutter_eff_in_active_region_percent; ++ double urgent_latency_supported_us; ++ double non_urgent_latency_supported_us; ++ double dram_clock_change_margin_us; ++ double dram_access_eff_percent; ++}; ++ ++struct _vcs_dpi_cstate_pstate_watermarks_st { ++ double cstate_exit_us; ++ double cstate_enter_plus_exit_us; ++ double pstate_change_us; ++}; ++ ++struct _vcs_dpi_wm_calc_pipe_params_st { ++ unsigned int num_dpp; ++ int voltage; ++ int output_type; ++ double dcfclk_mhz; ++ double socclk_mhz; ++ double dppclk_mhz; ++ double pixclk_mhz; ++ unsigned char interlace_en; ++ unsigned char pte_enable; ++ unsigned char dcc_enable; ++ double dcc_rate; ++ double bytes_per_pixel_c; ++ double bytes_per_pixel_y; ++ unsigned int swath_width_y; ++ unsigned int swath_height_y; ++ unsigned int swath_height_c; ++ unsigned int det_buffer_size_y; ++ double h_ratio; ++ double v_ratio; ++ unsigned int h_taps; ++ unsigned int h_total; ++ unsigned int v_total; ++ unsigned int v_active; ++ unsigned int e2e_index; ++ double display_pipe_line_delivery_time; ++ double read_bw; ++ unsigned int lines_in_det_y; ++ unsigned int lines_in_det_y_rounded_down_to_swath; ++ double full_det_buffering_time; ++ double dcfclk_deepsleep_mhz_per_plane; ++}; ++ ++struct _vcs_dpi_vratio_pre_st { ++ double vratio_pre_l; ++ double vratio_pre_c; ++}; ++ ++struct _vcs_dpi_display_data_rq_misc_params_st { ++ unsigned int full_swath_bytes; ++ unsigned int stored_swath_bytes; ++ unsigned int blk256_height; ++ unsigned int blk256_width; ++ unsigned int req_height; ++ unsigned int req_width; ++}; ++ ++struct _vcs_dpi_display_data_rq_sizing_params_st { ++ unsigned int chunk_bytes; ++ unsigned int min_chunk_bytes; ++ unsigned int meta_chunk_bytes; ++ unsigned int min_meta_chunk_bytes; ++ unsigned int mpte_group_bytes; ++ unsigned int dpte_group_bytes; ++}; ++ ++struct _vcs_dpi_display_data_rq_dlg_params_st { ++ unsigned int swath_width_ub; ++ unsigned int swath_height; ++ unsigned int req_per_swath_ub; ++ unsigned int meta_pte_bytes_per_frame_ub; ++ unsigned int dpte_req_per_row_ub; ++ unsigned int dpte_groups_per_row_ub; ++ unsigned int dpte_row_height; ++ unsigned int dpte_bytes_per_row_ub; ++ unsigned int meta_chunks_per_row_ub; ++ unsigned int meta_req_per_row_ub; ++ unsigned int meta_row_height; ++ unsigned int meta_bytes_per_row_ub; ++}; ++ ++struct _vcs_dpi_display_cur_rq_dlg_params_st { ++ unsigned char enable; ++ unsigned int swath_height; ++ unsigned int req_per_line; ++}; ++ ++struct _vcs_dpi_display_rq_dlg_params_st { ++ display_data_rq_dlg_params_st rq_l; ++ display_data_rq_dlg_params_st rq_c; ++ display_cur_rq_dlg_params_st rq_cur0; ++}; ++ ++struct _vcs_dpi_display_rq_sizing_params_st { ++ display_data_rq_sizing_params_st rq_l; ++ display_data_rq_sizing_params_st rq_c; ++}; ++ ++struct _vcs_dpi_display_rq_misc_params_st { ++ display_data_rq_misc_params_st rq_l; ++ display_data_rq_misc_params_st rq_c; ++}; ++ ++struct _vcs_dpi_display_rq_params_st { ++ unsigned char yuv420; ++ unsigned char yuv420_10bpc; ++ display_rq_misc_params_st misc; ++ display_rq_sizing_params_st sizing; ++ display_rq_dlg_params_st dlg; ++}; ++ ++struct _vcs_dpi_display_dlg_regs_st { ++ unsigned int refcyc_h_blank_end; ++ unsigned int dlg_vblank_end; ++ unsigned int min_dst_y_next_start; ++ unsigned int refcyc_per_htotal; ++ unsigned int refcyc_x_after_scaler; ++ unsigned int dst_y_after_scaler; ++ unsigned int dst_y_prefetch; ++ unsigned int dst_y_per_vm_vblank; ++ unsigned int dst_y_per_row_vblank; ++ unsigned int dst_y_per_vm_flip; ++ unsigned int dst_y_per_row_flip; ++ unsigned int ref_freq_to_pix_freq; ++ unsigned int vratio_prefetch; ++ unsigned int vratio_prefetch_c; ++ unsigned int refcyc_per_pte_group_vblank_l; ++ unsigned int refcyc_per_pte_group_vblank_c; ++ unsigned int refcyc_per_meta_chunk_vblank_l; ++ unsigned int refcyc_per_meta_chunk_vblank_c; ++ unsigned int refcyc_per_pte_group_flip_l; ++ unsigned int refcyc_per_pte_group_flip_c; ++ unsigned int refcyc_per_meta_chunk_flip_l; ++ unsigned int refcyc_per_meta_chunk_flip_c; ++ unsigned int dst_y_per_pte_row_nom_l; ++ unsigned int dst_y_per_pte_row_nom_c; ++ unsigned int refcyc_per_pte_group_nom_l; ++ unsigned int refcyc_per_pte_group_nom_c; ++ unsigned int dst_y_per_meta_row_nom_l; ++ unsigned int dst_y_per_meta_row_nom_c; ++ unsigned int refcyc_per_meta_chunk_nom_l; ++ unsigned int refcyc_per_meta_chunk_nom_c; ++ unsigned int refcyc_per_line_delivery_pre_l; ++ unsigned int refcyc_per_line_delivery_pre_c; ++ unsigned int refcyc_per_line_delivery_l; ++ unsigned int refcyc_per_line_delivery_c; ++ unsigned int chunk_hdl_adjust_cur0; ++ unsigned int chunk_hdl_adjust_cur1; ++ unsigned int vready_after_vcount0; ++ unsigned int dst_y_offset_cur0; ++ unsigned int dst_y_offset_cur1; ++ unsigned int xfc_reg_transfer_delay; ++ unsigned int xfc_reg_precharge_delay; ++ unsigned int xfc_reg_remote_surface_flip_latency; ++ unsigned int xfc_reg_prefetch_margin; ++ unsigned int dst_y_delta_drq_limit; ++}; ++ ++struct _vcs_dpi_display_ttu_regs_st { ++ unsigned int qos_level_low_wm; ++ unsigned int qos_level_high_wm; ++ unsigned int min_ttu_vblank; ++ unsigned int qos_level_flip; ++ unsigned int refcyc_per_req_delivery_l; ++ unsigned int refcyc_per_req_delivery_c; ++ unsigned int refcyc_per_req_delivery_cur0; ++ unsigned int refcyc_per_req_delivery_cur1; ++ unsigned int refcyc_per_req_delivery_pre_l; ++ unsigned int refcyc_per_req_delivery_pre_c; ++ unsigned int refcyc_per_req_delivery_pre_cur0; ++ unsigned int refcyc_per_req_delivery_pre_cur1; ++ unsigned int qos_level_fixed_l; ++ unsigned int qos_level_fixed_c; ++ unsigned int qos_level_fixed_cur0; ++ unsigned int qos_level_fixed_cur1; ++ unsigned int qos_ramp_disable_l; ++ unsigned int qos_ramp_disable_c; ++ unsigned int qos_ramp_disable_cur0; ++ unsigned int qos_ramp_disable_cur1; ++}; ++ ++struct _vcs_dpi_display_data_rq_regs_st { ++ unsigned int chunk_size; ++ unsigned int min_chunk_size; ++ unsigned int meta_chunk_size; ++ unsigned int min_meta_chunk_size; ++ unsigned int dpte_group_size; ++ unsigned int mpte_group_size; ++ unsigned int swath_height; ++ unsigned int pte_row_height_linear; ++}; ++ ++struct _vcs_dpi_display_rq_regs_st { ++ display_data_rq_regs_st rq_regs_l; ++ display_data_rq_regs_st rq_regs_c; ++ unsigned int drq_expansion_mode; ++ unsigned int prq_expansion_mode; ++ unsigned int mrq_expansion_mode; ++ unsigned int crq_expansion_mode; ++ unsigned int plane1_base_address; ++}; ++ ++struct _vcs_dpi_display_dlg_sys_params_st { ++ double t_mclk_wm_us; ++ double t_urg_wm_us; ++ double t_sr_wm_us; ++ double t_extra_us; ++ double mem_trip_us; ++ double t_srx_delay_us; ++ double deepsleep_dcfclk_mhz; ++ double total_flip_bw; ++ unsigned int total_flip_bytes; ++}; ++ ++struct _vcs_dpi_display_dlg_prefetch_param_st { ++ double prefetch_bw; ++ unsigned int flip_bytes; ++}; ++ ++struct _vcs_dpi_display_pipe_clock_st { ++ double dcfclk_mhz; ++ double dispclk_mhz; ++ double socclk_mhz; ++ double dscclk_mhz[6]; ++ double dppclk_mhz[6]; ++}; ++ ++struct _vcs_dpi_display_arb_params_st { ++ int max_req_outstanding; ++ int min_req_outstanding; ++ int sat_level_us; + }; + + #endif /*__DISPLAY_MODE_STRUCTS_H__*/ +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c +deleted file mode 100644 +index 3b4ee74..0000000 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c ++++ /dev/null +@@ -1,2326 +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. +- * +- * Authors: AMD +- * +- */ +- +-#include "display_mode_support.h" +-#include "display_mode_lib.h" +- +-int dml_ms_check( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- int num_pipes) +-{ +- struct _vcs_dpi_ip_params_st *ip; +- struct _vcs_dpi_soc_bounding_box_st *soc; +- struct _vcs_dpi_mode_evaluation_st *me; +- struct dml_ms_internal_vars *v; +- int num_planes, i, j, ij, k, ijk; +- +- ip = &(mode_lib->ip); +- soc = &(mode_lib->soc); +- me = &(mode_lib->me); +- v = &(mode_lib->vars); +- num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, v->planes); +- +- //instantiating variables to zero +- v->MacroTileBlockWidthC = 0; +- v->SwathWidthGranularityC = 0; +- +- v->DCFCLKPerState[5] = 0; +- v->DCFCLKPerState[4] = 0; +- v->DCFCLKPerState[3] = 0; +- v->DCFCLKPerState[2] = 0; +- v->DCFCLKPerState[1] = 0; +- v->DCFCLKPerState[0] = 0; +- +- if (soc->vmin.dcfclk_mhz > 0) { +- v->DCFCLKPerState[5] = soc->vmin.dcfclk_mhz; +- v->DCFCLKPerState[4] = soc->vmin.dcfclk_mhz; +- v->DCFCLKPerState[3] = soc->vmin.dcfclk_mhz; +- v->DCFCLKPerState[2] = soc->vmin.dcfclk_mhz; +- v->DCFCLKPerState[1] = soc->vmin.dcfclk_mhz; +- v->DCFCLKPerState[0] = soc->vmin.dcfclk_mhz; +- } +- +- if (soc->vmid.dcfclk_mhz > 0) { +- v->DCFCLKPerState[5] = soc->vmid.dcfclk_mhz; +- v->DCFCLKPerState[4] = soc->vmid.dcfclk_mhz; +- v->DCFCLKPerState[3] = soc->vmid.dcfclk_mhz; +- v->DCFCLKPerState[2] = soc->vmid.dcfclk_mhz; +- v->DCFCLKPerState[1] = soc->vmid.dcfclk_mhz; +- } +- +- if (soc->vnom.dcfclk_mhz > 0) { +- v->DCFCLKPerState[5] = soc->vnom.dcfclk_mhz; +- v->DCFCLKPerState[4] = soc->vnom.dcfclk_mhz; +- v->DCFCLKPerState[3] = soc->vnom.dcfclk_mhz; +- v->DCFCLKPerState[2] = soc->vnom.dcfclk_mhz; +- } +- +- if (soc->vmax.dcfclk_mhz > 0) { +- v->DCFCLKPerState[5] = soc->vmax.dcfclk_mhz; +- v->DCFCLKPerState[4] = soc->vmax.dcfclk_mhz; +- v->DCFCLKPerState[3] = soc->vmax.dcfclk_mhz; +- } +- +- v->FabricAndDRAMBandwidthPerState[5] = 0; +- v->FabricAndDRAMBandwidthPerState[4] = 0; +- v->FabricAndDRAMBandwidthPerState[3] = 0; +- v->FabricAndDRAMBandwidthPerState[2] = 0; +- v->FabricAndDRAMBandwidthPerState[1] = 0; +- v->FabricAndDRAMBandwidthPerState[0] = 0; +- +- if (soc->vmin.dram_bw_per_chan_gbps > 0) { +- v->FabricAndDRAMBandwidthPerState[5] = soc->vmin.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[4] = soc->vmin.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[3] = soc->vmin.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[2] = soc->vmin.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[1] = soc->vmin.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[0] = soc->vmin.dram_bw_per_chan_gbps; +- } +- +- if (soc->vmid.dram_bw_per_chan_gbps > 0) { +- v->FabricAndDRAMBandwidthPerState[5] = soc->vmid.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[4] = soc->vmid.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[3] = soc->vmid.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[2] = soc->vmid.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[1] = soc->vmid.dram_bw_per_chan_gbps; +- } +- +- if (soc->vnom.dram_bw_per_chan_gbps > 0) { +- v->FabricAndDRAMBandwidthPerState[5] = soc->vnom.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[4] = soc->vnom.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[3] = soc->vnom.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[2] = soc->vnom.dram_bw_per_chan_gbps; +- } +- +- if (soc->vmax.dram_bw_per_chan_gbps > 0) { +- v->FabricAndDRAMBandwidthPerState[5] = soc->vmax.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[4] = soc->vmax.dram_bw_per_chan_gbps; +- v->FabricAndDRAMBandwidthPerState[3] = soc->vmax.dram_bw_per_chan_gbps; +- } +- +- v->PHYCLKPerState[5] = 0; +- v->PHYCLKPerState[4] = 0; +- v->PHYCLKPerState[3] = 0; +- v->PHYCLKPerState[2] = 0; +- v->PHYCLKPerState[1] = 0; +- v->PHYCLKPerState[0] = 0; +- +- if (soc->vmin.phyclk_mhz > 0) { +- v->PHYCLKPerState[5] = soc->vmin.phyclk_mhz; +- v->PHYCLKPerState[4] = soc->vmin.phyclk_mhz; +- v->PHYCLKPerState[3] = soc->vmin.phyclk_mhz; +- v->PHYCLKPerState[2] = soc->vmin.phyclk_mhz; +- v->PHYCLKPerState[1] = soc->vmin.phyclk_mhz; +- v->PHYCLKPerState[0] = soc->vmin.phyclk_mhz; +- } +- +- if (soc->vmid.phyclk_mhz > 0) { +- v->PHYCLKPerState[5] = soc->vmid.phyclk_mhz; +- v->PHYCLKPerState[4] = soc->vmid.phyclk_mhz; +- v->PHYCLKPerState[3] = soc->vmid.phyclk_mhz; +- v->PHYCLKPerState[2] = soc->vmid.phyclk_mhz; +- v->PHYCLKPerState[1] = soc->vmid.phyclk_mhz; +- } +- +- if (soc->vnom.phyclk_mhz > 0) { +- v->PHYCLKPerState[5] = soc->vnom.phyclk_mhz; +- v->PHYCLKPerState[4] = soc->vnom.phyclk_mhz; +- v->PHYCLKPerState[3] = soc->vnom.phyclk_mhz; +- v->PHYCLKPerState[2] = soc->vnom.phyclk_mhz; +- } +- +- if (soc->vmax.phyclk_mhz > 0) { +- v->PHYCLKPerState[5] = soc->vmax.phyclk_mhz; +- v->PHYCLKPerState[4] = soc->vmax.phyclk_mhz; +- v->PHYCLKPerState[3] = soc->vmax.phyclk_mhz; +- } +- +- v->MaxDispclk[5] = 0; +- v->MaxDispclk[4] = 0; +- v->MaxDispclk[3] = 0; +- v->MaxDispclk[2] = 0; +- v->MaxDispclk[1] = 0; +- v->MaxDispclk[0] = 0; +- +- if (soc->vmin.dispclk_mhz > 0) { +- v->MaxDispclk[5] = soc->vmin.dispclk_mhz; +- v->MaxDispclk[4] = soc->vmin.dispclk_mhz; +- v->MaxDispclk[3] = soc->vmin.dispclk_mhz; +- v->MaxDispclk[2] = soc->vmin.dispclk_mhz; +- v->MaxDispclk[1] = soc->vmin.dispclk_mhz; +- v->MaxDispclk[0] = soc->vmin.dispclk_mhz; +- } +- +- if (soc->vmid.dispclk_mhz > 0) { +- v->MaxDispclk[5] = soc->vmid.dispclk_mhz; +- v->MaxDispclk[4] = soc->vmid.dispclk_mhz; +- v->MaxDispclk[3] = soc->vmid.dispclk_mhz; +- v->MaxDispclk[2] = soc->vmid.dispclk_mhz; +- v->MaxDispclk[1] = soc->vmid.dispclk_mhz; +- } +- +- if (soc->vnom.dispclk_mhz > 0) { +- v->MaxDispclk[5] = soc->vnom.dispclk_mhz; +- v->MaxDispclk[4] = soc->vnom.dispclk_mhz; +- v->MaxDispclk[3] = soc->vnom.dispclk_mhz; +- v->MaxDispclk[2] = soc->vnom.dispclk_mhz; +- } +- +- if (soc->vmax.dispclk_mhz > 0) { +- v->MaxDispclk[5] = soc->vmax.dispclk_mhz; +- v->MaxDispclk[4] = soc->vmax.dispclk_mhz; +- v->MaxDispclk[3] = soc->vmax.dispclk_mhz; +- } +- +- v->MaxDppclk[5] = 0; +- v->MaxDppclk[4] = 0; +- v->MaxDppclk[3] = 0; +- v->MaxDppclk[2] = 0; +- v->MaxDppclk[1] = 0; +- v->MaxDppclk[0] = 0; +- +- if (soc->vmin.dppclk_mhz > 0) { +- v->MaxDppclk[5] = soc->vmin.dppclk_mhz; +- v->MaxDppclk[4] = soc->vmin.dppclk_mhz; +- v->MaxDppclk[3] = soc->vmin.dppclk_mhz; +- v->MaxDppclk[2] = soc->vmin.dppclk_mhz; +- v->MaxDppclk[1] = soc->vmin.dppclk_mhz; +- v->MaxDppclk[0] = soc->vmin.dppclk_mhz; +- } +- +- if (soc->vmid.dppclk_mhz > 0) { +- v->MaxDppclk[5] = soc->vmid.dppclk_mhz; +- v->MaxDppclk[4] = soc->vmid.dppclk_mhz; +- v->MaxDppclk[3] = soc->vmid.dppclk_mhz; +- v->MaxDppclk[2] = soc->vmid.dppclk_mhz; +- v->MaxDppclk[1] = soc->vmid.dppclk_mhz; +- } +- +- if (soc->vnom.dppclk_mhz > 0) { +- v->MaxDppclk[5] = soc->vnom.dppclk_mhz; +- v->MaxDppclk[4] = soc->vnom.dppclk_mhz; +- v->MaxDppclk[3] = soc->vnom.dppclk_mhz; +- v->MaxDppclk[2] = soc->vnom.dppclk_mhz; +- } +- +- if (soc->vmax.dppclk_mhz > 0) { +- v->MaxDppclk[5] = soc->vmax.dppclk_mhz; +- v->MaxDppclk[4] = soc->vmax.dppclk_mhz; +- v->MaxDppclk[3] = soc->vmax.dppclk_mhz; +- } +- +- if (me->voltage_override == dm_vmax) { +- v->VoltageOverrideLevel = NumberOfStates - 1; +- } else if (me->voltage_override == dm_vnom) { +- v->VoltageOverrideLevel = NumberOfStates - 2; +- } else if (me->voltage_override == dm_vmid) { +- v->VoltageOverrideLevel = NumberOfStates - 3; +- } else { +- v->VoltageOverrideLevel = 0; +- } +- +- // Scale Ratio Support Check +- +- v->ScaleRatioSupport = 1; +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = +- e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; +- struct _vcs_dpi_scaler_taps_st scale_taps = +- e2e[v->planes[k].e2e_index].pipe.scale_taps; +- struct _vcs_dpi_display_pipe_source_params_st src = +- e2e[v->planes[k].e2e_index].pipe.src; +- +- if (scale_ratio_depth.hscl_ratio > ip->max_hscl_ratio +- || scale_ratio_depth.vscl_ratio > ip->max_vscl_ratio +- || scale_ratio_depth.hscl_ratio > scale_taps.htaps +- || scale_ratio_depth.vscl_ratio > scale_taps.vtaps +- || (src.source_format != dm_444_64 && src.source_format != dm_444_32 +- && src.source_format != dm_444_16 +- && ((scale_ratio_depth.hscl_ratio / 2 +- > scale_taps.htaps_c) +- || (scale_ratio_depth.vscl_ratio / 2 +- > scale_taps.vtaps_c)))) +- +- { +- v->ScaleRatioSupport = 0; +- } +- } +- +- // Source Format, Pixel Format and Scan Support Check +- +- v->SourceFormatPixelAndScanSupport = 1; +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_source_params_st src = +- e2e[v->planes[k].e2e_index].pipe.src; +- +- if ((src.sw_mode == dm_sw_linear && src.source_scan != dm_horz) +- || ((src.sw_mode == dm_sw_4kb_d || src.sw_mode == dm_sw_4kb_d_x +- || src.sw_mode == dm_sw_64kb_d +- || src.sw_mode == dm_sw_64kb_d_t +- || src.sw_mode == dm_sw_64kb_d_x +- || src.sw_mode == dm_sw_var_d +- || src.sw_mode == dm_sw_var_d_x) +- && (src.source_format != dm_444_64))) { +- v->SourceFormatPixelAndScanSupport = 0; +- } +- } +- +- // Bandwidth Support Check +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_source_params_st src = +- e2e[v->planes[k].e2e_index].pipe.src; +- +- if (src.source_scan == dm_horz) { +- v->SwathWidthYSingleDPP[k] = src.viewport_width; +- } else { +- v->SwathWidthYSingleDPP[k] = src.viewport_height; +- } +- +- if (src.source_format == dm_444_64) { +- v->BytePerPixelInDETY[k] = 8; +- v->BytePerPixelInDETC[k] = 0; +- } else if (src.source_format == dm_444_32) { +- v->BytePerPixelInDETY[k] = 4; +- v->BytePerPixelInDETC[k] = 0; +- } else if (src.source_format == dm_444_16) { +- v->BytePerPixelInDETY[k] = 2; +- v->BytePerPixelInDETC[k] = 0; +- } else if (src.source_format == dm_420_8) { +- v->BytePerPixelInDETY[k] = 1; +- v->BytePerPixelInDETC[k] = 2; +- } else { +- v->BytePerPixelInDETY[k] = 4.00 / 3.00; +- v->BytePerPixelInDETC[k] = 8.00 / 3.00; +- } +- } +- +- v->TotalReadBandwidthConsumedGBytePerSecond = 0; +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_source_params_st src = +- e2e[v->planes[k].e2e_index].pipe.src; +- struct _vcs_dpi_display_pipe_dest_params_st dest = +- e2e[v->planes[k].e2e_index].pipe.dest; +- struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = +- e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; +- +- v->ReadBandwidth[k] = +- v->SwathWidthYSingleDPP[k] +- * (dml_ceil_ex(v->BytePerPixelInDETY[k], 1) +- * scale_ratio_depth.vscl_ratio +- + (dml_ceil_ex( +- v->BytePerPixelInDETC[k], +- 2) / 2) +- * (scale_ratio_depth.vscl_ratio +- / 2)) +- / (dest.htotal / dest.pixel_rate_mhz); +- +- if (src.dcc == 1) { +- v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 256); +- } +- +- if (ip->pte_enable == 1 && src.source_scan != dm_horz +- && (src.sw_mode == dm_sw_4kb_s || src.sw_mode == dm_sw_4kb_s_x +- || src.sw_mode == dm_sw_4kb_d +- || src.sw_mode == dm_sw_4kb_d_x)) { +- v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 64); +- } else if (ip->pte_enable == 1 && src.source_scan == dm_horz +- && (src.source_format == dm_444_64 || src.source_format == dm_444_32) +- && (src.sw_mode == dm_sw_64kb_s || src.sw_mode == dm_sw_64kb_s_t +- || src.sw_mode == dm_sw_64kb_s_x +- || src.sw_mode == dm_sw_64kb_d +- || src.sw_mode == dm_sw_64kb_d_t +- || src.sw_mode == dm_sw_64kb_d_x)) { +- v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 256); +- } else if (ip->pte_enable == 1) { +- v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 512); +- } +- +- v->TotalReadBandwidthConsumedGBytePerSecond = +- v->TotalReadBandwidthConsumedGBytePerSecond +- + v->ReadBandwidth[k] / 1000; +- } +- +- v->TotalWriteBandwidthConsumedGBytePerSecond = 0; +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_dest_params_st dest = +- e2e[v->planes[k].e2e_index].pipe.dest; +- struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout; +- +- if (dout.output_type == dm_wb && dout.output_format == dm_444) { +- v->WriteBandwidth[k] = dest.recout_width +- / (dest.htotal / dest.pixel_rate_mhz) * 4; +- } else if (dout.output_type == dm_wb) { +- v->WriteBandwidth[k] = dest.recout_width +- / (dest.htotal / dest.pixel_rate_mhz) * 1.5; +- } else { +- v->WriteBandwidth[k] = 0; +- } +- +- v->TotalWriteBandwidthConsumedGBytePerSecond = +- v->TotalWriteBandwidthConsumedGBytePerSecond +- + v->WriteBandwidth[k] / 1000; +- } +- +- v->TotalBandwidthConsumedGBytePerSecond = v->TotalReadBandwidthConsumedGBytePerSecond +- + v->TotalWriteBandwidthConsumedGBytePerSecond; +- +- v->DCCEnabledInAnyPlane = 0; +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_source_params_st src = +- e2e[v->planes[k].e2e_index].pipe.src; +- +- if (src.dcc == 1) { +- v->DCCEnabledInAnyPlane = 1; +- } +- } +- +- for (i = 0; i < NumberOfStatesPlusTwo; i++) { +- v->ReturnBWToDCNPerState = dml_min( +- soc->return_bus_width_bytes * v->DCFCLKPerState[i], +- v->FabricAndDRAMBandwidthPerState[i] * 1000 +- * soc->ideal_dram_bw_after_urgent_percent / 100); +- +- v->ReturnBWPerState[i] = v->ReturnBWToDCNPerState; +- +- if (v->DCCEnabledInAnyPlane == 1 +- && v->ReturnBWToDCNPerState +- > (v->DCFCLKPerState[i] +- * soc->return_bus_width_bytes / 4)) { +- v->ReturnBWPerState[i] = +- dml_min( +- v->ReturnBWPerState[i], +- v->ReturnBWToDCNPerState * 4 +- * (1 +- - soc->urgent_latency_us +- / ((ip->rob_buffer_size_kbytes +- - ip->pixel_chunk_size_kbytes) +- * 1024 +- / (v->ReturnBWToDCNPerState +- - v->DCFCLKPerState[i] +- * soc->return_bus_width_bytes +- / 4) +- + soc->urgent_latency_us))); +- } +- +- v->CriticalPoint = 2 * soc->return_bus_width_bytes * v->DCFCLKPerState[i] +- * soc->urgent_latency_us +- / (v->ReturnBWToDCNPerState * soc->urgent_latency_us +- + (ip->rob_buffer_size_kbytes +- - ip->pixel_chunk_size_kbytes) +- * 1024); +- +- if (v->DCCEnabledInAnyPlane == 1 && v->CriticalPoint > 1 && v->CriticalPoint < 4) { +- v->ReturnBWPerState[i] = +- dml_min( +- v->ReturnBWPerState[i], +- 4 * v->ReturnBWToDCNPerState +- * (ip->rob_buffer_size_kbytes +- - ip->pixel_chunk_size_kbytes) +- * 1024 +- * soc->return_bus_width_bytes +- * v->DCFCLKPerState[i] +- * soc->urgent_latency_us +- / dml_pow( +- (v->ReturnBWToDCNPerState +- * soc->urgent_latency_us +- + (ip->rob_buffer_size_kbytes +- - ip->pixel_chunk_size_kbytes) +- * 1024), +- 2)); +- } +- +- v->ReturnBWToDCNPerState = dml_min( +- soc->return_bus_width_bytes * v->DCFCLKPerState[i], +- v->FabricAndDRAMBandwidthPerState[i] * 1000); +- +- if (v->DCCEnabledInAnyPlane == 1 +- && v->ReturnBWToDCNPerState +- > (v->DCFCLKPerState[i] +- * soc->return_bus_width_bytes / 4)) { +- v->ReturnBWPerState[i] = +- dml_min( +- v->ReturnBWPerState[i], +- v->ReturnBWToDCNPerState * 4 +- * (1 +- - soc->urgent_latency_us +- / ((ip->rob_buffer_size_kbytes +- - ip->pixel_chunk_size_kbytes) +- * 1024 +- / (v->ReturnBWToDCNPerState +- - v->DCFCLKPerState[i] +- * soc->return_bus_width_bytes +- / 4) +- + soc->urgent_latency_us))); +- } +- +- v->CriticalPoint = 2 * soc->return_bus_width_bytes * v->DCFCLKPerState[i] +- * soc->urgent_latency_us +- / (v->ReturnBWToDCNPerState * soc->urgent_latency_us +- + (ip->rob_buffer_size_kbytes +- - ip->pixel_chunk_size_kbytes) +- * 1024); +- +- if (v->DCCEnabledInAnyPlane == 1 && v->CriticalPoint > 1 && v->CriticalPoint < 4) { +- v->ReturnBWPerState[i] = +- dml_min( +- v->ReturnBWPerState[i], +- 4 * v->ReturnBWToDCNPerState +- * (ip->rob_buffer_size_kbytes +- - ip->pixel_chunk_size_kbytes) +- * 1024 +- * soc->return_bus_width_bytes +- * v->DCFCLKPerState[i] +- * soc->urgent_latency_us +- / dml_pow( +- (v->ReturnBWToDCNPerState +- * soc->urgent_latency_us +- + (ip->rob_buffer_size_kbytes +- - ip->pixel_chunk_size_kbytes) +- * 1024), +- 2)); +- } +- } +- +- for (i = 0; i < NumberOfStatesPlusTwo; i++) { +- if ((v->TotalReadBandwidthConsumedGBytePerSecond * 1000 <= v->ReturnBWPerState[i]) +- && (v->TotalBandwidthConsumedGBytePerSecond * 1000 +- <= v->FabricAndDRAMBandwidthPerState[i] * 1000 +- * soc->ideal_dram_bw_after_urgent_percent +- / 100)) { +- v->BandwidthSupport[i] = 1; +- } else { +- v->BandwidthSupport[i] = 0; +- } +- } +- +- // Writeback Latency support check +- +- v->WritebackLatencySupport = 1; +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_dest_params_st dest = +- e2e[v->planes[k].e2e_index].pipe.dest; +- struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout; +- +- if (dout.output_type == dm_wb && dout.output_format == dm_444 +- && (dest.recout_width / (dest.htotal / dest.pixel_rate_mhz) * 4) +- > ((ip->writeback_luma_buffer_size_kbytes +- + ip->writeback_chroma_buffer_size_kbytes) +- * 1024 / soc->writeback_latency_us)) { +- v->WritebackLatencySupport = 0; +- } else if (dout.output_type == dm_wb +- && (dest.recout_width / (dest.htotal / dest.pixel_rate_mhz)) +- > (dml_min( +- ip->writeback_luma_buffer_size_kbytes, +- 2 +- * ip->writeback_chroma_buffer_size_kbytes) +- * 1024 / soc->writeback_latency_us)) { +- v->WritebackLatencySupport = 0; +- } +- } +- +- // Re-ordering Buffer Support Check +- +- for (i = 0; i < NumberOfStatesPlusTwo; i++) { +- v->UrgentRoundTripAndOutOfOrderLatencyPerState[i] = +- (soc->round_trip_ping_latency_dcfclk_cycles + 32) +- / v->DCFCLKPerState[i] +- + soc->urgent_out_of_order_return_per_channel_bytes +- * soc->num_chans +- / v->ReturnBWPerState[i]; +- +- if ((ip->rob_buffer_size_kbytes - ip->pixel_chunk_size_kbytes) * 1024 +- / v->ReturnBWPerState[i] +- > v->UrgentRoundTripAndOutOfOrderLatencyPerState[i]) { +- v->ROBSupport[i] = 1; +- } else { +- v->ROBSupport[i] = 0; +- } +- } +- +- // Display IO Support Check +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_dest_params_st dest = +- e2e[v->planes[k].e2e_index].pipe.dest; +- struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout; +- +- if (dout.output_format == dm_420) { +- v->RequiredOutputBW = dest.pixel_rate_mhz * 3 / 2; +- } else { +- v->RequiredOutputBW = dest.pixel_rate_mhz * 3; +- } +- +- if (dout.output_type == dm_hdmi) { +- v->RequiredPHYCLK[k] = v->RequiredOutputBW / 3; +- } else if (dout.output_type == dm_dp) { +- v->RequiredPHYCLK[k] = v->RequiredOutputBW / 4; +- } else { +- v->RequiredPHYCLK[k] = 0; +- } +- } +- +- for (i = 0; i < NumberOfStatesPlusTwo; i++) { +- v->DIOSupport[i] = 1; +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_output_params_st dout = +- e2e[v->planes[k].e2e_index].dout; +- +- if ((v->RequiredPHYCLK[k] > v->PHYCLKPerState[i]) +- || (dout.output_type == dm_hdmi +- && v->RequiredPHYCLK[k] > 600)) { +- v->DIOSupport[i] = 0; +- } +- } +- } +- +- // Total Available Writeback Support Check +- +- v->TotalNumberOfActiveWriteback = 0; +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout; +- +- if (dout.output_type == dm_wb) { +- v->TotalNumberOfActiveWriteback = v->TotalNumberOfActiveWriteback + 1; +- } +- } +- +- if (v->TotalNumberOfActiveWriteback <= ip->max_num_wb) { +- v->TotalAvailableWritebackSupport = 1; +- } else { +- v->TotalAvailableWritebackSupport = 0; +- } +- +- // Maximum DISPCLK/DPPCLK Support check +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_dest_params_st dest = +- e2e[v->planes[k].e2e_index].pipe.dest; +- struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = +- e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; +- struct _vcs_dpi_scaler_taps_st scale_taps = +- e2e[v->planes[k].e2e_index].pipe.scale_taps; +- +- if (scale_ratio_depth.hscl_ratio > 1) { +- v->PSCL_FACTOR[k] = dml_min( +- ip->max_dchub_pscl_bw_pix_per_clk, +- ip->max_pscl_lb_bw_pix_per_clk +- * scale_ratio_depth.hscl_ratio +- / dml_ceil_ex(scale_taps.htaps / 6, 1)); +- } else { +- v->PSCL_FACTOR[k] = dml_min( +- ip->max_dchub_pscl_bw_pix_per_clk, +- ip->max_pscl_lb_bw_pix_per_clk); +- } +- +- if (v->BytePerPixelInDETC[k] == 0) { +- v->PSCL_FACTOR_CHROMA[k] = 0; +- v->MinDPPCLKUsingSingleDPP[k] = +- dest.pixel_rate_mhz +- * dml_max( +- scale_taps.vtaps / 6 +- * dml_min( +- 1, +- scale_ratio_depth.hscl_ratio), +- dml_max( +- scale_ratio_depth.hscl_ratio +- * scale_ratio_depth.vscl_ratio +- / v->PSCL_FACTOR[k], +- 1)); +- +- } else { +- if (scale_ratio_depth.hscl_ratio / 2 > 1) { +- v->PSCL_FACTOR_CHROMA[k] = dml_min( +- ip->max_dchub_pscl_bw_pix_per_clk, +- ip->max_pscl_lb_bw_pix_per_clk +- * scale_ratio_depth.hscl_ratio / 2 +- / dml_ceil_ex( +- scale_taps.htaps_c +- / 6, +- 1)); +- } else { +- v->PSCL_FACTOR_CHROMA[k] = dml_min( +- ip->max_dchub_pscl_bw_pix_per_clk, +- ip->max_pscl_lb_bw_pix_per_clk); +- } +- v->MinDPPCLKUsingSingleDPP[k] = +- dest.pixel_rate_mhz +- * dml_max( +- dml_max( +- scale_taps.vtaps +- / 6 +- * dml_min( +- 1, +- scale_ratio_depth.hscl_ratio), +- scale_ratio_depth.hscl_ratio +- * scale_ratio_depth.vscl_ratio +- / v->PSCL_FACTOR[k]), +- dml_max( +- dml_max( +- scale_taps.vtaps_c +- / 6 +- * dml_min( +- 1, +- scale_ratio_depth.hscl_ratio +- / 2), +- scale_ratio_depth.hscl_ratio +- * scale_ratio_depth.vscl_ratio +- / 4 +- / v->PSCL_FACTOR_CHROMA[k]), +- 1)); +- +- } +- } +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_source_params_st src = +- e2e[v->planes[k].e2e_index].pipe.src; +- struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = +- e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; +- struct _vcs_dpi_scaler_taps_st scale_taps = +- e2e[v->planes[k].e2e_index].pipe.scale_taps; +- +- if (src.source_format == dm_444_64 || src.source_format == dm_444_32 +- || src.source_format == dm_444_16) { +- if (src.sw_mode == dm_sw_linear) { +- v->Read256BlockHeightY[k] = 1; +- } else if (src.source_format == dm_444_64) { +- v->Read256BlockHeightY[k] = 4; +- } else { +- v->Read256BlockHeightY[k] = 8; +- } +- +- v->Read256BlockWidthY[k] = 256 / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) +- / v->Read256BlockHeightY[k]; +- v->Read256BlockHeightC[k] = 0; +- v->Read256BlockWidthC[k] = 0; +- } else { +- if (src.sw_mode == dm_sw_linear) { +- v->Read256BlockHeightY[k] = 1; +- v->Read256BlockHeightC[k] = 1; +- } else if (src.source_format == dm_420_8) { +- v->Read256BlockHeightY[k] = 16; +- v->Read256BlockHeightC[k] = 8; +- } else { +- v->Read256BlockHeightY[k] = 8; +- v->Read256BlockHeightC[k] = 8; +- } +- +- v->Read256BlockWidthY[k] = 256 / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) +- / v->Read256BlockHeightY[k]; +- v->Read256BlockWidthC[k] = 256 / dml_ceil_ex(v->BytePerPixelInDETC[k], 2) +- / v->Read256BlockHeightC[k]; +- } +- +- if (src.source_scan == dm_horz) { +- v->MaxSwathHeightY[k] = v->Read256BlockHeightY[k]; +- v->MaxSwathHeightC[k] = v->Read256BlockHeightC[k]; +- } else { +- v->MaxSwathHeightY[k] = v->Read256BlockWidthY[k]; +- v->MaxSwathHeightC[k] = v->Read256BlockWidthC[k]; +- } +- +- if (src.source_format == dm_444_64 || src.source_format == dm_444_32 +- || src.source_format == dm_444_16) { +- if (src.sw_mode == dm_sw_linear +- || (src.source_format == dm_444_64 +- && (src.sw_mode == dm_sw_4kb_s +- || src.sw_mode +- == dm_sw_4kb_s_x +- || src.sw_mode +- == dm_sw_64kb_s +- || src.sw_mode +- == dm_sw_64kb_s_t +- || src.sw_mode +- == dm_sw_64kb_s_x +- || src.sw_mode +- == dm_sw_var_s +- || src.sw_mode +- == dm_sw_var_s_x) +- && src.source_scan == dm_horz)) { +- v->MinSwathHeightY[k] = v->MaxSwathHeightY[k]; +- } else { +- v->MinSwathHeightY[k] = v->MaxSwathHeightY[k] / 2; +- } +- v->MinSwathHeightC[k] = v->MaxSwathHeightC[k]; +- } else { +- if (src.sw_mode == dm_sw_linear) { +- v->MinSwathHeightY[k] = v->MaxSwathHeightY[k]; +- v->MinSwathHeightC[k] = v->MaxSwathHeightC[k]; +- } else if (src.source_format == dm_420_8 && src.source_scan == dm_horz) { +- v->MinSwathHeightY[k] = v->MaxSwathHeightY[k] / 2; +- if (ip->bug_forcing_LC_req_same_size_fixed == 1) { +- v->MinSwathHeightC[k] = v->MaxSwathHeightC[k]; +- } else { +- v->MinSwathHeightC[k] = v->MaxSwathHeightC[k] / 2; +- } +- } else if (src.source_format == dm_420_10 && src.source_scan == dm_horz) { +- v->MinSwathHeightC[k] = v->MaxSwathHeightC[k] / 2; +- if (ip->bug_forcing_LC_req_same_size_fixed == 1) { +- v->MinSwathHeightY[k] = v->MaxSwathHeightY[k]; +- } else { +- v->MinSwathHeightY[k] = v->MaxSwathHeightY[k] / 2; +- } +- } else { +- v->MinSwathHeightY[k] = v->MaxSwathHeightY[k]; +- v->MinSwathHeightC[k] = v->MaxSwathHeightC[k]; +- } +- } +- +- if (src.sw_mode == dm_sw_linear) { +- v->MaximumSwathWidth = 8192; +- } else { +- v->MaximumSwathWidth = 5120; +- } +- +- v->NumberOfDPPRequiredForDETSize = +- dml_ceil_ex( +- v->SwathWidthYSingleDPP[k] +- / dml_min( +- v->MaximumSwathWidth, +- ip->det_buffer_size_kbytes +- * 1024 +- / 2 +- / (v->BytePerPixelInDETY[k] +- * v->MinSwathHeightY[k] +- + v->BytePerPixelInDETC[k] +- / 2 +- * v->MinSwathHeightC[k])), +- 1); +- +- if (v->BytePerPixelInDETC[k] == 0) { +- v->NumberOfDPPRequiredForLBSize = +- dml_ceil_ex( +- (scale_taps.vtaps +- + dml_max( +- dml_ceil_ex( +- scale_ratio_depth.vscl_ratio, +- 1) +- - 2, +- 0)) +- * v->SwathWidthYSingleDPP[k] +- / dml_max( +- scale_ratio_depth.hscl_ratio, +- 1) +- * scale_ratio_depth.lb_depth +- / ip->line_buffer_size_bits, +- 1); +- } else { +- v->NumberOfDPPRequiredForLBSize = +- dml_max( +- dml_ceil_ex( +- (scale_taps.vtaps +- + dml_max( +- dml_ceil_ex( +- scale_ratio_depth.vscl_ratio, +- 1) +- - 2, +- 0)) +- * v->SwathWidthYSingleDPP[k] +- / dml_max( +- scale_ratio_depth.hscl_ratio, +- 1) +- * scale_ratio_depth.lb_depth +- / ip->line_buffer_size_bits, +- 1), +- dml_ceil_ex( +- (scale_taps.vtaps_c +- + dml_max( +- dml_ceil_ex( +- scale_ratio_depth.vscl_ratio +- / 2, +- 1) +- - 2, +- 0)) +- * v->SwathWidthYSingleDPP[k] +- / 2 +- / dml_max( +- scale_ratio_depth.hscl_ratio +- / 2, +- 1) +- * scale_ratio_depth.lb_depth +- / ip->line_buffer_size_bits, +- 1)); +- } +- +- v->NumberOfDPPRequiredForDETAndLBSize[k] = dml_max( +- v->NumberOfDPPRequiredForDETSize, +- v->NumberOfDPPRequiredForLBSize); +- +- } +- +- for (i = 0; i < NumberOfStatesPlusTwo; i++) { +- for (j = 0; j < 2; j++) { +- v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = 0; +- v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = 0; +- v->DISPCLK_DPPCLK_Support[j * NumberOfStatesPlusTwo + i] = 1; +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_dest_params_st dest = +- e2e[v->planes[k].e2e_index].pipe.dest; +- ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; +- +- v->MinDispclkUsingSingleDPP = dml_max( +- dest.pixel_rate_mhz, +- v->MinDPPCLKUsingSingleDPP[k] * (j + 1)) +- * (1 + soc->downspread_percent / 100); +- v->MinDispclkUsingDualDPP = dml_max( +- dest.pixel_rate_mhz, +- v->MinDPPCLKUsingSingleDPP[k] / 2 * (j + 1)) +- * (1 + soc->downspread_percent / 100); +- +- if (i < NumberOfStates) { +- v->MinDispclkUsingSingleDPP = +- v->MinDispclkUsingSingleDPP +- * (1 +- + ip->dispclk_ramp_margin_percent +- / 100); +- v->MinDispclkUsingDualDPP = +- v->MinDispclkUsingDualDPP +- * (1 +- + ip->dispclk_ramp_margin_percent +- / 100); +- } +- +- if (v->MinDispclkUsingSingleDPP +- <= dml_min( +- v->MaxDispclk[i], +- (j + 1) * v->MaxDppclk[i]) +- && v->NumberOfDPPRequiredForDETAndLBSize[k] <= 1) { +- v->NoOfDPP[ijk] = 1; +- v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = dml_max( +- v->RequiredDISPCLK[j * NumberOfStatesPlusTwo +- + i], +- v->MinDispclkUsingSingleDPP); +- } else if (v->MinDispclkUsingDualDPP +- <= dml_min( +- v->MaxDispclk[i], +- (j + 1) * v->MaxDppclk[i])) { +- v->NoOfDPP[ijk] = 2; +- v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = dml_max( +- v->RequiredDISPCLK[j * NumberOfStatesPlusTwo +- + i], +- v->MinDispclkUsingDualDPP); +- } else { +- v->NoOfDPP[ijk] = 2; +- v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = dml_max( +- v->RequiredDISPCLK[j * NumberOfStatesPlusTwo +- + i], +- v->MinDispclkUsingDualDPP); +- v->DISPCLK_DPPCLK_Support[j * NumberOfStatesPlusTwo + i] = +- 0; +- } +- +- v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = +- v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo +- + i] + v->NoOfDPP[ijk]; +- } +- +- if (v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] +- > ip->max_num_dpp) { +- v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = 0; +- v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = 0; +- v->DISPCLK_DPPCLK_Support[j * NumberOfStatesPlusTwo + i] = 1; +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_dest_params_st dest = +- e2e[v->planes[k].e2e_index].pipe.dest; +- ijk = k * 2 * NumberOfStatesPlusTwo +- + j * NumberOfStatesPlusTwo + i; +- +- v->MinDispclkUsingSingleDPP = dml_max( +- dest.pixel_rate_mhz, +- v->MinDPPCLKUsingSingleDPP[k] * (j + 1)) +- * (1 + soc->downspread_percent / 100); +- v->MinDispclkUsingDualDPP = dml_max( +- dest.pixel_rate_mhz, +- v->MinDPPCLKUsingSingleDPP[k] / 2 * (j + 1)) +- * (1 + soc->downspread_percent / 100); +- +- if (i < NumberOfStates) { +- v->MinDispclkUsingSingleDPP = +- v->MinDispclkUsingSingleDPP +- * (1 +- + ip->dispclk_ramp_margin_percent +- / 100); +- v->MinDispclkUsingDualDPP = +- v->MinDispclkUsingDualDPP +- * (1 +- + ip->dispclk_ramp_margin_percent +- / 100); +- } +- +- if (v->NumberOfDPPRequiredForDETAndLBSize[k] <= 1) { +- v->NoOfDPP[ijk] = 1; +- v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = +- dml_max( +- v->RequiredDISPCLK[j +- * NumberOfStatesPlusTwo +- + i], +- v->MinDispclkUsingSingleDPP); +- if (v->MinDispclkUsingSingleDPP +- > dml_min( +- v->MaxDispclk[i], +- (j + 1) +- * v->MaxDppclk[i])) { +- v->DISPCLK_DPPCLK_Support[j +- * NumberOfStatesPlusTwo + i] = +- 0; +- } +- } else { +- v->NoOfDPP[ijk] = 2; +- v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = +- dml_max( +- v->RequiredDISPCLK[j +- * NumberOfStatesPlusTwo +- + i], +- v->MinDispclkUsingDualDPP); +- if (v->MinDispclkUsingDualDPP +- > dml_min( +- v->MaxDispclk[i], +- (j + 1) +- * v->MaxDppclk[i])) { +- v->DISPCLK_DPPCLK_Support[j +- * NumberOfStatesPlusTwo + i] = +- 0; +- } +- } +- v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = +- v->TotalNumberOfActiveDPP[j +- * NumberOfStatesPlusTwo + i] +- + v->NoOfDPP[ijk]; +- } +- } +- } +- } +- +- // Viewport Size Check +- +- v->ViewportSizeSupport = 1; +- +- for (k = 0; k < num_planes; k++) { +- if (v->NumberOfDPPRequiredForDETAndLBSize[k] > 2) { +- v->ViewportSizeSupport = 0; +- } +- } +- +- // Total Available Pipes Support Check +- +- for (i = 0; i < NumberOfStatesPlusTwo; i++) { +- for (j = 0; j < 2; j++) { +- if (v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] +- <= ip->max_num_dpp) { +- v->TotalAvailablePipesSupport[j * NumberOfStatesPlusTwo + i] = 1; +- } else { +- v->TotalAvailablePipesSupport[j * NumberOfStatesPlusTwo + i] = 0; +- } +- } +- } +- +- // Urgent Latency Support Check +- +- for (j = 0; j < 2; j++) { +- for (i = 0; i < NumberOfStatesPlusTwo; i++) { +- ij = j * NumberOfStatesPlusTwo + i; +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_source_params_st src = +- e2e[v->planes[k].e2e_index].pipe.src; +- struct _vcs_dpi_display_pipe_dest_params_st dest = +- e2e[v->planes[k].e2e_index].pipe.dest; +- struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = +- e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; +- struct _vcs_dpi_scaler_taps_st scale_taps = +- e2e[v->planes[k].e2e_index].pipe.scale_taps; +- ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; +- +- v->SwathWidthYPerState[ijk] = v->SwathWidthYSingleDPP[k] +- / v->NoOfDPP[ijk]; +- +- v->SwathWidthGranularityY = 256 +- / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) +- / v->MaxSwathHeightY[k]; +- v->RoundedUpMaxSwathSizeBytesY = (dml_ceil_ex( +- v->SwathWidthYPerState[ijk] - 1, +- v->SwathWidthGranularityY) +- + v->SwathWidthGranularityY) +- * v->BytePerPixelInDETY[k] * v->MaxSwathHeightY[k]; +- if (src.source_format == dm_420_10) { +- v->RoundedUpMaxSwathSizeBytesY = dml_ceil_ex( +- v->RoundedUpMaxSwathSizeBytesY, +- 256) + 256; +- } +- if (v->MaxSwathHeightC[k] > 0) { +- v->SwathWidthGranularityC = 256 +- / dml_ceil_ex(v->BytePerPixelInDETC[k], 2) +- / v->MaxSwathHeightC[k]; +- } +- v->RoundedUpMaxSwathSizeBytesC = (dml_ceil_ex( +- v->SwathWidthYPerState[ijk] / 2 - 1, +- v->SwathWidthGranularityC) +- + v->SwathWidthGranularityC) +- * v->BytePerPixelInDETC[k] * v->MaxSwathHeightC[k]; +- if (src.source_format == dm_420_10) { +- v->RoundedUpMaxSwathSizeBytesC = dml_ceil_ex( +- v->RoundedUpMaxSwathSizeBytesC, +- 256) + 256; +- } +- +- if (v->RoundedUpMaxSwathSizeBytesY + v->RoundedUpMaxSwathSizeBytesC +- <= ip->det_buffer_size_kbytes * 1024 / 2) { +- v->SwathHeightYPerState[ijk] = v->MaxSwathHeightY[k]; +- v->SwathHeightCPerState[ijk] = v->MaxSwathHeightC[k]; +- } else { +- v->SwathHeightYPerState[ijk] = v->MinSwathHeightY[k]; +- v->SwathHeightCPerState[ijk] = v->MinSwathHeightC[k]; +- } +- +- if (v->BytePerPixelInDETC[k] == 0) { +- v->LinesInDETLuma = ip->det_buffer_size_kbytes * 1024 +- / v->BytePerPixelInDETY[k] +- / v->SwathWidthYPerState[ijk]; +- +- v->LinesInDETChroma = 0; +- } else if (v->SwathHeightYPerState[ijk] +- <= v->SwathHeightCPerState[ijk]) { +- v->LinesInDETLuma = ip->det_buffer_size_kbytes * 1024 / 2 +- / v->BytePerPixelInDETY[k] +- / v->SwathWidthYPerState[ijk]; +- v->LinesInDETChroma = ip->det_buffer_size_kbytes * 1024 / 2 +- / v->BytePerPixelInDETC[k] +- / (v->SwathWidthYPerState[ijk] / 2); +- } else { +- v->LinesInDETLuma = ip->det_buffer_size_kbytes * 1024 * 2 +- / 3 / v->BytePerPixelInDETY[k] +- / v->SwathWidthYPerState[ijk]; +- v->LinesInDETChroma = ip->det_buffer_size_kbytes * 1024 / 3 +- / v->BytePerPixelInDETY[k] +- / (v->SwathWidthYPerState[ijk] / 2); +- } +- +- v->EffectiveLBLatencyHidingSourceLinesLuma = +- dml_min( +- ip->max_line_buffer_lines, +- dml_floor_ex( +- ip->line_buffer_size_bits +- / scale_ratio_depth.lb_depth +- / (v->SwathWidthYPerState[ijk] +- / dml_max( +- scale_ratio_depth.hscl_ratio, +- 1)), +- 1)) +- - (scale_taps.vtaps - 1); +- +- v->EffectiveLBLatencyHidingSourceLinesChroma = +- dml_min( +- ip->max_line_buffer_lines, +- dml_floor_ex( +- ip->line_buffer_size_bits +- / scale_ratio_depth.lb_depth +- / (v->SwathWidthYPerState[ijk] +- / 2 +- / dml_max( +- scale_ratio_depth.hscl_ratio +- / 2, +- 1)), +- 1)) +- - (scale_taps.vtaps_c - 1); +- +- v->EffectiveDETLBLinesLuma = +- dml_floor_ex( +- v->LinesInDETLuma +- + dml_min( +- v->LinesInDETLuma +- * v->RequiredDISPCLK[ij] +- * v->BytePerPixelInDETY[k] +- * v->PSCL_FACTOR[k] +- / v->ReturnBWPerState[i], +- v->EffectiveLBLatencyHidingSourceLinesLuma), +- v->SwathHeightYPerState[ijk]); +- +- v->EffectiveDETLBLinesChroma = +- dml_floor_ex( +- v->LinesInDETChroma +- + dml_min( +- v->LinesInDETChroma +- * v->RequiredDISPCLK[ij] +- * v->BytePerPixelInDETC[k] +- * v->PSCL_FACTOR_CHROMA[k] +- / v->ReturnBWPerState[i], +- v->EffectiveLBLatencyHidingSourceLinesChroma), +- v->SwathHeightCPerState[ijk]); +- +- if (v->BytePerPixelInDETC[k] == 0) { +- v->UrgentLatencySupportUsPerState[ijk] = +- v->EffectiveDETLBLinesLuma +- * (dest.htotal +- / dest.pixel_rate_mhz) +- / scale_ratio_depth.vscl_ratio +- - v->EffectiveDETLBLinesLuma +- * v->SwathWidthYPerState[ijk] +- * dml_ceil_ex( +- v->BytePerPixelInDETY[k], +- 1) +- / (v->ReturnBWPerState[i] +- / v->NoOfDPP[ijk]); +- } else { +- v->UrgentLatencySupportUsPerState[ijk] = +- dml_min( +- v->EffectiveDETLBLinesLuma +- * (dest.htotal +- / dest.pixel_rate_mhz) +- / scale_ratio_depth.vscl_ratio +- - v->EffectiveDETLBLinesLuma +- * v->SwathWidthYPerState[ijk] +- * dml_ceil_ex( +- v->BytePerPixelInDETY[k], +- 1) +- / (v->ReturnBWPerState[i] +- / v->NoOfDPP[ijk]), +- v->EffectiveDETLBLinesChroma +- * (dest.htotal +- / dest.pixel_rate_mhz) +- / (scale_ratio_depth.vscl_ratio +- / 2) +- - v->EffectiveDETLBLinesChroma +- * v->SwathWidthYPerState[ijk] +- / 2 +- * dml_ceil_ex( +- v->BytePerPixelInDETC[k], +- 2) +- / (v->ReturnBWPerState[i] +- / v->NoOfDPP[ijk])); +- } +- +- } +- } +- } +- +- for (i = 0; i < NumberOfStatesPlusTwo; i++) { +- for (j = 0; j < 2; j++) { +- ij = j * NumberOfStatesPlusTwo + i; +- +- v->UrgentLatencySupport[ij] = 1; +- for (k = 0; k < num_planes; k++) { +- ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; +- +- if (v->UrgentLatencySupportUsPerState[ijk] +- < soc->urgent_latency_us / 1) { +- v->UrgentLatencySupport[ij] = 0; +- } +- } +- } +- } +- +- // Prefetch Check +- +- for (i = 0; i < NumberOfStatesPlusTwo; i++) { +- for (j = 0; j < 2; j++) { +- ij = j * NumberOfStatesPlusTwo + i; +- +- v->TotalNumberOfDCCActiveDPP[ij] = 0; +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_source_params_st src = +- e2e[v->planes[k].e2e_index].pipe.src; +- ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; +- +- if (src.dcc == 1) { +- v->TotalNumberOfDCCActiveDPP[ij] = +- v->TotalNumberOfDCCActiveDPP[ij] +- + v->NoOfDPP[ijk]; +- } +- } +- } +- } +- +- for (i = 0; i < NumberOfStatesPlusTwo; i++) { +- for (j = 0; j < 2; j++) { +- ij = j * NumberOfStatesPlusTwo + i; +- +- v->ProjectedDCFCLKDeepSleep = 8; +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_dest_params_st dest = +- e2e[v->planes[k].e2e_index].pipe.dest; +- struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = +- e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; +- ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; +- +- v->ProjectedDCFCLKDeepSleep = dml_max( +- v->ProjectedDCFCLKDeepSleep, +- dest.pixel_rate_mhz / 16); +- if (v->BytePerPixelInDETC[k] == 0) { +- if (scale_ratio_depth.vscl_ratio <= 1) { +- v->ProjectedDCFCLKDeepSleep = +- dml_max( +- v->ProjectedDCFCLKDeepSleep, +- 1.1 +- * dml_ceil_ex( +- v->BytePerPixelInDETY[k], +- 1) +- / 64 +- * scale_ratio_depth.hscl_ratio +- * dest.pixel_rate_mhz +- / v->NoOfDPP[ijk]); +- } else { +- v->ProjectedDCFCLKDeepSleep = +- dml_max( +- v->ProjectedDCFCLKDeepSleep, +- 1.1 +- * dml_ceil_ex( +- v->BytePerPixelInDETY[k], +- 1) +- / 64 +- * v->PSCL_FACTOR[k] +- * v->RequiredDISPCLK[ij] +- / (1 +- + j)); +- } +- +- } else { +- if (scale_ratio_depth.vscl_ratio <= 1) { +- v->ProjectedDCFCLKDeepSleep = +- dml_max( +- v->ProjectedDCFCLKDeepSleep, +- 1.1 +- * dml_ceil_ex( +- v->BytePerPixelInDETY[k], +- 1) +- / 32 +- * scale_ratio_depth.hscl_ratio +- * dest.pixel_rate_mhz +- / v->NoOfDPP[ijk]); +- } else { +- v->ProjectedDCFCLKDeepSleep = +- dml_max( +- v->ProjectedDCFCLKDeepSleep, +- 1.1 +- * dml_ceil_ex( +- v->BytePerPixelInDETY[k], +- 1) +- / 32 +- * v->PSCL_FACTOR[k] +- * v->RequiredDISPCLK[ij] +- / (1 +- + j)); +- } +- if ((scale_ratio_depth.vscl_ratio / 2) <= 1) { +- v->ProjectedDCFCLKDeepSleep = +- dml_max( +- v->ProjectedDCFCLKDeepSleep, +- 1.1 +- * dml_ceil_ex( +- v->BytePerPixelInDETC[k], +- 2) +- / 32 +- * scale_ratio_depth.hscl_ratio +- / 2 +- * dest.pixel_rate_mhz +- / v->NoOfDPP[ijk]); +- } else { +- v->ProjectedDCFCLKDeepSleep = +- dml_max( +- v->ProjectedDCFCLKDeepSleep, +- 1.1 +- * dml_ceil_ex( +- v->BytePerPixelInDETC[k], +- 2) +- / 32 +- * v->PSCL_FACTOR_CHROMA[k] +- * v->RequiredDISPCLK[ij] +- / (1 +- + j)); +- } +- +- } +- } +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_source_params_st src = +- e2e[v->planes[k].e2e_index].pipe.src; +- struct _vcs_dpi_display_pipe_dest_params_st dest = +- e2e[v->planes[k].e2e_index].pipe.dest; +- struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = +- e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; +- struct _vcs_dpi_scaler_taps_st scale_taps = +- e2e[v->planes[k].e2e_index].pipe.scale_taps; +- struct _vcs_dpi_display_output_params_st dout = +- e2e[v->planes[k].e2e_index].dout; +- ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; +- +- if (src.dcc == 1) { +- v->MetaReqHeightY = 8 * v->Read256BlockHeightY[k]; +- v->MetaReqWidthY = 64 * 256 +- / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) +- / v->MetaReqHeightY; +- v->MetaSurfaceWidthY = dml_ceil_ex( +- src.viewport_width / v->NoOfDPP[ijk] - 1, +- v->MetaReqWidthY) + v->MetaReqWidthY; +- v->MetaSurfaceHeightY = dml_ceil_ex( +- src.viewport_height - 1, +- v->MetaReqHeightY) + v->MetaReqHeightY; +- if (ip->pte_enable == 1) { +- v->MetaPteBytesPerFrameY = +- (dml_ceil_ex( +- (v->MetaSurfaceWidthY +- * v->MetaSurfaceHeightY +- * dml_ceil_ex( +- v->BytePerPixelInDETY[k], +- 1) +- / 256.0 +- - 4096) +- / 8 +- / 4096, +- 1) + 1) * 64; +- } else { +- v->MetaPteBytesPerFrameY = 0; +- } +- if (src.source_scan == dm_horz) { +- v->MetaRowBytesY = +- v->MetaSurfaceWidthY +- * v->MetaReqHeightY +- * dml_ceil_ex( +- v->BytePerPixelInDETY[k], +- 1) +- / 256; +- } else { +- v->MetaRowBytesY = +- v->MetaSurfaceHeightY +- * v->MetaReqWidthY +- * dml_ceil_ex( +- v->BytePerPixelInDETY[k], +- 1) +- / 256; +- } +- } else { +- v->MetaPteBytesPerFrameY = 0; +- v->MetaRowBytesY = 0; +- } +- +- if (ip->pte_enable == 1) { +- if (src.sw_mode == dm_sw_linear) { +- v->MacroTileBlockSizeBytesY = 256; +- v->MacroTileBlockHeightY = 1; +- } else if (src.sw_mode == dm_sw_4kb_s +- || src.sw_mode == dm_sw_4kb_s_x +- || src.sw_mode == dm_sw_4kb_d +- || src.sw_mode == dm_sw_4kb_d_x) { +- v->MacroTileBlockSizeBytesY = 4096; +- v->MacroTileBlockHeightY = 4 +- * v->Read256BlockHeightY[k]; +- } else if (src.sw_mode == dm_sw_64kb_s +- || src.sw_mode == dm_sw_64kb_s_t +- || src.sw_mode == dm_sw_64kb_s_x +- || src.sw_mode == dm_sw_64kb_d +- || src.sw_mode == dm_sw_64kb_d_t +- || src.sw_mode == dm_sw_64kb_d_x) { +- v->MacroTileBlockSizeBytesY = 64 * 1024; +- v->MacroTileBlockHeightY = 16 +- * v->Read256BlockHeightY[k]; +- } else { +- v->MacroTileBlockSizeBytesY = 256 * 1024; +- v->MacroTileBlockHeightY = 32 +- * v->Read256BlockHeightY[k]; +- } +- if (v->MacroTileBlockSizeBytesY <= 65536) { +- v->DataPTEReqHeightY = v->MacroTileBlockHeightY; +- } else { +- v->DataPTEReqHeightY = 16 +- * v->Read256BlockHeightY[k]; +- } +- v->DataPTEReqWidthY = 4096 +- / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) +- / v->DataPTEReqHeightY * 8; +- if (src.sw_mode == dm_sw_linear) { +- v->DPTEBytesPerRowY = +- 64 +- * (dml_ceil_ex( +- (src.viewport_width +- / v->NoOfDPP[ijk] +- * dml_min( +- 128, +- dml_pow( +- 2, +- dml_floor_ex( +- dml_log( +- ip->dpte_buffer_size_in_pte_reqs +- * v->DataPTEReqWidthY +- / (src.viewport_width +- / v->NoOfDPP[ijk]), +- 2), +- 1))) +- - 1) +- / v->DataPTEReqWidthY, +- 1) +- + 1); +- } else if (src.source_scan == dm_horz) { +- v->DPTEBytesPerRowY = +- 64 +- * (dml_ceil_ex( +- (src.viewport_width +- / v->NoOfDPP[ijk] +- - 1) +- / v->DataPTEReqWidthY, +- 1) +- + 1); +- } else { +- v->DPTEBytesPerRowY = +- 64 +- * (dml_ceil_ex( +- (src.viewport_height +- - 1) +- / v->DataPTEReqHeightY, +- 1) +- + 1); +- } +- } else { +- v->DPTEBytesPerRowY = 0; +- } +- +- if (src.source_format != dm_444_64 && src.source_format != dm_444_32 +- && src.source_format != dm_444_16) { +- if (src.dcc == 1) { +- v->MetaReqHeightC = 8 * v->Read256BlockHeightC[k]; +- v->MetaReqWidthC = +- 64 * 256 +- / dml_ceil_ex( +- v->BytePerPixelInDETC[k], +- 2) +- / v->MetaReqHeightC; +- v->MetaSurfaceWidthC = dml_ceil_ex( +- src.viewport_width / v->NoOfDPP[ijk] +- / 2 - 1, +- v->MetaReqWidthC) +- + v->MetaReqWidthC; +- v->MetaSurfaceHeightC = dml_ceil_ex( +- src.viewport_height / 2 - 1, +- v->MetaReqHeightC) +- + v->MetaReqHeightC; +- if (ip->pte_enable == 1) { +- v->MetaPteBytesPerFrameC = +- (dml_ceil_ex( +- (v->MetaSurfaceWidthC +- * v->MetaSurfaceHeightC +- * dml_ceil_ex( +- v->BytePerPixelInDETC[k], +- 2) +- / 256.0 +- - 4096) +- / 8 +- / 4096, +- 1) + 1) +- * 64; +- } else { +- v->MetaPteBytesPerFrameC = 0; +- } +- if (src.source_scan == dm_horz) { +- v->MetaRowBytesC = +- v->MetaSurfaceWidthC +- * v->MetaReqHeightC +- * dml_ceil_ex( +- v->BytePerPixelInDETC[k], +- 2) +- / 256; +- } else { +- v->MetaRowBytesC = +- v->MetaSurfaceHeightC +- * v->MetaReqWidthC +- * dml_ceil_ex( +- v->BytePerPixelInDETC[k], +- 2) +- / 256; +- } +- } else { +- v->MetaPteBytesPerFrameC = 0; +- v->MetaRowBytesC = 0; +- } +- +- if (ip->pte_enable == 1) { +- if (src.sw_mode == dm_sw_linear) { +- v->MacroTileBlockSizeBytesC = 256; +- v->MacroTileBlockHeightC = 1; +- } else if (src.sw_mode == dm_sw_4kb_s +- || src.sw_mode == dm_sw_4kb_s_x +- || src.sw_mode == dm_sw_4kb_d +- || src.sw_mode == dm_sw_4kb_d_x) { +- v->MacroTileBlockSizeBytesC = 4096; +- v->MacroTileBlockHeightC = 4 +- * v->Read256BlockHeightC[k]; +- } else if (src.sw_mode == dm_sw_64kb_s +- || src.sw_mode == dm_sw_64kb_s_t +- || src.sw_mode == dm_sw_64kb_s_x +- || src.sw_mode == dm_sw_64kb_d +- || src.sw_mode == dm_sw_64kb_d_t +- || src.sw_mode == dm_sw_64kb_d_x) { +- v->MacroTileBlockSizeBytesC = 64 * 1024; +- v->MacroTileBlockHeightC = 16 +- * v->Read256BlockHeightC[k]; +- } else { +- v->MacroTileBlockSizeBytesC = 256 * 1024; +- v->MacroTileBlockHeightC = 32 +- * v->Read256BlockHeightC[k]; +- } +- v->MacroTileBlockWidthC = +- v->MacroTileBlockSizeBytesC +- / dml_ceil_ex( +- v->BytePerPixelInDETC[k], +- 2) +- / v->MacroTileBlockHeightC; +- if (v->MacroTileBlockSizeBytesC <= 65536) { +- v->DataPTEReqHeightC = +- v->MacroTileBlockHeightC; +- } else { +- v->DataPTEReqHeightC = 16 +- * v->Read256BlockHeightC[k]; +- } +- v->DataPTEReqWidthC = +- 4096 +- / dml_ceil_ex( +- v->BytePerPixelInDETC[k], +- 2) +- / v->DataPTEReqHeightC +- * 8; +- if (src.sw_mode == dm_sw_linear) { +- v->DPTEBytesPerRowC = +- 64 +- * (dml_ceil_ex( +- (src.viewport_width +- / v->NoOfDPP[ijk] +- / 2 +- * dml_min( +- 128, +- dml_pow( +- 2, +- dml_floor_ex( +- dml_log( +- ip->dpte_buffer_size_in_pte_reqs +- * v->DataPTEReqWidthC +- / (src.viewport_width +- / v->NoOfDPP[ijk] +- / 2), +- 2), +- 1))) +- - 1) +- / v->DataPTEReqWidthC, +- 1) +- + 1); +- } else if (src.source_scan == dm_horz) { +- v->DPTEBytesPerRowC = +- 64 +- * (dml_ceil_ex( +- (src.viewport_width +- / v->NoOfDPP[ijk] +- / 2 +- - 1) +- / v->DataPTEReqWidthC, +- 1) +- + 1); +- } else { +- v->DPTEBytesPerRowC = +- 64 +- * (dml_ceil_ex( +- (src.viewport_height +- / 2 +- - 1) +- / v->DataPTEReqHeightC, +- 1) +- + 1); +- } +- } else { +- v->DPTEBytesPerRowC = 0; +- } +- } else { +- v->DPTEBytesPerRowC = 0; +- v->MetaPteBytesPerFrameC = 0; +- v->MetaRowBytesC = 0; +- } +- +- v->DPTEBytesPerRow[k] = v->DPTEBytesPerRowY + v->DPTEBytesPerRowC; +- v->MetaPTEBytesPerFrame[k] = v->MetaPteBytesPerFrameY +- + v->MetaPteBytesPerFrameC; +- v->MetaRowBytes[k] = v->MetaRowBytesY + v->MetaRowBytesC; +- +- v->VInitY = (scale_ratio_depth.vscl_ratio + scale_taps.vtaps + 1 +- + dest.interlaced * 0.5 +- * scale_ratio_depth.vscl_ratio) +- / 2.0; +- v->PrefillY[k] = dml_floor_ex(v->VInitY, 1); +- v->MaxNumSwY[k] = dml_ceil_ex( +- (v->PrefillY[k] - 1.0) +- / v->SwathHeightYPerState[ijk], +- 1) + 1.0; +- +- if (v->PrefillY[k] > 1) { +- v->MaxPartialSwY = ((int) (v->PrefillY[k] - 2)) +- % ((int) v->SwathHeightYPerState[ijk]); +- } else { +- v->MaxPartialSwY = ((int) (v->PrefillY[k] +- + v->SwathHeightYPerState[ijk] - 2)) +- % ((int) v->SwathHeightYPerState[ijk]); +- } +- v->MaxPartialSwY = dml_max(1, v->MaxPartialSwY); +- +- v->PrefetchLinesY[k] = v->MaxNumSwY[k] +- * v->SwathHeightYPerState[ijk] + v->MaxPartialSwY; +- +- if (src.source_format != dm_444_64 && src.source_format != dm_444_32 +- && src.source_format != dm_444_16) { +- v->VInitC = +- (scale_ratio_depth.vscl_ratio / 2 +- + scale_taps.vtaps + 1 +- + dest.interlaced * 0.5 +- * scale_ratio_depth.vscl_ratio +- / 2) / 2.0; +- v->PrefillC[k] = dml_floor_ex(v->VInitC, 1); +- v->MaxNumSwC[k] = +- dml_ceil_ex( +- (v->PrefillC[k] - 1.0) +- / v->SwathHeightCPerState[ijk], +- 1) + 1.0; +- if (v->PrefillC[k] > 1) { +- v->MaxPartialSwC = +- ((int) (v->PrefillC[k] - 2)) +- % ((int) v->SwathHeightCPerState[ijk]); +- } else { +- v->MaxPartialSwC = +- ((int) (v->PrefillC[k] +- + v->SwathHeightCPerState[ijk] +- - 2)) +- % ((int) v->SwathHeightCPerState[ijk]); +- } +- v->MaxPartialSwC = dml_max(1, v->MaxPartialSwC); +- +- v->PrefetchLinesC[k] = v->MaxNumSwC[k] +- * v->SwathHeightCPerState[ijk] +- + v->MaxPartialSwC; +- } else { +- v->PrefetchLinesC[k] = 0; +- } +- +- v->dst_x_after_scaler = 90 * dest.pixel_rate_mhz +- / (v->RequiredDISPCLK[ij] / (j + 1)) +- + 42 * dest.pixel_rate_mhz / v->RequiredDISPCLK[ij]; +- if (v->NoOfDPP[ijk] > 1) { +- v->dst_x_after_scaler = v->dst_x_after_scaler +- + dest.recout_width / 2.0; +- } +- +- if (dout.output_format == dm_420) { +- v->dst_y_after_scaler = 1; +- } else { +- v->dst_y_after_scaler = 0; +- } +- +- v->TimeCalc = 24 / v->ProjectedDCFCLKDeepSleep; +- +- v->VUpdateOffset = dml_ceil_ex(dest.htotal / 4, 1); +- v->TotalRepeaterDelay = ip->max_inter_dcn_tile_repeaters +- * (2 / (v->RequiredDISPCLK[ij] / (j + 1)) +- + 3 / v->RequiredDISPCLK[ij]); +- v->VUpdateWidth = (14 / v->ProjectedDCFCLKDeepSleep +- + 12 / (v->RequiredDISPCLK[ij] / (j + 1)) +- + v->TotalRepeaterDelay) * dest.pixel_rate_mhz; +- v->VReadyOffset = +- dml_max( +- 150 +- / (v->RequiredDISPCLK[ij] +- / (j +- + 1)), +- v->TotalRepeaterDelay +- + 20 +- / v->ProjectedDCFCLKDeepSleep +- + 10 +- / (v->RequiredDISPCLK[ij] +- / (j +- + 1))) +- * dest.pixel_rate_mhz; +- +- v->TimeSetup = +- (v->VUpdateOffset + v->VUpdateWidth +- + v->VReadyOffset) +- / dest.pixel_rate_mhz; +- +- v->ExtraLatency = +- v->UrgentRoundTripAndOutOfOrderLatencyPerState[i] +- + (v->TotalNumberOfActiveDPP[ij] +- * ip->pixel_chunk_size_kbytes +- + v->TotalNumberOfDCCActiveDPP[ij] +- * ip->meta_chunk_size_kbytes) +- * 1024 +- / v->ReturnBWPerState[i]; +- +- if (ip->pte_enable == 1) { +- v->ExtraLatency = v->ExtraLatency +- + v->TotalNumberOfActiveDPP[ij] +- * ip->pte_chunk_size_kbytes +- * 1024 +- / v->ReturnBWPerState[i]; +- } +- +- if (ip->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one +- == 1) { +- v->MaximumVStartup = dest.vtotal - dest.vactive - 1; +- } else { +- v->MaximumVStartup = dest.vsync_plus_back_porch - 1; +- } +- +- v->LineTimesForPrefetch[k] = +- v->MaximumVStartup +- - soc->urgent_latency_us +- / (dest.htotal +- / dest.pixel_rate_mhz) +- - (v->TimeCalc + v->TimeSetup) +- / (dest.htotal +- / dest.pixel_rate_mhz) +- - (v->dst_y_after_scaler +- + v->dst_x_after_scaler +- / dest.htotal); +- +- v->LineTimesForPrefetch[k] = dml_floor_ex( +- 4.0 * (v->LineTimesForPrefetch[k] + 0.125), +- 1) / 4; +- +- v->PrefetchBW[k] = +- (v->MetaPTEBytesPerFrame[k] + 2 * v->MetaRowBytes[k] +- + 2 * v->DPTEBytesPerRow[k] +- + v->PrefetchLinesY[k] +- * v->SwathWidthYPerState[ijk] +- * dml_ceil_ex( +- v->BytePerPixelInDETY[k], +- 1) +- + v->PrefetchLinesC[k] +- * v->SwathWidthYPerState[ijk] +- / 2 +- * dml_ceil_ex( +- v->BytePerPixelInDETC[k], +- 2)) +- / (v->LineTimesForPrefetch[k] +- * dest.htotal +- / dest.pixel_rate_mhz); +- } +- +- v->BWAvailableForImmediateFlip = v->ReturnBWPerState[i]; +- +- for (k = 0; k < num_planes; k++) { +- v->BWAvailableForImmediateFlip = v->BWAvailableForImmediateFlip +- - dml_max(v->ReadBandwidth[k], v->PrefetchBW[k]); +- } +- +- v->TotalImmediateFlipBytes = 0; +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_source_params_st src = +- e2e[v->planes[k].e2e_index].pipe.src; +- +- if (src.source_format != dm_420_8 +- && src.source_format != dm_420_10) { +- v->TotalImmediateFlipBytes = v->TotalImmediateFlipBytes +- + v->MetaPTEBytesPerFrame[k] +- + v->MetaRowBytes[k] +- + v->DPTEBytesPerRow[k]; +- } +- } +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_source_params_st src = +- e2e[v->planes[k].e2e_index].pipe.src; +- struct _vcs_dpi_display_pipe_dest_params_st dest = +- e2e[v->planes[k].e2e_index].pipe.dest; +- ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; +- +- if (ip->pte_enable == 1 && src.dcc == 1) { +- v->TimeForMetaPTEWithImmediateFlip = +- dml_max( +- v->MetaPTEBytesPerFrame[k] +- / v->PrefetchBW[k], +- dml_max( +- v->MetaPTEBytesPerFrame[k] +- * v->TotalImmediateFlipBytes +- / (v->BWAvailableForImmediateFlip +- * (v->MetaPTEBytesPerFrame[k] +- + v->MetaRowBytes[k] +- + v->DPTEBytesPerRow[k])), +- dml_max( +- v->ExtraLatency, +- dml_max( +- soc->urgent_latency_us, +- dest.htotal +- / dest.pixel_rate_mhz +- / 4)))); +- +- v->TimeForMetaPTEWithoutImmediateFlip = +- dml_max( +- v->MetaPTEBytesPerFrame[k] +- / v->PrefetchBW[k], +- dml_max( +- v->ExtraLatency, +- dest.htotal +- / dest.pixel_rate_mhz +- / 4)); +- } else { +- v->TimeForMetaPTEWithImmediateFlip = dest.htotal +- / dest.pixel_rate_mhz / 4; +- v->TimeForMetaPTEWithoutImmediateFlip = dest.htotal +- / dest.pixel_rate_mhz / 4; +- } +- +- if (ip->pte_enable == 1 || src.dcc == 1) { +- v->TimeForMetaAndDPTERowWithImmediateFlip = +- dml_max( +- (v->MetaRowBytes[k] +- + v->DPTEBytesPerRow[k]) +- / v->PrefetchBW[k], +- dml_max( +- (v->MetaRowBytes[k] +- + v->DPTEBytesPerRow[k]) +- * v->TotalImmediateFlipBytes +- / (v->BWAvailableForImmediateFlip +- * (v->MetaPTEBytesPerFrame[k] +- + v->MetaRowBytes[k] +- + v->DPTEBytesPerRow[k])), +- dml_max( +- dest.htotal +- / dest.pixel_rate_mhz +- - v->TimeForMetaPTEWithImmediateFlip, +- dml_max( +- v->ExtraLatency, +- 2 +- * soc->urgent_latency_us)))); +- +- v->TimeForMetaAndDPTERowWithoutImmediateFlip = +- dml_max( +- (v->MetaRowBytes[k] +- + v->DPTEBytesPerRow[k]) +- / v->PrefetchBW[k], +- dml_max( +- dest.htotal +- / dest.pixel_rate_mhz +- - v->TimeForMetaPTEWithoutImmediateFlip, +- v->ExtraLatency)); +- } else { +- v->TimeForMetaAndDPTERowWithImmediateFlip = +- dml_max( +- dest.htotal +- / dest.pixel_rate_mhz +- - v->TimeForMetaPTEWithImmediateFlip, +- v->ExtraLatency +- - v->TimeForMetaPTEWithImmediateFlip); +- v->TimeForMetaAndDPTERowWithoutImmediateFlip = +- dml_max( +- dest.htotal +- / dest.pixel_rate_mhz +- - v->TimeForMetaPTEWithoutImmediateFlip, +- v->ExtraLatency +- - v->TimeForMetaPTEWithoutImmediateFlip); +- } +- +- v->LinesForMetaPTEWithImmediateFlip[k] = +- dml_floor_ex( +- 4.0 +- * (v->TimeForMetaPTEWithImmediateFlip +- / (dest.htotal +- / dest.pixel_rate_mhz) +- + 0.125), +- 1) / 4.0; +- +- v->LinesForMetaPTEWithoutImmediateFlip[k] = +- dml_floor_ex( +- 4.0 +- * (v->TimeForMetaPTEWithoutImmediateFlip +- / (dest.htotal +- / dest.pixel_rate_mhz) +- + 0.125), +- 1) / 4.0; +- +- v->LinesForMetaAndDPTERowWithImmediateFlip[k] = +- dml_floor_ex( +- 4.0 +- * (v->TimeForMetaAndDPTERowWithImmediateFlip +- / (dest.htotal +- / dest.pixel_rate_mhz) +- + 0.125), +- 1) / 4.0; +- +- v->LinesForMetaAndDPTERowWithoutImmediateFlip[k] = +- dml_floor_ex( +- 4.0 +- * (v->TimeForMetaAndDPTERowWithoutImmediateFlip +- / (dest.htotal +- / dest.pixel_rate_mhz) +- + 0.125), +- 1) / 4.0; +- +- v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip = +- v->LineTimesForPrefetch[k] +- - v->LinesForMetaPTEWithImmediateFlip[k] +- - v->LinesForMetaAndDPTERowWithImmediateFlip[k]; +- +- v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip = +- v->LineTimesForPrefetch[k] +- - v->LinesForMetaPTEWithoutImmediateFlip[k] +- - v->LinesForMetaAndDPTERowWithoutImmediateFlip[k]; +- +- if (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip > 0) { +- v->VRatioPreYWithImmediateFlip[ijk] = +- v->PrefetchLinesY[k] +- / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip; +- if (v->SwathHeightYPerState[ijk] > 4) { +- if (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip +- - (v->PrefillY[k] - 3.0) / 2.0 +- > 0) { +- v->VRatioPreYWithImmediateFlip[ijk] = +- dml_max( +- v->VRatioPreYWithImmediateFlip[ijk], +- (v->MaxNumSwY[k] +- * v->SwathHeightYPerState[ijk]) +- / (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip +- - (v->PrefillY[k] +- - 3.0) +- / 2.0)); +- } else { +- v->VRatioPreYWithImmediateFlip[ijk] = +- 999999; +- } +- } +- v->VRatioPreCWithImmediateFlip[ijk] = +- v->PrefetchLinesC[k] +- / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip; +- if (v->SwathHeightCPerState[ijk] > 4) { +- if (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip +- - (v->PrefillC[k] - 3.0) / 2.0 +- > 0) { +- v->VRatioPreCWithImmediateFlip[ijk] = +- dml_max( +- v->VRatioPreCWithImmediateFlip[ijk], +- (v->MaxNumSwC[k] +- * v->SwathHeightCPerState[ijk]) +- / (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip +- - (v->PrefillC[k] +- - 3.0) +- / 2.0)); +- } else { +- v->VRatioPreCWithImmediateFlip[ijk] = +- 999999; +- } +- } +- +- v->RequiredPrefetchPixelDataBWWithImmediateFlip[ijk] = +- v->NoOfDPP[ijk] +- * (v->PrefetchLinesY[k] +- / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip +- * dml_ceil_ex( +- v->BytePerPixelInDETY[k], +- 1) +- + v->PrefetchLinesC[k] +- / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip +- * dml_ceil_ex( +- v->BytePerPixelInDETC[k], +- 2) +- / 2) +- * v->SwathWidthYPerState[ijk] +- / (dest.htotal +- / dest.pixel_rate_mhz); +- } else { +- v->VRatioPreYWithImmediateFlip[ijk] = 999999; +- v->VRatioPreCWithImmediateFlip[ijk] = 999999; +- v->RequiredPrefetchPixelDataBWWithImmediateFlip[ijk] = +- 999999; +- } +- +- if (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip +- > 0) { +- v->VRatioPreYWithoutImmediateFlip[ijk] = +- v->PrefetchLinesY[k] +- / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip; +- if (v->SwathHeightYPerState[ijk] > 4) { +- if (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip +- - (v->PrefillY[k] - 3.0) / 2.0 +- > 0) { +- v->VRatioPreYWithoutImmediateFlip[ijk] = +- dml_max( +- v->VRatioPreYWithoutImmediateFlip[ijk], +- (v->MaxNumSwY[k] +- * v->SwathHeightYPerState[ijk]) +- / (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip +- - (v->PrefillY[k] +- - 3.0) +- / 2.0)); +- } else { +- v->VRatioPreYWithoutImmediateFlip[ijk] = +- 999999; +- } +- } +- v->VRatioPreCWithoutImmediateFlip[ijk] = +- v->PrefetchLinesC[k] +- / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip; +- if (v->SwathHeightCPerState[ijk] > 4) { +- if (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip +- - (v->PrefillC[k] - 3.0) / 2.0 +- > 0) { +- v->VRatioPreCWithoutImmediateFlip[ijk] = +- dml_max( +- v->VRatioPreCWithoutImmediateFlip[ijk], +- (v->MaxNumSwC[k] +- * v->SwathHeightCPerState[ijk]) +- / (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip +- - (v->PrefillC[k] +- - 3.0) +- / 2.0)); +- } else { +- v->VRatioPreCWithoutImmediateFlip[ijk] = +- 999999; +- } +- } +- +- v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk] = +- v->NoOfDPP[ijk] +- * (v->PrefetchLinesY[k] +- / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip +- * dml_ceil_ex( +- v->BytePerPixelInDETY[k], +- 1) +- + v->PrefetchLinesC[k] +- / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip +- * dml_ceil_ex( +- v->BytePerPixelInDETC[k], +- 2) +- / 2) +- * v->SwathWidthYPerState[ijk] +- / (dest.htotal +- / dest.pixel_rate_mhz); +- } else { +- v->VRatioPreYWithoutImmediateFlip[ijk] = 999999; +- v->VRatioPreCWithoutImmediateFlip[ijk] = 999999; +- v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk] = +- 999999; +- } +- } +- +- v->MaximumReadBandwidthWithPrefetchWithImmediateFlip = 0; +- +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_source_params_st src = +- e2e[v->planes[k].e2e_index].pipe.src; +- struct _vcs_dpi_display_pipe_dest_params_st dest = +- e2e[v->planes[k].e2e_index].pipe.dest; +- ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; +- +- if (src.source_format != dm_420_8 +- && src.source_format != dm_420_10) { +- v->MaximumReadBandwidthWithPrefetchWithImmediateFlip = +- v->MaximumReadBandwidthWithPrefetchWithImmediateFlip +- + dml_max( +- v->ReadBandwidth[k], +- v->RequiredPrefetchPixelDataBWWithImmediateFlip[ijk]) +- + dml_max( +- v->MetaPTEBytesPerFrame[k] +- / (v->LinesForMetaPTEWithImmediateFlip[k] +- * dest.htotal +- / dest.pixel_rate_mhz), +- (v->MetaRowBytes[k] +- + v->DPTEBytesPerRow[k]) +- / (v->LinesForMetaAndDPTERowWithImmediateFlip[k] +- * dest.htotal +- / dest.pixel_rate_mhz)); +- } else { +- v->MaximumReadBandwidthWithPrefetchWithImmediateFlip = +- v->MaximumReadBandwidthWithPrefetchWithImmediateFlip +- + dml_max( +- v->ReadBandwidth[k], +- v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk]); +- } +- } +- +- v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip = 0; +- +- for (k = 0; k < num_planes; k++) { +- ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; +- +- v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip = +- v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip +- + dml_max( +- v->ReadBandwidth[k], +- v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk]); +- } +- +- v->PrefetchSupportedWithImmediateFlip[ij] = 1; +- if (v->MaximumReadBandwidthWithPrefetchWithImmediateFlip +- > v->ReturnBWPerState[i]) { +- v->PrefetchSupportedWithImmediateFlip[ij] = 0; +- } +- for (k = 0; k < num_planes; k++) { +- if (v->LineTimesForPrefetch[k] < 2 +- || v->LinesForMetaPTEWithImmediateFlip[k] >= 8 +- || v->LinesForMetaAndDPTERowWithImmediateFlip[k] +- >= 16) { +- v->PrefetchSupportedWithImmediateFlip[ij] = 0; +- } +- } +- +- v->PrefetchSupportedWithoutImmediateFlip[ij] = 1; +- if (v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip +- > v->ReturnBWPerState[i]) { +- v->PrefetchSupportedWithoutImmediateFlip[ij] = 0; +- } +- for (k = 0; k < num_planes; k++) { +- if (v->LineTimesForPrefetch[k] < 2 +- || v->LinesForMetaPTEWithoutImmediateFlip[k] >= 8 +- || v->LinesForMetaAndDPTERowWithoutImmediateFlip[k] +- >= 16) { +- v->PrefetchSupportedWithoutImmediateFlip[ij] = 0; +- } +- } +- } +- } +- +- for (i = 0; i < NumberOfStatesPlusTwo; i++) { +- for (j = 0; j < 2; j++) { +- ij = j * NumberOfStatesPlusTwo + i; +- +- v->VRatioInPrefetchSupportedWithImmediateFlip[ij] = 1; +- for (k = 0; k < num_planes; k++) { +- struct _vcs_dpi_display_pipe_source_params_st src = +- e2e[v->planes[k].e2e_index].pipe.src; +- ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; +- +- if (((src.source_format != dm_420_8 +- && src.source_format != dm_420_10) +- && (v->VRatioPreYWithImmediateFlip[ijk] > 4 +- || v->VRatioPreCWithImmediateFlip[ijk] +- > 4)) +- || ((src.source_format == dm_420_8 +- || src.source_format == dm_420_10) +- && (v->VRatioPreYWithoutImmediateFlip[ijk] +- > 4 +- || v->VRatioPreCWithoutImmediateFlip[ijk] +- > 4))) { +- v->VRatioInPrefetchSupportedWithImmediateFlip[ij] = 0; +- } +- } +- v->VRatioInPrefetchSupportedWithoutImmediateFlip[ij] = 1; +- for (k = 0; k < num_planes; k++) { +- ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; +- +- if (v->VRatioPreYWithoutImmediateFlip[ijk] > 4 +- || v->VRatioPreCWithoutImmediateFlip[ijk] > 4) { +- v->VRatioInPrefetchSupportedWithoutImmediateFlip[ij] = 0; +- } +- } +- } +- } +- +- // Mode Support, Voltage State and SOC Configuration +- +- for (i = (NumberOfStatesPlusTwo - 1); i >= 0; i--) // use int type here +- { +- for (j = 0; j < 2; j++) { +- ij = j * NumberOfStatesPlusTwo + i; +- +- if (v->ScaleRatioSupport == 1 && v->SourceFormatPixelAndScanSupport == 1 +- && v->ViewportSizeSupport == 1 +- && v->BandwidthSupport[i] == 1 && v->DIOSupport[i] == 1 +- && v->UrgentLatencySupport[ij] == 1 && v->ROBSupport[i] == 1 +- && v->DISPCLK_DPPCLK_Support[ij] == 1 +- && v->TotalAvailablePipesSupport[ij] == 1 +- && v->TotalAvailableWritebackSupport == 1 +- && v->WritebackLatencySupport == 1) { +- if (v->PrefetchSupportedWithImmediateFlip[ij] == 1 +- && v->VRatioInPrefetchSupportedWithImmediateFlip[ij] +- == 1) { +- v->ModeSupportWithImmediateFlip[ij] = 1; +- } else { +- v->ModeSupportWithImmediateFlip[ij] = 0; +- } +- if (v->PrefetchSupportedWithoutImmediateFlip[ij] == 1 +- && v->VRatioInPrefetchSupportedWithoutImmediateFlip[ij] +- == 1) { +- v->ModeSupportWithoutImmediateFlip[ij] = 1; +- } else { +- v->ModeSupportWithoutImmediateFlip[ij] = 0; +- } +- } else { +- v->ModeSupportWithImmediateFlip[ij] = 0; +- v->ModeSupportWithoutImmediateFlip[ij] = 0; +- } +- } +- } +- +- for (i = (NumberOfStatesPlusTwo - 1); i >= 0; i--) // use int type here +- { +- if ((i == (NumberOfStatesPlusTwo - 1) +- || v->ModeSupportWithImmediateFlip[1 * NumberOfStatesPlusTwo + i] +- == 1 +- || v->ModeSupportWithImmediateFlip[0 * NumberOfStatesPlusTwo + i] +- == 1) && i >= v->VoltageOverrideLevel) { +- v->VoltageLevelWithImmediateFlip = i; +- } +- } +- +- for (i = (NumberOfStatesPlusTwo - 1); i >= 0; i--) // use int type here +- { +- if ((i == (NumberOfStatesPlusTwo - 1) +- || v->ModeSupportWithoutImmediateFlip[1 * NumberOfStatesPlusTwo + i] +- == 1 +- || v->ModeSupportWithoutImmediateFlip[0 * NumberOfStatesPlusTwo + i] +- == 1) && i >= v->VoltageOverrideLevel) { +- v->VoltageLevelWithoutImmediateFlip = i; +- } +- } +- +- if (v->VoltageLevelWithImmediateFlip == (NumberOfStatesPlusTwo - 1)) { +- v->ImmediateFlipSupported = 0; +- v->VoltageLevel = v->VoltageLevelWithoutImmediateFlip; +- } else { +- v->ImmediateFlipSupported = 1; +- v->VoltageLevel = v->VoltageLevelWithImmediateFlip; +- } +- +- v->DCFCLK = v->DCFCLKPerState[(int) v->VoltageLevel]; +- v->FabricAndDRAMBandwidth = v->FabricAndDRAMBandwidthPerState[(int) v->VoltageLevel]; +- +- for (j = 0; j < 2; j++) { +- v->RequiredDISPCLKPerRatio[j] = v->RequiredDISPCLK[j * NumberOfStatesPlusTwo +- + (int) v->VoltageLevel]; +- for (k = 0; k < num_planes; k++) { +- v->DPPPerPlanePerRatio[k * 2 + j] = v->NoOfDPP[k * 2 * NumberOfStatesPlusTwo +- + j * NumberOfStatesPlusTwo + (int) v->VoltageLevel]; +- } +- v->DISPCLK_DPPCLK_SupportPerRatio[j] = v->DISPCLK_DPPCLK_Support[j +- * NumberOfStatesPlusTwo + (int) v->VoltageLevel]; +- } +- +- ASSERT(v->ImmediateFlipSupported || v->MacroTileBlockWidthC || v->DCFCLK || v->FabricAndDRAMBandwidth); +- +- return (v->VoltageLevel); +-} +- +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h +deleted file mode 100644 +index ead4942..0000000 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h ++++ /dev/null +@@ -1,199 +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. +- * +- * Authors: AMD +- * +- */ +-#ifndef __DISPLAY_MODE_SUPPORT_H__ +-#define __DISPLAY_MODE_SUPPORT_H__ +- +-#include "dml_common_defs.h" +- +-struct display_mode_lib; +- +-#define NumberOfStates 4 +-#define NumberOfStatesPlusTwo (NumberOfStates+2) +- +-struct dml_ms_internal_vars { +- double ScaleRatioSupport; +- double SourceFormatPixelAndScanSupport; +- double TotalReadBandwidthConsumedGBytePerSecond; +- double TotalWriteBandwidthConsumedGBytePerSecond; +- double TotalBandwidthConsumedGBytePerSecond; +- double DCCEnabledInAnyPlane; +- double ReturnBWToDCNPerState; +- double CriticalPoint; +- double WritebackLatencySupport; +- double RequiredOutputBW; +- double TotalNumberOfActiveWriteback; +- double TotalAvailableWritebackSupport; +- double MaximumSwathWidth; +- double NumberOfDPPRequiredForDETSize; +- double NumberOfDPPRequiredForLBSize; +- double MinDispclkUsingSingleDPP; +- double MinDispclkUsingDualDPP; +- double ViewportSizeSupport; +- double SwathWidthGranularityY; +- double RoundedUpMaxSwathSizeBytesY; +- double SwathWidthGranularityC; +- double RoundedUpMaxSwathSizeBytesC; +- double LinesInDETLuma; +- double LinesInDETChroma; +- double EffectiveLBLatencyHidingSourceLinesLuma; +- double EffectiveLBLatencyHidingSourceLinesChroma; +- double EffectiveDETLBLinesLuma; +- double EffectiveDETLBLinesChroma; +- double ProjectedDCFCLKDeepSleep; +- double MetaReqHeightY; +- double MetaReqWidthY; +- double MetaSurfaceWidthY; +- double MetaSurfaceHeightY; +- double MetaPteBytesPerFrameY; +- double MetaRowBytesY; +- double MacroTileBlockSizeBytesY; +- double MacroTileBlockHeightY; +- double DataPTEReqHeightY; +- double DataPTEReqWidthY; +- double DPTEBytesPerRowY; +- double MetaReqHeightC; +- double MetaReqWidthC; +- double MetaSurfaceWidthC; +- double MetaSurfaceHeightC; +- double MetaPteBytesPerFrameC; +- double MetaRowBytesC; +- double MacroTileBlockSizeBytesC; +- double MacroTileBlockHeightC; +- double MacroTileBlockWidthC; +- double DataPTEReqHeightC; +- double DataPTEReqWidthC; +- double DPTEBytesPerRowC; +- double VInitY; +- double MaxPartialSwY; +- double VInitC; +- double MaxPartialSwC; +- double dst_x_after_scaler; +- double dst_y_after_scaler; +- double TimeCalc; +- double VUpdateOffset; +- double TotalRepeaterDelay; +- double VUpdateWidth; +- double VReadyOffset; +- double TimeSetup; +- double ExtraLatency; +- double MaximumVStartup; +- double BWAvailableForImmediateFlip; +- double TotalImmediateFlipBytes; +- double TimeForMetaPTEWithImmediateFlip; +- double TimeForMetaPTEWithoutImmediateFlip; +- double TimeForMetaAndDPTERowWithImmediateFlip; +- double TimeForMetaAndDPTERowWithoutImmediateFlip; +- double LineTimesToRequestPrefetchPixelDataWithImmediateFlip; +- double LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip; +- double MaximumReadBandwidthWithPrefetchWithImmediateFlip; +- double MaximumReadBandwidthWithPrefetchWithoutImmediateFlip; +- double VoltageOverrideLevel; +- double VoltageLevelWithImmediateFlip; +- double VoltageLevelWithoutImmediateFlip; +- double ImmediateFlipSupported; +- double VoltageLevel; +- double DCFCLK; +- double FabricAndDRAMBandwidth; +- double SwathWidthYSingleDPP[DC__NUM_PIPES__MAX]; +- double BytePerPixelInDETY[DC__NUM_PIPES__MAX]; +- double BytePerPixelInDETC[DC__NUM_PIPES__MAX]; +- double ReadBandwidth[DC__NUM_PIPES__MAX]; +- double WriteBandwidth[DC__NUM_PIPES__MAX]; +- double DCFCLKPerState[NumberOfStatesPlusTwo]; +- double FabricAndDRAMBandwidthPerState[NumberOfStatesPlusTwo]; +- double ReturnBWPerState[NumberOfStatesPlusTwo]; +- double BandwidthSupport[NumberOfStatesPlusTwo]; +- double UrgentRoundTripAndOutOfOrderLatencyPerState[NumberOfStatesPlusTwo]; +- double ROBSupport[NumberOfStatesPlusTwo]; +- double RequiredPHYCLK[DC__NUM_PIPES__MAX]; +- double DIOSupport[NumberOfStatesPlusTwo]; +- double PHYCLKPerState[NumberOfStatesPlusTwo]; +- double PSCL_FACTOR[DC__NUM_PIPES__MAX]; +- double PSCL_FACTOR_CHROMA[DC__NUM_PIPES__MAX]; +- double MinDPPCLKUsingSingleDPP[DC__NUM_PIPES__MAX]; +- double Read256BlockHeightY[DC__NUM_PIPES__MAX]; +- double Read256BlockWidthY[DC__NUM_PIPES__MAX]; +- double Read256BlockHeightC[DC__NUM_PIPES__MAX]; +- double Read256BlockWidthC[DC__NUM_PIPES__MAX]; +- double MaxSwathHeightY[DC__NUM_PIPES__MAX]; +- double MaxSwathHeightC[DC__NUM_PIPES__MAX]; +- double MinSwathHeightY[DC__NUM_PIPES__MAX]; +- double MinSwathHeightC[DC__NUM_PIPES__MAX]; +- double NumberOfDPPRequiredForDETAndLBSize[DC__NUM_PIPES__MAX]; +- double TotalNumberOfActiveDPP[NumberOfStatesPlusTwo * 2]; +- double RequiredDISPCLK[NumberOfStatesPlusTwo * 2]; +- double DISPCLK_DPPCLK_Support[NumberOfStatesPlusTwo * 2]; +- double MaxDispclk[NumberOfStatesPlusTwo]; +- double MaxDppclk[NumberOfStatesPlusTwo]; +- double NoOfDPP[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; +- double TotalAvailablePipesSupport[NumberOfStatesPlusTwo * 2]; +- double SwathWidthYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; +- double SwathHeightYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; +- double SwathHeightCPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; +- double DETBufferSizeYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; +- double UrgentLatencySupportUsPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; +- double UrgentLatencySupport[NumberOfStatesPlusTwo * 2]; +- double TotalNumberOfDCCActiveDPP[NumberOfStatesPlusTwo * 2]; +- double DPTEBytesPerRow[DC__NUM_PIPES__MAX]; +- double MetaPTEBytesPerFrame[DC__NUM_PIPES__MAX]; +- double MetaRowBytes[DC__NUM_PIPES__MAX]; +- double PrefillY[DC__NUM_PIPES__MAX]; +- double MaxNumSwY[DC__NUM_PIPES__MAX]; +- double PrefetchLinesY[DC__NUM_PIPES__MAX]; +- double PrefillC[DC__NUM_PIPES__MAX]; +- double MaxNumSwC[DC__NUM_PIPES__MAX]; +- double PrefetchLinesC[DC__NUM_PIPES__MAX]; +- double LineTimesForPrefetch[DC__NUM_PIPES__MAX]; +- double PrefetchBW[DC__NUM_PIPES__MAX]; +- double LinesForMetaPTEWithImmediateFlip[DC__NUM_PIPES__MAX]; +- double LinesForMetaPTEWithoutImmediateFlip[DC__NUM_PIPES__MAX]; +- double LinesForMetaAndDPTERowWithImmediateFlip[DC__NUM_PIPES__MAX]; +- double LinesForMetaAndDPTERowWithoutImmediateFlip[DC__NUM_PIPES__MAX]; +- double VRatioPreYWithImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; +- double VRatioPreCWithImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; +- double RequiredPrefetchPixelDataBWWithImmediateFlip[NumberOfStatesPlusTwo * 2 +- * DC__NUM_PIPES__MAX]; +- double VRatioPreYWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; +- double VRatioPreCWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; +- double RequiredPrefetchPixelDataBWWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 +- * DC__NUM_PIPES__MAX]; +- double PrefetchSupportedWithImmediateFlip[NumberOfStatesPlusTwo * 2]; +- double PrefetchSupportedWithoutImmediateFlip[NumberOfStatesPlusTwo * 2]; +- double VRatioInPrefetchSupportedWithImmediateFlip[NumberOfStatesPlusTwo * 2]; +- double VRatioInPrefetchSupportedWithoutImmediateFlip[NumberOfStatesPlusTwo * 2]; +- double ModeSupportWithImmediateFlip[NumberOfStatesPlusTwo * 2]; +- double ModeSupportWithoutImmediateFlip[NumberOfStatesPlusTwo * 2]; +- double RequiredDISPCLKPerRatio[2]; +- double DPPPerPlanePerRatio[2 * DC__NUM_PIPES__MAX]; +- double DISPCLK_DPPCLK_SupportPerRatio[2]; +- struct _vcs_dpi_wm_calc_pipe_params_st planes[DC__NUM_PIPES__MAX]; +-}; +- +-int dml_ms_check( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- int num_pipes); +- +-#endif +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +new file mode 100644 +index 0000000..ada0eee +--- /dev/null ++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +@@ -0,0 +1,3263 @@ ++#include "display_mode_lib.h" ++#include "display_mode_vba.h" ++ ++static const unsigned int NumberOfStates = DC__VOLTAGE_STATES; ++ ++static void fetch_socbb_params(struct display_mode_lib *mode_lib); ++static void fetch_ip_params(struct display_mode_lib *mode_lib); ++static void fetch_pipe_params(struct display_mode_lib *mode_lib); ++static void recalculate_params(struct display_mode_lib *mode_lib, ++ const display_e2e_pipe_params_st *pipes, ++ unsigned int num_pipes); ++static void recalculate(struct display_mode_lib *mode_lib); ++static double adjust_ReturnBW(struct display_mode_lib *mode_lib, double ReturnBW, bool DCCEnabledAnyPlane, double ReturnBandwidthToDCN); ++static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib); ++static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib); ++static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(struct display_mode_lib *mode_lib); ++static unsigned int dscceComputeDelay(unsigned int bpc, ++ double bpp, ++ unsigned int sliceWidth, ++ unsigned int numSlices, ++ enum output_format_class pixelFormat); ++static unsigned int dscComputeDelay(enum output_format_class pixelFormat); ++// Super monster function with some 45 argument ++static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, ++ double DPPCLK, ++ double DISPCLK, ++ double PixelClock, ++ double DCFClkDeepSleep, ++ unsigned int DSCDelay, ++ unsigned int DPPPerPlane, ++ bool ScalerEnabled, ++ unsigned int NumberOfCursors, ++ double DPPCLKDelaySubtotal, ++ double DPPCLKDelaySCL, ++ double DPPCLKDelaySCLLBOnly, ++ double DPPCLKDelayCNVCFormater, ++ double DPPCLKDelayCNVCCursor, ++ double DISPCLKDelaySubtotal, ++ unsigned int ScalerRecoutWidth, ++ enum output_format_class OutputFormat, ++ unsigned int VBlank, ++ unsigned int HTotal, ++ unsigned int MaxInterDCNTileRepeaters, ++ unsigned int VStartup, ++ unsigned int PageTableLevels, ++ bool VirtualMemoryEnable, ++ bool DynamicMetadataEnable, ++ unsigned int DynamicMetadataLinesBeforeActiveRequired, ++ unsigned int DynamicMetadataTransmittedBytes, ++ bool DCCEnable, ++ double UrgentLatency, ++ double UrgentExtraLatency, ++ double TCalc, ++ unsigned int PDEAndMetaPTEBytesFrame, ++ unsigned int MetaRowByte, ++ unsigned int PixelPTEBytesPerRow, ++ double PrefetchSourceLinesY, ++ unsigned int SwathWidthY, ++ double BytePerPixelDETY, ++ double VInitPreFillY, ++ unsigned int MaxNumSwathY, ++ double PrefetchSourceLinesC, ++ double BytePerPixelDETC, ++ double VInitPreFillC, ++ unsigned int MaxNumSwathC, ++ unsigned int SwathHeightY, ++ unsigned int SwathHeightC, ++ double TWait, ++ bool XFCEnabled, ++ double XFCRemoteSurfaceFlipDelay, ++ bool InterlaceEnable, ++ bool ProgressiveToInterlaceUnitInOPP, ++ double *DSTXAfterScaler, ++ double *DSTYAfterScaler, ++ double *DestinationLinesForPrefetch, ++ double *PrefetchBandwidth, ++ double *DestinationLinesToRequestVMInVBlank, ++ double *DestinationLinesToRequestRowInVBlank, ++ double *VRatioPrefetchY, ++ double *VRatioPrefetchC, ++ double *RequiredPrefetchPixDataBW, ++ unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, ++ double *Tno_bw); ++static double CeilToDFSGranularity(double Clock, double VCOSpeed); ++static double FloorToDFSGranularity(double Clock, double VCOSpeed); ++static double CalculatePrefetchSourceLines(struct display_mode_lib *mode_lib, ++ double VRatio, ++ double vtaps, ++ bool Interlace, ++ bool ProgressiveToInterlaceUnitInOPP, ++ unsigned int SwathHeight, ++ unsigned int ViewportYStart, ++ double *VInitPreFill, ++ unsigned int *MaxNumSwath); ++static unsigned int CalculateVMAndRowBytes(struct display_mode_lib *mode_lib, ++ bool DCCEnable, ++ unsigned int BlockHeight256Bytes, ++ unsigned int BlockWidth256Bytes, ++ enum source_format_class SourcePixelFormat, ++ unsigned int SurfaceTiling, ++ unsigned int BytePerPixel, ++ enum scan_direction_class ScanDirection, ++ unsigned int ViewportWidth, ++ unsigned int ViewportHeight, ++ unsigned int SwathWidthY, ++ bool VirtualMemoryEnable, ++ unsigned int VMMPageSize, ++ unsigned int PTEBufferSizeInRequests, ++ unsigned int PDEProcessingBufIn64KBReqs, ++ unsigned int Pitch, ++ unsigned int DCCMetaPitch, ++ unsigned int *MacroTileWidth, ++ unsigned int *MetaRowByte, ++ unsigned int *PixelPTEBytesPerRow, ++ bool *PTEBufferSizeNotExceeded, ++ unsigned int *dpte_row_height, ++ unsigned int *meta_row_height); ++static double CalculateTWait(unsigned int PrefetchMode, ++ double DRAMClockChangeLatency, ++ double UrgentLatency, ++ double SREnterPlusExitTime); ++static double CalculateRemoteSurfaceFlipDelay(struct display_mode_lib *mode_lib, ++ double VRatio, ++ double SwathWidth, ++ double Bpp, ++ double LineTime, ++ double XFCTSlvVupdateOffset, ++ double XFCTSlvVupdateWidth, ++ double XFCTSlvVreadyOffset, ++ double XFCXBUFLatencyTolerance, ++ double XFCFillBWOverhead, ++ double XFCSlvChunkSize, ++ double XFCBusTransportTime, ++ double TCalc, ++ double TWait, ++ double *SrcActiveDrainRate, ++ double *TInitXFill, ++ double *TslvChk); ++static double CalculateWriteBackDISPCLK(enum source_format_class WritebackPixelFormat, ++ double PixelClock, ++ double WritebackHRatio, ++ double WritebackVRatio, ++ unsigned int WritebackLumaHTaps, ++ unsigned int WritebackLumaVTaps, ++ unsigned int WritebackChromaHTaps, ++ unsigned int WritebackChromaVTaps, ++ double WritebackDestinationWidth, ++ unsigned int HTotal, ++ unsigned int WritebackChromaLineBufferWidth); ++static void CalculateActiveRowBandwidth(bool VirtualMemoryEnable, ++ enum source_format_class SourcePixelFormat, ++ double VRatio, ++ bool DCCEnable, ++ double LineTime, ++ unsigned int MetaRowByteLuma, ++ unsigned int MetaRowByteChroma, ++ unsigned int meta_row_height_luma, ++ unsigned int meta_row_height_chroma, ++ unsigned int PixelPTEBytesPerRowLuma, ++ unsigned int PixelPTEBytesPerRowChroma, ++ unsigned int dpte_row_height_luma, ++ unsigned int dpte_row_height_chroma, ++ double *meta_row_bw, ++ double *dpte_row_bw, ++ double *qual_row_bw); ++static void CalculateFlipSchedule(struct display_mode_lib *mode_lib, ++ double UrgentExtraLatency, ++ double UrgentLatency, ++ unsigned int MaxPageTableLevels, ++ bool VirtualMemoryEnable, ++ double BandwidthAvailableForImmediateFlip, ++ unsigned int TotImmediateFlipBytes, ++ enum source_format_class SourcePixelFormat, ++ unsigned int ImmediateFlipBytes, ++ double LineTime, ++ double Tno_bw, ++ double VRatio, ++ double PDEAndMetaPTEBytesFrame, ++ unsigned int MetaRowByte, ++ unsigned int PixelPTEBytesPerRow, ++ bool DCCEnable, ++ unsigned int dpte_row_height, ++ unsigned int meta_row_height, ++ double qual_row_bw, ++ double *DestinationLinesToRequestVMInImmediateFlip, ++ double *DestinationLinesToRequestRowInImmediateFlip, ++ double *final_flip_bw, ++ bool *ImmediateFlipSupportedForPipe); ++static double CalculateWriteBackDelay(enum source_format_class WritebackPixelFormat, ++ double WritebackHRatio, ++ double WritebackVRatio, ++ unsigned int WritebackLumaHTaps, ++ unsigned int WritebackLumaVTaps, ++ unsigned int WritebackChromaHTaps, ++ unsigned int WritebackChromaVTaps, ++ unsigned int WritebackDestinationWidth); ++static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib); ++static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp); ++ ++void set_prefetch_mode(struct display_mode_lib *mode_lib, ++ bool cstate_en, ++ bool pstate_en, ++ bool ignore_viewport_pos, ++ bool immediate_flip_support) ++{ ++ unsigned int prefetch_mode; ++ ++ if (cstate_en && pstate_en) ++ prefetch_mode = 0; ++ else if (cstate_en) ++ prefetch_mode = 1; ++ else ++ prefetch_mode = 2; ++ if (prefetch_mode != mode_lib->vba.PrefetchMode || ignore_viewport_pos != mode_lib->vba.IgnoreViewportPositioning ++ || immediate_flip_support != mode_lib->vba.ImmediateFlipSupport) { ++ DTRACE(" Prefetch mode has changed from %i to %i. Recalculating.", ++ prefetch_mode, ++ mode_lib->vba.PrefetchMode); ++ mode_lib->vba.PrefetchMode = prefetch_mode; ++ mode_lib->vba.IgnoreViewportPositioning = ignore_viewport_pos; ++ mode_lib->vba.ImmediateFlipSupport = immediate_flip_support; ++ recalculate(mode_lib); ++ } ++} ++ ++#define dml_get_attr_func(attr, var) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes) \ ++{ \ ++ recalculate_params(mode_lib, pipes, num_pipes); \ ++ return var; \ ++} ++ ++dml_get_attr_func(clk_dcf_deepsleep, mode_lib->vba.DCFClkDeepSleep); ++dml_get_attr_func(wm_urgent, mode_lib->vba.UrgentWatermark); ++dml_get_attr_func(wm_memory_trip, mode_lib->vba.MemoryTripWatermark); ++dml_get_attr_func(wm_writeback_urgent, mode_lib->vba.WritebackUrgentWatermark); ++dml_get_attr_func(wm_stutter_exit, mode_lib->vba.StutterExitWatermark); ++dml_get_attr_func(wm_stutter_enter_exit, mode_lib->vba.StutterEnterPlusExitWatermark); ++dml_get_attr_func(wm_dram_clock_change, mode_lib->vba.DRAMClockChangeWatermark); ++dml_get_attr_func(wm_writeback_dram_clock_change, mode_lib->vba.WritebackDRAMClockChangeWatermark); ++dml_get_attr_func(wm_xfc_underflow, mode_lib->vba.UrgentWatermark); // xfc_underflow maps to urgent ++dml_get_attr_func(stutter_efficiency, mode_lib->vba.StutterEfficiency); ++dml_get_attr_func(stutter_efficiency_no_vblank, mode_lib->vba.StutterEfficiencyNotIncludingVBlank); ++dml_get_attr_func(urgent_latency, mode_lib->vba.MinUrgentLatencySupportUs); ++dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency); ++dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance); ++dml_get_attr_func(dram_clock_change_latency, mode_lib->vba.MinActiveDRAMClockChangeLatencySupported); ++dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated); ++dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth); ++dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW); ++dml_get_attr_func(tcalc, mode_lib->vba.TCalc); ++ ++#define dml_get_pipe_attr_func(attr, var) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes, unsigned int which_pipe) \ ++{\ ++ unsigned int which_plane; \ ++ recalculate_params(mode_lib, pipes, num_pipes); \ ++ which_plane = mode_lib->vba.pipe_plane[which_pipe]; \ ++ return var[which_plane]; \ ++} ++ ++dml_get_pipe_attr_func(dsc_delay, mode_lib->vba.DSCDelay); ++dml_get_pipe_attr_func(dppclk_calculated, mode_lib->vba.DPPCLK_calculated); ++dml_get_pipe_attr_func(dscclk_calculated, mode_lib->vba.DSCCLK_calculated); ++dml_get_pipe_attr_func(min_ttu_vblank, mode_lib->vba.MinTTUVBlank); ++dml_get_pipe_attr_func(vratio_prefetch_l, mode_lib->vba.VRatioPrefetchY); ++dml_get_pipe_attr_func(vratio_prefetch_c, mode_lib->vba.VRatioPrefetchC); ++dml_get_pipe_attr_func(dst_x_after_scaler, mode_lib->vba.DSTXAfterScaler); ++dml_get_pipe_attr_func(dst_y_after_scaler, mode_lib->vba.DSTYAfterScaler); ++dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequestVMInVBlank); ++dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank); ++dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch); ++dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip); ++dml_get_pipe_attr_func(dst_y_per_row_flip, mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip); ++ ++dml_get_pipe_attr_func(xfc_transfer_delay, mode_lib->vba.XFCTransferDelay); ++dml_get_pipe_attr_func(xfc_precharge_delay, mode_lib->vba.XFCPrechargeDelay); ++dml_get_pipe_attr_func(xfc_remote_surface_flip_latency, mode_lib->vba.XFCRemoteSurfaceFlipLatency); ++dml_get_pipe_attr_func(xfc_prefetch_margin, mode_lib->vba.XFCPrefetchMargin); ++ ++unsigned int get_vstartup_calculated(struct display_mode_lib *mode_lib, ++ const display_e2e_pipe_params_st *pipes, ++ unsigned int num_pipes, ++ unsigned int which_pipe) ++{ ++ unsigned int which_plane; ++ ++ recalculate_params(mode_lib, pipes, num_pipes); ++ which_plane = mode_lib->vba.pipe_plane[which_pipe]; ++ return mode_lib->vba.VStartup[which_plane]; ++} ++ ++double get_total_immediate_flip_bytes(struct display_mode_lib *mode_lib, ++ const display_e2e_pipe_params_st *pipes, ++ unsigned int num_pipes) ++{ ++ recalculate_params(mode_lib, pipes, num_pipes); ++ return mode_lib->vba.TotImmediateFlipBytes; ++} ++ ++double get_total_immediate_flip_bw(struct display_mode_lib *mode_lib, ++ const display_e2e_pipe_params_st *pipes, ++ unsigned int num_pipes) ++{ ++ recalculate_params(mode_lib, pipes, num_pipes); ++ return mode_lib->vba.ImmediateFlipBW; ++} ++ ++double get_total_prefetch_bw(struct display_mode_lib *mode_lib, ++ const display_e2e_pipe_params_st *pipes, ++ unsigned int num_pipes) ++{ ++ unsigned int k; ++ double total_prefetch_bw = 0.0; ++ ++ recalculate_params(mode_lib, pipes, num_pipes); ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) ++ total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k]; ++ return total_prefetch_bw; ++} ++ ++static void fetch_socbb_params(struct display_mode_lib *mode_lib) ++{ ++ soc_bounding_box_st *soc = &mode_lib->vba.soc; ++ unsigned int i; ++ ++ // SOC Bounding Box Parameters ++ mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes; ++ mode_lib->vba.NumberOfChannels = soc->num_chans; ++ mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency = ++ soc->ideal_dram_bw_after_urgent_percent; // there's always that one bastard variable that's so long it throws everything out of alignment! ++ mode_lib->vba.UrgentLatency = soc->urgent_latency_us; ++ mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles; ++ mode_lib->vba.UrgentOutOfOrderReturnPerChannel = soc->urgent_out_of_order_return_per_channel_bytes; ++ mode_lib->vba.WritebackLatency = soc->writeback_latency_us; ++ mode_lib->vba.SRExitTime = soc->sr_exit_time_us; ++ mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us; ++ mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us; ++ mode_lib->vba.Downspreading = soc->downspread_percent; ++ mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes; // new! ++ mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new! ++ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent; // new ++ mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz; // new ++ mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes; ++ // Set the voltage scaling clocks as the defaults. Most of these will ++ // be set to different values by the test ++ for (i = 0; i < DC__VOLTAGE_STATES; ++i) ++ if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel) ++ break; ++ ++ mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz; ++ mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz; ++ mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mhz; ++ mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz; ++ ++ mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us; ++ mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us; ++} ++ ++static void fetch_ip_params(struct display_mode_lib *mode_lib) ++{ ++ ip_params_st *ip = &mode_lib->vba.ip; ++ ++ // IP Parameters ++ mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk; ++ mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk; ++ mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes; ++ mode_lib->vba.DETBufferSizeInKByte = ip->det_buffer_size_kbytes; ++ mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes; ++ mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes; ++ mode_lib->vba.PTEChunkSize = ip->pte_chunk_size_kbytes; ++ mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes; ++ mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits; ++ mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines; ++ mode_lib->vba.PTEBufferSizeInRequests = ip->dpte_buffer_size_in_pte_reqs; ++ mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels; ++ mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines; ++ mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes; ++ mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes; ++ mode_lib->vba.WritebackChromaLineBufferWidth = ip->writeback_chroma_line_buffer_width_pixels; ++ mode_lib->vba.MaxPageTableLevels = ip->max_page_table_levels; ++ mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters; ++ mode_lib->vba.NumberOfDSC = ip->num_dsc; ++ mode_lib->vba.ODMCapability = ip->odm_capable; ++ mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent; ++ ++ mode_lib->vba.XFCSupported = ip->xfc_supported; ++ mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent; ++ mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes; ++ mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal; ++ mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl; ++ mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only; ++ mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter; ++ mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor; ++ mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal; ++ ++ mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported; ++ ++ mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs; ++} ++ ++static void fetch_pipe_params(struct display_mode_lib *mode_lib) ++{ ++ display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes; ++ ip_params_st *ip = &mode_lib->vba.ip; ++ ++ unsigned int OTGInstPlane[DC__NUM_DPP]; ++ unsigned int j, k; ++ bool PlaneVisited[DC__NUM_DPP]; ++ bool visited[DC__NUM_PIPES__MAX]; ++ ++ // Convert Pipes to Planes ++ for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) ++ visited[k] = false; ++ ++ mode_lib->vba.NumberOfActivePlanes = 0; ++ for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) { ++ display_pipe_source_params_st *src = &pipes[j].pipe.src; ++ display_pipe_dest_params_st *dst = &pipes[j].pipe.dest; ++ scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth; ++ scaler_taps_st *taps = &pipes[j].pipe.scale_taps; ++ display_output_params_st *dout = &pipes[j].dout; ++ display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg; ++ ++ if (visited[j]) ++ continue; ++ visited[j] = true; ++ ++ mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes; ++ ++ mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1; ++ mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] = (enum scan_direction_class)(src->source_scan); ++ mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width; ++ mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height; ++ mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] = src->viewport_y_y; ++ mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] = src->viewport_y_c; ++ mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch; ++ mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c; ++ mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch; ++ mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio; ++ mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio; ++ mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable; ++ mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced; ++ if (mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes]) ++ mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0; ++ mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps; ++ mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps; ++ mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c; ++ mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c; ++ mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal; ++ mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal; ++ mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] = ++ src->dcc_use_global ? ip->dcc_supported : src->dcc & ip->dcc_supported; ++ mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate; ++ mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] = (enum source_format_class)(src->source_format); ++ mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive; ++ mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive; ++ mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] = (enum dm_swizzle_mode)(src->sw_mode); ++ mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] = dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode? ++ mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] = dst->odm_combine; ++ mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] = (enum output_format_class)(dout->output_format); ++ mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] = (enum output_encoder_class)(dout->output_type); ++ mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp; ++ mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable; ++ mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_slices; ++ mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] = ++ dout->output_bpc == 0 ? 12 : dout->output_bpc; ++ mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable; ++ mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_src_height; ++ mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_dst_width; ++ mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_dst_height; ++ mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] = (enum source_format_class)(dout->wb.wb_pixel_format); ++ mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_htaps_luma; ++ mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_vtaps_luma; ++ mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_htaps_chroma; ++ mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_vtaps_chroma; ++ mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_hratio; ++ mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_vratio; ++ ++ mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] = src->dynamic_metadata_enable; ++ mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] = ++ src->dynamic_metadata_lines_before_active; ++ mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] = ++ src->dynamic_metadata_xmit_bytes; ++ ++ mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable && ip->xfc_supported; ++ mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes; ++ mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us; ++ mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us; ++ mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us; ++ mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz; ++ mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz; ++ if (ip->is_line_buffer_bpp_fixed) ++ mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = ip->line_buffer_fixed_bpp; ++ else { ++ unsigned int lb_depth; ++ ++ switch (scl->lb_depth) { ++ case dm_lb_6: ++ lb_depth = 18; ++ break; ++ case dm_lb_8: ++ lb_depth = 24; ++ break; ++ case dm_lb_10: ++ lb_depth = 30; ++ break; ++ case dm_lb_12: ++ lb_depth = 36; ++ break; ++ case dm_lb_16: ++ lb_depth = 48; ++ break; ++ default: ++ lb_depth = 36; ++ } ++ mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth; ++ } ++ mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0; ++ // The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll ++ // calculate things a little more accurately ++ for (k = 0; k < DC__NUM_CURSOR; ++k) { ++ switch (k) { ++ case 0: ++ mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] = CursorBppEnumToBits((enum cursor_bpp)(src->cur0_bpp)); ++ mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] = src->cur0_src_width; ++ if (src->cur0_src_width > 0) ++ mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++; ++ break; ++ case 1: ++ mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] = CursorBppEnumToBits((enum cursor_bpp)(src->cur1_bpp)); ++ mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] = src->cur1_src_width; ++ if (src->cur1_src_width > 0) ++ mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++; ++ break; ++ default: ++ dml_print("ERROR: Number of cursors specified exceeds supported maximum\n"); ++ } ++ } ++ ++ OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst; ++ ++ if (dst->odm_combine && !src->is_hsplit) ++ dml_print("ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n", ++ j); ++ ++ if (src->is_hsplit) { ++ for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) { ++ display_pipe_source_params_st *src_k = &pipes[k].pipe.src; ++ display_output_params_st *dout_k = &pipes[k].dout; ++ ++ if (src_k->is_hsplit && !visited[k] ++ && src->hsplit_grp == src_k->hsplit_grp) { ++ mode_lib->vba.pipe_plane[k] = mode_lib->vba.NumberOfActivePlanes; ++ mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++; ++ if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] == dm_horz) ++ mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] += ++ src_k->viewport_width; ++ else ++ mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] += ++ src_k->viewport_height; ++ ++ mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] += ++ dout_k->dsc_slices; ++ visited[k] = true; ++ } ++ } ++ } ++ ++ mode_lib->vba.NumberOfActivePlanes++; ++ } ++ ++ // handle overlays through dml_ml->vba.BlendingAndTiming ++ // dml_ml->vba.BlendingAndTiming tells you which instance to look at to get timing, the so called 'master' ++ ++ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) ++ PlaneVisited[j] = false; ++ ++ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) { ++ for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) { ++ // doesn't matter, so choose the smaller one ++ mode_lib->vba.BlendingAndTiming[j] = j; ++ PlaneVisited[j] = true; ++ mode_lib->vba.BlendingAndTiming[k] = j; ++ PlaneVisited[k] = true; ++ } ++ } ++ ++ if (!PlaneVisited[j]) { ++ mode_lib->vba.BlendingAndTiming[j] = j; ++ PlaneVisited[j] = true; ++ } ++ } ++ ++ // TODO: dml_ml->vba.ODMCombineEnabled => 2 * dml_ml->vba.DPPPerPlane...actually maybe not since all pipes are specified ++ // Do we want the dscclk to automatically be halved? Guess not since the value is specified ++ ++ mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes; ++ for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k) ++ ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes); ++ ++ mode_lib->vba.VirtualMemoryEnable = 0; ++ mode_lib->vba.OverridePageTableLevels = 0; ++ ++ for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) { ++ mode_lib->vba.VirtualMemoryEnable |= pipes[k].pipe.src.vm; ++ mode_lib->vba.OverridePageTableLevels = ++ (pipes[k].pipe.src.vm_levels_force_en ++ && mode_lib->vba.OverridePageTableLevels ++ < pipes[k].pipe.src.vm_levels_force) ? ++ pipes[k].pipe.src.vm_levels_force : ++ mode_lib->vba.OverridePageTableLevels; ++ } ++ ++ if (mode_lib->vba.OverridePageTableLevels) ++ mode_lib->vba.MaxPageTableLevels = mode_lib->vba.OverridePageTableLevels; ++ ++ mode_lib->vba.VirtualMemoryEnable &= ip->pte_enable; ++ ++ mode_lib->vba.FabricAndDRAMBandwidth = dml_min(mode_lib->vba.DRAMSpeed * mode_lib->vba.NumberOfChannels * mode_lib->vba.DRAMChannelWidth, ++ mode_lib->vba.FabricClock * mode_lib->vba.FabricDatapathToDCNDataReturn) / 1000.0; ++ ++ // TODO: Must be consistent across all pipes ++ // DCCProgrammingAssumesScanDirectionUnknown = src.dcc_scan_dir_unknown; ++} ++ ++static void recalculate(struct display_mode_lib *mode_lib) ++{ ++ ModeSupportAndSystemConfiguration(mode_lib); ++ PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib); ++ DisplayPipeConfiguration(mode_lib); ++ DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(mode_lib); ++} ++ ++// in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs ++// rather than working them out as in recalculate_ms ++static void recalculate_params(struct display_mode_lib *mode_lib, ++ const display_e2e_pipe_params_st *pipes, ++ unsigned int num_pipes) ++{ ++ // This is only safe to use memcmp because there are non-POD types in struct display_mode_lib ++ if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0 ++ || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0 ++ || memcmp(&mode_lib->me, &mode_lib->vba.me, sizeof(mode_lib->vba.me)) != 0 ++ || num_pipes != mode_lib->vba.cache_num_pipes ++ || memcmp(pipes, mode_lib->vba.cache_pipes, sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) { ++ mode_lib->vba.soc = mode_lib->soc; ++ mode_lib->vba.ip = mode_lib->ip; ++ mode_lib->vba.me = mode_lib->me; ++ memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes); ++ mode_lib->vba.cache_num_pipes = num_pipes; ++ recalculate(mode_lib); ++ } ++} ++ ++static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib) ++{ ++ soc_bounding_box_st *soc = &mode_lib->vba.soc; ++ unsigned int i, k; ++ unsigned int total_pipes = 0; ++ ++ mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage; ++ for (i = 1; i < mode_lib->vba.cache_num_pipes; ++i) ++ ASSERT(mode_lib->vba.VoltageLevel == -1 || mode_lib->vba.VoltageLevel == mode_lib->vba.cache_pipes[i].clks_cfg.voltage); ++ ++ mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz; ++ mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz; ++ ++ if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0) ++ mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz; ++ else ++ mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz; ++ ++ fetch_socbb_params(mode_lib); ++ fetch_ip_params(mode_lib); ++ fetch_pipe_params(mode_lib); ++ ++ // Total Available Pipes Support Check ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) ++ total_pipes += mode_lib->vba.DPPPerPlane[k]; ++ ASSERT(total_pipes <= DC__NUM_DPP); ++} ++ ++static double adjust_ReturnBW(struct display_mode_lib *mode_lib, double ReturnBW, bool DCCEnabledAnyPlane, double ReturnBandwidthToDCN) ++{ ++ double CriticalCompression; ++ ++ if (DCCEnabledAnyPlane && ReturnBandwidthToDCN > mode_lib->vba.DCFCLK * mode_lib->vba.ReturnBusWidth / 4.0) ++ ReturnBW = ++ dml_min(ReturnBW, ++ ReturnBandwidthToDCN * 4 ++ * (1.0 ++ - mode_lib->vba.UrgentLatency ++ / ((mode_lib->vba.ROBBufferSizeInKByte ++ - mode_lib->vba.PixelChunkSizeInKByte) ++ * 1024 ++ / ReturnBandwidthToDCN ++ - mode_lib->vba.DCFCLK ++ * mode_lib->vba.ReturnBusWidth ++ / 4) ++ + mode_lib->vba.UrgentLatency)); ++ ++ CriticalCompression = 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK * mode_lib->vba.UrgentLatency ++ / (ReturnBandwidthToDCN * mode_lib->vba.UrgentLatency ++ + (mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024); ++ ++ if (DCCEnabledAnyPlane && CriticalCompression > 1.0 && CriticalCompression < 4.0) ++ ReturnBW = ++ dml_min(ReturnBW, ++ 4.0 * ReturnBandwidthToDCN ++ * (mode_lib->vba.ROBBufferSizeInKByte ++ - mode_lib->vba.PixelChunkSizeInKByte) ++ * 1024 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK ++ * mode_lib->vba.UrgentLatency ++ / dml_pow((ReturnBandwidthToDCN ++ * mode_lib->vba.UrgentLatency ++ + (mode_lib->vba.ROBBufferSizeInKByte ++ - mode_lib->vba.PixelChunkSizeInKByte) ++ * 1024), ++ 2)); ++ ++ return ReturnBW; ++} ++ ++static unsigned int dscceComputeDelay(unsigned int bpc, ++ double bpp, ++ unsigned int sliceWidth, ++ unsigned int numSlices, ++ enum output_format_class pixelFormat) ++{ ++ // 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, lstall, D, initalXmitDelay, w, s, ix, wx, p, l0, a, ax, l, Delay, ++ pixels; ++ ++ if (pixelFormat == dm_n422 || pixelFormat == dm_420) ++ pixelsPerClock = 2; ++ // #all other modes operate at 1 pixel per clock ++ else ++ pixelsPerClock = 1; ++ ++ //initial transmit delay as per PPS ++ initalXmitDelay = dml_round(rcModelSize / 2.0 / bpp / pixelsPerClock); ++ ++ //compute ssm delay ++ if (bpc == 8) ++ D = 81; ++ else if (bpc == 10) ++ D = 89; ++ else ++ D = 113; ++ ++ //divide by pixel per cycle to compute slice width as seen by DSC ++ w = sliceWidth / pixelsPerClock; ++ ++ //422 mode has an additional cycle of delay ++ if (pixelFormat == dm_s422) ++ s = 1; ++ else ++ s = 0; ++ ++ //main calculation for the dscce ++ ix = initalXmitDelay + 45; ++ wx = (w + 2) / 3; ++ p = 3 * wx - w; ++ l0 = ix / w; ++ a = ix + p * l0; ++ ax = (a + 2) / 3 + D + 6 + 1; ++ l = (ax + wx - 1) / wx; ++ if ((ix % w) == 0 && p != 0) ++ lstall = 1; ++ else ++ lstall = 0; ++ Delay = l * wx * (numSlices - 1) + ax + s + lstall + 22; ++ ++ //dsc processes 3 pixel containers per cycle and a container can contain 1 or 2 pixels ++ pixels = Delay * 3 * pixelsPerClock; ++ return pixels; ++} ++ ++static unsigned int dscComputeDelay(enum output_format_class pixelFormat) ++{ ++ unsigned int Delay = 0; ++ ++ if (pixelFormat == dm_420) { ++ // sfr ++ Delay = Delay + 2; ++ // dsccif ++ Delay = Delay + 0; ++ // dscc - input deserializer ++ Delay = Delay + 3; ++ // dscc gets pixels every other cycle ++ Delay = Delay + 2; ++ // dscc - input cdc fifo ++ Delay = Delay + 12; ++ // dscc gets pixels every other cycle ++ Delay = Delay + 13; ++ // dscc - cdc uncertainty ++ Delay = Delay + 2; ++ // dscc - output cdc fifo ++ Delay = Delay + 7; ++ // dscc gets pixels every other cycle ++ Delay = Delay + 3; ++ // dscc - cdc uncertainty ++ Delay = Delay + 2; ++ // dscc - output serializer ++ Delay = Delay + 1; ++ // sft ++ Delay = Delay + 1; ++ } else if (pixelFormat == dm_n422) { ++ // sfr ++ Delay = Delay + 2; ++ // dsccif ++ Delay = Delay + 1; ++ // dscc - input deserializer ++ Delay = Delay + 5; ++ // dscc - input cdc fifo ++ Delay = Delay + 25; ++ // dscc - cdc uncertainty ++ Delay = Delay + 2; ++ // dscc - output cdc fifo ++ Delay = Delay + 10; ++ // dscc - cdc uncertainty ++ Delay = Delay + 2; ++ // dscc - output serializer ++ Delay = Delay + 1; ++ // sft ++ Delay = Delay + 1; ++ } else { ++ // sfr ++ Delay = Delay + 2; ++ // dsccif ++ Delay = Delay + 0; ++ // dscc - input deserializer ++ Delay = Delay + 3; ++ // dscc - input cdc fifo ++ Delay = Delay + 12; ++ // dscc - cdc uncertainty ++ Delay = Delay + 2; ++ // dscc - output cdc fifo ++ Delay = Delay + 7; ++ // dscc - output serializer ++ Delay = Delay + 1; ++ // dscc - cdc uncertainty ++ Delay = Delay + 2; ++ // sft ++ Delay = Delay + 1; ++ } ++ ++ return Delay; ++} ++ ++static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, ++ double DPPCLK, ++ double DISPCLK, ++ double PixelClock, ++ double DCFClkDeepSleep, ++ unsigned int DSCDelay, ++ unsigned int DPPPerPlane, ++ bool ScalerEnabled, ++ unsigned int NumberOfCursors, ++ double DPPCLKDelaySubtotal, ++ double DPPCLKDelaySCL, ++ double DPPCLKDelaySCLLBOnly, ++ double DPPCLKDelayCNVCFormater, ++ double DPPCLKDelayCNVCCursor, ++ double DISPCLKDelaySubtotal, ++ unsigned int ScalerRecoutWidth, ++ enum output_format_class OutputFormat, ++ unsigned int VBlank, ++ unsigned int HTotal, ++ unsigned int MaxInterDCNTileRepeaters, ++ unsigned int VStartup, ++ unsigned int PageTableLevels, ++ bool VirtualMemoryEnable, ++ bool DynamicMetadataEnable, ++ unsigned int DynamicMetadataLinesBeforeActiveRequired, ++ unsigned int DynamicMetadataTransmittedBytes, ++ bool DCCEnable, ++ double UrgentLatency, ++ double UrgentExtraLatency, ++ double TCalc, ++ unsigned int PDEAndMetaPTEBytesFrame, ++ unsigned int MetaRowByte, ++ unsigned int PixelPTEBytesPerRow, ++ double PrefetchSourceLinesY, ++ unsigned int SwathWidthY, ++ double BytePerPixelDETY, ++ double VInitPreFillY, ++ unsigned int MaxNumSwathY, ++ double PrefetchSourceLinesC, ++ double BytePerPixelDETC, ++ double VInitPreFillC, ++ unsigned int MaxNumSwathC, ++ unsigned int SwathHeightY, ++ unsigned int SwathHeightC, ++ double TWait, ++ bool XFCEnabled, ++ double XFCRemoteSurfaceFlipDelay, ++ bool InterlaceEnable, ++ bool ProgressiveToInterlaceUnitInOPP, ++ double *DSTXAfterScaler, ++ double *DSTYAfterScaler, ++ double *DestinationLinesForPrefetch, ++ double *PrefetchBandwidth, ++ double *DestinationLinesToRequestVMInVBlank, ++ double *DestinationLinesToRequestRowInVBlank, ++ double *VRatioPrefetchY, ++ double *VRatioPrefetchC, ++ double *RequiredPrefetchPixDataBW, ++ unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, ++ double *Tno_bw) ++{ ++ bool MyError = false; ++ unsigned int DPPCycles, DISPCLKCycles, VUpdateOffsetPix, VUpdateWidthPix, VReadyOffsetPix; ++ double DSTTotalPixelsAfterScaler, TotalRepeaterDelayTime; ++ double Tdm, LineTime, Tsetup; ++ double dst_y_prefetch_equ; ++ double Tsw_oto; ++ double prefetch_bw_oto; ++ double Tvm_oto; ++ double Tr0_oto; ++ double Tpre_oto; ++ double dst_y_prefetch_oto; ++ double TimeForFetchingMetaPTE = 0; ++ double TimeForFetchingRowInVBlank = 0; ++ double LinesToRequestPrefetchPixelData = 0; ++ ++ if (ScalerEnabled) ++ DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCL; ++ else ++ DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCLLBOnly; ++ ++ DPPCycles = DPPCycles + DPPCLKDelayCNVCFormater + NumberOfCursors * DPPCLKDelayCNVCCursor; ++ ++ DISPCLKCycles = DISPCLKDelaySubtotal; ++ ++ if (DPPCLK == 0.0 || DISPCLK == 0.0) ++ return true; ++ ++ *DSTXAfterScaler = DPPCycles * PixelClock / DPPCLK + DISPCLKCycles * PixelClock / DISPCLK ++ + DSCDelay; ++ ++ if (DPPPerPlane > 1) ++ *DSTXAfterScaler = *DSTXAfterScaler + ScalerRecoutWidth; ++ ++ if (OutputFormat == dm_420 || (InterlaceEnable && ProgressiveToInterlaceUnitInOPP)) ++ *DSTYAfterScaler = 1; ++ else ++ *DSTYAfterScaler = 0; ++ ++ DSTTotalPixelsAfterScaler = ((double)(*DSTYAfterScaler * HTotal)) + *DSTXAfterScaler; ++ *DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / HTotal, 1); ++ *DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double)(*DSTYAfterScaler * HTotal)); ++ ++ VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1); ++ TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2.0 / DPPCLK + 3.0 / DISPCLK); ++ VUpdateWidthPix = (14.0 / DCFClkDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime) ++ * PixelClock; ++ ++ VReadyOffsetPix = dml_max(150.0 / DPPCLK, ++ TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / DPPCLK) ++ * PixelClock; ++ ++ Tsetup = (double)(VUpdateOffsetPix + VUpdateWidthPix + VReadyOffsetPix) / PixelClock; ++ ++ LineTime = (double)HTotal / PixelClock; ++ ++ if (DynamicMetadataEnable) { ++ double Tdmbf, Tdmec, Tdmsks; ++ ++ Tdm = dml_max(0.0, UrgentExtraLatency - TCalc); ++ Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / DISPCLK; ++ Tdmec = LineTime; ++ if (DynamicMetadataLinesBeforeActiveRequired == 0) ++ Tdmsks = VBlank * LineTime / 2.0; ++ else ++ Tdmsks = DynamicMetadataLinesBeforeActiveRequired * LineTime; ++ if (InterlaceEnable && !ProgressiveToInterlaceUnitInOPP) ++ Tdmsks = Tdmsks / 2; ++ if (VStartup * LineTime ++ < Tsetup + TWait + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) { ++ MyError = true; ++ *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = (Tsetup + TWait ++ + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) / LineTime; ++ } else ++ *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = 0.0; ++ } else ++ Tdm = 0; ++ ++ if (VirtualMemoryEnable) { ++ if (PageTableLevels == 4) ++ *Tno_bw = UrgentExtraLatency + UrgentLatency; ++ else if (PageTableLevels == 3) ++ *Tno_bw = UrgentExtraLatency; ++ else ++ Tno_bw = 0; ++ } else if (DCCEnable) ++ *Tno_bw = LineTime; ++ else ++ *Tno_bw = LineTime / 4; ++ ++ dst_y_prefetch_equ = VStartup - dml_max(TCalc + TWait, XFCRemoteSurfaceFlipDelay) / LineTime ++ - (Tsetup + Tdm) / LineTime ++ - (*DSTYAfterScaler + *DSTXAfterScaler / HTotal); ++ ++ Tsw_oto = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime; ++ ++ prefetch_bw_oto = (MetaRowByte + PixelPTEBytesPerRow ++ + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1) ++ + PrefetchSourceLinesC * SwathWidthY / 2 * dml_ceil(BytePerPixelDETC, 2)) ++ / Tsw_oto; ++ ++ if (VirtualMemoryEnable == true) { ++ Tvm_oto = ++ dml_max(*Tno_bw + PDEAndMetaPTEBytesFrame / prefetch_bw_oto, ++ dml_max(UrgentExtraLatency ++ + UrgentLatency ++ * (PageTableLevels ++ - 1), ++ LineTime / 4.0)); ++ } else ++ Tvm_oto = LineTime / 4.0; ++ ++ if ((VirtualMemoryEnable == true || DCCEnable == true)) { ++ Tr0_oto = dml_max((MetaRowByte + PixelPTEBytesPerRow) / prefetch_bw_oto, ++ dml_max(UrgentLatency, dml_max(LineTime - Tvm_oto, LineTime / 4))); ++ } else ++ Tr0_oto = LineTime - Tvm_oto; ++ ++ Tpre_oto = Tvm_oto + Tr0_oto + Tsw_oto; ++ ++ dst_y_prefetch_oto = Tpre_oto / LineTime; ++ ++ if (dst_y_prefetch_oto < dst_y_prefetch_equ) ++ *DestinationLinesForPrefetch = dst_y_prefetch_oto; ++ else ++ *DestinationLinesForPrefetch = dst_y_prefetch_equ; ++ ++ *DestinationLinesForPrefetch = dml_floor(4.0 * (*DestinationLinesForPrefetch + 0.125), 1) / 4; ++ ++ dml_print("DML: VStartup: %d\n", VStartup); ++ dml_print("DML: TCalc: %f\n", TCalc); ++ dml_print("DML: TWait: %f\n", TWait); ++ dml_print("DML: XFCRemoteSurfaceFlipDelay: %f\n", XFCRemoteSurfaceFlipDelay); ++ dml_print("DML: LineTime: %f\n", LineTime); ++ dml_print("DML: Tsetup: %f\n", Tsetup); ++ dml_print("DML: Tdm: %f\n", Tdm); ++ dml_print("DML: DSTYAfterScaler: %f\n", *DSTYAfterScaler); ++ dml_print("DML: DSTXAfterScaler: %f\n", *DSTXAfterScaler); ++ dml_print("DML: HTotal: %d\n", HTotal); ++ ++ *PrefetchBandwidth = 0; ++ *DestinationLinesToRequestVMInVBlank = 0; ++ *DestinationLinesToRequestRowInVBlank = 0; ++ *VRatioPrefetchY = 0; ++ *VRatioPrefetchC = 0; ++ *RequiredPrefetchPixDataBW = 0; ++ if (*DestinationLinesForPrefetch > 1) { ++ *PrefetchBandwidth = (PDEAndMetaPTEBytesFrame + 2 * MetaRowByte ++ + 2 * PixelPTEBytesPerRow ++ + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1) ++ + PrefetchSourceLinesC * SwathWidthY / 2 ++ * dml_ceil(BytePerPixelDETC, 2)) ++ / (*DestinationLinesForPrefetch * LineTime - *Tno_bw); ++ if (VirtualMemoryEnable) { ++ TimeForFetchingMetaPTE = ++ dml_max(*Tno_bw ++ + (double)PDEAndMetaPTEBytesFrame ++ / *PrefetchBandwidth, ++ dml_max(UrgentExtraLatency ++ + UrgentLatency ++ * (PageTableLevels ++ - 1), ++ LineTime / 4)); ++ } else { ++ if (NumberOfCursors > 0 || XFCEnabled) ++ TimeForFetchingMetaPTE = LineTime / 4; ++ else ++ TimeForFetchingMetaPTE = 0.0; ++ } ++ ++ if ((VirtualMemoryEnable == true || DCCEnable == true)) { ++ TimeForFetchingRowInVBlank = ++ dml_max((MetaRowByte + PixelPTEBytesPerRow) ++ / *PrefetchBandwidth, ++ dml_max(UrgentLatency, ++ dml_max(LineTime ++ - TimeForFetchingMetaPTE, ++ LineTime ++ / 4.0))); ++ } else { ++ if (NumberOfCursors > 0 || XFCEnabled) ++ TimeForFetchingRowInVBlank = LineTime - TimeForFetchingMetaPTE; ++ else ++ TimeForFetchingRowInVBlank = 0.0; ++ } ++ ++ *DestinationLinesToRequestVMInVBlank = dml_floor(4.0 * (TimeForFetchingMetaPTE / LineTime + 0.125), ++ 1) / 4.0; ++ ++ *DestinationLinesToRequestRowInVBlank = dml_floor(4.0 * (TimeForFetchingRowInVBlank / LineTime + 0.125), ++ 1) / 4.0; ++ ++ LinesToRequestPrefetchPixelData = ++ *DestinationLinesForPrefetch ++ - ((NumberOfCursors > 0 || VirtualMemoryEnable ++ || DCCEnable) ? ++ (*DestinationLinesToRequestVMInVBlank ++ + *DestinationLinesToRequestRowInVBlank) : ++ 0.0); ++ ++ if (LinesToRequestPrefetchPixelData > 0) { ++ ++ *VRatioPrefetchY = (double)PrefetchSourceLinesY ++ / LinesToRequestPrefetchPixelData; ++ *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0); ++ if ((SwathHeightY > 4) && (VInitPreFillY > 3)) { ++ if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) { ++ *VRatioPrefetchY = ++ dml_max((double)PrefetchSourceLinesY ++ / LinesToRequestPrefetchPixelData, ++ (double)MaxNumSwathY ++ * SwathHeightY ++ / (LinesToRequestPrefetchPixelData ++ - (VInitPreFillY ++ - 3.0) ++ / 2.0)); ++ *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0); ++ } else { ++ MyError = true; ++ *VRatioPrefetchY = 0; ++ } ++ } ++ ++ *VRatioPrefetchC = (double)PrefetchSourceLinesC ++ / LinesToRequestPrefetchPixelData; ++ *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0); ++ ++ if ((SwathHeightC > 4)) { ++ if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) { ++ *VRatioPrefetchC = ++ dml_max(*VRatioPrefetchC, ++ (double)MaxNumSwathC ++ * SwathHeightC ++ / (LinesToRequestPrefetchPixelData ++ - (VInitPreFillC ++ - 3.0) ++ / 2.0)); ++ *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0); ++ } else { ++ MyError = true; ++ *VRatioPrefetchC = 0; ++ } ++ } ++ ++ *RequiredPrefetchPixDataBW = ++ DPPPerPlane ++ * ((double)PrefetchSourceLinesY ++ / LinesToRequestPrefetchPixelData ++ * dml_ceil(BytePerPixelDETY, ++ 1) ++ + (double)PrefetchSourceLinesC ++ / LinesToRequestPrefetchPixelData ++ * dml_ceil(BytePerPixelDETC, ++ 2) ++ / 2) ++ * SwathWidthY / LineTime; ++ } else { ++ MyError = true; ++ *VRatioPrefetchY = 0; ++ *VRatioPrefetchC = 0; ++ *RequiredPrefetchPixDataBW = 0; ++ } ++ ++ } else { ++ MyError = true; ++ } ++ ++ if (MyError) { ++ *PrefetchBandwidth = 0; ++ TimeForFetchingMetaPTE = 0; ++ TimeForFetchingRowInVBlank = 0; ++ *DestinationLinesToRequestVMInVBlank = 0; ++ *DestinationLinesToRequestRowInVBlank = 0; ++ *DestinationLinesForPrefetch = 0; ++ LinesToRequestPrefetchPixelData = 0; ++ *VRatioPrefetchY = 0; ++ *VRatioPrefetchC = 0; ++ *RequiredPrefetchPixDataBW = 0; ++ } ++ ++ return MyError; ++} ++ ++static double CeilToDFSGranularity(double Clock, double VCOSpeed) ++{ ++ return VCOSpeed * 4 / dml_floor(VCOSpeed * 4 / Clock, 1); ++} ++ ++static double FloorToDFSGranularity(double Clock, double VCOSpeed) ++{ ++ return VCOSpeed * 4 / dml_ceil(VCOSpeed * 4 / Clock, 1); ++} ++ ++static double CalculatePrefetchSourceLines(struct display_mode_lib *mode_lib, ++ double VRatio, ++ double vtaps, ++ bool Interlace, ++ bool ProgressiveToInterlaceUnitInOPP, ++ unsigned int SwathHeight, ++ unsigned int ViewportYStart, ++ double *VInitPreFill, ++ unsigned int *MaxNumSwath) ++{ ++ unsigned int MaxPartialSwath; ++ ++ if (ProgressiveToInterlaceUnitInOPP) ++ *VInitPreFill = dml_floor((VRatio + vtaps + 1) / 2.0, 1); ++ else ++ *VInitPreFill = dml_floor((VRatio + vtaps + 1 + Interlace * 0.5 * VRatio) / 2.0, 1); ++ ++ if (!mode_lib->vba.IgnoreViewportPositioning) { ++ ++ *MaxNumSwath = dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0; ++ ++ if (*VInitPreFill > 1.0) ++ MaxPartialSwath = (unsigned int)(*VInitPreFill - 2) % SwathHeight; ++ else ++ MaxPartialSwath = (unsigned int)(*VInitPreFill + SwathHeight - 2) % SwathHeight; ++ MaxPartialSwath = dml_max(1U, MaxPartialSwath); ++ ++ } else { ++ ++ if (ViewportYStart != 0) ++ dml_print("WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n"); ++ ++ *MaxNumSwath = dml_ceil(*VInitPreFill / SwathHeight, 1); ++ ++ if (*VInitPreFill > 1.0) ++ MaxPartialSwath = (unsigned int)(*VInitPreFill - 1) % SwathHeight; ++ else ++ MaxPartialSwath = (unsigned int)(*VInitPreFill + SwathHeight - 1) % SwathHeight; ++ } ++ ++ return *MaxNumSwath * SwathHeight + MaxPartialSwath; ++} ++ ++static unsigned int CalculateVMAndRowBytes(struct display_mode_lib *mode_lib, ++ bool DCCEnable, ++ unsigned int BlockHeight256Bytes, ++ unsigned int BlockWidth256Bytes, ++ enum source_format_class SourcePixelFormat, ++ unsigned int SurfaceTiling, ++ unsigned int BytePerPixel, ++ enum scan_direction_class ScanDirection, ++ unsigned int ViewportWidth, ++ unsigned int ViewportHeight, ++ unsigned int SwathWidth, ++ bool VirtualMemoryEnable, ++ unsigned int VMMPageSize, ++ unsigned int PTEBufferSizeInRequests, ++ unsigned int PDEProcessingBufIn64KBReqs, ++ unsigned int Pitch, ++ unsigned int DCCMetaPitch, ++ unsigned int *MacroTileWidth, ++ unsigned int *MetaRowByte, ++ unsigned int *PixelPTEBytesPerRow, ++ bool *PTEBufferSizeNotExceeded, ++ unsigned int *dpte_row_height, ++ unsigned int *meta_row_height) ++{ ++ unsigned int MetaRequestHeight; ++ unsigned int MetaRequestWidth; ++ unsigned int MetaSurfWidth; ++ unsigned int MetaSurfHeight; ++ unsigned int MPDEBytesFrame; ++ unsigned int MetaPTEBytesFrame; ++ unsigned int DCCMetaSurfaceBytes; ++ ++ unsigned int MacroTileSizeBytes; ++ unsigned int MacroTileHeight; ++ unsigned int DPDE0BytesFrame; ++ unsigned int ExtraDPDEBytesFrame; ++ unsigned int PDEAndMetaPTEBytesFrame; ++ ++ if (DCCEnable == true) { ++ MetaRequestHeight = 8 * BlockHeight256Bytes; ++ MetaRequestWidth = 8 * BlockWidth256Bytes; ++ if (ScanDirection == dm_horz) { ++ *meta_row_height = MetaRequestHeight; ++ MetaSurfWidth = dml_ceil((double)SwathWidth - 1, MetaRequestWidth) ++ + MetaRequestWidth; ++ *MetaRowByte = MetaSurfWidth * MetaRequestHeight * BytePerPixel / 256.0; ++ } else { ++ *meta_row_height = MetaRequestWidth; ++ MetaSurfHeight = dml_ceil((double)SwathWidth - 1, MetaRequestHeight) ++ + MetaRequestHeight; ++ *MetaRowByte = MetaSurfHeight * MetaRequestWidth * BytePerPixel / 256.0; ++ } ++ if (ScanDirection == dm_horz) { ++ DCCMetaSurfaceBytes = DCCMetaPitch ++ * (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes) ++ + 64 * BlockHeight256Bytes) * BytePerPixel ++ / 256; ++ } else { ++ DCCMetaSurfaceBytes = DCCMetaPitch ++ * (dml_ceil((double)ViewportHeight - 1, ++ 64 * BlockHeight256Bytes) ++ + 64 * BlockHeight256Bytes) * BytePerPixel ++ / 256; ++ } ++ if (VirtualMemoryEnable == true) { ++ MetaPTEBytesFrame = (dml_ceil((double)(DCCMetaSurfaceBytes - VMMPageSize) ++ / (8 * VMMPageSize), ++ 1) + 1) * 64; ++ MPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 1); ++ } else { ++ MetaPTEBytesFrame = 0; ++ MPDEBytesFrame = 0; ++ } ++ } else { ++ MetaPTEBytesFrame = 0; ++ MPDEBytesFrame = 0; ++ *MetaRowByte = 0; ++ } ++ ++ if (SurfaceTiling == dm_sw_linear) { ++ MacroTileSizeBytes = 256; ++ MacroTileHeight = 1; ++ } else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x ++ || SurfaceTiling == dm_sw_4kb_d || SurfaceTiling == dm_sw_4kb_d_x) { ++ MacroTileSizeBytes = 4096; ++ MacroTileHeight = 4 * BlockHeight256Bytes; ++ } else if (SurfaceTiling == dm_sw_64kb_s || SurfaceTiling == dm_sw_64kb_s_t ++ || SurfaceTiling == dm_sw_64kb_s_x || SurfaceTiling == dm_sw_64kb_d ++ || SurfaceTiling == dm_sw_64kb_d_t || SurfaceTiling == dm_sw_64kb_d_x ++ || SurfaceTiling == dm_sw_64kb_r_x) { ++ MacroTileSizeBytes = 65536; ++ MacroTileHeight = 16 * BlockHeight256Bytes; ++ } else { ++ MacroTileSizeBytes = 262144; ++ MacroTileHeight = 32 * BlockHeight256Bytes; ++ } ++ *MacroTileWidth = MacroTileSizeBytes / BytePerPixel / MacroTileHeight; ++ ++ if (VirtualMemoryEnable == true && mode_lib->vba.MaxPageTableLevels > 1) { ++ if (ScanDirection == dm_horz) { ++ DPDE0BytesFrame = ++ 64 ++ * (dml_ceil(((Pitch ++ * (dml_ceil(ViewportHeight ++ - 1, ++ MacroTileHeight) ++ + MacroTileHeight) ++ * BytePerPixel) ++ - MacroTileSizeBytes) ++ / (8 ++ * 2097152), ++ 1) + 1); ++ } else { ++ DPDE0BytesFrame = ++ 64 ++ * (dml_ceil(((Pitch ++ * (dml_ceil((double)SwathWidth ++ - 1, ++ MacroTileHeight) ++ + MacroTileHeight) ++ * BytePerPixel) ++ - MacroTileSizeBytes) ++ / (8 ++ * 2097152), ++ 1) + 1); ++ } ++ ExtraDPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 2); ++ } else { ++ DPDE0BytesFrame = 0; ++ ExtraDPDEBytesFrame = 0; ++ } ++ ++ PDEAndMetaPTEBytesFrame = MetaPTEBytesFrame + MPDEBytesFrame + DPDE0BytesFrame ++ + ExtraDPDEBytesFrame; ++ ++ if (VirtualMemoryEnable == true) { ++ unsigned int PTERequestSize; ++ unsigned int PixelPTEReqHeight; ++ unsigned int PixelPTEReqWidth; ++ double FractionOfPTEReturnDrop; ++ unsigned int EffectivePDEProcessingBufIn64KBReqs; ++ ++ if (SurfaceTiling == dm_sw_linear) { ++ PixelPTEReqHeight = 1; ++ PixelPTEReqWidth = 8.0 * VMMPageSize / BytePerPixel; ++ PTERequestSize = 64; ++ FractionOfPTEReturnDrop = 0; ++ } else if (MacroTileSizeBytes == 4096) { ++ PixelPTEReqHeight = MacroTileHeight; ++ PixelPTEReqWidth = 8 * *MacroTileWidth; ++ PTERequestSize = 64; ++ if (ScanDirection == dm_horz) ++ FractionOfPTEReturnDrop = 0; ++ else ++ FractionOfPTEReturnDrop = 7 / 8; ++ } else if (VMMPageSize == 4096 && MacroTileSizeBytes > 4096) { ++ PixelPTEReqHeight = 16 * BlockHeight256Bytes; ++ PixelPTEReqWidth = 16 * BlockWidth256Bytes; ++ PTERequestSize = 128; ++ FractionOfPTEReturnDrop = 0; ++ } else { ++ PixelPTEReqHeight = MacroTileHeight; ++ PixelPTEReqWidth = 8 * *MacroTileWidth; ++ PTERequestSize = 64; ++ FractionOfPTEReturnDrop = 0; ++ } ++ ++ if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) ++ EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs / 2; ++ else ++ EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs; ++ ++ if (SurfaceTiling == dm_sw_linear) { ++ *dpte_row_height = ++ dml_min(128, ++ 1 ++ << (unsigned int)dml_floor(dml_log2(dml_min((double)PTEBufferSizeInRequests ++ * PixelPTEReqWidth, ++ EffectivePDEProcessingBufIn64KBReqs ++ * 65536.0 ++ / BytePerPixel) ++ / Pitch), ++ 1)); ++ *PixelPTEBytesPerRow = PTERequestSize ++ * (dml_ceil((double)(Pitch * *dpte_row_height - 1) ++ / PixelPTEReqWidth, ++ 1) + 1); ++ } else if (ScanDirection == dm_horz) { ++ *dpte_row_height = PixelPTEReqHeight; ++ *PixelPTEBytesPerRow = PTERequestSize ++ * (dml_ceil(((double)SwathWidth - 1) / PixelPTEReqWidth, 1) ++ + 1); ++ } else { ++ *dpte_row_height = dml_min(PixelPTEReqWidth, *MacroTileWidth); ++ *PixelPTEBytesPerRow = PTERequestSize ++ * (dml_ceil(((double)SwathWidth - 1) ++ / PixelPTEReqHeight, ++ 1) + 1); ++ } ++ if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop) ++ <= 64 * PTEBufferSizeInRequests) { ++ *PTEBufferSizeNotExceeded = true; ++ } else { ++ *PTEBufferSizeNotExceeded = false; ++ } ++ } else { ++ *PixelPTEBytesPerRow = 0; ++ *PTEBufferSizeNotExceeded = true; ++ } ++ ++ return PDEAndMetaPTEBytesFrame; ++} ++ ++static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(struct display_mode_lib *mode_lib) ++{ ++ unsigned int j, k; ++ ++ mode_lib->vba.WritebackDISPCLK = 0.0; ++ mode_lib->vba.DISPCLKWithRamping = 0; ++ mode_lib->vba.DISPCLKWithoutRamping = 0; ++ mode_lib->vba.GlobalDPPCLK = 0.0; ++ ++ // dml_ml->vba.DISPCLK and dml_ml->vba.DPPCLK Calculation ++ // ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.WritebackEnable[k]) { ++ mode_lib->vba.WritebackDISPCLK = dml_max(mode_lib->vba.WritebackDISPCLK, ++ CalculateWriteBackDISPCLK(mode_lib->vba.WritebackPixelFormat[k], ++ mode_lib->vba.PixelClock[k], ++ mode_lib->vba.WritebackHRatio[k], ++ mode_lib->vba.WritebackVRatio[k], ++ mode_lib->vba.WritebackLumaHTaps[k], ++ mode_lib->vba.WritebackLumaVTaps[k], ++ mode_lib->vba.WritebackChromaHTaps[k], ++ mode_lib->vba.WritebackChromaVTaps[k], ++ mode_lib->vba.WritebackDestinationWidth[k], ++ mode_lib->vba.HTotal[k], ++ mode_lib->vba.WritebackChromaLineBufferWidth)); ++ } ++ } ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.HRatio[k] > 1) { ++ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(mode_lib->vba.MaxDCHUBToPSCLThroughput, ++ mode_lib->vba.MaxPSCLToLBThroughput * mode_lib->vba.HRatio[k] ++ / dml_ceil(mode_lib->vba.htaps[k] / 6.0, 1)); ++ } else { ++ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(mode_lib->vba.MaxDCHUBToPSCLThroughput, ++ mode_lib->vba.MaxPSCLToLBThroughput); ++ } ++ ++ mode_lib->vba.DPPCLKUsingSingleDPPLuma = ++ mode_lib->vba.PixelClock[k] ++ * dml_max(mode_lib->vba.vtaps[k] / 6.0 ++ * dml_min(1.0, ++ mode_lib->vba.HRatio[k]), ++ dml_max(mode_lib->vba.HRatio[k] ++ * mode_lib->vba.VRatio[k] ++ / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k], ++ 1.0)); ++ ++ if ((mode_lib->vba.htaps[k] > 6 || mode_lib->vba.vtaps[k] > 6) ++ && mode_lib->vba.DPPCLKUsingSingleDPPLuma < 2 * mode_lib->vba.PixelClock[k]) { ++ mode_lib->vba.DPPCLKUsingSingleDPPLuma = 2 * mode_lib->vba.PixelClock[k]; ++ } ++ ++ if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8 && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { ++ mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = 0.0; ++ mode_lib->vba.DPPCLKUsingSingleDPP[k] = mode_lib->vba.DPPCLKUsingSingleDPPLuma; ++ } else { ++ if (mode_lib->vba.HRatio[k] > 1) { ++ mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = ++ dml_min(mode_lib->vba.MaxDCHUBToPSCLThroughput, ++ mode_lib->vba.MaxPSCLToLBThroughput * mode_lib->vba.HRatio[k] ++ / 2 ++ / dml_ceil(mode_lib->vba.HTAPsChroma[k] ++ / 6.0, ++ 1.0)); ++ } else { ++ mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = dml_min(mode_lib->vba.MaxDCHUBToPSCLThroughput, ++ mode_lib->vba.MaxPSCLToLBThroughput); ++ } ++ mode_lib->vba.DPPCLKUsingSingleDPPChroma = ++ mode_lib->vba.PixelClock[k] ++ * dml_max(mode_lib->vba.VTAPsChroma[k] / 6.0 ++ * dml_min(1.0, ++ mode_lib->vba.HRatio[k] ++ / 2), ++ dml_max(mode_lib->vba.HRatio[k] ++ * mode_lib->vba.VRatio[k] ++ / 4 ++ / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k], ++ 1.0)); ++ ++ if ((mode_lib->vba.HTAPsChroma[k] > 6 || mode_lib->vba.VTAPsChroma[k] > 6) ++ && mode_lib->vba.DPPCLKUsingSingleDPPChroma < 2 * mode_lib->vba.PixelClock[k]) { ++ mode_lib->vba.DPPCLKUsingSingleDPPChroma = 2 * mode_lib->vba.PixelClock[k]; ++ } ++ ++ mode_lib->vba.DPPCLKUsingSingleDPP[k] = dml_max(mode_lib->vba.DPPCLKUsingSingleDPPLuma, ++ mode_lib->vba.DPPCLKUsingSingleDPPChroma); ++ } ++ } ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.BlendingAndTiming[k] != k) ++ continue; ++ if (mode_lib->vba.ODMCombineEnabled[k]) { ++ mode_lib->vba.DISPCLKWithRamping = ++ dml_max(mode_lib->vba.DISPCLKWithRamping, ++ mode_lib->vba.PixelClock[k] / 2 ++ * (1 ++ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading ++ / 100) ++ * (1 ++ + mode_lib->vba.DISPCLKRampingMargin ++ / 100)); ++ mode_lib->vba.DISPCLKWithoutRamping = ++ dml_max(mode_lib->vba.DISPCLKWithoutRamping, ++ mode_lib->vba.PixelClock[k] / 2 ++ * (1 ++ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading ++ / 100)); ++ } else if (!mode_lib->vba.ODMCombineEnabled[k]) { ++ mode_lib->vba.DISPCLKWithRamping = dml_max(mode_lib->vba.DISPCLKWithRamping, ++ mode_lib->vba.PixelClock[k] * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100) ++ * (1 + mode_lib->vba.DISPCLKRampingMargin / 100)); ++ mode_lib->vba.DISPCLKWithoutRamping = ++ dml_max(mode_lib->vba.DISPCLKWithoutRamping, ++ mode_lib->vba.PixelClock[k] ++ * (1 ++ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading ++ / 100)); ++ } ++ } ++ ++ mode_lib->vba.DISPCLKWithRamping = dml_max(mode_lib->vba.DISPCLKWithRamping, mode_lib->vba.WritebackDISPCLK); ++ mode_lib->vba.DISPCLKWithoutRamping = dml_max(mode_lib->vba.DISPCLKWithoutRamping, mode_lib->vba.WritebackDISPCLK); ++ ++ mode_lib->vba.MaxDispclk = mode_lib->vba.soc.clock_limits[NumberOfStates - 1].dispclk_mhz; ++ ASSERT(mode_lib->vba.DISPCLKDPPCLKVCOSpeed != 0); ++ mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity = CeilToDFSGranularity( ++ mode_lib->vba.DISPCLKWithRamping, ++ mode_lib->vba.DISPCLKDPPCLKVCOSpeed); ++ mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity = CeilToDFSGranularity( ++ mode_lib->vba.DISPCLKWithoutRamping, ++ mode_lib->vba.DISPCLKDPPCLKVCOSpeed); ++ mode_lib->vba.MaxDispclkRoundedToDFSGranularity = FloorToDFSGranularity( ++ mode_lib->vba.MaxDispclk, ++ mode_lib->vba.DISPCLKDPPCLKVCOSpeed); ++ if (mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity ++ > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) { ++ mode_lib->vba.DISPCLK_calculated = mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity; ++ } else if (mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity ++ > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) { ++ mode_lib->vba.DISPCLK_calculated = mode_lib->vba.MaxDispclkRoundedToDFSGranularity; ++ } else { ++ mode_lib->vba.DISPCLK_calculated = mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity; ++ } ++ DTRACE(" dispclk_mhz (calculated) = %f", mode_lib->vba.DISPCLK_calculated); ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.DPPCLKUsingSingleDPP[k] / mode_lib->vba.DPPPerPlane[k] ++ * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100); ++ mode_lib->vba.GlobalDPPCLK = dml_max(mode_lib->vba.GlobalDPPCLK, mode_lib->vba.DPPCLK_calculated[k]); ++ } ++ mode_lib->vba.GlobalDPPCLK = CeilToDFSGranularity(mode_lib->vba.GlobalDPPCLK, mode_lib->vba.DISPCLKDPPCLKVCOSpeed); ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.GlobalDPPCLK / 255 ++ * dml_ceil(mode_lib->vba.DPPCLK_calculated[k] * 255 / mode_lib->vba.GlobalDPPCLK, 1); ++ DTRACE(" dppclk_mhz[%i] (calculated) = %f", k, mode_lib->vba.DPPCLK_calculated[k]); ++ } ++ ++ // Urgent Watermark ++ mode_lib->vba.DCCEnabledAnyPlane = false; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) ++ if (mode_lib->vba.DCCEnable[k]) ++ mode_lib->vba.DCCEnabledAnyPlane = true; ++ ++ mode_lib->vba.ReturnBandwidthToDCN = dml_min(mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK, mode_lib->vba.FabricAndDRAMBandwidth * 1000) ++ * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency / 100; ++ ++ mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBandwidthToDCN; ++ mode_lib->vba.ReturnBW = adjust_ReturnBW(mode_lib, mode_lib->vba.ReturnBW, mode_lib->vba.DCCEnabledAnyPlane, mode_lib->vba.ReturnBandwidthToDCN); ++ ++ // Let's do this calculation again?? ++ mode_lib->vba.ReturnBandwidthToDCN = dml_min(mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK, mode_lib->vba.FabricAndDRAMBandwidth * 1000); ++ mode_lib->vba.ReturnBW = adjust_ReturnBW(mode_lib, mode_lib->vba.ReturnBW, mode_lib->vba.DCCEnabledAnyPlane, mode_lib->vba.ReturnBandwidthToDCN); ++ ++ DTRACE(" dcfclk_mhz = %f", mode_lib->vba.DCFCLK); ++ DTRACE(" return_bw_to_dcn = %f", mode_lib->vba.ReturnBandwidthToDCN); ++ DTRACE(" return_bus_bw = %f", mode_lib->vba.ReturnBW); ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ bool MainPlaneDoesODMCombine = false; ++ ++ if (mode_lib->vba.SourceScan[k] == dm_horz) ++ mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportWidth[k]; ++ else ++ mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportHeight[k]; ++ ++ if (mode_lib->vba.ODMCombineEnabled[k] == true) ++ MainPlaneDoesODMCombine = true; ++ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) ++ if (mode_lib->vba.BlendingAndTiming[k] == j && mode_lib->vba.ODMCombineEnabled[j] == true) ++ MainPlaneDoesODMCombine = true; ++ ++ if (MainPlaneDoesODMCombine == true) ++ mode_lib->vba.SwathWidthY[k] = dml_min((double)mode_lib->vba.SwathWidthSingleDPPY[k], ++ dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k])); ++ else ++ mode_lib->vba.SwathWidthY[k] = mode_lib->vba.SwathWidthSingleDPPY[k] / mode_lib->vba.DPPPerPlane[k]; ++ } ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) { ++ mode_lib->vba.BytePerPixelDETY[k] = 8; ++ mode_lib->vba.BytePerPixelDETC[k] = 0; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) { ++ mode_lib->vba.BytePerPixelDETY[k] = 4; ++ mode_lib->vba.BytePerPixelDETC[k] = 0; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) { ++ mode_lib->vba.BytePerPixelDETY[k] = 2; ++ mode_lib->vba.BytePerPixelDETC[k] = 0; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) { ++ mode_lib->vba.BytePerPixelDETY[k] = 1; ++ mode_lib->vba.BytePerPixelDETC[k] = 0; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) { ++ mode_lib->vba.BytePerPixelDETY[k] = 1; ++ mode_lib->vba.BytePerPixelDETC[k] = 2; ++ } else { // dm_420_10 ++ mode_lib->vba.BytePerPixelDETY[k] = 4.0 / 3.0; ++ mode_lib->vba.BytePerPixelDETC[k] = 8.0 / 3.0; ++ } ++ } ++ ++ mode_lib->vba.TotalDataReadBandwidth = 0.0; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ mode_lib->vba.ReadBandwidthPlaneLuma[k] = mode_lib->vba.SwathWidthSingleDPPY[k] ++ * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) ++ * mode_lib->vba.VRatio[k]; ++ mode_lib->vba.ReadBandwidthPlaneChroma[k] = mode_lib->vba.SwathWidthSingleDPPY[k] / 2 ++ * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2) / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) ++ * mode_lib->vba.VRatio[k] / 2; ++ DTRACE(" read_bw[%i] = %fBps", ++ k, ++ mode_lib->vba.ReadBandwidthPlaneLuma[k] + mode_lib->vba.ReadBandwidthPlaneChroma[k]); ++ mode_lib->vba.TotalDataReadBandwidth += mode_lib->vba.ReadBandwidthPlaneLuma[k] ++ + mode_lib->vba.ReadBandwidthPlaneChroma[k]; ++ } ++ ++ mode_lib->vba.TotalDCCActiveDPP = 0; ++ mode_lib->vba.TotalActiveDPP = 0; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP + mode_lib->vba.DPPPerPlane[k]; ++ if (mode_lib->vba.DCCEnable[k]) ++ mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP + mode_lib->vba.DPPPerPlane[k]; ++ } ++ ++ mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency = (mode_lib->vba.RoundTripPingLatencyCycles + 32) / mode_lib->vba.DCFCLK ++ + mode_lib->vba.UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels / mode_lib->vba.ReturnBW; ++ ++ mode_lib->vba.LastPixelOfLineExtraWatermark = 0; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ double DataFabricLineDeliveryTimeLuma, DataFabricLineDeliveryTimeChroma; ++ ++ if (mode_lib->vba.VRatio[k] <= 1.0) ++ mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] = (double)mode_lib->vba.SwathWidthY[k] ++ * mode_lib->vba.DPPPerPlane[k] / mode_lib->vba.HRatio[k] / mode_lib->vba.PixelClock[k]; ++ else ++ mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] = (double)mode_lib->vba.SwathWidthY[k] ++ / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] / mode_lib->vba.DPPCLK[k]; ++ ++ DataFabricLineDeliveryTimeLuma = ++ mode_lib->vba.SwathWidthSingleDPPY[k] * mode_lib->vba.SwathHeightY[k] ++ * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) ++ / (mode_lib->vba.ReturnBW * mode_lib->vba.ReadBandwidthPlaneLuma[k] ++ / mode_lib->vba.TotalDataReadBandwidth); ++ mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(mode_lib->vba.LastPixelOfLineExtraWatermark, ++ DataFabricLineDeliveryTimeLuma ++ - mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k]); ++ ++ if (mode_lib->vba.BytePerPixelDETC[k] == 0) ++ mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = 0.0; ++ else if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) ++ mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = mode_lib->vba.SwathWidthY[k] / 2.0 ++ * mode_lib->vba.DPPPerPlane[k] / (mode_lib->vba.HRatio[k] / 2.0) / mode_lib->vba.PixelClock[k]; ++ else ++ mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = mode_lib->vba.SwathWidthY[k] / 2.0 ++ / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] / mode_lib->vba.DPPCLK[k]; ++ ++ DataFabricLineDeliveryTimeChroma = mode_lib->vba.SwathWidthSingleDPPY[k] / 2.0 ++ * mode_lib->vba.SwathHeightC[k] * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2) ++ / (mode_lib->vba.ReturnBW * mode_lib->vba.ReadBandwidthPlaneChroma[k] ++ / mode_lib->vba.TotalDataReadBandwidth); ++ mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(mode_lib->vba.LastPixelOfLineExtraWatermark, ++ DataFabricLineDeliveryTimeChroma ++ - mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]); ++ } ++ ++ mode_lib->vba.UrgentExtraLatency = mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency ++ + (mode_lib->vba.TotalActiveDPP * mode_lib->vba.PixelChunkSizeInKByte ++ + mode_lib->vba.TotalDCCActiveDPP * mode_lib->vba.MetaChunkSize) * 1024.0 ++ / mode_lib->vba.ReturnBW; ++ ++ if (mode_lib->vba.VirtualMemoryEnable) ++ mode_lib->vba.UrgentExtraLatency += mode_lib->vba.TotalActiveDPP * mode_lib->vba.PTEChunkSize * 1024.0 / mode_lib->vba.ReturnBW; ++ ++ mode_lib->vba.UrgentWatermark = mode_lib->vba.UrgentLatency + mode_lib->vba.LastPixelOfLineExtraWatermark + mode_lib->vba.UrgentExtraLatency; ++ ++ DTRACE(" urgent_extra_latency = %fus", mode_lib->vba.UrgentExtraLatency); ++ DTRACE(" wm_urgent = %fus", mode_lib->vba.UrgentWatermark); ++ ++ mode_lib->vba.MemoryTripWatermark = mode_lib->vba.UrgentLatency; ++ ++ mode_lib->vba.TotalActiveWriteback = 0; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.WritebackEnable[k]) ++ mode_lib->vba.TotalActiveWriteback = mode_lib->vba.TotalActiveWriteback + 1; ++ } ++ ++ if (mode_lib->vba.TotalActiveWriteback <= 1) ++ mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency; ++ else ++ mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency ++ + mode_lib->vba.WritebackChunkSize * 1024.0 / 32 / mode_lib->vba.SOCCLK; ++ ++ DTRACE(" wm_wb_urgent = %fus", mode_lib->vba.WritebackUrgentWatermark); ++ ++ // NB P-State/DRAM Clock Change Watermark ++ mode_lib->vba.DRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency + mode_lib->vba.UrgentWatermark; ++ ++ DTRACE(" wm_pstate_change = %fus", mode_lib->vba.DRAMClockChangeWatermark); ++ ++ DTRACE(" calculating wb pstate watermark"); ++ DTRACE(" total wb outputs %d", mode_lib->vba.TotalActiveWriteback); ++ DTRACE(" socclk frequency %f Mhz", mode_lib->vba.SOCCLK); ++ ++ if (mode_lib->vba.TotalActiveWriteback <= 1) ++ mode_lib->vba.WritebackDRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency + mode_lib->vba.WritebackLatency; ++ else ++ mode_lib->vba.WritebackDRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency + mode_lib->vba.WritebackLatency ++ + mode_lib->vba.WritebackChunkSize * 1024.0 / 32 / mode_lib->vba.SOCCLK; ++ ++ DTRACE(" wm_wb_pstate %fus", mode_lib->vba.WritebackDRAMClockChangeWatermark); ++ ++ // Stutter Efficiency ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ mode_lib->vba.LinesInDETY[k] = mode_lib->vba.DETBufferSizeY[k] / mode_lib->vba.BytePerPixelDETY[k] ++ / mode_lib->vba.SwathWidthY[k]; ++ mode_lib->vba.LinesInDETYRoundedDownToSwath[k] = dml_floor(mode_lib->vba.LinesInDETY[k], ++ mode_lib->vba.SwathHeightY[k]); ++ mode_lib->vba.FullDETBufferingTimeY[k] = mode_lib->vba.LinesInDETYRoundedDownToSwath[k] ++ * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) / mode_lib->vba.VRatio[k]; ++ if (mode_lib->vba.BytePerPixelDETC[k] > 0) { ++ mode_lib->vba.LinesInDETC[k] = mode_lib->vba.DETBufferSizeC[k] / mode_lib->vba.BytePerPixelDETC[k] ++ / (mode_lib->vba.SwathWidthY[k] / 2); ++ mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = dml_floor(mode_lib->vba.LinesInDETC[k], ++ mode_lib->vba.SwathHeightC[k]); ++ mode_lib->vba.FullDETBufferingTimeC[k] = mode_lib->vba.LinesInDETCRoundedDownToSwath[k] ++ * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) / (mode_lib->vba.VRatio[k] / 2); ++ } else { ++ mode_lib->vba.LinesInDETC[k] = 0; ++ mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = 0; ++ mode_lib->vba.FullDETBufferingTimeC[k] = 999999; ++ } ++ } ++ ++ mode_lib->vba.MinFullDETBufferingTime = 999999.0; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.FullDETBufferingTimeY[k] < mode_lib->vba.MinFullDETBufferingTime) { ++ mode_lib->vba.MinFullDETBufferingTime = mode_lib->vba.FullDETBufferingTimeY[k]; ++ mode_lib->vba.FrameTimeForMinFullDETBufferingTime = (double)mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k] ++ / mode_lib->vba.PixelClock[k]; ++ } ++ if (mode_lib->vba.FullDETBufferingTimeC[k] < mode_lib->vba.MinFullDETBufferingTime) { ++ mode_lib->vba.MinFullDETBufferingTime = mode_lib->vba.FullDETBufferingTimeC[k]; ++ mode_lib->vba.FrameTimeForMinFullDETBufferingTime = (double)mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k] ++ / mode_lib->vba.PixelClock[k]; ++ } ++ } ++ ++ mode_lib->vba.AverageReadBandwidthGBytePerSecond = 0.0; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.DCCEnable[k]) { ++ mode_lib->vba.AverageReadBandwidthGBytePerSecond = ++ mode_lib->vba.AverageReadBandwidthGBytePerSecond ++ + mode_lib->vba.ReadBandwidthPlaneLuma[k] / mode_lib->vba.DCCRate[k] ++ / 1000 ++ + mode_lib->vba.ReadBandwidthPlaneChroma[k] ++ / mode_lib->vba.DCCRate[k] / 1000; ++ } else { ++ mode_lib->vba.AverageReadBandwidthGBytePerSecond = ++ mode_lib->vba.AverageReadBandwidthGBytePerSecond ++ + mode_lib->vba.ReadBandwidthPlaneLuma[k] / 1000 ++ + mode_lib->vba.ReadBandwidthPlaneChroma[k] / 1000; ++ } ++ if (mode_lib->vba.DCCEnable[k]) { ++ mode_lib->vba.AverageReadBandwidthGBytePerSecond = ++ mode_lib->vba.AverageReadBandwidthGBytePerSecond ++ + mode_lib->vba.ReadBandwidthPlaneLuma[k] / 1000 / 256 ++ + mode_lib->vba.ReadBandwidthPlaneChroma[k] / 1000 ++ / 256; ++ } ++ if (mode_lib->vba.VirtualMemoryEnable) { ++ mode_lib->vba.AverageReadBandwidthGBytePerSecond = ++ mode_lib->vba.AverageReadBandwidthGBytePerSecond ++ + mode_lib->vba.ReadBandwidthPlaneLuma[k] / 1000 / 512 ++ + mode_lib->vba.ReadBandwidthPlaneChroma[k] / 1000 ++ / 512; ++ } ++ } ++ ++ mode_lib->vba.PartOfBurstThatFitsInROB = dml_min(mode_lib->vba.MinFullDETBufferingTime * mode_lib->vba.TotalDataReadBandwidth, ++ mode_lib->vba.ROBBufferSizeInKByte * 1024 * mode_lib->vba.TotalDataReadBandwidth ++ / (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000)); ++ mode_lib->vba.StutterBurstTime = mode_lib->vba.PartOfBurstThatFitsInROB ++ * (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000) / mode_lib->vba.TotalDataReadBandwidth ++ / mode_lib->vba.ReturnBW ++ + (mode_lib->vba.MinFullDETBufferingTime * mode_lib->vba.TotalDataReadBandwidth ++ - mode_lib->vba.PartOfBurstThatFitsInROB) / (mode_lib->vba.DCFCLK * 64); ++ if (mode_lib->vba.TotalActiveWriteback == 0) { ++ mode_lib->vba.StutterEfficiencyNotIncludingVBlank = (1 ++ - (mode_lib->vba.SRExitTime + mode_lib->vba.StutterBurstTime) / mode_lib->vba.MinFullDETBufferingTime) ++ * 100; ++ } else { ++ mode_lib->vba.StutterEfficiencyNotIncludingVBlank = 0; ++ } ++ ++ mode_lib->vba.SmallestVBlank = 999999; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) { ++ mode_lib->vba.VBlankTime = (double)(mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]) * mode_lib->vba.HTotal[k] ++ / mode_lib->vba.PixelClock[k]; ++ } else { ++ mode_lib->vba.VBlankTime = 0; ++ } ++ mode_lib->vba.SmallestVBlank = dml_min(mode_lib->vba.SmallestVBlank, mode_lib->vba.VBlankTime); ++ } ++ ++ mode_lib->vba.StutterEfficiency = (mode_lib->vba.StutterEfficiencyNotIncludingVBlank / 100 ++ * (mode_lib->vba.FrameTimeForMinFullDETBufferingTime - mode_lib->vba.SmallestVBlank) ++ + mode_lib->vba.SmallestVBlank) / mode_lib->vba.FrameTimeForMinFullDETBufferingTime * 100; ++ ++ // dml_ml->vba.DCFCLK Deep Sleep ++ mode_lib->vba.DCFClkDeepSleep = 8.0; ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++) { ++ if (mode_lib->vba.BytePerPixelDETC[k] > 0) { ++ mode_lib->vba.DCFCLKDeepSleepPerPlane = dml_max(1.1 * mode_lib->vba.SwathWidthY[k] ++ * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 32 ++ / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k], ++ 1.1 * mode_lib->vba.SwathWidthY[k] / 2.0 ++ * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2) / 32 ++ / mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]); ++ } else ++ mode_lib->vba.DCFCLKDeepSleepPerPlane = 1.1 * mode_lib->vba.SwathWidthY[k] ++ * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 64.0 ++ / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k]; ++ mode_lib->vba.DCFCLKDeepSleepPerPlane = dml_max(mode_lib->vba.DCFCLKDeepSleepPerPlane, ++ mode_lib->vba.PixelClock[k] / 16.0); ++ mode_lib->vba.DCFClkDeepSleep = dml_max(mode_lib->vba.DCFClkDeepSleep, mode_lib->vba.DCFCLKDeepSleepPerPlane); ++ ++ DTRACE(" dcfclk_deepsleep_per_plane[%i] = %fMHz", k, mode_lib->vba.DCFCLKDeepSleepPerPlane); ++ } ++ ++ DTRACE(" dcfclk_deepsleep_mhz = %fMHz", mode_lib->vba.DCFClkDeepSleep); ++ ++ // Stutter Watermark ++ mode_lib->vba.StutterExitWatermark = mode_lib->vba.SRExitTime + mode_lib->vba.LastPixelOfLineExtraWatermark + mode_lib->vba.UrgentExtraLatency ++ + 10 / mode_lib->vba.DCFClkDeepSleep; ++ mode_lib->vba.StutterEnterPlusExitWatermark = mode_lib->vba.SREnterPlusExitTime + mode_lib->vba.LastPixelOfLineExtraWatermark ++ + mode_lib->vba.UrgentExtraLatency; ++ ++ DTRACE(" wm_cstate_exit = %fus", mode_lib->vba.StutterExitWatermark); ++ DTRACE(" wm_cstate_enter_exit = %fus", mode_lib->vba.StutterEnterPlusExitWatermark); ++ ++ // Urgent Latency Supported ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ mode_lib->vba.EffectiveDETPlusLBLinesLuma = ++ dml_floor(mode_lib->vba.LinesInDETY[k] ++ + dml_min(mode_lib->vba.LinesInDETY[k] ++ * mode_lib->vba.DPPCLK[k] ++ * mode_lib->vba.BytePerPixelDETY[k] ++ * mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] ++ / (mode_lib->vba.ReturnBW ++ / mode_lib->vba.DPPPerPlane[k]), ++ (double)mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma), ++ mode_lib->vba.SwathHeightY[k]); ++ ++ mode_lib->vba.UrgentLatencySupportUsLuma = mode_lib->vba.EffectiveDETPlusLBLinesLuma ++ * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) / mode_lib->vba.VRatio[k] ++ - mode_lib->vba.EffectiveDETPlusLBLinesLuma * mode_lib->vba.SwathWidthY[k] ++ * mode_lib->vba.BytePerPixelDETY[k] ++ / (mode_lib->vba.ReturnBW / mode_lib->vba.DPPPerPlane[k]); ++ ++ if (mode_lib->vba.BytePerPixelDETC[k] > 0) { ++ mode_lib->vba.EffectiveDETPlusLBLinesChroma = ++ dml_floor(mode_lib->vba.LinesInDETC[k] ++ + dml_min(mode_lib->vba.LinesInDETC[k] ++ * mode_lib->vba.DPPCLK[k] ++ * mode_lib->vba.BytePerPixelDETC[k] ++ * mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] ++ / (mode_lib->vba.ReturnBW ++ / mode_lib->vba.DPPPerPlane[k]), ++ (double)mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma), ++ mode_lib->vba.SwathHeightC[k]); ++ mode_lib->vba.UrgentLatencySupportUsChroma = mode_lib->vba.EffectiveDETPlusLBLinesChroma ++ * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) / (mode_lib->vba.VRatio[k] / 2) ++ - mode_lib->vba.EffectiveDETPlusLBLinesChroma ++ * (mode_lib->vba.SwathWidthY[k] / 2) ++ * mode_lib->vba.BytePerPixelDETC[k] ++ / (mode_lib->vba.ReturnBW / mode_lib->vba.DPPPerPlane[k]); ++ mode_lib->vba.UrgentLatencySupportUs[k] = dml_min(mode_lib->vba.UrgentLatencySupportUsLuma, ++ mode_lib->vba.UrgentLatencySupportUsChroma); ++ } else { ++ mode_lib->vba.UrgentLatencySupportUs[k] = mode_lib->vba.UrgentLatencySupportUsLuma; ++ } ++ } ++ ++ mode_lib->vba.MinUrgentLatencySupportUs = 999999; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ mode_lib->vba.MinUrgentLatencySupportUs = dml_min(mode_lib->vba.MinUrgentLatencySupportUs, ++ mode_lib->vba.UrgentLatencySupportUs[k]); ++ } ++ ++ // Non-Urgent Latency Tolerance ++ mode_lib->vba.NonUrgentLatencyTolerance = mode_lib->vba.MinUrgentLatencySupportUs - mode_lib->vba.UrgentWatermark; ++ ++ // DSCCLK ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if ((mode_lib->vba.BlendingAndTiming[k] != k) || !mode_lib->vba.DSCEnabled[k]) { ++ mode_lib->vba.DSCCLK_calculated[k] = 0.0; ++ } else { ++ if (mode_lib->vba.OutputFormat[k] == dm_420 || mode_lib->vba.OutputFormat[k] == dm_n422) ++ mode_lib->vba.DSCFormatFactor = 2; ++ else ++ mode_lib->vba.DSCFormatFactor = 1; ++ if (mode_lib->vba.ODMCombineEnabled[k]) ++ mode_lib->vba.DSCCLK_calculated[k] = mode_lib->vba.PixelClockBackEnd[k] / 6 ++ / mode_lib->vba.DSCFormatFactor ++ / (1 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100); ++ else ++ mode_lib->vba.DSCCLK_calculated[k] = mode_lib->vba.PixelClockBackEnd[k] / 3 ++ / mode_lib->vba.DSCFormatFactor ++ / (1 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100); ++ } ++ } ++ ++ // DSC Delay ++ // TODO ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ double bpp = mode_lib->vba.OutputBpp[k]; ++ unsigned int slices = mode_lib->vba.NumberOfDSCSlices[k]; ++ ++ if (mode_lib->vba.DSCEnabled[k] && bpp != 0) { ++ if (!mode_lib->vba.ODMCombineEnabled[k]) { ++ mode_lib->vba.DSCDelay[k] = ++ dscceComputeDelay(mode_lib->vba.DSCInputBitPerComponent[k], ++ bpp, ++ dml_ceil((double)mode_lib->vba.HActive[k] ++ / mode_lib->vba.NumberOfDSCSlices[k], ++ 1), ++ slices, ++ mode_lib->vba.OutputFormat[k]) ++ + dscComputeDelay(mode_lib->vba.OutputFormat[k]); ++ } else { ++ mode_lib->vba.DSCDelay[k] = ++ 2 ++ * (dscceComputeDelay(mode_lib->vba.DSCInputBitPerComponent[k], ++ bpp, ++ dml_ceil((double)mode_lib->vba.HActive[k] ++ / mode_lib->vba.NumberOfDSCSlices[k], ++ 1), ++ slices / 2.0, ++ mode_lib->vba.OutputFormat[k]) ++ + dscComputeDelay(mode_lib->vba.OutputFormat[k])); ++ } ++ mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[k] * mode_lib->vba.PixelClock[k] / mode_lib->vba.PixelClockBackEnd[k]; ++ } else { ++ mode_lib->vba.DSCDelay[k] = 0; ++ } ++ } ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) ++ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) // NumberOfPlanes ++ if (j != k && mode_lib->vba.BlendingAndTiming[k] == j && mode_lib->vba.DSCEnabled[j]) ++ mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[j]; ++ ++ // Prefetch ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ unsigned int PDEAndMetaPTEBytesFrameY; ++ unsigned int PixelPTEBytesPerRowY; ++ unsigned int MetaRowByteY; ++ unsigned int MetaRowByteC; ++ unsigned int PDEAndMetaPTEBytesFrameC; ++ unsigned int PixelPTEBytesPerRowC; ++ ++ Calculate256BBlockSizes(mode_lib->vba.SourcePixelFormat[k], ++ mode_lib->vba.SurfaceTiling[k], ++ dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), ++ dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2), ++ &mode_lib->vba.BlockHeight256BytesY[k], ++ &mode_lib->vba.BlockHeight256BytesC[k], ++ &mode_lib->vba.BlockWidth256BytesY[k], ++ &mode_lib->vba.BlockWidth256BytesC[k]); ++ PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(mode_lib, ++ mode_lib->vba.DCCEnable[k], ++ mode_lib->vba.BlockHeight256BytesY[k], ++ mode_lib->vba.BlockWidth256BytesY[k], ++ mode_lib->vba.SourcePixelFormat[k], ++ mode_lib->vba.SurfaceTiling[k], ++ dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), ++ mode_lib->vba.SourceScan[k], ++ mode_lib->vba.ViewportWidth[k], ++ mode_lib->vba.ViewportHeight[k], ++ mode_lib->vba.SwathWidthY[k], ++ mode_lib->vba.VirtualMemoryEnable, ++ mode_lib->vba.VMMPageSize, ++ mode_lib->vba.PTEBufferSizeInRequests, ++ mode_lib->vba.PDEProcessingBufIn64KBReqs, ++ mode_lib->vba.PitchY[k], ++ mode_lib->vba.DCCMetaPitchY[k], ++ &mode_lib->vba.MacroTileWidthY, ++ &MetaRowByteY, ++ &PixelPTEBytesPerRowY, ++ &mode_lib->vba.PTEBufferSizeNotExceeded, ++ &mode_lib->vba.dpte_row_height[k], ++ &mode_lib->vba.meta_row_height[k]); ++ mode_lib->vba.PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(mode_lib, ++ mode_lib->vba.VRatio[k], ++ mode_lib->vba.vtaps[k], ++ mode_lib->vba.Interlace[k], ++ mode_lib->vba.ProgressiveToInterlaceUnitInOPP, ++ mode_lib->vba.SwathHeightY[k], ++ mode_lib->vba.ViewportYStartY[k], ++ &mode_lib->vba.VInitPreFillY[k], ++ &mode_lib->vba.MaxNumSwathY[k]); ++ ++ if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32 ++ && mode_lib->vba.SourcePixelFormat[k] != dm_444_16 ++ && mode_lib->vba.SourcePixelFormat[k] != dm_444_8)) { ++ PDEAndMetaPTEBytesFrameC = CalculateVMAndRowBytes(mode_lib, ++ mode_lib->vba.DCCEnable[k], ++ mode_lib->vba.BlockHeight256BytesC[k], ++ mode_lib->vba.BlockWidth256BytesC[k], ++ mode_lib->vba.SourcePixelFormat[k], ++ mode_lib->vba.SurfaceTiling[k], ++ dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2), ++ mode_lib->vba.SourceScan[k], ++ mode_lib->vba.ViewportWidth[k] / 2, ++ mode_lib->vba.ViewportHeight[k] / 2, ++ mode_lib->vba.SwathWidthY[k] / 2, ++ mode_lib->vba.VirtualMemoryEnable, ++ mode_lib->vba.VMMPageSize, ++ mode_lib->vba.PTEBufferSizeInRequests, ++ mode_lib->vba.PDEProcessingBufIn64KBReqs, ++ mode_lib->vba.PitchC[k], ++ 0, ++ &mode_lib->vba.MacroTileWidthC, ++ &MetaRowByteC, ++ &PixelPTEBytesPerRowC, ++ &mode_lib->vba.PTEBufferSizeNotExceeded, ++ &mode_lib->vba.dpte_row_height_chroma[k], ++ &mode_lib->vba.meta_row_height_chroma[k]); ++ mode_lib->vba.PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(mode_lib, ++ mode_lib->vba.VRatio[k] / 2, ++ mode_lib->vba.VTAPsChroma[k], ++ mode_lib->vba.Interlace[k], ++ mode_lib->vba.ProgressiveToInterlaceUnitInOPP, ++ mode_lib->vba.SwathHeightC[k], ++ mode_lib->vba.ViewportYStartC[k], ++ &mode_lib->vba.VInitPreFillC[k], ++ &mode_lib->vba.MaxNumSwathC[k]); ++ } else { ++ PixelPTEBytesPerRowC = 0; ++ PDEAndMetaPTEBytesFrameC = 0; ++ MetaRowByteC = 0; ++ mode_lib->vba.MaxNumSwathC[k] = 0; ++ mode_lib->vba.PrefetchSourceLinesC[k] = 0; ++ } ++ ++ mode_lib->vba.PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC; ++ mode_lib->vba.PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY + PDEAndMetaPTEBytesFrameC; ++ mode_lib->vba.MetaRowByte[k] = MetaRowByteY + MetaRowByteC; ++ ++ CalculateActiveRowBandwidth(mode_lib->vba.VirtualMemoryEnable, ++ mode_lib->vba.SourcePixelFormat[k], ++ mode_lib->vba.VRatio[k], ++ mode_lib->vba.DCCEnable[k], ++ mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], ++ MetaRowByteY, ++ MetaRowByteC, ++ mode_lib->vba.meta_row_height[k], ++ mode_lib->vba.meta_row_height_chroma[k], ++ PixelPTEBytesPerRowY, ++ PixelPTEBytesPerRowC, ++ mode_lib->vba.dpte_row_height[k], ++ mode_lib->vba.dpte_row_height_chroma[k], ++ &mode_lib->vba.meta_row_bw[k], ++ &mode_lib->vba.dpte_row_bw[k], ++ &mode_lib->vba.qual_row_bw[k]); ++ } ++ ++ mode_lib->vba.TCalc = 24.0 / mode_lib->vba.DCFClkDeepSleep; ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.BlendingAndTiming[k] == k) { ++ if (mode_lib->vba.WritebackEnable[k] == true) { ++ mode_lib->vba.WritebackDelay[k] = mode_lib->vba.WritebackLatency ++ + CalculateWriteBackDelay(mode_lib->vba.WritebackPixelFormat[k], ++ mode_lib->vba.WritebackHRatio[k], ++ mode_lib->vba.WritebackVRatio[k], ++ mode_lib->vba.WritebackLumaHTaps[k], ++ mode_lib->vba.WritebackLumaVTaps[k], ++ mode_lib->vba.WritebackChromaHTaps[k], ++ mode_lib->vba.WritebackChromaVTaps[k], ++ mode_lib->vba.WritebackDestinationWidth[k]) ++ / mode_lib->vba.DISPCLK; ++ } else ++ mode_lib->vba.WritebackDelay[k] = 0; ++ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) { ++ if (mode_lib->vba.BlendingAndTiming[j] == k && mode_lib->vba.WritebackEnable[j] == true) { ++ mode_lib->vba.WritebackDelay[k] = ++ dml_max(mode_lib->vba.WritebackDelay[k], ++ mode_lib->vba.WritebackLatency ++ + CalculateWriteBackDelay(mode_lib->vba.WritebackPixelFormat[j], ++ mode_lib->vba.WritebackHRatio[j], ++ mode_lib->vba.WritebackVRatio[j], ++ mode_lib->vba.WritebackLumaHTaps[j], ++ mode_lib->vba.WritebackLumaVTaps[j], ++ mode_lib->vba.WritebackChromaHTaps[j], ++ mode_lib->vba.WritebackChromaVTaps[j], ++ mode_lib->vba.WritebackDestinationWidth[j]) ++ / mode_lib->vba.DISPCLK); ++ } ++ } ++ } ++ } ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) ++ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) ++ if (mode_lib->vba.BlendingAndTiming[k] == j) ++ mode_lib->vba.WritebackDelay[k] = mode_lib->vba.WritebackDelay[j]; ++ ++ mode_lib->vba.VStartupLines = 13; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ mode_lib->vba.MaxVStartupLines[k] = ++ mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k] ++ - dml_max(1.0, ++ dml_ceil(mode_lib->vba.WritebackDelay[k] ++ / (mode_lib->vba.HTotal[k] ++ / mode_lib->vba.PixelClock[k]), ++ 1)); ++ } ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) ++ mode_lib->vba.MaximumMaxVStartupLines = dml_max(mode_lib->vba.MaximumMaxVStartupLines, mode_lib->vba.MaxVStartupLines[k]); ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ mode_lib->vba.cursor_bw[k] = 0.0; ++ for (j = 0; j < mode_lib->vba.NumberOfCursors[k]; ++j) ++ mode_lib->vba.cursor_bw[k] += mode_lib->vba.CursorWidth[k][j] * mode_lib->vba.CursorBPP[k][j] / 8.0 ++ / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k]; ++ } ++ ++ do { ++ double MaxTotalRDBandwidth = 0; ++ bool DestinationLineTimesForPrefetchLessThan2 = false; ++ bool VRatioPrefetchMoreThan4 = false; ++ bool prefetch_vm_bw_valid = true; ++ bool prefetch_row_bw_valid = true; ++ double TWait = CalculateTWait(mode_lib->vba.PrefetchMode, ++ mode_lib->vba.DRAMClockChangeLatency, ++ mode_lib->vba.UrgentLatency, ++ mode_lib->vba.SREnterPlusExitTime); ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.XFCEnabled[k] == true) { ++ mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(mode_lib, ++ mode_lib->vba.VRatio[k], ++ mode_lib->vba.SwathWidthY[k], ++ dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), ++ mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], ++ mode_lib->vba.XFCTSlvVupdateOffset, ++ mode_lib->vba.XFCTSlvVupdateWidth, ++ mode_lib->vba.XFCTSlvVreadyOffset, ++ mode_lib->vba.XFCXBUFLatencyTolerance, ++ mode_lib->vba.XFCFillBWOverhead, ++ mode_lib->vba.XFCSlvChunkSize, ++ mode_lib->vba.XFCBusTransportTime, ++ mode_lib->vba.TCalc, ++ TWait, ++ &mode_lib->vba.SrcActiveDrainRate, ++ &mode_lib->vba.TInitXFill, ++ &mode_lib->vba.TslvChk); ++ } else { ++ mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0; ++ } ++ mode_lib->vba.ErrorResult[k] = CalculatePrefetchSchedule(mode_lib, ++ mode_lib->vba.DPPCLK[k], ++ mode_lib->vba.DISPCLK, ++ mode_lib->vba.PixelClock[k], ++ mode_lib->vba.DCFClkDeepSleep, ++ mode_lib->vba.DSCDelay[k], ++ mode_lib->vba.DPPPerPlane[k], ++ mode_lib->vba.ScalerEnabled[k], ++ mode_lib->vba.NumberOfCursors[k], ++ mode_lib->vba.DPPCLKDelaySubtotal, ++ mode_lib->vba.DPPCLKDelaySCL, ++ mode_lib->vba.DPPCLKDelaySCLLBOnly, ++ mode_lib->vba.DPPCLKDelayCNVCFormater, ++ mode_lib->vba.DPPCLKDelayCNVCCursor, ++ mode_lib->vba.DISPCLKDelaySubtotal, ++ (unsigned int)(mode_lib->vba.SwathWidthY[k] / mode_lib->vba.HRatio[k]), ++ mode_lib->vba.OutputFormat[k], ++ mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k], ++ mode_lib->vba.HTotal[k], ++ mode_lib->vba.MaxInterDCNTileRepeaters, ++ dml_min(mode_lib->vba.VStartupLines, mode_lib->vba.MaxVStartupLines[k]), ++ mode_lib->vba.MaxPageTableLevels, ++ mode_lib->vba.VirtualMemoryEnable, ++ mode_lib->vba.DynamicMetadataEnable[k], ++ mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k], ++ mode_lib->vba.DynamicMetadataTransmittedBytes[k], ++ mode_lib->vba.DCCEnable[k], ++ mode_lib->vba.UrgentLatency, ++ mode_lib->vba.UrgentExtraLatency, ++ mode_lib->vba.TCalc, ++ mode_lib->vba.PDEAndMetaPTEBytesFrame[k], ++ mode_lib->vba.MetaRowByte[k], ++ mode_lib->vba.PixelPTEBytesPerRow[k], ++ mode_lib->vba.PrefetchSourceLinesY[k], ++ mode_lib->vba.SwathWidthY[k], ++ mode_lib->vba.BytePerPixelDETY[k], ++ mode_lib->vba.VInitPreFillY[k], ++ mode_lib->vba.MaxNumSwathY[k], ++ mode_lib->vba.PrefetchSourceLinesC[k], ++ mode_lib->vba.BytePerPixelDETC[k], ++ mode_lib->vba.VInitPreFillC[k], ++ mode_lib->vba.MaxNumSwathC[k], ++ mode_lib->vba.SwathHeightY[k], ++ mode_lib->vba.SwathHeightC[k], ++ TWait, ++ mode_lib->vba.XFCEnabled[k], ++ mode_lib->vba.XFCRemoteSurfaceFlipDelay, ++ mode_lib->vba.Interlace[k], ++ mode_lib->vba.ProgressiveToInterlaceUnitInOPP, ++ &mode_lib->vba.DSTXAfterScaler[k], ++ &mode_lib->vba.DSTYAfterScaler[k], ++ &mode_lib->vba.DestinationLinesForPrefetch[k], ++ &mode_lib->vba.PrefetchBandwidth[k], ++ &mode_lib->vba.DestinationLinesToRequestVMInVBlank[k], ++ &mode_lib->vba.DestinationLinesToRequestRowInVBlank[k], ++ &mode_lib->vba.VRatioPrefetchY[k], ++ &mode_lib->vba.VRatioPrefetchC[k], ++ &mode_lib->vba.RequiredPrefetchPixDataBW[k], ++ &mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, ++ &mode_lib->vba.Tno_bw[k]); ++ if (mode_lib->vba.BlendingAndTiming[k] == k) { ++ mode_lib->vba.VStartup[k] = dml_min(mode_lib->vba.VStartupLines, mode_lib->vba.MaxVStartupLines[k]); ++ if (mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata != 0) { ++ mode_lib->vba.VStartup[k] = ++ mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata; ++ } ++ } else { ++ mode_lib->vba.VStartup[k] = dml_min(mode_lib->vba.VStartupLines, ++ mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]]); ++ } ++ } ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ ++ if (mode_lib->vba.PDEAndMetaPTEBytesFrame[k] == 0) ++ mode_lib->vba.prefetch_vm_bw[k] = 0; ++ else if (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] > 0) { ++ mode_lib->vba.prefetch_vm_bw[k] = (double)mode_lib->vba.PDEAndMetaPTEBytesFrame[k] ++ / (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] ++ * mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); ++ } else { ++ mode_lib->vba.prefetch_vm_bw[k] = 0; ++ prefetch_vm_bw_valid = false; ++ } ++ if (mode_lib->vba.MetaRowByte[k] + mode_lib->vba.PixelPTEBytesPerRow[k] == 0) ++ mode_lib->vba.prefetch_row_bw[k] = 0; ++ else if (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] > 0) { ++ mode_lib->vba.prefetch_row_bw[k] = (double)(mode_lib->vba.MetaRowByte[k] ++ + mode_lib->vba.PixelPTEBytesPerRow[k]) ++ / (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] ++ * mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); ++ } else { ++ mode_lib->vba.prefetch_row_bw[k] = 0; ++ prefetch_row_bw_valid = false; ++ } ++ ++ MaxTotalRDBandwidth = ++ MaxTotalRDBandwidth + mode_lib->vba.cursor_bw[k] ++ + dml_max(mode_lib->vba.prefetch_vm_bw[k], ++ dml_max(mode_lib->vba.prefetch_row_bw[k], ++ dml_max(mode_lib->vba.ReadBandwidthPlaneLuma[k] ++ + mode_lib->vba.ReadBandwidthPlaneChroma[k], ++ mode_lib->vba.RequiredPrefetchPixDataBW[k]) ++ + mode_lib->vba.meta_row_bw[k] ++ + mode_lib->vba.dpte_row_bw[k])); ++ ++ if (mode_lib->vba.DestinationLinesForPrefetch[k] < 2) ++ DestinationLineTimesForPrefetchLessThan2 = true; ++ if (mode_lib->vba.VRatioPrefetchY[k] > 4 || mode_lib->vba.VRatioPrefetchC[k] > 4) ++ VRatioPrefetchMoreThan4 = true; ++ } ++ ++ if (MaxTotalRDBandwidth <= mode_lib->vba.ReturnBW && prefetch_vm_bw_valid && prefetch_row_bw_valid ++ && !VRatioPrefetchMoreThan4 ++ && !DestinationLineTimesForPrefetchLessThan2) ++ mode_lib->vba.PrefetchModeSupported = true; ++ else { ++ mode_lib->vba.PrefetchModeSupported = false; ++ dml_print("DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n"); ++ } ++ ++ if (mode_lib->vba.PrefetchModeSupported == true) { ++ double final_flip_bw[DC__NUM_PIPES__MAX]; ++ unsigned int ImmediateFlipBytes[DC__NUM_PIPES__MAX]; ++ double total_dcn_read_bw_with_flip = 0; ++ ++ mode_lib->vba.BandwidthAvailableForImmediateFlip = mode_lib->vba.ReturnBW; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ mode_lib->vba.BandwidthAvailableForImmediateFlip = ++ mode_lib->vba.BandwidthAvailableForImmediateFlip - mode_lib->vba.cursor_bw[k] ++ - dml_max(mode_lib->vba.ReadBandwidthPlaneLuma[k] ++ + mode_lib->vba.ReadBandwidthPlaneChroma[k] ++ + mode_lib->vba.qual_row_bw[k], ++ mode_lib->vba.PrefetchBandwidth[k]); ++ } ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ ImmediateFlipBytes[k] = 0; ++ if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8 ++ && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { ++ ImmediateFlipBytes[k] = mode_lib->vba.PDEAndMetaPTEBytesFrame[k] ++ + mode_lib->vba.MetaRowByte[k] ++ + mode_lib->vba.PixelPTEBytesPerRow[k]; ++ } ++ } ++ mode_lib->vba.TotImmediateFlipBytes = 0; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8 ++ && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { ++ mode_lib->vba.TotImmediateFlipBytes = mode_lib->vba.TotImmediateFlipBytes ++ + ImmediateFlipBytes[k]; ++ } ++ } ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ CalculateFlipSchedule(mode_lib, ++ mode_lib->vba.UrgentExtraLatency, ++ mode_lib->vba.UrgentLatency, ++ mode_lib->vba.MaxPageTableLevels, ++ mode_lib->vba.VirtualMemoryEnable, ++ mode_lib->vba.BandwidthAvailableForImmediateFlip, ++ mode_lib->vba.TotImmediateFlipBytes, ++ mode_lib->vba.SourcePixelFormat[k], ++ ImmediateFlipBytes[k], ++ mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], ++ mode_lib->vba.VRatio[k], ++ mode_lib->vba.Tno_bw[k], ++ mode_lib->vba.PDEAndMetaPTEBytesFrame[k], ++ mode_lib->vba.MetaRowByte[k], ++ mode_lib->vba.PixelPTEBytesPerRow[k], ++ mode_lib->vba.DCCEnable[k], ++ mode_lib->vba.dpte_row_height[k], ++ mode_lib->vba.meta_row_height[k], ++ mode_lib->vba.qual_row_bw[k], ++ &mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k], ++ &mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k], ++ &final_flip_bw[k], ++ &mode_lib->vba.ImmediateFlipSupportedForPipe[k]); ++ } ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ total_dcn_read_bw_with_flip = ++ total_dcn_read_bw_with_flip + mode_lib->vba.cursor_bw[k] ++ + dml_max(mode_lib->vba.prefetch_vm_bw[k], ++ dml_max(mode_lib->vba.prefetch_row_bw[k], ++ final_flip_bw[k] ++ + dml_max(mode_lib->vba.ReadBandwidthPlaneLuma[k] ++ + mode_lib->vba.ReadBandwidthPlaneChroma[k], ++ mode_lib->vba.RequiredPrefetchPixDataBW[k]))); ++ } ++ mode_lib->vba.ImmediateFlipSupported = true; ++ if (total_dcn_read_bw_with_flip > mode_lib->vba.ReturnBW) { ++ mode_lib->vba.ImmediateFlipSupported = false; ++ } ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) { ++ mode_lib->vba.ImmediateFlipSupported = false; ++ } ++ } ++ } else { ++ mode_lib->vba.ImmediateFlipSupported = false; ++ } ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.ErrorResult[k]) { ++ mode_lib->vba.PrefetchModeSupported = false; ++ dml_print("DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n"); ++ } ++ } ++ ++ mode_lib->vba.VStartupLines = mode_lib->vba.VStartupLines + 1; ++ } while (!((mode_lib->vba.PrefetchModeSupported ++ && (!mode_lib->vba.ImmediateFlipSupport || mode_lib->vba.ImmediateFlipSupported)) ++ || mode_lib->vba.MaximumMaxVStartupLines < mode_lib->vba.VStartupLines)); ++ ++ //Display Pipeline Delivery Time in Prefetch ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.VRatioPrefetchY[k] <= 1) { ++ mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] = mode_lib->vba.SwathWidthY[k] ++ * mode_lib->vba.DPPPerPlane[k] / mode_lib->vba.HRatio[k] / mode_lib->vba.PixelClock[k]; ++ } else { ++ mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] = mode_lib->vba.SwathWidthY[k] ++ / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] / mode_lib->vba.DPPCLK[k]; ++ } ++ if (mode_lib->vba.BytePerPixelDETC[k] == 0) { ++ mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0; ++ } else { ++ if (mode_lib->vba.VRatioPrefetchC[k] <= 1) { ++ mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = ++ mode_lib->vba.SwathWidthY[k] * mode_lib->vba.DPPPerPlane[k] / mode_lib->vba.HRatio[k] ++ / mode_lib->vba.PixelClock[k]; ++ } else { ++ mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = ++ mode_lib->vba.SwathWidthY[k] / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] ++ / mode_lib->vba.DPPCLK[k]; ++ } ++ } ++ } ++ ++ // Min TTUVBlank ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.PrefetchMode == 0) { ++ mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = true; ++ mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true; ++ mode_lib->vba.MinTTUVBlank[k] = dml_max(mode_lib->vba.DRAMClockChangeWatermark, ++ dml_max(mode_lib->vba.StutterEnterPlusExitWatermark, mode_lib->vba.UrgentWatermark)); ++ } else if (mode_lib->vba.PrefetchMode == 1) { ++ mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false; ++ mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true; ++ mode_lib->vba.MinTTUVBlank[k] = dml_max(mode_lib->vba.StutterEnterPlusExitWatermark, mode_lib->vba.UrgentWatermark); ++ } else { ++ mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false; ++ mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = false; ++ mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.UrgentWatermark; ++ } ++ if (!mode_lib->vba.DynamicMetadataEnable[k]) ++ mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.TCalc + mode_lib->vba.MinTTUVBlank[k]; ++ } ++ ++ // DCC Configuration ++ mode_lib->vba.ActiveDPPs = 0; ++ // NB P-State/DRAM Clock Change Support ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ mode_lib->vba.ActiveDPPs = mode_lib->vba.ActiveDPPs + mode_lib->vba.DPPPerPlane[k]; ++ } ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ double EffectiveLBLatencyHidingY; ++ double EffectiveLBLatencyHidingC; ++ double DPPOutputBufferLinesY; ++ double DPPOutputBufferLinesC; ++ double DPPOPPBufferingY; ++ double MaxDETBufferingTimeY; ++ double ActiveDRAMClockChangeLatencyMarginY; ++ ++ mode_lib->vba.LBLatencyHidingSourceLinesY = ++ dml_min(mode_lib->vba.MaxLineBufferLines, ++ (unsigned int)dml_floor((double)mode_lib->vba.LineBufferSize ++ / mode_lib->vba.LBBitPerPixel[k] ++ / (mode_lib->vba.SwathWidthY[k] ++ / dml_max(mode_lib->vba.HRatio[k], ++ 1.0)), ++ 1)) - (mode_lib->vba.vtaps[k] - 1); ++ ++ mode_lib->vba.LBLatencyHidingSourceLinesC = ++ dml_min(mode_lib->vba.MaxLineBufferLines, ++ (unsigned int)dml_floor((double)mode_lib->vba.LineBufferSize ++ / mode_lib->vba.LBBitPerPixel[k] ++ / (mode_lib->vba.SwathWidthY[k] ++ / 2.0 ++ / dml_max(mode_lib->vba.HRatio[k] ++ / 2, ++ 1.0)), ++ 1)) - (mode_lib->vba.VTAPsChroma[k] - 1); ++ ++ EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY / mode_lib->vba.VRatio[k] ++ * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); ++ ++ EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC / (mode_lib->vba.VRatio[k] / 2) ++ * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); ++ ++ if (mode_lib->vba.SwathWidthY[k] > 2 * mode_lib->vba.DPPOutputBufferPixels) { ++ DPPOutputBufferLinesY = mode_lib->vba.DPPOutputBufferPixels / mode_lib->vba.SwathWidthY[k]; ++ } else if (mode_lib->vba.SwathWidthY[k] > mode_lib->vba.DPPOutputBufferPixels) { ++ DPPOutputBufferLinesY = 0.5; ++ } else { ++ DPPOutputBufferLinesY = 1; ++ } ++ ++ if (mode_lib->vba.SwathWidthY[k] / 2 > 2 * mode_lib->vba.DPPOutputBufferPixels) { ++ DPPOutputBufferLinesC = mode_lib->vba.DPPOutputBufferPixels / (mode_lib->vba.SwathWidthY[k] / 2); ++ } else if (mode_lib->vba.SwathWidthY[k] / 2 > mode_lib->vba.DPPOutputBufferPixels) { ++ DPPOutputBufferLinesC = 0.5; ++ } else { ++ DPPOutputBufferLinesC = 1; ++ } ++ ++ DPPOPPBufferingY = (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) ++ * (DPPOutputBufferLinesY + mode_lib->vba.OPPOutputBufferLines); ++ MaxDETBufferingTimeY = mode_lib->vba.FullDETBufferingTimeY[k] ++ + (mode_lib->vba.LinesInDETY[k] - mode_lib->vba.LinesInDETYRoundedDownToSwath[k]) ++ / mode_lib->vba.SwathHeightY[k] * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); ++ ++ ActiveDRAMClockChangeLatencyMarginY = DPPOPPBufferingY + EffectiveLBLatencyHidingY ++ + MaxDETBufferingTimeY - mode_lib->vba.DRAMClockChangeWatermark; ++ ++ if (mode_lib->vba.ActiveDPPs > 1) { ++ ActiveDRAMClockChangeLatencyMarginY = ActiveDRAMClockChangeLatencyMarginY ++ - (1 - 1 / (mode_lib->vba.ActiveDPPs - 1)) * mode_lib->vba.SwathHeightY[k] ++ * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); ++ } ++ ++ if (mode_lib->vba.BytePerPixelDETC[k] > 0) { ++ double DPPOPPBufferingC = (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) ++ * (DPPOutputBufferLinesC + mode_lib->vba.OPPOutputBufferLines); ++ double MaxDETBufferingTimeC = ++ mode_lib->vba.FullDETBufferingTimeC[k] ++ + (mode_lib->vba.LinesInDETC[k] ++ - mode_lib->vba.LinesInDETCRoundedDownToSwath[k]) ++ / mode_lib->vba.SwathHeightC[k] ++ * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); ++ double ActiveDRAMClockChangeLatencyMarginC = DPPOPPBufferingC ++ + EffectiveLBLatencyHidingC + MaxDETBufferingTimeC ++ - mode_lib->vba.DRAMClockChangeWatermark; ++ ++ if (mode_lib->vba.ActiveDPPs > 1) { ++ ActiveDRAMClockChangeLatencyMarginC = ++ ActiveDRAMClockChangeLatencyMarginC ++ - (1 - 1 / (mode_lib->vba.ActiveDPPs - 1)) ++ * mode_lib->vba.SwathHeightC[k] ++ * (mode_lib->vba.HTotal[k] ++ / mode_lib->vba.PixelClock[k]); ++ } ++ mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(ActiveDRAMClockChangeLatencyMarginY, ++ ActiveDRAMClockChangeLatencyMarginC); ++ } else { ++ mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = ++ ActiveDRAMClockChangeLatencyMarginY; ++ } ++ ++ if (mode_lib->vba.WritebackEnable[k]) { ++ double WritebackDRAMClockChangeLatencyMargin; ++ ++ if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) { ++ WritebackDRAMClockChangeLatencyMargin = ++ (double)(mode_lib->vba.WritebackInterfaceLumaBufferSize ++ + mode_lib->vba.WritebackInterfaceChromaBufferSize) ++ / (mode_lib->vba.WritebackDestinationWidth[k] ++ * mode_lib->vba.WritebackDestinationHeight[k] ++ / (mode_lib->vba.WritebackSourceHeight[k] ++ * mode_lib->vba.HTotal[k] ++ / mode_lib->vba.PixelClock[k]) ++ * 4) ++ - mode_lib->vba.WritebackDRAMClockChangeWatermark; ++ } else if (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) { ++ WritebackDRAMClockChangeLatencyMargin = dml_min((double)mode_lib->vba.WritebackInterfaceLumaBufferSize * 8.0 ++ / 10, ++ 2.0 * mode_lib->vba.WritebackInterfaceChromaBufferSize * 8 / 10) ++ / (mode_lib->vba.WritebackDestinationWidth[k] ++ * mode_lib->vba.WritebackDestinationHeight[k] ++ / (mode_lib->vba.WritebackSourceHeight[k] ++ * mode_lib->vba.HTotal[k] ++ / mode_lib->vba.PixelClock[k])) ++ - mode_lib->vba.WritebackDRAMClockChangeWatermark; ++ } else { ++ WritebackDRAMClockChangeLatencyMargin = dml_min((double)mode_lib->vba.WritebackInterfaceLumaBufferSize, ++ 2.0 * mode_lib->vba.WritebackInterfaceChromaBufferSize) ++ / (mode_lib->vba.WritebackDestinationWidth[k] ++ * mode_lib->vba.WritebackDestinationHeight[k] ++ / (mode_lib->vba.WritebackSourceHeight[k] ++ * mode_lib->vba.HTotal[k] ++ / mode_lib->vba.PixelClock[k])) ++ - mode_lib->vba.WritebackDRAMClockChangeWatermark; ++ } ++ mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k], ++ WritebackDRAMClockChangeLatencyMargin); ++ } ++ } ++ ++ mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] ++ < mode_lib->vba.MinActiveDRAMClockChangeMargin) { ++ mode_lib->vba.MinActiveDRAMClockChangeMargin = ++ mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]; ++ } ++ } ++ ++ mode_lib->vba.MinActiveDRAMClockChangeLatencySupported = mode_lib->vba.MinActiveDRAMClockChangeMargin ++ + mode_lib->vba.DRAMClockChangeLatency; ++ ++ if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) { ++ mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vactive; ++ } else { ++ if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) { ++ mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vblank; ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (!mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k]) { ++ mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_unsupported; ++ } ++ } ++ } else { ++ mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_unsupported; ++ } ++ } ++ ++ //XFC Parameters: ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ if (mode_lib->vba.XFCEnabled[k] == true) { ++ double TWait; ++ ++ mode_lib->vba.XFCSlaveVUpdateOffset[k] = mode_lib->vba.XFCTSlvVupdateOffset; ++ mode_lib->vba.XFCSlaveVupdateWidth[k] = mode_lib->vba.XFCTSlvVupdateWidth; ++ mode_lib->vba.XFCSlaveVReadyOffset[k] = mode_lib->vba.XFCTSlvVreadyOffset; ++ TWait = CalculateTWait(mode_lib->vba.PrefetchMode, ++ mode_lib->vba.DRAMClockChangeLatency, ++ mode_lib->vba.UrgentLatency, ++ mode_lib->vba.SREnterPlusExitTime); ++ mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(mode_lib, ++ mode_lib->vba.VRatio[k], ++ mode_lib->vba.SwathWidthY[k], ++ dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), ++ mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], ++ mode_lib->vba.XFCTSlvVupdateOffset, ++ mode_lib->vba.XFCTSlvVupdateWidth, ++ mode_lib->vba.XFCTSlvVreadyOffset, ++ mode_lib->vba.XFCXBUFLatencyTolerance, ++ mode_lib->vba.XFCFillBWOverhead, ++ mode_lib->vba.XFCSlvChunkSize, ++ mode_lib->vba.XFCBusTransportTime, ++ mode_lib->vba.TCalc, ++ TWait, ++ &mode_lib->vba.SrcActiveDrainRate, ++ &mode_lib->vba.TInitXFill, ++ &mode_lib->vba.TslvChk); ++ mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = dml_floor(mode_lib->vba.XFCRemoteSurfaceFlipDelay / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), ++ 1); ++ mode_lib->vba.XFCTransferDelay[k] = dml_ceil(mode_lib->vba.XFCBusTransportTime / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), ++ 1); ++ mode_lib->vba.XFCPrechargeDelay[k] = dml_ceil((mode_lib->vba.XFCBusTransportTime + mode_lib->vba.TInitXFill + mode_lib->vba.TslvChk) ++ / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), ++ 1); ++ mode_lib->vba.InitFillLevel = mode_lib->vba.XFCXBUFLatencyTolerance * mode_lib->vba.SrcActiveDrainRate; ++ mode_lib->vba.FinalFillMargin = (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] ++ + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]) * mode_lib->vba.HTotal[k] ++ / mode_lib->vba.PixelClock[k] * mode_lib->vba.SrcActiveDrainRate + mode_lib->vba.XFCFillConstant; ++ mode_lib->vba.FinalFillLevel = mode_lib->vba.XFCRemoteSurfaceFlipDelay * mode_lib->vba.SrcActiveDrainRate ++ + mode_lib->vba.FinalFillMargin; ++ mode_lib->vba.RemainingFillLevel = dml_max(0.0, ++ mode_lib->vba.FinalFillLevel - mode_lib->vba.InitFillLevel); ++ mode_lib->vba.TFinalxFill = mode_lib->vba.RemainingFillLevel ++ / (mode_lib->vba.SrcActiveDrainRate * mode_lib->vba.XFCFillBWOverhead / 100); ++ mode_lib->vba.XFCPrefetchMargin[k] = mode_lib->vba.XFCRemoteSurfaceFlipDelay + mode_lib->vba.TFinalxFill ++ + (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] ++ + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]) ++ * mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]; ++ } else { ++ mode_lib->vba.XFCSlaveVUpdateOffset[k] = 0; ++ mode_lib->vba.XFCSlaveVupdateWidth[k] = 0; ++ mode_lib->vba.XFCSlaveVReadyOffset[k] = 0; ++ mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = 0; ++ mode_lib->vba.XFCPrechargeDelay[k] = 0; ++ mode_lib->vba.XFCTransferDelay[k] = 0; ++ mode_lib->vba.XFCPrefetchMargin[k] = 0; ++ } ++ } ++} ++ ++static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib) ++{ ++ double BytePerPixDETY; ++ double BytePerPixDETC; ++ double Read256BytesBlockHeightY; ++ double Read256BytesBlockHeightC; ++ double Read256BytesBlockWidthY; ++ double Read256BytesBlockWidthC; ++ double MaximumSwathHeightY; ++ double MaximumSwathHeightC; ++ double MinimumSwathHeightY; ++ double MinimumSwathHeightC; ++ double SwathWidth; ++ double SwathWidthGranularityY; ++ double SwathWidthGranularityC; ++ double RoundedUpMaxSwathSizeBytesY; ++ double RoundedUpMaxSwathSizeBytesC; ++ unsigned int j, k; ++ ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ bool MainPlaneDoesODMCombine = false; ++ ++ if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) { ++ BytePerPixDETY = 8; ++ BytePerPixDETC = 0; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) { ++ BytePerPixDETY = 4; ++ BytePerPixDETC = 0; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) { ++ BytePerPixDETY = 2; ++ BytePerPixDETC = 0; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) { ++ BytePerPixDETY = 1; ++ BytePerPixDETC = 0; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) { ++ BytePerPixDETY = 1; ++ BytePerPixDETC = 2; ++ } else { ++ BytePerPixDETY = 4.0 / 3.0; ++ BytePerPixDETC = 8.0 / 3.0; ++ } ++ ++ if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32 ++ || mode_lib->vba.SourcePixelFormat[k] == dm_444_16 ++ || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) { ++ if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) { ++ Read256BytesBlockHeightY = 1; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) { ++ Read256BytesBlockHeightY = 4; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32 ++ || mode_lib->vba.SourcePixelFormat[k] == dm_444_16) { ++ Read256BytesBlockHeightY = 8; ++ } else { ++ Read256BytesBlockHeightY = 16; ++ } ++ Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1) ++ / Read256BytesBlockHeightY; ++ Read256BytesBlockHeightC = 0; ++ Read256BytesBlockWidthC = 0; ++ } else { ++ if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) { ++ Read256BytesBlockHeightY = 1; ++ Read256BytesBlockHeightC = 1; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) { ++ Read256BytesBlockHeightY = 16; ++ Read256BytesBlockHeightC = 8; ++ } else { ++ Read256BytesBlockHeightY = 8; ++ Read256BytesBlockHeightC = 8; ++ } ++ Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1) ++ / Read256BytesBlockHeightY; ++ Read256BytesBlockWidthC = 256 / dml_ceil(BytePerPixDETC, 2) ++ / Read256BytesBlockHeightC; ++ } ++ ++ if (mode_lib->vba.SourceScan[k] == dm_horz) { ++ MaximumSwathHeightY = Read256BytesBlockHeightY; ++ MaximumSwathHeightC = Read256BytesBlockHeightC; ++ } else { ++ MaximumSwathHeightY = Read256BytesBlockWidthY; ++ MaximumSwathHeightC = Read256BytesBlockWidthC; ++ } ++ ++ if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32 ++ || mode_lib->vba.SourcePixelFormat[k] == dm_444_16 ++ || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) { ++ if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear ++ || (mode_lib->vba.SourcePixelFormat[k] == dm_444_64 ++ && (mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_s ++ || mode_lib->vba.SurfaceTiling[k] ++ == dm_sw_4kb_s_x ++ || mode_lib->vba.SurfaceTiling[k] ++ == dm_sw_64kb_s ++ || mode_lib->vba.SurfaceTiling[k] ++ == dm_sw_64kb_s_t ++ || mode_lib->vba.SurfaceTiling[k] ++ == dm_sw_64kb_s_x ++ || mode_lib->vba.SurfaceTiling[k] ++ == dm_sw_var_s ++ || mode_lib->vba.SurfaceTiling[k] ++ == dm_sw_var_s_x) ++ && mode_lib->vba.SourceScan[k] == dm_horz)) { ++ MinimumSwathHeightY = MaximumSwathHeightY; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8 && mode_lib->vba.SourceScan[k] != dm_horz) { ++ MinimumSwathHeightY = MaximumSwathHeightY; ++ } else { ++ MinimumSwathHeightY = MaximumSwathHeightY / 2.0; ++ } ++ MinimumSwathHeightC = MaximumSwathHeightC; ++ } else { ++ if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) { ++ MinimumSwathHeightY = MaximumSwathHeightY; ++ MinimumSwathHeightC = MaximumSwathHeightC; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8 && mode_lib->vba.SourceScan[k] == dm_horz) { ++ MinimumSwathHeightY = MaximumSwathHeightY / 2.0; ++ MinimumSwathHeightC = MaximumSwathHeightC; ++ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10 && mode_lib->vba.SourceScan[k] == dm_horz) { ++ MinimumSwathHeightC = MaximumSwathHeightC / 2.0; ++ MinimumSwathHeightY = MaximumSwathHeightY; ++ } else { ++ MinimumSwathHeightY = MaximumSwathHeightY; ++ MinimumSwathHeightC = MaximumSwathHeightC; ++ } ++ } ++ ++ if (mode_lib->vba.SourceScan[k] == dm_horz) { ++ SwathWidth = mode_lib->vba.ViewportWidth[k]; ++ } else { ++ SwathWidth = mode_lib->vba.ViewportHeight[k]; ++ } ++ ++ if (mode_lib->vba.ODMCombineEnabled[k] == true) { ++ MainPlaneDoesODMCombine = true; ++ } ++ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) { ++ if (mode_lib->vba.BlendingAndTiming[k] == j && mode_lib->vba.ODMCombineEnabled[j] == true) { ++ MainPlaneDoesODMCombine = true; ++ } ++ } ++ ++ if (MainPlaneDoesODMCombine == true) { ++ SwathWidth = dml_min(SwathWidth, mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]); ++ } else { ++ SwathWidth = SwathWidth / mode_lib->vba.DPPPerPlane[k]; ++ } ++ ++ SwathWidthGranularityY = 256 / dml_ceil(BytePerPixDETY, 1) / MaximumSwathHeightY; ++ RoundedUpMaxSwathSizeBytesY = (dml_ceil((double)(SwathWidth - 1), ++ SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY ++ * MaximumSwathHeightY; ++ if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) { ++ RoundedUpMaxSwathSizeBytesY = dml_ceil(RoundedUpMaxSwathSizeBytesY, 256) ++ + 256; ++ } ++ if (MaximumSwathHeightC > 0) { ++ SwathWidthGranularityC = 256.0 / dml_ceil(BytePerPixDETC, 2) ++ / MaximumSwathHeightC; ++ RoundedUpMaxSwathSizeBytesC = (dml_ceil((double)(SwathWidth / 2.0 - 1), ++ SwathWidthGranularityC) + SwathWidthGranularityC) ++ * BytePerPixDETC * MaximumSwathHeightC; ++ if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) { ++ RoundedUpMaxSwathSizeBytesC = dml_ceil(RoundedUpMaxSwathSizeBytesC, ++ 256) + 256; ++ } ++ } else ++ RoundedUpMaxSwathSizeBytesC = 0.0; ++ ++ if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC ++ <= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) { ++ mode_lib->vba.SwathHeightY[k] = MaximumSwathHeightY; ++ mode_lib->vba.SwathHeightC[k] = MaximumSwathHeightC; ++ } else { ++ mode_lib->vba.SwathHeightY[k] = MinimumSwathHeightY; ++ mode_lib->vba.SwathHeightC[k] = MinimumSwathHeightC; ++ } ++ ++ if (mode_lib->vba.SwathHeightC[k] == 0) { ++ mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024; ++ mode_lib->vba.DETBufferSizeC[k] = 0; ++ } else if (mode_lib->vba.SwathHeightY[k] <= mode_lib->vba.SwathHeightC[k]) { ++ mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2; ++ mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2; ++ } else { ++ mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024.0 * 2 / 3; ++ mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 3; ++ } ++ } ++} ++ ++bool Calculate256BBlockSizes(enum source_format_class SourcePixelFormat, ++ enum dm_swizzle_mode SurfaceTiling, ++ unsigned int BytePerPixelY, ++ unsigned int BytePerPixelC, ++ unsigned int *BlockHeight256BytesY, ++ unsigned int *BlockHeight256BytesC, ++ unsigned int *BlockWidth256BytesY, ++ unsigned int *BlockWidth256BytesC) ++{ ++ if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32 ++ || SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_16 ++ || SourcePixelFormat == dm_444_8)) { ++ if (SurfaceTiling == dm_sw_linear) { ++ *BlockHeight256BytesY = 1; ++ } else if (SourcePixelFormat == dm_444_64) { ++ *BlockHeight256BytesY = 4; ++ } else if (SourcePixelFormat == dm_444_8) { ++ *BlockHeight256BytesY = 16; ++ } else { ++ *BlockHeight256BytesY = 8; ++ } ++ *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY; ++ *BlockHeight256BytesC = 0; ++ *BlockWidth256BytesC = 0; ++ } else { ++ if (SurfaceTiling == dm_sw_linear) { ++ *BlockHeight256BytesY = 1; ++ *BlockHeight256BytesC = 1; ++ } else if (SourcePixelFormat == dm_420_8) { ++ *BlockHeight256BytesY = 16; ++ *BlockHeight256BytesC = 8; ++ } else { ++ *BlockHeight256BytesY = 8; ++ *BlockHeight256BytesC = 8; ++ } ++ *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY; ++ *BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC; ++ } ++ return true; ++} ++ ++static double CalculateTWait(unsigned int PrefetchMode, ++ double DRAMClockChangeLatency, ++ double UrgentLatency, ++ double SREnterPlusExitTime) ++{ ++ if (PrefetchMode == 0) { ++ return dml_max(DRAMClockChangeLatency + UrgentLatency, ++ dml_max(SREnterPlusExitTime, UrgentLatency)); ++ } else if (PrefetchMode == 1) { ++ return dml_max(SREnterPlusExitTime, UrgentLatency); ++ } else { ++ return UrgentLatency; ++ } ++} ++ ++static double CalculateRemoteSurfaceFlipDelay(struct display_mode_lib *mode_lib, ++ double VRatio, ++ double SwathWidth, ++ double Bpp, ++ double LineTime, ++ double XFCTSlvVupdateOffset, ++ double XFCTSlvVupdateWidth, ++ double XFCTSlvVreadyOffset, ++ double XFCXBUFLatencyTolerance, ++ double XFCFillBWOverhead, ++ double XFCSlvChunkSize, ++ double XFCBusTransportTime, ++ double TCalc, ++ double TWait, ++ double *SrcActiveDrainRate, ++ double *TInitXFill, ++ double *TslvChk) ++{ ++ double TSlvSetup, AvgfillRate, result; ++ ++ *SrcActiveDrainRate = VRatio * SwathWidth * Bpp / LineTime; ++ TSlvSetup = XFCTSlvVupdateOffset + XFCTSlvVupdateWidth + XFCTSlvVreadyOffset; ++ *TInitXFill = XFCXBUFLatencyTolerance / (1 + XFCFillBWOverhead / 100); ++ AvgfillRate = *SrcActiveDrainRate * (1 + XFCFillBWOverhead / 100); ++ *TslvChk = XFCSlvChunkSize / AvgfillRate; ++ dml_print("DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n", ++ *SrcActiveDrainRate); ++ dml_print("DML::CalculateRemoteSurfaceFlipDelay: TSlvSetup: %f\n", TSlvSetup); ++ dml_print("DML::CalculateRemoteSurfaceFlipDelay: TInitXFill: %f\n", *TInitXFill); ++ dml_print("DML::CalculateRemoteSurfaceFlipDelay: AvgfillRate: %f\n", AvgfillRate); ++ dml_print("DML::CalculateRemoteSurfaceFlipDelay: TslvChk: %f\n", *TslvChk); ++ result = 2 * XFCBusTransportTime + TSlvSetup + TCalc + TWait + *TslvChk + *TInitXFill; // TODO: This doesn't seem to match programming guide ++ dml_print("DML::CalculateRemoteSurfaceFlipDelay: RemoteSurfaceFlipDelay: %f\n", result); ++ return result; ++} ++ ++static double CalculateWriteBackDISPCLK(enum source_format_class WritebackPixelFormat, ++ double PixelClock, ++ double WritebackHRatio, ++ double WritebackVRatio, ++ unsigned int WritebackLumaHTaps, ++ unsigned int WritebackLumaVTaps, ++ unsigned int WritebackChromaHTaps, ++ unsigned int WritebackChromaVTaps, ++ double WritebackDestinationWidth, ++ unsigned int HTotal, ++ unsigned int WritebackChromaLineBufferWidth) ++{ ++ double CalculateWriteBackDISPCLK = 1.01 * PixelClock ++ * dml_max( ++ dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio, ++ dml_max( ++ (WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) ++ * dml_ceil(WritebackDestinationWidth / 4.0, 1) ++ + dml_ceil(WritebackDestinationWidth / 4.0, 1)) / (double)HTotal ++ + dml_ceil(1.0 / WritebackVRatio, 1) * (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4.0) ++ / (double)HTotal, ++ dml_ceil(1.0 / WritebackVRatio, 1) * WritebackDestinationWidth / (double)HTotal)); ++ if (WritebackPixelFormat != dm_444_32) { ++ CalculateWriteBackDISPCLK = dml_max( ++ CalculateWriteBackDISPCLK, ++ 1.01 * PixelClock ++ * dml_max( ++ dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio), ++ dml_max( ++ (WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) ++ * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1) ++ + dml_ceil(WritebackDestinationWidth / 2.0 / WritebackChromaLineBufferWidth, 1)) ++ / HTotal ++ + dml_ceil(1 / (2 * WritebackVRatio), 1) ++ * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4) / HTotal, ++ dml_ceil(1.0 / (2 * WritebackVRatio), 1) * WritebackDestinationWidth / 2.0 ++ / HTotal))); ++ } ++ return CalculateWriteBackDISPCLK; ++} ++ ++static double CalculateWriteBackDelay( ++enum source_format_class WritebackPixelFormat, ++ double WritebackHRatio, ++ double WritebackVRatio, ++ unsigned int WritebackLumaHTaps, ++ unsigned int WritebackLumaVTaps, ++ unsigned int WritebackChromaHTaps, ++ unsigned int WritebackChromaVTaps, ++ unsigned int WritebackDestinationWidth) ++{ ++ double CalculateWriteBackDelay = dml_max( ++ dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio, ++ WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) ++ * dml_ceil(WritebackDestinationWidth / 4.0, 1) ++ + dml_ceil(1.0 / WritebackVRatio, 1) * (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4)); ++ ++ if (WritebackPixelFormat != dm_444_32) { ++ CalculateWriteBackDelay = dml_max( ++ CalculateWriteBackDelay, ++ dml_max( ++ dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio), ++ WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) ++ * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1) ++ + dml_ceil(1 / (2 * WritebackVRatio), 1) ++ * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4))); ++ } ++ return CalculateWriteBackDelay; ++} ++ ++static void CalculateActiveRowBandwidth(bool VirtualMemoryEnable, ++ enum source_format_class SourcePixelFormat, ++ double VRatio, ++ bool DCCEnable, ++ double LineTime, ++ unsigned int MetaRowByteLuma, ++ unsigned int MetaRowByteChroma, ++ unsigned int meta_row_height_luma, ++ unsigned int meta_row_height_chroma, ++ unsigned int PixelPTEBytesPerRowLuma, ++ unsigned int PixelPTEBytesPerRowChroma, ++ unsigned int dpte_row_height_luma, ++ unsigned int dpte_row_height_chroma, ++ double *meta_row_bw, ++ double *dpte_row_bw, ++ double *qual_row_bw) ++{ ++ if (DCCEnable != true) { ++ *meta_row_bw = 0; ++ } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) { ++ *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime) ++ + VRatio / 2 * MetaRowByteChroma ++ / (meta_row_height_chroma * LineTime); ++ } else { ++ *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime); ++ } ++ ++ if (VirtualMemoryEnable != true) { ++ *dpte_row_bw = 0; ++ } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) { ++ *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime) ++ + VRatio / 2 * PixelPTEBytesPerRowChroma ++ / (dpte_row_height_chroma * LineTime); ++ } else { ++ *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime); ++ } ++ ++ if ((SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)) { ++ *qual_row_bw = *meta_row_bw + *dpte_row_bw; ++ } else { ++ *qual_row_bw = 0; ++ } ++} ++ ++static void CalculateFlipSchedule(struct display_mode_lib *mode_lib, ++ double UrgentExtraLatency, ++ double UrgentLatency, ++ unsigned int MaxPageTableLevels, ++ bool VirtualMemoryEnable, ++ double BandwidthAvailableForImmediateFlip, ++ unsigned int TotImmediateFlipBytes, ++ enum source_format_class SourcePixelFormat, ++ unsigned int ImmediateFlipBytes, ++ double LineTime, ++ double Tno_bw, ++ double VRatio, ++ double PDEAndMetaPTEBytesFrame, ++ unsigned int MetaRowByte, ++ unsigned int PixelPTEBytesPerRow, ++ bool DCCEnable, ++ unsigned int dpte_row_height, ++ unsigned int meta_row_height, ++ double qual_row_bw, ++ double *DestinationLinesToRequestVMInImmediateFlip, ++ double *DestinationLinesToRequestRowInImmediateFlip, ++ double *final_flip_bw, ++ bool *ImmediateFlipSupportedForPipe) ++{ ++ double min_row_time = 0.0; ++ ++ if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) { ++ *DestinationLinesToRequestVMInImmediateFlip = 0.0; ++ *DestinationLinesToRequestRowInImmediateFlip = 0.0; ++ *final_flip_bw = qual_row_bw; ++ *ImmediateFlipSupportedForPipe = true; ++ } else { ++ double TimeForFetchingMetaPTEImmediateFlip; ++ double TimeForFetchingRowInVBlankImmediateFlip; ++ ++ if (VirtualMemoryEnable == true) { ++ mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip * ImmediateFlipBytes ++ / TotImmediateFlipBytes; ++ TimeForFetchingMetaPTEImmediateFlip = ++ dml_max(Tno_bw ++ + PDEAndMetaPTEBytesFrame ++ / mode_lib->vba.ImmediateFlipBW, ++ dml_max(UrgentExtraLatency ++ + UrgentLatency ++ * (MaxPageTableLevels ++ - 1), ++ LineTime / 4.0)); ++ } else { ++ TimeForFetchingMetaPTEImmediateFlip = 0; ++ } ++ ++ *DestinationLinesToRequestVMInImmediateFlip = dml_floor(4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125), ++ 1) / 4.0; ++ ++ if ((VirtualMemoryEnable == true || DCCEnable == true)) { ++ mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip * ImmediateFlipBytes ++ / TotImmediateFlipBytes; ++ TimeForFetchingRowInVBlankImmediateFlip = dml_max((MetaRowByte + PixelPTEBytesPerRow) / mode_lib->vba.ImmediateFlipBW, ++ dml_max(UrgentLatency, LineTime / 4.0)); ++ } else { ++ TimeForFetchingRowInVBlankImmediateFlip = 0; ++ } ++ ++ *DestinationLinesToRequestRowInImmediateFlip = dml_floor(4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime + 0.125), ++ 1) / 4.0; ++ ++ if (VirtualMemoryEnable == true) { ++ *final_flip_bw = ++ dml_max(PDEAndMetaPTEBytesFrame ++ / (*DestinationLinesToRequestVMInImmediateFlip ++ * LineTime), ++ (MetaRowByte + PixelPTEBytesPerRow) ++ / (TimeForFetchingRowInVBlankImmediateFlip ++ * LineTime)); ++ } else if (MetaRowByte + PixelPTEBytesPerRow > 0) { ++ *final_flip_bw = (MetaRowByte + PixelPTEBytesPerRow) ++ / (TimeForFetchingRowInVBlankImmediateFlip * LineTime); ++ } else { ++ *final_flip_bw = 0; ++ } ++ ++ if (VirtualMemoryEnable && !DCCEnable) ++ min_row_time = dpte_row_height * LineTime / VRatio; ++ else if (!VirtualMemoryEnable && DCCEnable) ++ min_row_time = meta_row_height * LineTime / VRatio; ++ else ++ min_row_time = dml_min(dpte_row_height, meta_row_height) * LineTime ++ / VRatio; ++ ++ if (*DestinationLinesToRequestVMInImmediateFlip >= 8 ++ || *DestinationLinesToRequestRowInImmediateFlip >= 16 ++ || TimeForFetchingMetaPTEImmediateFlip ++ + 2 * TimeForFetchingRowInVBlankImmediateFlip > min_row_time) ++ *ImmediateFlipSupportedForPipe = false; ++ else ++ *ImmediateFlipSupportedForPipe = true; ++ } ++} ++ ++static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib) ++{ ++ unsigned int k; ++ ++ //Progressive To dml_ml->vba.Interlace Unit Effect ++ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ++ mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k]; ++ if (mode_lib->vba.Interlace[k] == 1 && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) { ++ mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k]; ++ } ++ } ++} ++ ++static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp) ++{ ++ switch (ebpp) { ++ case dm_cur_2bit: ++ return 2; ++ case dm_cur_32bit: ++ return 32; ++ case dm_cur_64bit: ++ return 64; ++ default: ++ return 0; ++ } ++} +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h +new file mode 100644 +index 0000000..a24fe9a +--- /dev/null ++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h +@@ -0,0 +1,410 @@ ++/* ++ * display_mode_vba.h ++ * ++ * Created on: Aug 18, 2017 ++ * Author: dlaktyus ++ */ ++ ++#ifndef __DML2_DISPLAY_MODE_VBA_H__ ++#define __DML2_DISPLAY_MODE_VBA_H__ ++ ++#include "dml_common_defs.h" ++ ++struct display_mode_lib; ++ ++void set_prefetch_mode(struct display_mode_lib *mode_lib, ++ bool cstate_en, ++ bool pstate_en, ++ bool ignore_viewport_pos, ++ bool immediate_flip_support); ++ ++#define dml_get_attr_decl(attr) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes) ++ ++dml_get_attr_decl(clk_dcf_deepsleep); ++dml_get_attr_decl(wm_urgent); ++dml_get_attr_decl(wm_memory_trip); ++dml_get_attr_decl(wm_writeback_urgent); ++dml_get_attr_decl(wm_stutter_exit); ++dml_get_attr_decl(wm_stutter_enter_exit); ++dml_get_attr_decl(wm_dram_clock_change); ++dml_get_attr_decl(wm_writeback_dram_clock_change); ++dml_get_attr_decl(wm_xfc_underflow); ++dml_get_attr_decl(stutter_efficiency_no_vblank); ++dml_get_attr_decl(stutter_efficiency); ++dml_get_attr_decl(urgent_latency); ++dml_get_attr_decl(urgent_extra_latency); ++dml_get_attr_decl(nonurgent_latency); ++dml_get_attr_decl(dram_clock_change_latency); ++dml_get_attr_decl(dispclk_calculated); ++dml_get_attr_decl(total_data_read_bw); ++dml_get_attr_decl(return_bw); ++dml_get_attr_decl(tcalc); ++ ++#define dml_get_pipe_attr_decl(attr) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes, unsigned int which_pipe) ++ ++dml_get_pipe_attr_decl(dsc_delay); ++dml_get_pipe_attr_decl(dppclk_calculated); ++dml_get_pipe_attr_decl(dscclk_calculated); ++dml_get_pipe_attr_decl(min_ttu_vblank); ++dml_get_pipe_attr_decl(vratio_prefetch_l); ++dml_get_pipe_attr_decl(vratio_prefetch_c); ++dml_get_pipe_attr_decl(dst_x_after_scaler); ++dml_get_pipe_attr_decl(dst_y_after_scaler); ++dml_get_pipe_attr_decl(dst_y_per_vm_vblank); ++dml_get_pipe_attr_decl(dst_y_per_row_vblank); ++dml_get_pipe_attr_decl(dst_y_prefetch); ++dml_get_pipe_attr_decl(dst_y_per_vm_flip); ++dml_get_pipe_attr_decl(dst_y_per_row_flip); ++dml_get_pipe_attr_decl(xfc_transfer_delay); ++dml_get_pipe_attr_decl(xfc_precharge_delay); ++dml_get_pipe_attr_decl(xfc_remote_surface_flip_latency); ++dml_get_pipe_attr_decl(xfc_prefetch_margin); ++ ++unsigned int get_vstartup_calculated( ++ struct display_mode_lib *mode_lib, ++ const display_e2e_pipe_params_st *pipes, ++ unsigned int num_pipes, ++ unsigned int which_pipe); ++ ++double get_total_immediate_flip_bytes( ++ struct display_mode_lib *mode_lib, ++ const display_e2e_pipe_params_st *pipes, ++ unsigned int num_pipes); ++double get_total_immediate_flip_bw( ++ struct display_mode_lib *mode_lib, ++ const display_e2e_pipe_params_st *pipes, ++ unsigned int num_pipes); ++double get_total_prefetch_bw( ++ struct display_mode_lib *mode_lib, ++ const display_e2e_pipe_params_st *pipes, ++ unsigned int num_pipes); ++ ++bool Calculate256BBlockSizes( ++ enum source_format_class SourcePixelFormat, ++ enum dm_swizzle_mode SurfaceTiling, ++ unsigned int BytePerPixelY, ++ unsigned int BytePerPixelC, ++ unsigned int *BlockHeight256BytesY, ++ unsigned int *BlockHeight256BytesC, ++ unsigned int *BlockWidth256BytesY, ++ unsigned int *BlockWidth256BytesC); ++ ++ ++struct vba_vars_st { ++ ip_params_st ip; ++ soc_bounding_box_st soc; ++ mode_evaluation_st me; ++ ++ unsigned int MaximumMaxVStartupLines; ++ double cursor_bw[DC__NUM_PIPES__MAX]; ++ double meta_row_bw[DC__NUM_PIPES__MAX]; ++ double dpte_row_bw[DC__NUM_PIPES__MAX]; ++ double qual_row_bw[DC__NUM_PIPES__MAX]; ++ double WritebackDISPCLK; ++ double PSCL_THROUGHPUT_LUMA[DC__NUM_PIPES__MAX]; ++ double PSCL_THROUGHPUT_CHROMA[DC__NUM_PIPES__MAX]; ++ double DPPCLKUsingSingleDPPLuma; ++ double DPPCLKUsingSingleDPPChroma; ++ double DPPCLKUsingSingleDPP[DC__NUM_PIPES__MAX]; ++ double DISPCLKWithRamping; ++ double DISPCLKWithoutRamping; ++ double GlobalDPPCLK; ++ double MaxDispclk; ++ double DISPCLKWithRampingRoundedToDFSGranularity; ++ double DISPCLKWithoutRampingRoundedToDFSGranularity; ++ double MaxDispclkRoundedToDFSGranularity; ++ bool DCCEnabledAnyPlane; ++ double ReturnBandwidthToDCN; ++ unsigned int SwathWidthY[DC__NUM_PIPES__MAX]; ++ unsigned int SwathWidthSingleDPPY[DC__NUM_PIPES__MAX]; ++ double BytePerPixelDETY[DC__NUM_PIPES__MAX]; ++ double BytePerPixelDETC[DC__NUM_PIPES__MAX]; ++ double ReadBandwidthPlaneLuma[DC__NUM_PIPES__MAX]; ++ double ReadBandwidthPlaneChroma[DC__NUM_PIPES__MAX]; ++ unsigned int TotalActiveDPP; ++ unsigned int TotalDCCActiveDPP; ++ double UrgentRoundTripAndOutOfOrderLatency; ++ double DisplayPipeLineDeliveryTimeLuma[DC__NUM_PIPES__MAX]; // WM ++ double DisplayPipeLineDeliveryTimeChroma[DC__NUM_PIPES__MAX]; // WM ++ double LinesInDETY[DC__NUM_PIPES__MAX]; // WM ++ double LinesInDETC[DC__NUM_PIPES__MAX]; // WM ++ unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_PIPES__MAX]; // WM ++ unsigned int LinesInDETCRoundedDownToSwath[DC__NUM_PIPES__MAX]; // WM ++ double FullDETBufferingTimeY[DC__NUM_PIPES__MAX]; // WM ++ double FullDETBufferingTimeC[DC__NUM_PIPES__MAX]; // WM ++ double MinFullDETBufferingTime; ++ double FrameTimeForMinFullDETBufferingTime; ++ double AverageReadBandwidthGBytePerSecond; ++ double PartOfBurstThatFitsInROB; ++ double StutterBurstTime; ++ //unsigned int NextPrefetchMode; ++ double VBlankTime; ++ double SmallestVBlank; ++ double DCFCLKDeepSleepPerPlane; ++ double EffectiveDETPlusLBLinesLuma; ++ double EffectiveDETPlusLBLinesChroma; ++ double UrgentLatencySupportUsLuma; ++ double UrgentLatencySupportUsChroma; ++ double UrgentLatencySupportUs[DC__NUM_PIPES__MAX]; ++ unsigned int DSCFormatFactor; ++ unsigned int BlockHeight256BytesY[DC__NUM_PIPES__MAX]; ++ unsigned int BlockHeight256BytesC[DC__NUM_PIPES__MAX]; ++ unsigned int BlockWidth256BytesY[DC__NUM_PIPES__MAX]; ++ unsigned int BlockWidth256BytesC[DC__NUM_PIPES__MAX]; ++ double VInitPreFillY[DC__NUM_PIPES__MAX]; ++ double VInitPreFillC[DC__NUM_PIPES__MAX]; ++ unsigned int MaxNumSwathY[DC__NUM_PIPES__MAX]; ++ unsigned int MaxNumSwathC[DC__NUM_PIPES__MAX]; ++ double PrefetchSourceLinesY[DC__NUM_PIPES__MAX]; ++ double PrefetchSourceLinesC[DC__NUM_PIPES__MAX]; ++ double PixelPTEBytesPerRow[DC__NUM_PIPES__MAX]; ++ double MetaRowByte[DC__NUM_PIPES__MAX]; ++ bool PTEBufferSizeNotExceeded; // not used ++ unsigned int dpte_row_height[DC__NUM_PIPES__MAX]; ++ unsigned int dpte_row_height_chroma[DC__NUM_PIPES__MAX]; ++ unsigned int meta_row_height[DC__NUM_PIPES__MAX]; ++ unsigned int meta_row_height_chroma[DC__NUM_PIPES__MAX]; ++ ++ unsigned int MacroTileWidthY; ++ unsigned int MacroTileWidthC; ++ unsigned int MaxVStartupLines[DC__NUM_PIPES__MAX]; ++ double WritebackDelay[DC__NUM_PIPES__MAX]; ++ bool PrefetchModeSupported; ++ bool AllowDRAMClockChangeDuringVBlank[DC__NUM_PIPES__MAX]; ++ bool AllowDRAMSelfRefreshDuringVBlank[DC__NUM_PIPES__MAX]; ++ double RequiredPrefetchPixDataBW[DC__NUM_PIPES__MAX]; ++ double XFCRemoteSurfaceFlipDelay; ++ double TInitXFill; ++ double TslvChk; ++ double SrcActiveDrainRate; ++ double Tno_bw[DC__NUM_PIPES__MAX]; ++ bool ImmediateFlipSupported; ++ ++ double prefetch_vm_bw[DC__NUM_PIPES__MAX]; ++ double prefetch_row_bw[DC__NUM_PIPES__MAX]; ++ bool ImmediateFlipSupportedForPipe[DC__NUM_PIPES__MAX]; ++ unsigned int VStartupLines; ++ double DisplayPipeLineDeliveryTimeLumaPrefetch[DC__NUM_PIPES__MAX]; ++ double DisplayPipeLineDeliveryTimeChromaPrefetch[DC__NUM_PIPES__MAX]; ++ unsigned int ActiveDPPs; ++ unsigned int LBLatencyHidingSourceLinesY; ++ unsigned int LBLatencyHidingSourceLinesC; ++ double ActiveDRAMClockChangeLatencyMargin[DC__NUM_PIPES__MAX]; ++ double MinActiveDRAMClockChangeMargin; ++ double XFCSlaveVUpdateOffset[DC__NUM_PIPES__MAX]; ++ double XFCSlaveVupdateWidth[DC__NUM_PIPES__MAX]; ++ double XFCSlaveVReadyOffset[DC__NUM_PIPES__MAX]; ++ double InitFillLevel; ++ double FinalFillMargin; ++ double FinalFillLevel; ++ double RemainingFillLevel; ++ double TFinalxFill; ++ ++ ++ // ++ // SOC Bounding Box Parameters ++ // ++ double SRExitTime; ++ double SREnterPlusExitTime; ++ double UrgentLatency; ++ double WritebackLatency; ++ double PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency; ++ double NumberOfChannels; ++ double DRAMChannelWidth; ++ double FabricDatapathToDCNDataReturn; ++ double ReturnBusWidth; ++ double Downspreading; ++ double DISPCLKDPPCLKDSCCLKDownSpreading; ++ double DISPCLKDPPCLKVCOSpeed; ++ double RoundTripPingLatencyCycles; ++ double UrgentOutOfOrderReturnPerChannel; ++ unsigned int VMMPageSize; ++ double DRAMClockChangeLatency; ++ double XFCBusTransportTime; ++ double XFCXBUFLatencyTolerance; ++ ++ // ++ // IP Parameters ++ // ++ unsigned int ROBBufferSizeInKByte; ++ double DETBufferSizeInKByte; ++ unsigned int DPPOutputBufferPixels; ++ unsigned int OPPOutputBufferLines; ++ unsigned int PixelChunkSizeInKByte; ++ double ReturnBW; ++ bool VirtualMemoryEnable; ++ unsigned int MaxPageTableLevels; ++ unsigned int OverridePageTableLevels; ++ unsigned int PTEChunkSize; ++ unsigned int MetaChunkSize; ++ unsigned int WritebackChunkSize; ++ bool ODMCapability; ++ unsigned int NumberOfDSC; ++ unsigned int LineBufferSize; ++ unsigned int MaxLineBufferLines; ++ unsigned int WritebackInterfaceLumaBufferSize; ++ unsigned int WritebackInterfaceChromaBufferSize; ++ unsigned int WritebackChromaLineBufferWidth; ++ double MaxDCHUBToPSCLThroughput; ++ double MaxPSCLToLBThroughput; ++ unsigned int PTEBufferSizeInRequests; ++ double DISPCLKRampingMargin; ++ unsigned int MaxInterDCNTileRepeaters; ++ bool XFCSupported; ++ double XFCSlvChunkSize; ++ double XFCFillBWOverhead; ++ double XFCFillConstant; ++ double XFCTSlvVupdateOffset; ++ double XFCTSlvVupdateWidth; ++ double XFCTSlvVreadyOffset; ++ double DPPCLKDelaySubtotal; ++ double DPPCLKDelaySCL; ++ double DPPCLKDelaySCLLBOnly; ++ double DPPCLKDelayCNVCFormater; ++ double DPPCLKDelayCNVCCursor; ++ double DISPCLKDelaySubtotal; ++ bool ProgressiveToInterlaceUnitInOPP; ++ unsigned int PDEProcessingBufIn64KBReqs; ++ ++ // Pipe/Plane Parameters ++ int VoltageLevel; ++ double FabricAndDRAMBandwidth; ++ double FabricClock; ++ double DRAMSpeed; ++ double DISPCLK; ++ double SOCCLK; ++ double DCFCLK; ++ ++ unsigned int NumberOfActivePlanes; ++ unsigned int ViewportWidth[DC__NUM_DPP]; ++ unsigned int ViewportHeight[DC__NUM_DPP]; ++ unsigned int ViewportYStartY[DC__NUM_DPP]; ++ unsigned int ViewportYStartC[DC__NUM_DPP]; ++ unsigned int PitchY[DC__NUM_DPP]; ++ unsigned int PitchC[DC__NUM_DPP]; ++ double HRatio[DC__NUM_DPP]; ++ double VRatio[DC__NUM_DPP]; ++ unsigned int htaps[DC__NUM_DPP]; ++ unsigned int vtaps[DC__NUM_DPP]; ++ unsigned int HTAPsChroma[DC__NUM_DPP]; ++ unsigned int VTAPsChroma[DC__NUM_DPP]; ++ unsigned int HTotal[DC__NUM_DPP]; ++ unsigned int VTotal[DC__NUM_DPP]; ++ unsigned int DPPPerPlane[DC__NUM_DPP]; ++ double PixelClock[DC__NUM_DPP]; ++ double PixelClockBackEnd[DC__NUM_DPP]; ++ double DPPCLK[DC__NUM_DPP]; ++ bool DCCEnable[DC__NUM_DPP]; ++ unsigned int DCCMetaPitchY[DC__NUM_DPP]; ++ enum scan_direction_class SourceScan[DC__NUM_DPP]; ++ enum source_format_class SourcePixelFormat[DC__NUM_DPP]; ++ bool WritebackEnable[DC__NUM_DPP]; ++ double WritebackDestinationWidth[DC__NUM_DPP]; ++ double WritebackDestinationHeight[DC__NUM_DPP]; ++ double WritebackSourceHeight[DC__NUM_DPP]; ++ enum source_format_class WritebackPixelFormat[DC__NUM_DPP]; ++ unsigned int WritebackLumaHTaps[DC__NUM_DPP]; ++ unsigned int WritebackLumaVTaps[DC__NUM_DPP]; ++ unsigned int WritebackChromaHTaps[DC__NUM_DPP]; ++ unsigned int WritebackChromaVTaps[DC__NUM_DPP]; ++ double WritebackHRatio[DC__NUM_DPP]; ++ double WritebackVRatio[DC__NUM_DPP]; ++ unsigned int HActive[DC__NUM_DPP]; ++ unsigned int VActive[DC__NUM_DPP]; ++ bool Interlace[DC__NUM_DPP]; ++ enum dm_swizzle_mode SurfaceTiling[DC__NUM_DPP]; ++ unsigned int ScalerRecoutWidth[DC__NUM_DPP]; ++ bool DynamicMetadataEnable[DC__NUM_DPP]; ++ unsigned int DynamicMetadataLinesBeforeActiveRequired[DC__NUM_DPP]; ++ unsigned int DynamicMetadataTransmittedBytes[DC__NUM_DPP]; ++ double DCCRate[DC__NUM_DPP]; ++ bool ODMCombineEnabled[DC__NUM_DPP]; ++ double OutputBpp[DC__NUM_DPP]; ++ unsigned int NumberOfDSCSlices[DC__NUM_DPP]; ++ bool DSCEnabled[DC__NUM_DPP]; ++ unsigned int DSCDelay[DC__NUM_DPP]; ++ unsigned int DSCInputBitPerComponent[DC__NUM_DPP]; ++ enum output_format_class OutputFormat[DC__NUM_DPP]; ++ enum output_encoder_class Output[DC__NUM_DPP]; ++ unsigned int BlendingAndTiming[DC__NUM_DPP]; ++ bool SynchronizedVBlank; ++ unsigned int NumberOfCursors[DC__NUM_DPP]; ++ unsigned int CursorWidth[DC__NUM_DPP][DC__NUM_CURSOR]; ++ unsigned int CursorBPP[DC__NUM_DPP][DC__NUM_CURSOR]; ++ bool XFCEnabled[DC__NUM_DPP]; ++ bool ScalerEnabled[DC__NUM_DPP]; ++ ++ // Intermediates/Informational ++ bool ImmediateFlipSupport; ++ unsigned int SwathHeightY[DC__NUM_DPP]; ++ unsigned int SwathHeightC[DC__NUM_DPP]; ++ unsigned int DETBufferSizeY[DC__NUM_DPP]; ++ unsigned int DETBufferSizeC[DC__NUM_DPP]; ++ unsigned int LBBitPerPixel[DC__NUM_DPP]; ++ double LastPixelOfLineExtraWatermark; ++ double TotalDataReadBandwidth; ++ unsigned int TotalActiveWriteback; ++ unsigned int EffectiveLBLatencyHidingSourceLinesLuma; ++ unsigned int EffectiveLBLatencyHidingSourceLinesChroma; ++ double BandwidthAvailableForImmediateFlip; ++ unsigned int PrefetchMode; ++ bool IgnoreViewportPositioning; ++ double PrefetchBandwidth[DC__NUM_DPP]; ++ bool ErrorResult[DC__NUM_DPP]; ++ double PDEAndMetaPTEBytesFrame[DC__NUM_DPP]; ++ ++ // ++ // Calculated dml_ml->vba.Outputs ++ // ++ double DCFClkDeepSleep; ++ double UrgentWatermark; ++ double UrgentExtraLatency; ++ double MemoryTripWatermark; ++ double WritebackUrgentWatermark; ++ double StutterExitWatermark; ++ double StutterEnterPlusExitWatermark; ++ double DRAMClockChangeWatermark; ++ double WritebackDRAMClockChangeWatermark; ++ double StutterEfficiency; ++ double StutterEfficiencyNotIncludingVBlank; ++ double MinUrgentLatencySupportUs; ++ double NonUrgentLatencyTolerance; ++ double MinActiveDRAMClockChangeLatencySupported; ++ enum clock_change_support DRAMClockChangeSupport; ++ ++ // These are the clocks calcuated by the library but they are not actually ++ // used explicitly. They are fetched by tests and then possibly used. The ++ // ultimate values to use are the ones specified by the parameters to DML ++ double DISPCLK_calculated; ++ double DSCCLK_calculated[DC__NUM_DPP]; ++ double DPPCLK_calculated[DC__NUM_DPP]; ++ ++ unsigned int VStartup[DC__NUM_DPP]; ++ unsigned int VStartupRequiredWhenNotEnoughTimeForDynamicMetadata; ++ ++ double ImmediateFlipBW; ++ unsigned int TotImmediateFlipBytes; ++ double TCalc; ++ double MinTTUVBlank[DC__NUM_DPP]; ++ double VRatioPrefetchY[DC__NUM_DPP]; ++ double VRatioPrefetchC[DC__NUM_DPP]; ++ double DSTXAfterScaler[DC__NUM_DPP]; ++ double DSTYAfterScaler[DC__NUM_DPP]; ++ ++ double DestinationLinesToRequestVMInVBlank[DC__NUM_DPP]; ++ double DestinationLinesToRequestRowInVBlank[DC__NUM_DPP]; ++ double DestinationLinesForPrefetch[DC__NUM_DPP]; ++ double DestinationLinesToRequestRowInImmediateFlip[DC__NUM_DPP]; ++ double DestinationLinesToRequestVMInImmediateFlip[DC__NUM_DPP]; ++ ++ double XFCTransferDelay[DC__NUM_DPP]; ++ double XFCPrechargeDelay[DC__NUM_DPP]; ++ double XFCRemoteSurfaceFlipLatency[DC__NUM_DPP]; ++ double XFCPrefetchMargin[DC__NUM_DPP]; ++ ++ display_e2e_pipe_params_st cache_pipes[DC__NUM_DPP]; ++ unsigned int cache_num_pipes; ++ unsigned int pipe_plane[DC__NUM_PIPES__MAX]; ++}; ++ ++#endif /* _DML2_DISPLAY_MODE_VBA_H_ */ +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c +index 2e4dc57..30c379d 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c +@@ -27,340 +27,79 @@ + #include "display_mode_lib.h" + #include "soc_bounding_box.h" + +-static enum voltage_state power_state( ++display_pipe_clock_st dml_clks_get_pipe_clocks( + struct display_mode_lib *mode_lib, +- double dispclk, +- double dppclk) +-{ +- enum voltage_state state1; +- enum voltage_state state2; +- +- if (dispclk <= mode_lib->soc.vmin.dispclk_mhz) +- state1 = dm_vmin; +- else if (dispclk <= mode_lib->soc.vnom.dispclk_mhz) +- state1 = dm_vnom; +- else if (dispclk <= mode_lib->soc.vmax.dispclk_mhz) +- state1 = dm_vmax; +- else +- state1 = dm_vmax_exceeded; +- +- if (dppclk <= mode_lib->soc.vmin.dppclk_mhz) +- state2 = dm_vmin; +- else if (dppclk <= mode_lib->soc.vnom.dppclk_mhz) +- state2 = dm_vnom; +- else if (dppclk <= mode_lib->soc.vmax.dppclk_mhz) +- state2 = dm_vmax; +- else +- state2 = dm_vmax_exceeded; +- +- if (state1 > state2) +- return state1; +- else +- return state2; +-} +- +-static unsigned int dpp_in_grp( +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- unsigned int num_pipes, +- unsigned int hsplit_grp) +-{ +- unsigned int num_dpp = 0; +- unsigned int i; +- +- for (i = 0; i < num_pipes; i++) { +- if (e2e[i].pipe.src.is_hsplit) { +- if (e2e[i].pipe.src.hsplit_grp == hsplit_grp) { +- num_dpp++; +- } +- } +- } +- +- if (0 == num_dpp) +- num_dpp = 1; +- +- return num_dpp; +-} +- +-static void calculate_pipe_clk_requirement( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- unsigned int num_dpp_in_grp, +- double *dppclk, +- double *dispclk, +- bool *dppdiv) +-{ +- double pscl_throughput = 0.0; +- double max_hratio = e2e->pipe.scale_ratio_depth.hscl_ratio; +- double max_vratio = e2e->pipe.scale_ratio_depth.vscl_ratio; +- double max_htaps = e2e->pipe.scale_taps.htaps; +- double max_vtaps = e2e->pipe.scale_taps.vtaps; +- double dpp_clock_divider = (double) num_dpp_in_grp; +- double dispclk_dppclk_ratio; +- double dispclk_ramp_margin_percent; +- +- if (max_hratio > 1.0) { +- double pscl_to_lb = ((double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk * max_hratio) +- / dml_ceil(max_htaps / 6.0); +- pscl_throughput = dml_min( +- pscl_to_lb, +- (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk); +- } else { +- pscl_throughput = dml_min( +- (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk, +- (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk); +- } +- +- DTRACE("pscl_throughput: %f pix per clk", pscl_throughput); +- DTRACE("vtaps: %f hratio: %f vratio: %f", max_vtaps, max_hratio, max_vratio); +- *dppclk = dml_max( +- max_vtaps / 6.0 * dml_min(1.0, max_hratio), +- max_hratio * max_vratio / pscl_throughput); +- DTRACE("pixel rate multiplier: %f", *dppclk); +- *dppclk = dml_max(*dppclk, 1.0); +- DTRACE("pixel rate multiplier clamped: %f", *dppclk); +- *dppclk = *dppclk * e2e->pipe.dest.pixel_rate_mhz; +- +- *dppclk = *dppclk / dpp_clock_divider; +- DTRACE("dppclk after split: %f", *dppclk); +- +- if (dpp_clock_divider > 1.0 && (*dppclk < e2e->pipe.dest.pixel_rate_mhz)) { +- dispclk_dppclk_ratio = 2.0; +- *dppdiv = true; +- } else { +- dispclk_dppclk_ratio = 1.0; +- *dppdiv = false; +- } +- +- dispclk_ramp_margin_percent = mode_lib->ip.dispclk_ramp_margin_percent; +- +- /* Comment this out because of Gabes possible bug in spreadsheet, +- * just to make other cases evident during debug +- * +- *if(e2e->clks_cfg.voltage == dm_vmax) +- * dispclk_ramp_margin_percent = 0.0; +- */ +- +- /* account for ramping margin and downspread */ +- *dispclk = dml_max(*dppclk * dispclk_dppclk_ratio, e2e->pipe.dest.pixel_rate_mhz) +- * (1.0 + (double) mode_lib->soc.downspread_percent / 100.0) +- * (1.0 + (double) dispclk_ramp_margin_percent / 100.0); +- +- return; +-} +- +-bool dml_clks_pipe_clock_requirement_fit_power_constraint( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- unsigned int num_dpp_in_grp) +-{ +- double dppclk = 0; +- double dispclk = 0; +- bool dppdiv = 0; +- +- calculate_pipe_clk_requirement(mode_lib, e2e, num_dpp_in_grp, &dppclk, &dispclk, &dppdiv); +- +- if (power_state(mode_lib, dispclk, dppclk) > e2e->clks_cfg.voltage) { +- return false; +- } +- +- return true; +-} +- +-static void get_plane_clks( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- unsigned int num_pipes, +- double *dppclks, +- double *dispclks, +- bool *dppdiv) +-{ +- /* it is assumed that the scale ratios passed into the e2e pipe params have already been calculated +- * for any split pipe configurations, where extra pixels inthe overlap region do not contribute to +- * the scale ratio. This means that we can simply calculate the dppclk for each dpp independently +- * and we would expect the same result on any split pipes, which would be handled +- */ +- unsigned int i; +- +- for (i = 0; i < num_pipes; i++) { +- double num_dpp_in_grp; +- double dispclk_ramp_margin_percent; +- double dispclk_margined; +- +- if (e2e[i].pipe.src.is_hsplit) +- num_dpp_in_grp = (double) dpp_in_grp( +- e2e, +- num_pipes, +- e2e[i].pipe.src.hsplit_grp); +- else +- num_dpp_in_grp = 1; +- +- calculate_pipe_clk_requirement( +- mode_lib, +- &e2e[i], +- num_dpp_in_grp, +- &dppclks[i], +- &dispclks[i], +- &dppdiv[i]); +- +- dispclk_ramp_margin_percent = mode_lib->ip.dispclk_ramp_margin_percent; +- +- dispclk_margined = e2e[i].pipe.dest.pixel_rate_mhz +- * (1.0 + (double) mode_lib->soc.downspread_percent / 100.0) +- * (1.0 + (double) dispclk_ramp_margin_percent / 100.0); +- +- DTRACE("p%d: requested power state: %d", i, (int) e2e[0].clks_cfg.voltage); +- +- if (power_state(mode_lib, dispclks[i], dppclks[i]) +- > power_state(mode_lib, dispclk_margined, dispclk_margined) +- && dispclk_margined > dppclks[i]) { +- if (power_state(mode_lib, dispclks[i], dppclks[i]) +- > e2e[0].clks_cfg.voltage) { +- dispclks[i] = dispclk_margined; +- dppclks[i] = dispclk_margined; +- dppdiv[i] = false; +- } +- } +- +- DTRACE("p%d: dispclk: %f", i, dispclks[i]); +- } +-} +- +-static void get_dcfclk( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- unsigned int num_pipes, +- double *dcfclk_mhz) +-{ +- double bytes_per_pixel_det_y[DC__NUM_PIPES__MAX]; +- double bytes_per_pixel_det_c[DC__NUM_PIPES__MAX]; +- double swath_width_y[DC__NUM_PIPES__MAX]; +- unsigned int i; +- double total_read_bandwidth_gbps = 0.0; +- +- for (i = 0; i < num_pipes; i++) { +- if (e2e[i].pipe.src.source_scan == dm_horz) { +- swath_width_y[i] = e2e[i].pipe.src.viewport_width * 1.0; +- } else { +- swath_width_y[i] = e2e[i].pipe.src.viewport_height * 1.0; +- } +- +- switch (e2e[i].pipe.src.source_format) { +- case dm_444_64: +- bytes_per_pixel_det_y[i] = 8.0; +- bytes_per_pixel_det_c[i] = 0.0; +- break; +- case dm_444_32: +- bytes_per_pixel_det_y[i] = 4.0; +- bytes_per_pixel_det_c[i] = 0.0; +- break; +- case dm_444_16: +- bytes_per_pixel_det_y[i] = 2.0; +- bytes_per_pixel_det_c[i] = 0.0; +- break; +- case dm_422_8: +- bytes_per_pixel_det_y[i] = 2.0; +- bytes_per_pixel_det_c[i] = 0.0; +- break; +- case dm_422_10: +- bytes_per_pixel_det_y[i] = 4.0; +- bytes_per_pixel_det_c[i] = 0.0; +- break; +- case dm_420_8: +- bytes_per_pixel_det_y[i] = 1.0; +- bytes_per_pixel_det_c[i] = 2.0; +- break; +- case dm_420_10: +- bytes_per_pixel_det_y[i] = 4.0 / 3.0; +- bytes_per_pixel_det_c[i] = 8.0 / 3.0; +- break; +- default: +- BREAK_TO_DEBUGGER(); /* invalid src_format in get_dcfclk */ +- } +- } +- +- for (i = 0; i < num_pipes; i++) { +- double read_bandwidth_plane_mbps = 0.0; +- read_bandwidth_plane_mbps = (double) swath_width_y[i] +- * ((double) bytes_per_pixel_det_y[i] +- + (double) bytes_per_pixel_det_c[i] / 2.0) +- / ((double) e2e[i].pipe.dest.htotal +- / (double) e2e[i].pipe.dest.pixel_rate_mhz) +- * e2e[i].pipe.scale_ratio_depth.vscl_ratio; +- +- if (e2e[i].pipe.src.dcc) { +- read_bandwidth_plane_mbps += (read_bandwidth_plane_mbps / 1000.0 / 256.0); +- } +- +- if (e2e[i].pipe.src.vm) { +- read_bandwidth_plane_mbps += (read_bandwidth_plane_mbps / 1000.0 / 512.0); +- } +- +- total_read_bandwidth_gbps = total_read_bandwidth_gbps +- + read_bandwidth_plane_mbps / 1000.0; +- } +- +- DTRACE("total bandwidth = %f gbps", total_read_bandwidth_gbps); +- +- (*dcfclk_mhz) = (total_read_bandwidth_gbps * 1000.0) / mode_lib->soc.return_bus_width_bytes; +- +- DTRACE( +- "minimum theoretical dcfclk without stutter and full utilization = %f MHz", +- (*dcfclk_mhz)); +- +-} +- +-struct _vcs_dpi_display_pipe_clock_st dml_clks_get_pipe_clocks( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, ++ display_e2e_pipe_params_st *e2e, + unsigned int num_pipes) + { +- struct _vcs_dpi_display_pipe_clock_st clocks; +- double max_dispclk = 0.0; +- double dcfclk; +- double dispclks[DC__NUM_PIPES__MAX]; +- double dppclks[DC__NUM_PIPES__MAX]; +- bool dppdiv[DC__NUM_PIPES__MAX]; +- unsigned int i; ++ display_pipe_clock_st clocks; ++ bool visited[DC__NUM_PIPES__MAX]; ++ double max_dispclk = 25.0; //the min dispclk is 25MHz, so keep the min dispclk caculated larger thant 25MHz ++ double dcfclk, socclk; ++ unsigned int i, j, k; ++ unsigned int dsc_inst = 0; + + DTRACE("Calculating pipe clocks..."); + +- /* this is the theoretical minimum, have to adjust based on valid values for soc */ +- get_dcfclk(mode_lib, e2e, num_pipes, &dcfclk); +- +- /* if(dcfclk > soc.vnom.dcfclk_mhz) +- * dcfclk = soc.vmax.dcfclk_mhz; +- * else if(dcfclk > soc.vmin.dcfclk_mhz) +- * dcfclk = soc.vnom.dcfclk_mhz; +- * else +- * dcfclk = soc.vmin.dcfclk_mhz; +- */ +- + dcfclk = dml_socbb_voltage_scaling( + &mode_lib->soc, + (enum voltage_state) e2e[0].clks_cfg.voltage).dcfclk_mhz; ++ socclk = dml_socbb_voltage_scaling( ++ &mode_lib->soc, ++ (enum voltage_state) e2e[0].clks_cfg.voltage).socclk_mhz; + clocks.dcfclk_mhz = dcfclk; ++ clocks.socclk_mhz = socclk; + +- get_plane_clks(mode_lib, e2e, num_pipes, dppclks, dispclks, dppdiv); +- +- for (i = 0; i < num_pipes; i++) { +- max_dispclk = dml_max(max_dispclk, dispclks[i]); +- } +- ++ max_dispclk = dml_max(max_dispclk, get_dispclk_calculated(mode_lib, e2e, num_pipes)); + clocks.dispclk_mhz = max_dispclk; +- DTRACE("dispclk: %f Mhz", clocks.dispclk_mhz); +- DTRACE("dcfclk: %f Mhz", clocks.dcfclk_mhz); ++ DTRACE(" dispclk: %f Mhz", clocks.dispclk_mhz); ++ DTRACE(" dcfclk: %f Mhz", clocks.dcfclk_mhz); ++ DTRACE(" socclk: %f Mhz", clocks.socclk_mhz); + +- for (i = 0; i < num_pipes; i++) { +- if (dppclks[i] * 2 < max_dispclk) +- dppdiv[i] = 1; ++ for (k = 0; k < num_pipes; ++k) ++ visited[k] = false; + +- if (dppdiv[i]) +- clocks.dppclk_div[i] = 1; +- else +- clocks.dppclk_div[i] = 0; ++ for (i = 0; i < num_pipes; i++) { ++ clocks.dppclk_mhz[i] = get_dppclk_calculated(mode_lib, e2e, num_pipes, i); ++ DTRACE(" dppclk%d: %f Mhz", i, clocks.dppclk_mhz[i]); ++ ++ if (e2e[i].pipe.src.is_hsplit && !visited[i]) { ++ unsigned int grp = e2e[i].pipe.src.hsplit_grp; ++ ++ for (j = i; j < num_pipes; j++) { ++ if (e2e[j].pipe.src.hsplit_grp == grp && e2e[j].pipe.src.is_hsplit ++ && !visited[j]) { ++ clocks.dscclk_mhz[j] = get_dscclk_calculated( ++ mode_lib, ++ e2e, ++ num_pipes, ++ dsc_inst); ++ DTRACE(" dscclk%d: %f Mhz", j, clocks.dscclk_mhz[j]); ++ visited[j] = true; ++ } ++ } ++ dsc_inst++; ++ } + +- clocks.dppclk_mhz[i] = max_dispclk / ((dppdiv[i]) ? 2.0 : 1.0); +- DTRACE("dppclk%d: %f Mhz", i, clocks.dppclk_mhz[i]); ++ if (!visited[i]) { ++ unsigned int otg_inst = e2e[i].pipe.dest.otg_inst; ++ ++ for (j = i; j < num_pipes; j++) { ++ // assign dscclk to all planes with this otg, except if they're doing odm combine, or mpc combine ++ // which is handled by the conditions above, the odm_combine is not required, but it helps make sense of this code ++ if (e2e[j].pipe.dest.otg_inst == otg_inst ++ && !e2e[j].pipe.dest.odm_combine && !visited[j]) { ++ clocks.dscclk_mhz[j] = get_dscclk_calculated( ++ mode_lib, ++ e2e, ++ num_pipes, ++ dsc_inst); ++ DTRACE(" dscclk%d: %f Mhz", j, clocks.dscclk_mhz[j]); ++ visited[j] = true; ++ } ++ } ++ dsc_inst++; ++ } + } + + return clocks; +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h +index aed5f33..a712dc3 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h ++++ b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h +@@ -29,13 +29,9 @@ + + struct display_mode_lib; + +-struct _vcs_dpi_display_pipe_clock_st dml_clks_get_pipe_clocks( ++display_pipe_clock_st dml_clks_get_pipe_clocks( + struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, ++ display_e2e_pipe_params_st *e2e, + unsigned int num_pipes); + +-bool dml_clks_pipe_clock_requirement_fit_power_constraint( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- unsigned int num_dpp_in_grp); + #endif +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c +index 9fccbbf..657b738 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c +@@ -22,8 +22,22 @@ + * Authors: AMD + * + */ +-#include "display_rq_dlg_calc.h" ++ + #include "display_mode_lib.h" ++#include "display_mode_vba.h" ++#include "display_rq_dlg_calc.h" ++ ++static void calculate_ttu_cursor(struct display_mode_lib *mode_lib, ++ double *refcyc_per_req_delivery_pre_cur, ++ double *refcyc_per_req_delivery_cur, ++ double refclk_freq_in_mhz, ++ double ref_freq_to_pix_freq, ++ double hscale_pixel_rate_l, ++ double hscl_ratio, ++ double vratio_pre_l, ++ double vratio_l, ++ unsigned int cur_width, ++ enum cursor_bpp cur_bpp); + + static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma) + { +@@ -48,6 +62,8 @@ static unsigned int get_bytes_per_element(enum source_format_class source_format + ret_val = 4; + else + ret_val = 2; ++ } else if (source_format == dm_444_8) { ++ ret_val = 1; + } + return ret_val; + } +@@ -62,123 +78,43 @@ static bool is_dual_plane(enum source_format_class source_format) + return ret_val; + } + +-static void get_blk256_size( +- unsigned int *blk256_width, +- unsigned int *blk256_height, +- unsigned int bytes_per_element) +-{ +- if (bytes_per_element == 1) { +- *blk256_width = 16; +- *blk256_height = 16; +- } else if (bytes_per_element == 2) { +- *blk256_width = 16; +- *blk256_height = 8; +- } else if (bytes_per_element == 4) { +- *blk256_width = 8; +- *blk256_height = 8; +- } else if (bytes_per_element == 8) { +- *blk256_width = 8; +- *blk256_height = 4; +- } +-} +- +-static double get_refcyc_per_delivery( +- struct display_mode_lib *mode_lib, ++static double get_refcyc_per_delivery(struct display_mode_lib *mode_lib, + double refclk_freq_in_mhz, + double pclk_freq_in_mhz, +- int unsigned recout_width, ++ bool odm_combine, ++ unsigned int recout_width, ++ unsigned int hactive, + double vratio, + double hscale_pixel_rate, +- int unsigned delivery_width, +- int unsigned req_per_swath_ub) ++ unsigned int delivery_width, ++ unsigned int req_per_swath_ub) + { + double refcyc_per_delivery = 0.0; ++ + if (vratio <= 1.0) { +- refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width +- / pclk_freq_in_mhz / (double) req_per_swath_ub; ++ if (odm_combine) ++ refcyc_per_delivery = (double) refclk_freq_in_mhz ++ * dml_min((double) recout_width, (double) hactive / 2.0) ++ / pclk_freq_in_mhz / (double) req_per_swath_ub; ++ else ++ refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width ++ / pclk_freq_in_mhz / (double) req_per_swath_ub; + } else { + refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) delivery_width + / (double) hscale_pixel_rate / (double) req_per_swath_ub; + } + +- DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz); +- DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz); +- DTRACE("DLG: %s: recout_width = %d", __func__, recout_width); +- DTRACE("DLG: %s: vratio = %3.2f", __func__, vratio); +- DTRACE("DLG: %s: req_per_swath_ub = %d", __func__, req_per_swath_ub); +- DTRACE("DLG: %s: refcyc_per_delivery= %3.2f", __func__, refcyc_per_delivery); ++ dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz); ++ dml_print("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, pclk_freq_in_mhz); ++ dml_print("DML_DLG: %s: recout_width = %d\n", __func__, recout_width); ++ dml_print("DML_DLG: %s: vratio = %3.2f\n", __func__, vratio); ++ dml_print("DML_DLG: %s: req_per_swath_ub = %d\n", __func__, req_per_swath_ub); ++ dml_print("DML_DLG: %s: refcyc_per_delivery= %3.2f\n", __func__, refcyc_per_delivery); + + return refcyc_per_delivery; + + } + +-static double get_vratio_pre( +- struct display_mode_lib *mode_lib, +- unsigned int max_num_sw, +- unsigned int max_partial_sw, +- unsigned int swath_height, +- double vinit, +- double l_sw) +-{ +- double prefill = dml_floor(vinit); +- double vratio_pre = 1.0; +- +- vratio_pre = (max_num_sw * swath_height + max_partial_sw) / l_sw; +- +- if (swath_height > 4) { +- double tmp0 = (max_num_sw * swath_height) / (l_sw - (prefill - 3.0) / 2.0); +- if (tmp0 > vratio_pre) +- vratio_pre = tmp0; +- } +- +- DTRACE("DLG: %s: max_num_sw = %0d", __func__, max_num_sw); +- DTRACE("DLG: %s: max_partial_sw = %0d", __func__, max_partial_sw); +- DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height); +- DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit); +- DTRACE("DLG: %s: vratio_pre = %3.2f", __func__, vratio_pre); +- +- if (vratio_pre < 1.0) { +- DTRACE("WARNING_DLG: %s: vratio_pre=%3.2f < 1.0, set to 1.0", __func__, vratio_pre); +- vratio_pre = 1.0; +- } +- +- if (vratio_pre > 4.0) { +- DTRACE( +- "WARNING_DLG: %s: vratio_pre=%3.2f > 4.0 (max scaling ratio). set to 4.0", +- __func__, +- vratio_pre); +- vratio_pre = 4.0; +- } +- +- return vratio_pre; +-} +- +-static void get_swath_need( +- struct display_mode_lib *mode_lib, +- unsigned int *max_num_sw, +- unsigned int *max_partial_sw, +- unsigned int swath_height, +- double vinit) +-{ +- double prefill = dml_floor(vinit); +- unsigned int max_partial_sw_int; +- +- DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height); +- DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit); +- +- ASSERT(prefill > 0.0 && prefill <= 8.0); +- +- *max_num_sw = (int unsigned) (dml_ceil((prefill - 1.0) / (double) swath_height) + 1.0); /* prefill has to be >= 1 */ +- max_partial_sw_int = +- (prefill == 1) ? +- (swath_height - 1) : +- ((int unsigned) (prefill - 2.0) % swath_height); +- *max_partial_sw = (max_partial_sw_int < 1) ? 1 : max_partial_sw_int; /* ensure minimum of 1 is used */ +- +- DTRACE("DLG: %s: max_num_sw = %0d", __func__, *max_num_sw); +- DTRACE("DLG: %s: max_partial_sw = %0d", __func__, *max_partial_sw); +-} +- + static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size) + { + if (tile_size == dm_256k_tile) +@@ -189,12 +125,11 @@ static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_si + return (4 * 1024); + } + +-static void extract_rq_sizing_regs( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_data_rq_regs_st *rq_regs, +- const struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing) ++static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib, ++ display_data_rq_regs_st *rq_regs, ++ const display_data_rq_sizing_params_st rq_sizing) + { +- DTRACE("DLG: %s: rq_sizing param", __func__); ++ dml_print("DML_DLG: %s: rq_sizing param\n", __func__); + print__data_rq_sizing_params_st(mode_lib, rq_sizing); + + rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10; +@@ -214,25 +149,30 @@ static void extract_rq_sizing_regs( + rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6; + } + +-void extract_rq_regs( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_rq_regs_st *rq_regs, +- const struct _vcs_dpi_display_rq_params_st rq_param) ++static void extract_rq_regs(struct display_mode_lib *mode_lib, ++ display_rq_regs_st *rq_regs, ++ const display_rq_params_st rq_param) + { + unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; + unsigned int detile_buf_plane1_addr = 0; + + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l); +- if (rq_param.yuv420) ++ ++ rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_l.dpte_row_height), ++ 1) - 3; ++ ++ if (rq_param.yuv420) { + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c); ++ rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_c.dpte_row_height), ++ 1) - 3; ++ } + + rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height); + rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height); + +- /* FIXME: take the max between luma, chroma chunk size? +- * okay for now, as we are setting chunk_bytes to 8kb anyways +- */ +- if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { /*32kb */ ++ // FIXME: take the max between luma, chroma chunk size? ++ // okay for now, as we are setting chunk_bytes to 8kb anyways ++ if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { //32kb + rq_regs->drq_expansion_mode = 0; + } else { + rq_regs->drq_expansion_mode = 2; +@@ -244,21 +184,19 @@ void extract_rq_regs( + if (rq_param.yuv420) { + if ((double) rq_param.misc.rq_l.stored_swath_bytes + / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) { +- detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); /* half to chroma */ ++ detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); // half to chroma + } else { +- detile_buf_plane1_addr = dml_round_to_multiple( +- (unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0), ++ detile_buf_plane1_addr = dml_round_to_multiple((unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0), + 256, +- 0) / 64.0; /* 2/3 to chroma */ ++ 0) / 64.0; // 2/3 to chroma + } + } + rq_regs->plane1_base_address = detile_buf_plane1_addr; + } + +-static void handle_det_buf_split( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_rq_params_st *rq_param, +- const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param) ++static void handle_det_buf_split(struct display_mode_lib *mode_lib, ++ display_rq_params_st *rq_param, ++ const display_pipe_source_params_st pipe_src_param) + { + unsigned int total_swath_bytes = 0; + unsigned int swath_bytes_l = 0; +@@ -277,12 +215,10 @@ static void handle_det_buf_split( + full_swath_bytes_packed_c = rq_param->misc.rq_c.full_swath_bytes; + + if (rq_param->yuv420_10bpc) { +- full_swath_bytes_packed_l = dml_round_to_multiple( +- rq_param->misc.rq_l.full_swath_bytes * 2 / 3, ++ full_swath_bytes_packed_l = dml_round_to_multiple(rq_param->misc.rq_l.full_swath_bytes * 2 / 3, + 256, + 1) + 256; +- full_swath_bytes_packed_c = dml_round_to_multiple( +- rq_param->misc.rq_c.full_swath_bytes * 2 / 3, ++ full_swath_bytes_packed_c = dml_round_to_multiple(rq_param->misc.rq_c.full_swath_bytes * 2 / 3, + 256, + 1) + 256; + } +@@ -290,29 +226,19 @@ static void handle_det_buf_split( + if (rq_param->yuv420) { + total_swath_bytes = 2 * full_swath_bytes_packed_l + 2 * full_swath_bytes_packed_c; + +- if (total_swath_bytes <= detile_buf_size_in_bytes) { /*full 256b request */ ++ if (total_swath_bytes <= detile_buf_size_in_bytes) { //full 256b request + req128_l = 0; + req128_c = 0; + swath_bytes_l = full_swath_bytes_packed_l; + swath_bytes_c = full_swath_bytes_packed_c; +- } else { /*128b request (for luma only for yuv420 8bpc) */ ++ } else { //128b request (for luma only for yuv420 8bpc) + req128_l = 1; + req128_c = 0; + swath_bytes_l = full_swath_bytes_packed_l / 2; + swath_bytes_c = full_swath_bytes_packed_c; + } +- +- /* Bug workaround, luma and chroma req size needs to be the same. (see: DEGVIDCN10-137) +- * TODO: Remove after rtl fix +- */ +- if (req128_l == 1) { +- req128_c = 1; +- DTRACE("DLG: %s: bug workaround DEGVIDCN10-137", __func__); +- } +- +- /* Note: assumption, the config that pass in will fit into +- * the detiled buffer. +- */ ++ // Note: assumption, the config that pass in will fit into ++ // the detiled buffer. + } else { + total_swath_bytes = 2 * full_swath_bytes_packed_l; + +@@ -340,207 +266,47 @@ static void handle_det_buf_split( + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; + rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; + +- DTRACE("DLG: %s: req128_l = %0d", __func__, req128_l); +- DTRACE("DLG: %s: req128_c = %0d", __func__, req128_c); +- DTRACE("DLG: %s: full_swath_bytes_packed_l = %0d", __func__, full_swath_bytes_packed_l); +- DTRACE("DLG: %s: full_swath_bytes_packed_c = %0d", __func__, full_swath_bytes_packed_c); ++ dml_print("DML_DLG: %s: req128_l = %0d\n", __func__, req128_l); ++ dml_print("DML_DLG: %s: req128_c = %0d\n", __func__, req128_c); ++ dml_print("DML_DLG: %s: full_swath_bytes_packed_l = %0d\n", ++ __func__, ++ full_swath_bytes_packed_l); ++ dml_print("DML_DLG: %s: full_swath_bytes_packed_c = %0d\n", ++ __func__, ++ full_swath_bytes_packed_c); + } + +-/* Need refactor. */ +-void dml_rq_dlg_get_row_heights( +- struct display_mode_lib *mode_lib, +- unsigned int *o_dpte_row_height, +- unsigned int *o_meta_row_height, ++static void get_meta_and_pte_attr(struct display_mode_lib *mode_lib, ++ display_data_rq_dlg_params_st *rq_dlg_param, ++ display_data_rq_misc_params_st *rq_misc_param, ++ display_data_rq_sizing_params_st *rq_sizing_param, + unsigned int vp_width, ++ unsigned int vp_height, + unsigned int data_pitch, +- int source_format, +- int tiling, +- int macro_tile_size, +- int source_scan, +- int is_chroma) ++ unsigned int meta_pitch, ++ unsigned int source_format, ++ unsigned int tiling, ++ unsigned int macro_tile_size, ++ unsigned int source_scan, ++ unsigned int is_chroma) + { + bool surf_linear = (tiling == dm_sw_linear); + bool surf_vert = (source_scan == dm_vert); + +- unsigned int bytes_per_element = get_bytes_per_element( +- (enum source_format_class) source_format, +- is_chroma); +- unsigned int log2_bytes_per_element = dml_log2(bytes_per_element); ++ unsigned int bytes_per_element; ++ unsigned int bytes_per_element_y = get_bytes_per_element((enum source_format_class)(source_format), ++ false); ++ unsigned int bytes_per_element_c = get_bytes_per_element((enum source_format_class)(source_format), ++ true); ++ + unsigned int blk256_width = 0; + unsigned int blk256_height = 0; + +- unsigned int log2_blk256_height; +- unsigned int blk_bytes; +- unsigned int log2_blk_bytes; +- unsigned int log2_blk_height; +- unsigned int log2_blk_width; +- unsigned int log2_meta_req_bytes; +- unsigned int log2_meta_req_height; +- unsigned int log2_meta_req_width; +- unsigned int log2_meta_row_height; +- unsigned int log2_vmpg_bytes; +- unsigned int dpte_buf_in_pte_reqs; +- unsigned int log2_vmpg_height; +- unsigned int log2_vmpg_width; +- unsigned int log2_dpte_req_height_ptes; +- unsigned int log2_dpte_req_width_ptes; +- unsigned int log2_dpte_req_height; +- unsigned int log2_dpte_req_width; +- unsigned int log2_dpte_row_height_linear; +- unsigned int log2_dpte_row_height; +- unsigned int dpte_req_width; +- +- if (surf_linear) { +- blk256_width = 256; +- blk256_height = 1; +- } else { +- get_blk256_size(&blk256_width, &blk256_height, bytes_per_element); +- } +- +- log2_blk256_height = dml_log2((double) blk256_height); +- blk_bytes = surf_linear ? +- 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size); +- log2_blk_bytes = dml_log2((double) blk_bytes); +- log2_blk_height = 0; +- log2_blk_width = 0; +- +- /* remember log rule +- * "+" in log is multiply +- * "-" in log is divide +- * "/2" is like square root +- * blk is vertical biased +- */ +- if (tiling != dm_sw_linear) +- log2_blk_height = log2_blk256_height +- + dml_ceil((double) (log2_blk_bytes - 8) / 2.0); +- else +- log2_blk_height = 0; /* blk height of 1 */ +- +- log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height; +- +- /* ------- */ +- /* meta */ +- /* ------- */ +- log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */ +- +- /* each 64b meta request for dcn is 8x8 meta elements and +- * a meta element covers one 256b block of the the data surface. +- */ +- log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 */ +- log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element +- - log2_meta_req_height; +- log2_meta_row_height = 0; +- +- /* the dimensions of a meta row are meta_row_width x meta_row_height in elements. +- * calculate upper bound of the meta_row_width +- */ +- if (!surf_vert) +- log2_meta_row_height = log2_meta_req_height; +- else +- log2_meta_row_height = log2_meta_req_width; +- +- *o_meta_row_height = 1 << log2_meta_row_height; +- +- /* ------ */ +- /* dpte */ +- /* ------ */ +- log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes); +- dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs; +- +- log2_vmpg_height = 0; +- log2_vmpg_width = 0; +- log2_dpte_req_height_ptes = 0; +- log2_dpte_req_width_ptes = 0; +- log2_dpte_req_height = 0; +- log2_dpte_req_width = 0; +- log2_dpte_row_height_linear = 0; +- log2_dpte_row_height = 0; +- dpte_req_width = 0; /* 64b dpte req width in data element */ +- +- if (surf_linear) { +- log2_vmpg_height = 0; /* one line high */ +- } else { +- log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height; +- } +- log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height; +- +- /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */ +- if (log2_blk_bytes <= log2_vmpg_bytes) +- log2_dpte_req_height_ptes = 0; +- else if (log2_blk_height - log2_vmpg_height >= 2) +- log2_dpte_req_height_ptes = 2; +- else +- log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height; +- log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes; +- +- ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */ +- (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */ +- (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */ +- +- /* the dpte request dimensions in data elements is dpte_req_width x dpte_req_height +- * log2_wmpg_width is how much 1 pte represent, now trying to calculate how much 64b pte req represent +- */ +- log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes; +- log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes; +- dpte_req_width = 1 << log2_dpte_req_width; +- +- /* calculate pitch dpte row buffer can hold +- * round the result down to a power of two. +- */ +- if (surf_linear) { +- log2_dpte_row_height_linear = dml_floor( +- dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch)); +- +- ASSERT(log2_dpte_row_height_linear >= 3); +- +- if (log2_dpte_row_height_linear > 7) +- log2_dpte_row_height_linear = 7; +- +- log2_dpte_row_height = log2_dpte_row_height_linear; +- } else { +- /* the upper bound of the dpte_row_width without dependency on viewport position follows. */ +- if (!surf_vert) { +- log2_dpte_row_height = log2_dpte_req_height; +- } else { +- log2_dpte_row_height = +- (log2_blk_width < log2_dpte_req_width) ? +- log2_blk_width : log2_dpte_req_width; +- } +- } +- +- /* From programming guide: +- * There is a special case of saving only half of ptes returned due to buffer space limits. +- * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16 +- * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb). +- */ +- if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12 +- && log2_blk_bytes >= 16) { +- log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */ +- } +- +- *o_dpte_row_height = 1 << log2_dpte_row_height; +-} +- +-static void get_surf_rq_param( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing_param, +- struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param, +- struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param, +- const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param, +- bool is_chroma) +-{ +- bool mode_422 = 0; +- unsigned int vp_width = 0; +- unsigned int vp_height = 0; +- unsigned int data_pitch = 0; +- unsigned int meta_pitch = 0; +- unsigned int ppe = mode_422 ? 2 : 1; +- bool surf_linear; +- bool surf_vert; +- unsigned int bytes_per_element; ++ unsigned int blk256_width_y = 0; ++ unsigned int blk256_height_y = 0; ++ unsigned int blk256_width_c = 0; ++ unsigned int blk256_height_c = 0; + unsigned int log2_bytes_per_element; +- unsigned int blk256_width; +- unsigned int blk256_height; + unsigned int log2_blk256_width; + unsigned int log2_blk256_height; + unsigned int blk_bytes; +@@ -556,6 +322,8 @@ static void get_surf_rq_param( + unsigned int meta_row_width_ub; + unsigned int log2_meta_chunk_bytes; + unsigned int log2_meta_chunk_height; ++ ++ //full sized meta chunk width in unit of data elements + unsigned int log2_meta_chunk_width; + unsigned int log2_min_meta_chunk_bytes; + unsigned int min_meta_chunk_width; +@@ -570,93 +338,72 @@ static void get_surf_rq_param( + unsigned int vmpg_bytes; + unsigned int meta_pte_req_per_frame_ub; + unsigned int meta_pte_bytes_per_frame_ub; +- unsigned int log2_vmpg_bytes; +- unsigned int dpte_buf_in_pte_reqs; +- unsigned int log2_vmpg_height; +- unsigned int log2_vmpg_width; +- unsigned int log2_dpte_req_height_ptes; +- unsigned int log2_dpte_req_width_ptes; +- unsigned int log2_dpte_req_height; +- unsigned int log2_dpte_req_width; +- unsigned int log2_dpte_row_height_linear; +- unsigned int log2_dpte_row_height; +- unsigned int log2_dpte_group_width; +- unsigned int dpte_row_width_ub; +- unsigned int dpte_row_height; +- unsigned int dpte_req_height; +- unsigned int dpte_req_width; +- unsigned int dpte_group_width; +- unsigned int log2_dpte_group_bytes; +- unsigned int log2_dpte_group_length; +- unsigned int func_meta_row_height, func_dpte_row_height; +- +- /* FIXME check if ppe apply for both luma and chroma in 422 case */ +- if (is_chroma) { +- vp_width = pipe_src_param.viewport_width_c / ppe; +- vp_height = pipe_src_param.viewport_height_c; +- data_pitch = pipe_src_param.data_pitch_c; +- meta_pitch = pipe_src_param.meta_pitch_c; ++ const unsigned int log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes); ++ const unsigned int dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs; ++ const unsigned int pde_proc_buffer_size_64k_reqs = ++ mode_lib->ip.pde_proc_buffer_size_64k_reqs; ++ ++ unsigned int log2_vmpg_height = 0; ++ unsigned int log2_vmpg_width = 0; ++ unsigned int log2_dpte_req_height_ptes = 0; ++ unsigned int log2_dpte_req_height = 0; ++ unsigned int log2_dpte_req_width = 0; ++ unsigned int log2_dpte_row_height_linear = 0; ++ unsigned int log2_dpte_row_height = 0; ++ unsigned int log2_dpte_group_width = 0; ++ unsigned int dpte_row_width_ub = 0; ++ unsigned int dpte_req_height = 0; ++ unsigned int dpte_req_width = 0; ++ unsigned int dpte_group_width = 0; ++ unsigned int log2_dpte_group_bytes = 0; ++ unsigned int log2_dpte_group_length = 0; ++ unsigned int pde_buf_entries; ++ bool yuv420 = (source_format == dm_420_8 || source_format == dm_420_10); ++ ++ Calculate256BBlockSizes((enum source_format_class)(source_format), ++ (enum dm_swizzle_mode)(tiling), ++ bytes_per_element_y, ++ bytes_per_element_c, ++ &blk256_height_y, ++ &blk256_height_c, ++ &blk256_width_y, ++ &blk256_width_c); ++ ++ if (!is_chroma) { ++ blk256_width = blk256_width_y; ++ blk256_height = blk256_height_y; ++ bytes_per_element = bytes_per_element_y; + } else { +- vp_width = pipe_src_param.viewport_width / ppe; +- vp_height = pipe_src_param.viewport_height; +- data_pitch = pipe_src_param.data_pitch; +- meta_pitch = pipe_src_param.meta_pitch; ++ blk256_width = blk256_width_c; ++ blk256_height = blk256_height_c; ++ bytes_per_element = bytes_per_element_c; + } + +- rq_sizing_param->chunk_bytes = 8192; +- +- if (rq_sizing_param->chunk_bytes == 64 * 1024) +- rq_sizing_param->min_chunk_bytes = 0; +- else +- rq_sizing_param->min_chunk_bytes = 1024; +- +- rq_sizing_param->meta_chunk_bytes = 2048; +- rq_sizing_param->min_meta_chunk_bytes = 256; +- +- rq_sizing_param->mpte_group_bytes = 2048; +- +- surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); +- surf_vert = (pipe_src_param.source_scan == dm_vert); +- +- bytes_per_element = get_bytes_per_element( +- (enum source_format_class) pipe_src_param.source_format, +- is_chroma); + log2_bytes_per_element = dml_log2(bytes_per_element); +- blk256_width = 0; +- blk256_height = 0; +- +- if (surf_linear) { +- blk256_width = 256 / bytes_per_element; +- blk256_height = 1; +- } else { +- get_blk256_size(&blk256_width, &blk256_height, bytes_per_element); +- } + +- DTRACE("DLG: %s: surf_linear = %d", __func__, surf_linear); +- DTRACE("DLG: %s: surf_vert = %d", __func__, surf_vert); +- DTRACE("DLG: %s: blk256_width = %d", __func__, blk256_width); +- DTRACE("DLG: %s: blk256_height = %d", __func__, blk256_height); ++ dml_print("DML_DLG: %s: surf_linear = %d\n", __func__, surf_linear); ++ dml_print("DML_DLG: %s: surf_vert = %d\n", __func__, surf_vert); ++ dml_print("DML_DLG: %s: blk256_width = %d\n", __func__, blk256_width); ++ dml_print("DML_DLG: %s: blk256_height = %d\n", __func__, blk256_height); + + log2_blk256_width = dml_log2((double) blk256_width); + log2_blk256_height = dml_log2((double) blk256_height); +- blk_bytes = +- surf_linear ? 256 : get_blk_size_bytes( +- (enum source_macro_tile_size) pipe_src_param.macro_tile_size); ++ blk_bytes = surf_linear ? ++ 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size); + log2_blk_bytes = dml_log2((double) blk_bytes); + log2_blk_height = 0; + log2_blk_width = 0; + +- /* remember log rule +- * "+" in log is multiply +- * "-" in log is divide +- * "/2" is like square root +- * blk is vertical biased +- */ +- if (pipe_src_param.sw_mode != dm_sw_linear) ++ // remember log rule ++ // "+" in log is multiply ++ // "-" in log is divide ++ // "/2" is like square root ++ // blk is vertical biased ++ if (tiling != dm_sw_linear) + log2_blk_height = log2_blk256_height +- + dml_ceil((double) (log2_blk_bytes - 8) / 2.0); ++ + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1); + else +- log2_blk_height = 0; /* blk height of 1 */ ++ log2_blk_height = 0; // blk height of 1 + + log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height; + +@@ -665,10 +412,8 @@ static void get_surf_rq_param( + + blk256_width; + rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_width; + } else { +- rq_dlg_param->swath_width_ub = dml_round_to_multiple( +- vp_height - 1, +- blk256_height, +- 1) + blk256_height; ++ rq_dlg_param->swath_width_ub = dml_round_to_multiple(vp_height - 1, blk256_height, 1) ++ + blk256_height; + rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_height; + } + +@@ -682,15 +427,14 @@ static void get_surf_rq_param( + rq_misc_param->blk256_height = blk256_height; + rq_misc_param->blk256_width = blk256_width; + +- /* ------- */ +- /* meta */ +- /* ------- */ +- log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */ ++ // ------- ++ // meta ++ // ------- ++ log2_meta_req_bytes = 6; // meta request is 64b and is 8x8byte meta element + +- /* each 64b meta request for dcn is 8x8 meta elements and +- * a meta element covers one 256b block of the the data surface. +- */ +- log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 byte, each byte represent 1 blk256 */ ++ // each 64b meta request for dcn is 8x8 meta elements and ++ // a meta element covers one 256b block of the the data surface. ++ log2_meta_req_height = log2_blk256_height + 3; // meta req is 8x8 byte, each byte represent 1 blk256 + log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element + - log2_meta_req_height; + meta_req_width = 1 << log2_meta_req_width; +@@ -698,9 +442,8 @@ static void get_surf_rq_param( + log2_meta_row_height = 0; + meta_row_width_ub = 0; + +- /* the dimensions of a meta row are meta_row_width x meta_row_height in elements. +- * calculate upper bound of the meta_row_width +- */ ++ // the dimensions of a meta row are meta_row_width x meta_row_height in elements. ++ // calculate upper bound of the meta_row_width + if (!surf_vert) { + log2_meta_row_height = log2_meta_req_height; + meta_row_width_ub = dml_round_to_multiple(vp_width - 1, meta_req_width, 1) +@@ -714,10 +457,12 @@ static void get_surf_rq_param( + } + rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64; + ++ rq_dlg_param->meta_row_height = 1 << log2_meta_row_height; ++ + log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes); + log2_meta_chunk_height = log2_meta_row_height; + +- /*full sized meta chunk width in unit of data elements */ ++ //full sized meta chunk width in unit of data elements + log2_meta_chunk_width = log2_meta_chunk_bytes + 8 - log2_bytes_per_element + - log2_meta_chunk_height; + log2_min_meta_chunk_bytes = dml_log2(rq_sizing_param->min_meta_chunk_bytes); +@@ -732,21 +477,24 @@ static void get_surf_rq_param( + meta_blk_height = blk256_height * 64; + meta_blk_width = meta_blk_bytes * 256 / bytes_per_element / meta_blk_height; + meta_surface_bytes = meta_pitch +- * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1) +- + meta_blk_height) * bytes_per_element / 256; ++ * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1) + meta_blk_height) ++ * bytes_per_element / 256; + vmpg_bytes = mode_lib->soc.vmm_page_size_bytes; +- meta_pte_req_per_frame_ub = (dml_round_to_multiple( +- meta_surface_bytes - vmpg_bytes, ++ meta_pte_req_per_frame_ub = (dml_round_to_multiple(meta_surface_bytes - vmpg_bytes, + 8 * vmpg_bytes, + 1) + 8 * vmpg_bytes) / (8 * vmpg_bytes); +- meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; /*64B mpte request */ ++ meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; //64B mpte request + rq_dlg_param->meta_pte_bytes_per_frame_ub = meta_pte_bytes_per_frame_ub; + +- DTRACE("DLG: %s: meta_blk_height = %d", __func__, meta_blk_height); +- DTRACE("DLG: %s: meta_blk_width = %d", __func__, meta_blk_width); +- DTRACE("DLG: %s: meta_surface_bytes = %d", __func__, meta_surface_bytes); +- DTRACE("DLG: %s: meta_pte_req_per_frame_ub = %d", __func__, meta_pte_req_per_frame_ub); +- DTRACE("DLG: %s: meta_pte_bytes_per_frame_ub = %d", __func__, meta_pte_bytes_per_frame_ub); ++ dml_print("DML_DLG: %s: meta_blk_height = %d\n", __func__, meta_blk_height); ++ dml_print("DML_DLG: %s: meta_blk_width = %d\n", __func__, meta_blk_width); ++ dml_print("DML_DLG: %s: meta_surface_bytes = %d\n", __func__, meta_surface_bytes); ++ dml_print("DML_DLG: %s: meta_pte_req_per_frame_ub = %d\n", ++ __func__, ++ meta_pte_req_per_frame_ub); ++ dml_print("DML_DLG: %s: meta_pte_bytes_per_frame_ub = %d\n", ++ __func__, ++ meta_pte_bytes_per_frame_ub); + + if (!surf_vert) + meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width; +@@ -758,67 +506,58 @@ static void get_surf_rq_param( + else + rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 2; + +- rq_dlg_param->meta_row_height = 1 << log2_meta_row_height; +- +- /* ------ */ +- /* dpte */ +- /* ------ */ +- log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes); +- dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs; +- +- log2_vmpg_height = 0; +- log2_vmpg_width = 0; +- log2_dpte_req_height_ptes = 0; +- log2_dpte_req_width_ptes = 0; +- log2_dpte_req_height = 0; +- log2_dpte_req_width = 0; +- log2_dpte_row_height_linear = 0; +- log2_dpte_row_height = 0; +- log2_dpte_group_width = 0; +- dpte_row_width_ub = 0; +- dpte_row_height = 0; +- dpte_req_height = 0; /* 64b dpte req height in data element */ +- dpte_req_width = 0; /* 64b dpte req width in data element */ +- dpte_group_width = 0; +- log2_dpte_group_bytes = 0; +- log2_dpte_group_length = 0; +- ++ // ------ ++ // dpte ++ // ------ + if (surf_linear) { +- log2_vmpg_height = 0; /* one line high */ ++ log2_vmpg_height = 0; // one line high + } else { + log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height; + } + log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height; + +- /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */ +- if (log2_blk_bytes <= log2_vmpg_bytes) ++ // only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. ++ if (surf_linear) { //one 64B PTE request returns 8 PTEs + log2_dpte_req_height_ptes = 0; +- else if (log2_blk_height - log2_vmpg_height >= 2) +- log2_dpte_req_height_ptes = 2; +- else +- log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height; +- log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes; +- +- /* Ensure we only have the 3 shapes */ +- ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */ +- (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */ +- (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */ +- +- /* The dpte request dimensions in data elements is dpte_req_width x dpte_req_height +- * log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent +- * That depends on the pte shape (i.e. 8x1, 4x2, 2x4) +- */ +- log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes; +- log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes; ++ log2_dpte_req_width = log2_vmpg_width + 3; ++ log2_dpte_req_height = 0; ++ } else if (log2_blk_bytes == 12) { //4KB tile means 4kB page size ++ //one 64B req gives 8x1 PTEs for 4KB tile ++ log2_dpte_req_height_ptes = 0; ++ log2_dpte_req_width = log2_blk_width + 3; ++ log2_dpte_req_height = log2_blk_height + 0; ++ } else if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) { // tile block >= 64KB ++ //two 64B reqs of 2x4 PTEs give 16 PTEs to cover 64KB ++ log2_dpte_req_height_ptes = 4; ++ log2_dpte_req_width = log2_blk256_width + 4; // log2_64KB_width ++ log2_dpte_req_height = log2_blk256_height + 4; // log2_64KB_height ++ } else { //64KB page size and must 64KB tile block ++ //one 64B req gives 8x1 PTEs for 64KB tile ++ log2_dpte_req_height_ptes = 0; ++ log2_dpte_req_width = log2_blk_width + 3; ++ log2_dpte_req_height = log2_blk_height + 0; ++ } ++ ++ // The dpte request dimensions in data elements is dpte_req_width x dpte_req_height ++ // log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent ++ // That depends on the pte shape (i.e. 8x1, 4x2, 2x4) ++ //log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes; ++ //log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes; + dpte_req_height = 1 << log2_dpte_req_height; + dpte_req_width = 1 << log2_dpte_req_width; + +- /* calculate pitch dpte row buffer can hold +- * round the result down to a power of two. +- */ ++ // calculate pitch dpte row buffer can hold ++ // round the result down to a power of two. ++ pde_buf_entries = yuv420 ? (pde_proc_buffer_size_64k_reqs >> 1) : pde_proc_buffer_size_64k_reqs; + if (surf_linear) { +- log2_dpte_row_height_linear = dml_floor( +- dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch)); ++ unsigned int dpte_row_height; ++ ++ log2_dpte_row_height_linear = dml_floor(dml_log2(dml_min(64 * 1024 * pde_buf_entries ++ / bytes_per_element, ++ dpte_buf_in_pte_reqs ++ * dpte_req_width) ++ / data_pitch), ++ 1); + + ASSERT(log2_dpte_row_height_linear >= 3); + +@@ -826,18 +565,16 @@ static void get_surf_rq_param( + log2_dpte_row_height_linear = 7; + + log2_dpte_row_height = log2_dpte_row_height_linear; +- rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; +- +- /* For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary. +- * the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering. +- */ +- dpte_row_width_ub = dml_round_to_multiple( +- data_pitch * dpte_row_height - 1, ++ // For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary. ++ // the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering. ++ dpte_row_height = 1 << log2_dpte_row_height; ++ dpte_row_width_ub = dml_round_to_multiple(data_pitch * dpte_row_height - 1, + dpte_req_width, + 1) + dpte_req_width; + rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width; + } else { +- /* for tiled mode, row height is the same as req height and row store up to vp size upper bound */ ++ // the upper bound of the dpte_row_width without dependency on viewport position follows. ++ // for tiled mode, row height is the same as req height and row store up to vp size upper bound + if (!surf_vert) { + log2_dpte_row_height = log2_dpte_req_height; + dpte_row_width_ub = dml_round_to_multiple(vp_width - 1, dpte_req_width, 1) +@@ -851,103 +588,117 @@ static void get_surf_rq_param( + + dpte_req_height; + rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_height; + } +- rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; +- } +- rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64; +- +- /* From programming guide: +- * There is a special case of saving only half of ptes returned due to buffer space limits. +- * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16 +- * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb). +- */ +- if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12 +- && log2_blk_bytes >= 16) { +- log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */ +- rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; + } ++ if (log2_blk_bytes >= 16 && log2_vmpg_bytes == 12) // tile block >= 64KB ++ rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 128; //2*64B dpte request ++ else ++ rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64; //64B dpte request + +- /* the dpte_group_bytes is reduced for the specific case of vertical +- * access of a tile surface that has dpte request of 8x1 ptes. +- */ +- if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) /*reduced, in this case, will have page fault within a group */ ++ rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; ++ ++ // the dpte_group_bytes is reduced for the specific case of vertical ++ // access of a tile surface that has dpte request of 8x1 ptes. ++ if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) //reduced, in this case, will have page fault within a group + rq_sizing_param->dpte_group_bytes = 512; + else +- /*full size */ ++ //full size + rq_sizing_param->dpte_group_bytes = 2048; + +- /*since pte request size is 64byte, the number of data pte requests per full sized group is as follows. */ ++ //since pte request size is 64byte, the number of data pte requests per full sized group is as follows. + log2_dpte_group_bytes = dml_log2(rq_sizing_param->dpte_group_bytes); +- log2_dpte_group_length = log2_dpte_group_bytes - 6; /*length in 64b requests */ ++ log2_dpte_group_length = log2_dpte_group_bytes - 6; //length in 64b requests + +- /* full sized data pte group width in elements */ ++ // full sized data pte group width in elements + if (!surf_vert) + log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width; + else + log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height; + ++ //But if the tile block >=64KB and the page size is 4KB, then each dPTE request is 2*64B ++ if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) // tile block >= 64KB ++ log2_dpte_group_width = log2_dpte_group_width - 1; ++ + dpte_group_width = 1 << log2_dpte_group_width; + +- /* since dpte groups are only aligned to dpte_req_width and not dpte_group_width, +- * the upper bound for the dpte groups per row is as follows. +- */ +- rq_dlg_param->dpte_groups_per_row_ub = dml_ceil( +- (double) dpte_row_width_ub / dpte_group_width); ++ // since dpte groups are only aligned to dpte_req_width and not dpte_group_width, ++ // the upper bound for the dpte groups per row is as follows. ++ rq_dlg_param->dpte_groups_per_row_ub = dml_ceil((double) dpte_row_width_ub / dpte_group_width, ++ 1); ++} ++ ++static void get_surf_rq_param(struct display_mode_lib *mode_lib, ++ display_data_rq_sizing_params_st *rq_sizing_param, ++ display_data_rq_dlg_params_st *rq_dlg_param, ++ display_data_rq_misc_params_st *rq_misc_param, ++ const display_pipe_source_params_st pipe_src_param, ++ bool is_chroma) ++{ ++ bool mode_422 = 0; ++ unsigned int vp_width = 0; ++ unsigned int vp_height = 0; ++ unsigned int data_pitch = 0; ++ unsigned int meta_pitch = 0; ++ unsigned int ppe = mode_422 ? 2 : 1; ++ ++ // FIXME check if ppe apply for both luma and chroma in 422 case ++ if (is_chroma) { ++ vp_width = pipe_src_param.viewport_width_c / ppe; ++ vp_height = pipe_src_param.viewport_height_c; ++ data_pitch = pipe_src_param.data_pitch_c; ++ meta_pitch = pipe_src_param.meta_pitch_c; ++ } else { ++ vp_width = pipe_src_param.viewport_width / ppe; ++ vp_height = pipe_src_param.viewport_height; ++ data_pitch = pipe_src_param.data_pitch; ++ meta_pitch = pipe_src_param.meta_pitch; ++ } ++ ++ rq_sizing_param->chunk_bytes = 8192; ++ ++ if (rq_sizing_param->chunk_bytes == 64 * 1024) ++ rq_sizing_param->min_chunk_bytes = 0; ++ else ++ rq_sizing_param->min_chunk_bytes = 1024; ++ ++ rq_sizing_param->meta_chunk_bytes = 2048; ++ rq_sizing_param->min_meta_chunk_bytes = 256; ++ ++ rq_sizing_param->mpte_group_bytes = 2048; + +- dml_rq_dlg_get_row_heights( +- mode_lib, +- &func_dpte_row_height, +- &func_meta_row_height, ++ get_meta_and_pte_attr(mode_lib, ++ rq_dlg_param, ++ rq_misc_param, ++ rq_sizing_param, + vp_width, ++ vp_height, + data_pitch, ++ meta_pitch, + pipe_src_param.source_format, + pipe_src_param.sw_mode, + pipe_src_param.macro_tile_size, + pipe_src_param.source_scan, + is_chroma); +- +- /* Just a check to make sure this function and the new one give the same +- * result. The standalone get_row_heights() function is based off of the +- * code in this function so the same changes need to be made to both. +- */ +- if (rq_dlg_param->meta_row_height != func_meta_row_height) { +- DTRACE( +- "MISMATCH: rq_dlg_param->meta_row_height = %d", +- rq_dlg_param->meta_row_height); +- DTRACE("MISMATCH: func_meta_row_height = %d", func_meta_row_height); +- ASSERT(0); +- } +- +- if (rq_dlg_param->dpte_row_height != func_dpte_row_height) { +- DTRACE( +- "MISMATCH: rq_dlg_param->dpte_row_height = %d", +- rq_dlg_param->dpte_row_height); +- DTRACE("MISMATCH: func_dpte_row_height = %d", func_dpte_row_height); +- ASSERT(0); +- } + } + +-void dml_rq_dlg_get_rq_params( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_rq_params_st *rq_param, +- const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param) ++void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, ++ display_rq_params_st *rq_param, ++ const display_pipe_source_params_st pipe_src_param) + { +- /* get param for luma surface */ ++ // get param for luma surface + rq_param->yuv420 = pipe_src_param.source_format == dm_420_8 + || pipe_src_param.source_format == dm_420_10; + rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10; + +- get_surf_rq_param( +- mode_lib, ++ get_surf_rq_param(mode_lib, + &(rq_param->sizing.rq_l), + &(rq_param->dlg.rq_l), + &(rq_param->misc.rq_l), + pipe_src_param, + 0); + +- if (is_dual_plane((enum source_format_class) pipe_src_param.source_format)) { +- /* get param for chroma surface */ +- get_surf_rq_param( +- mode_lib, ++ if (is_dual_plane((enum source_format_class)(pipe_src_param.source_format))) { ++ // get param for chroma surface ++ get_surf_rq_param(mode_lib, + &(rq_param->sizing.rq_c), + &(rq_param->dlg.rq_c), + &(rq_param->misc.rq_c), +@@ -955,355 +706,126 @@ void dml_rq_dlg_get_rq_params( + 1); + } + +- /* calculate how to split the det buffer space between luma and chroma */ ++ // calculate how to split the det buffer space between luma and chroma + handle_det_buf_split(mode_lib, rq_param, pipe_src_param); + print__rq_params_st(mode_lib, *rq_param); + } + +-void dml_rq_dlg_get_rq_reg( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_rq_regs_st *rq_regs, +- const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param) ++void dml_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, ++ display_rq_regs_st *rq_regs, ++ const display_pipe_source_params_st pipe_src_param) + { +- struct _vcs_dpi_display_rq_params_st rq_param = {0}; ++ display_rq_params_st rq_param = {0}; + + memset(rq_regs, 0, sizeof(*rq_regs)); +- + dml_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_src_param); + extract_rq_regs(mode_lib, rq_regs, rq_param); + + print__rq_regs_st(mode_lib, *rq_regs); + } + +-/* TODO: Need refactor, so this is used by dml_rq_dlg_get_dlg_params as well +- * The problem is that there are some intermediate terms that would need by +- * some dlg calculation (i.e. rest of prefetch and active prog guide calculation) +- */ +-void dml_rq_dlg_get_dlg_params_prefetch( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_dlg_prefetch_param_st *prefetch_param, +- struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, +- struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, +- struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, ++// Note: currently taken in as is. ++// Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma. ++void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, ++ const display_e2e_pipe_params_st *e2e_pipe_param, ++ const unsigned int num_pipes, ++ const unsigned int pipe_idx, ++ display_dlg_regs_st *disp_dlg_regs, ++ display_ttu_regs_st *disp_ttu_regs, ++ const display_rq_dlg_params_st rq_dlg_param, ++ const display_dlg_sys_params_st dlg_sys_param, + const bool cstate_en, + const bool pstate_en, +- const bool vm_en) ++ const bool vm_en, ++ const bool ignore_viewport_pos, ++ const bool immediate_flip_support) + { +- /* Prefetch */ +- unsigned int htotal = e2e_pipe_param.pipe.dest.htotal; +- bool interlaced = e2e_pipe_param.pipe.dest.interlaced; ++ const display_pipe_source_params_st *src = &e2e_pipe_param[pipe_idx].pipe.src; ++ const display_pipe_dest_params_st *dst = &e2e_pipe_param[pipe_idx].pipe.dest; ++ const display_output_params_st *dout = &e2e_pipe_param[pipe_idx].dout; ++ const display_clocks_and_cfg_st *clks = &e2e_pipe_param[pipe_idx].clks_cfg; ++ const scaler_ratio_depth_st *scl = &e2e_pipe_param[pipe_idx].pipe.scale_ratio_depth; ++ const scaler_taps_st *taps = &e2e_pipe_param[pipe_idx].pipe.scale_taps; ++ ++ // ------------------------- ++ // Section 1.15.2.1: OTG dependent Params ++ // ------------------------- ++ // Timing ++ unsigned int htotal = dst->htotal; ++// unsigned int hblank_start = dst.hblank_start; // TODO: Remove ++ unsigned int hblank_end = dst->hblank_end; ++ unsigned int vblank_start = dst->vblank_start; ++ unsigned int vblank_end = dst->vblank_end; + unsigned int min_vblank = mode_lib->ip.min_vblank_lines; +- const double prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */ +- double min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz; +- double t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz; +- +- bool dcc_en = e2e_pipe_param.pipe.src.dcc; +- bool dual_plane = is_dual_plane( +- (enum source_format_class) e2e_pipe_param.pipe.src.source_format); +- unsigned int bytes_per_element_l = get_bytes_per_element( +- (enum source_format_class) e2e_pipe_param.pipe.src.source_format, +- 0); +- unsigned int bytes_per_element_c = get_bytes_per_element( +- (enum source_format_class) e2e_pipe_param.pipe.src.source_format, +- 1); +- +- double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz; +- double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz; +- double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz; +- +- double line_time_in_us = (htotal / pclk_freq_in_mhz); +- double vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit; +- double vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c; +- double vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot; +- double vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c; +- +- unsigned int swath_height_l = rq_dlg_param.rq_l.swath_height; +- unsigned int swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub; +- unsigned int dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub; +- unsigned int meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub; +- unsigned int meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub; +- +- unsigned int swath_height_c = rq_dlg_param.rq_c.swath_height; +- unsigned int swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub; +- unsigned int dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub; +- unsigned int vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset; +- unsigned int vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width; +- unsigned int vready_offset = e2e_pipe_param.pipe.dest.vready_offset; +- +- const unsigned int dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal; +- const unsigned int dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal; +- unsigned int pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz +- / dppclk_freq_in_mhz +- + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz; +- unsigned int dst_y_after_scaler = 0; +- unsigned int dst_x_after_scaler = 0; + +- unsigned int vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start; ++ double dppclk_freq_in_mhz = clks->dppclk_mhz; ++ double dispclk_freq_in_mhz = clks->dispclk_mhz; ++ double refclk_freq_in_mhz = clks->refclk_mhz; ++ double pclk_freq_in_mhz = dst->pixel_rate_mhz; ++ bool interlaced = dst->interlaced; + +- double line_wait; +- double line_o; +- double line_setup; +- double line_calc; +- double dst_y_prefetch; +- double t_pre_us; +- int unsigned vm_bytes; +- int unsigned meta_row_bytes; +- int unsigned max_num_sw_l; +- int unsigned max_num_sw_c; +- int unsigned max_partial_sw_l; +- int unsigned max_partial_sw_c; +- +- double max_vinit_l; +- double max_vinit_c; +- int unsigned lsw_l; +- int unsigned lsw_c; +- int unsigned sw_bytes_ub_l; +- int unsigned sw_bytes_ub_c; +- int unsigned sw_bytes; +- int unsigned dpte_row_bytes; ++ double ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz; + +- if (interlaced) +- vstartup_start = vstartup_start / 2; ++ double min_dcfclk_mhz; ++ double t_calc_us; ++ double min_ttu_vblank; + +- if (vstartup_start >= min_vblank) { +- min_vblank = vstartup_start + 1; +- DTRACE( +- "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d", +- __func__, +- vstartup_start, +- min_vblank); +- } ++ double min_dst_y_ttu_vblank; ++ unsigned int dlg_vblank_start; ++ bool dual_plane; ++ bool mode_422; ++ unsigned int access_dir; ++ unsigned int vp_height_l; ++ unsigned int vp_width_l; ++ unsigned int vp_height_c; ++ unsigned int vp_width_c; + +- if (e2e_pipe_param.pipe.src.is_hsplit) +- dst_x_after_scaler = pixel_rate_delay_subtotal +- + e2e_pipe_param.pipe.dest.recout_width; +- else +- dst_x_after_scaler = pixel_rate_delay_subtotal; ++ // Scaling ++ unsigned int htaps_l; ++ unsigned int htaps_c; ++ double hratio_l; ++ double hratio_c; ++ double vratio_l; ++ double vratio_c; ++ bool scl_enable; + +- if (e2e_pipe_param.dout.output_format == dm_420) +- dst_y_after_scaler = 1; +- else +- dst_y_after_scaler = 0; ++ double line_time_in_us; ++ // double vinit_l; ++ // double vinit_c; ++ // double vinit_bot_l; ++ // double vinit_bot_c; + +- if (dst_x_after_scaler >= htotal) { +- dst_x_after_scaler = dst_x_after_scaler - htotal; +- dst_y_after_scaler = dst_y_after_scaler + 1; +- } +- +- DTRACE("DLG: %s: htotal = %d", __func__, htotal); +- DTRACE( +- "DLG: %s: pixel_rate_delay_subtotal = %d", +- __func__, +- pixel_rate_delay_subtotal); +- DTRACE("DLG: %s: dst_x_after_scaler = %d", __func__, dst_x_after_scaler); +- DTRACE("DLG: %s: dst_y_after_scaler = %d", __func__, dst_y_after_scaler); +- +- line_wait = mode_lib->soc.urgent_latency_us; +- if (cstate_en) +- line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait); +- if (pstate_en) +- line_wait = dml_max( +- mode_lib->soc.dram_clock_change_latency_us +- + mode_lib->soc.urgent_latency_us, +- line_wait); +- line_wait = line_wait / line_time_in_us; +- +- line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal; +- line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal; +- line_calc = t_calc_us / line_time_in_us; +- +- DTRACE( +- "DLG: %s: soc.sr_enter_plus_exit_time_us = %3.2f", +- __func__, +- (double) mode_lib->soc.sr_enter_plus_exit_time_us); +- DTRACE( +- "DLG: %s: soc.dram_clock_change_latency_us = %3.2f", +- __func__, +- (double) mode_lib->soc.dram_clock_change_latency_us); +- +- DTRACE("DLG: %s: urgent_latency_us = %3.2f", __func__, mode_lib->soc.urgent_latency_us); +- DTRACE( +- "DLG: %s: t_srx_delay_us = %3.2f", +- __func__, +- (double) dlg_sys_param.t_srx_delay_us); +- DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us); +- DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset); +- DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width); +- DTRACE("DLG: %s: vready_offset = %d", __func__, vready_offset); +- DTRACE("DLG: %s: line_wait = %3.2f", __func__, line_wait); +- DTRACE("DLG: %s: line_o = %3.2f", __func__, line_o); +- DTRACE("DLG: %s: line_setup = %3.2f", __func__, line_setup); +- DTRACE("DLG: %s: line_calc = %3.2f", __func__, line_calc); +- +- dst_y_prefetch = ((double) min_vblank - 1.0) +- - (line_setup + line_calc + line_wait + line_o); +- DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch); +- ASSERT(dst_y_prefetch >= 2.0); +- +- dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125)) / 4; +- DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch); +- +- t_pre_us = dst_y_prefetch * line_time_in_us; +- vm_bytes = 0; +- meta_row_bytes = 0; +- +- if (dcc_en && vm_en) +- vm_bytes = meta_pte_bytes_per_frame_ub_l; +- if (dcc_en) +- meta_row_bytes = meta_bytes_per_row_ub_l; +- +- max_num_sw_l = 0; +- max_num_sw_c = 0; +- max_partial_sw_l = 0; +- max_partial_sw_c = 0; +- +- max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l; +- max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c; +- +- get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l); +- if (dual_plane) +- get_swath_need( +- mode_lib, +- &max_num_sw_c, +- &max_partial_sw_c, +- swath_height_c, +- max_vinit_c); +- +- lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l; +- lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c; +- sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l; +- sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c; +- sw_bytes = 0; +- dpte_row_bytes = 0; +- +- if (vm_en) { +- if (dual_plane) +- dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c; +- else +- dpte_row_bytes = dpte_bytes_per_row_ub_l; +- } else { +- dpte_row_bytes = 0; +- } +- +- if (dual_plane) +- sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c; +- else +- sw_bytes = sw_bytes_ub_l; +- +- DTRACE("DLG: %s: sw_bytes_ub_l = %d", __func__, sw_bytes_ub_l); +- DTRACE("DLG: %s: sw_bytes_ub_c = %d", __func__, sw_bytes_ub_c); +- DTRACE("DLG: %s: sw_bytes = %d", __func__, sw_bytes); +- DTRACE("DLG: %s: vm_bytes = %d", __func__, vm_bytes); +- DTRACE("DLG: %s: meta_row_bytes = %d", __func__, meta_row_bytes); +- DTRACE("DLG: %s: dpte_row_bytes = %d", __func__, dpte_row_bytes); +- +- prefetch_param->prefetch_bw = +- (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us; +- prefetch_param->flip_bytes = (vm_bytes + dpte_row_bytes + meta_row_bytes); +-} +- +-/* Note: currently taken in as is. +- * Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma. +- */ +-void dml_rq_dlg_get_dlg_params( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_dlg_regs_st *disp_dlg_regs, +- struct _vcs_dpi_display_ttu_regs_st *disp_ttu_regs, +- const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, +- const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, +- const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, +- const bool cstate_en, +- const bool pstate_en, +- const bool vm_en, +- const bool iflip_en) +-{ +- /* Timing */ +- unsigned int htotal = e2e_pipe_param.pipe.dest.htotal; +- unsigned int hblank_end = e2e_pipe_param.pipe.dest.hblank_end; +- unsigned int vblank_start = e2e_pipe_param.pipe.dest.vblank_start; +- unsigned int vblank_end = e2e_pipe_param.pipe.dest.vblank_end; +- bool interlaced = e2e_pipe_param.pipe.dest.interlaced; +- unsigned int min_vblank = mode_lib->ip.min_vblank_lines; +- +- double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz; +- double refclk_freq_in_mhz = e2e_pipe_param.clks_cfg.refclk_mhz; +- double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz; +- double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz; +- +- double ref_freq_to_pix_freq; +- double prefetch_xy_calc_in_dcfclk; +- double min_dcfclk_mhz; +- double t_calc_us; +- double min_ttu_vblank; +- double min_dst_y_ttu_vblank; +- int unsigned dlg_vblank_start; +- bool dcc_en; +- bool dual_plane; +- bool mode_422; +- unsigned int access_dir; +- unsigned int bytes_per_element_l; +- unsigned int bytes_per_element_c; +- unsigned int vp_height_l; +- unsigned int vp_width_l; +- unsigned int vp_height_c; +- unsigned int vp_width_c; +- unsigned int htaps_l; +- unsigned int htaps_c; +- double hratios_l; +- double hratios_c; +- double vratio_l; +- double vratio_c; +- double line_time_in_us; +- double vinit_l; +- double vinit_c; +- double vinit_bot_l; +- double vinit_bot_c; +- unsigned int swath_height_l; ++ // unsigned int swath_height_l; + unsigned int swath_width_ub_l; +- unsigned int dpte_bytes_per_row_ub_l; ++ // unsigned int dpte_bytes_per_row_ub_l; + unsigned int dpte_groups_per_row_ub_l; +- unsigned int meta_pte_bytes_per_frame_ub_l; +- unsigned int meta_bytes_per_row_ub_l; +- unsigned int swath_height_c; ++ // unsigned int meta_pte_bytes_per_frame_ub_l; ++ // unsigned int meta_bytes_per_row_ub_l; ++ ++ // unsigned int swath_height_c; + unsigned int swath_width_ub_c; +- unsigned int dpte_bytes_per_row_ub_c; ++ // unsigned int dpte_bytes_per_row_ub_c; + unsigned int dpte_groups_per_row_ub_c; ++ + unsigned int meta_chunks_per_row_ub_l; ++ unsigned int meta_chunks_per_row_ub_c; + unsigned int vupdate_offset; + unsigned int vupdate_width; + unsigned int vready_offset; ++ + unsigned int dppclk_delay_subtotal; + unsigned int dispclk_delay_subtotal; + unsigned int pixel_rate_delay_subtotal; ++ + unsigned int vstartup_start; + unsigned int dst_x_after_scaler; + unsigned int dst_y_after_scaler; + double line_wait; +- double line_o; +- double line_setup; +- double line_calc; + double dst_y_prefetch; +- double t_pre_us; +- int unsigned vm_bytes; +- int unsigned meta_row_bytes; +- int unsigned max_num_sw_l; +- int unsigned max_num_sw_c; +- int unsigned max_partial_sw_l; +- int unsigned max_partial_sw_c; +- double max_vinit_l; +- double max_vinit_c; +- int unsigned lsw_l; +- int unsigned lsw_c; +- int unsigned sw_bytes_ub_l; +- int unsigned sw_bytes_ub_c; +- int unsigned sw_bytes; +- int unsigned dpte_row_bytes; +- double prefetch_bw; +- double flip_bw; +- double t_vm_us; +- double t_r0_us; + double dst_y_per_vm_vblank; + double dst_y_per_row_vblank; ++ double dst_y_per_vm_flip; ++ double dst_y_per_row_flip; + double min_dst_y_per_vm_vblank; + double min_dst_y_per_row_vblank; + double lsw; +@@ -1312,6 +834,7 @@ void dml_rq_dlg_get_dlg_params( + unsigned int req_per_swath_ub_l; + unsigned int req_per_swath_ub_c; + unsigned int meta_row_height_l; ++ unsigned int meta_row_height_c; + unsigned int swath_width_pixels_ub_l; + unsigned int swath_width_pixels_ub_c; + unsigned int scaler_rec_in_width_l; +@@ -1326,59 +849,52 @@ void dml_rq_dlg_get_dlg_params( + double refcyc_per_line_delivery_pre_c; + double refcyc_per_line_delivery_l; + double refcyc_per_line_delivery_c; ++ + double refcyc_per_req_delivery_pre_l; + double refcyc_per_req_delivery_pre_c; + double refcyc_per_req_delivery_l; + double refcyc_per_req_delivery_c; ++ ++ unsigned int full_recout_width; ++ double xfc_transfer_delay; ++ double xfc_precharge_delay; ++ double xfc_remote_surface_flip_latency; ++ double xfc_dst_y_delta_drq_limit; ++ double xfc_prefetch_margin; + double refcyc_per_req_delivery_pre_cur0; + double refcyc_per_req_delivery_cur0; +- int unsigned full_recout_width; +- double hratios_cur0; +- unsigned int cur0_src_width; +- enum cursor_bpp cur0_bpp; +- unsigned int cur0_req_size; +- unsigned int cur0_req_width; +- double cur0_width_ub; +- double cur0_req_per_width; +- double hactive_cur0; ++ double refcyc_per_req_delivery_pre_cur1; ++ double refcyc_per_req_delivery_cur1; + + memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs)); + memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs)); + +- DTRACE("DLG: %s: cstate_en = %d", __func__, cstate_en); +- DTRACE("DLG: %s: pstate_en = %d", __func__, pstate_en); +- DTRACE("DLG: %s: vm_en = %d", __func__, vm_en); +- DTRACE("DLG: %s: iflip_en = %d", __func__, iflip_en); +- +- /* ------------------------- */ +- /* Section 1.5.2.1: OTG dependent Params */ +- /* ------------------------- */ +- DTRACE("DLG: %s: dppclk_freq_in_mhz = %3.2f", __func__, dppclk_freq_in_mhz); +- DTRACE("DLG: %s: dispclk_freq_in_mhz = %3.2f", __func__, dispclk_freq_in_mhz); +- DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz); +- DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz); +- DTRACE("DLG: %s: interlaced = %d", __func__, interlaced); +- +- ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz; ++ dml_print("DML_DLG: %s: cstate_en = %d\n", __func__, cstate_en); ++ dml_print("DML_DLG: %s: pstate_en = %d\n", __func__, pstate_en); ++ dml_print("DML_DLG: %s: vm_en = %d\n", __func__, vm_en); ++ dml_print("DML_DLG: %s: ignore_viewport_pos = %d\n", __func__, ignore_viewport_pos); ++ dml_print("DML_DLG: %s: immediate_flip_support = %d\n", __func__, immediate_flip_support); ++ ++ dml_print("DML_DLG: %s: dppclk_freq_in_mhz = %3.2f\n", __func__, dppclk_freq_in_mhz); ++ dml_print("DML_DLG: %s: dispclk_freq_in_mhz = %3.2f\n", __func__, dispclk_freq_in_mhz); ++ dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz); ++ dml_print("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, pclk_freq_in_mhz); ++ dml_print("DML_DLG: %s: interlaced = %d\n", __func__, interlaced); + ASSERT(ref_freq_to_pix_freq < 4.0); ++ + disp_dlg_regs->ref_freq_to_pix_freq = + (unsigned int) (ref_freq_to_pix_freq * dml_pow(2, 19)); + disp_dlg_regs->refcyc_per_htotal = (unsigned int) (ref_freq_to_pix_freq * (double) htotal + * dml_pow(2, 8)); ++ disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; // 15 bits + disp_dlg_regs->refcyc_h_blank_end = (unsigned int) ((double) hblank_end + * (double) ref_freq_to_pix_freq); + ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int) dml_pow(2, 13)); +- disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; /* 15 bits */ + +- prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */ + min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz; +- t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz; +- min_ttu_vblank = dlg_sys_param.t_urg_wm_us; +- if (cstate_en) +- min_ttu_vblank = dml_max(dlg_sys_param.t_sr_wm_us, min_ttu_vblank); +- if (pstate_en) +- min_ttu_vblank = dml_max(dlg_sys_param.t_mclk_wm_us, min_ttu_vblank); +- min_ttu_vblank = min_ttu_vblank + t_calc_us; ++ set_prefetch_mode(mode_lib, cstate_en, pstate_en, ignore_viewport_pos, immediate_flip_support); ++ t_calc_us = get_tcalc(mode_lib, e2e_pipe_param, num_pipes); ++ min_ttu_vblank = get_min_ttu_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); + + min_dst_y_ttu_vblank = min_ttu_vblank * pclk_freq_in_mhz / (double) htotal; + dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start; +@@ -1387,383 +903,202 @@ void dml_rq_dlg_get_dlg_params( + + min_dst_y_ttu_vblank) * dml_pow(2, 2)); + ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int) dml_pow(2, 18)); + +- DTRACE("DLG: %s: min_dcfclk_mhz = %3.2f", __func__, min_dcfclk_mhz); +- DTRACE("DLG: %s: min_ttu_vblank = %3.2f", __func__, min_ttu_vblank); +- DTRACE( +- "DLG: %s: min_dst_y_ttu_vblank = %3.2f", ++ dml_print("DML_DLG: %s: min_dcfclk_mhz = %3.2f\n", ++ __func__, ++ min_dcfclk_mhz); ++ dml_print("DML_DLG: %s: min_ttu_vblank = %3.2f\n", ++ __func__, ++ min_ttu_vblank); ++ dml_print("DML_DLG: %s: min_dst_y_ttu_vblank = %3.2f\n", + __func__, + min_dst_y_ttu_vblank); +- DTRACE("DLG: %s: t_calc_us = %3.2f", __func__, t_calc_us); +- DTRACE( +- "DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x", ++ dml_print("DML_DLG: %s: t_calc_us = %3.2f\n", ++ __func__, ++ t_calc_us); ++ dml_print("DML_DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x\n", + __func__, + disp_dlg_regs->min_dst_y_next_start); +- DTRACE( +- "DLG: %s: ref_freq_to_pix_freq = %3.2f", ++ dml_print("DML_DLG: %s: ref_freq_to_pix_freq = %3.2f\n", + __func__, + ref_freq_to_pix_freq); + +- /* ------------------------- */ +- /* Section 1.5.2.2: Prefetch, Active and TTU */ +- /* ------------------------- */ +- /* Prefetch Calc */ +- /* Source */ +- dcc_en = e2e_pipe_param.pipe.src.dcc; +- dual_plane = is_dual_plane( +- (enum source_format_class) e2e_pipe_param.pipe.src.source_format); +- mode_422 = 0; /* FIXME */ +- access_dir = (e2e_pipe_param.pipe.src.source_scan == dm_vert); /* vp access direction: horizontal or vertical accessed */ +- bytes_per_element_l = get_bytes_per_element( +- (enum source_format_class) e2e_pipe_param.pipe.src.source_format, +- 0); +- bytes_per_element_c = get_bytes_per_element( +- (enum source_format_class) e2e_pipe_param.pipe.src.source_format, +- 1); +- vp_height_l = e2e_pipe_param.pipe.src.viewport_height; +- vp_width_l = e2e_pipe_param.pipe.src.viewport_width; +- vp_height_c = e2e_pipe_param.pipe.src.viewport_height_c; +- vp_width_c = e2e_pipe_param.pipe.src.viewport_width_c; +- +- /* Scaling */ +- htaps_l = e2e_pipe_param.pipe.scale_taps.htaps; +- htaps_c = e2e_pipe_param.pipe.scale_taps.htaps_c; +- hratios_l = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio; +- hratios_c = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio_c; +- vratio_l = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio; +- vratio_c = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio_c; ++ // ------------------------- ++ // Section 1.15.2.2: Prefetch, Active and TTU ++ // ------------------------- ++ // Prefetch Calc ++ // Source ++// dcc_en = src.dcc; ++ dual_plane = is_dual_plane((enum source_format_class)(src->source_format)); ++ mode_422 = 0; // FIXME ++ access_dir = (src->source_scan == dm_vert); // vp access direction: horizontal or vertical accessed ++// bytes_per_element_l = get_bytes_per_element(source_format_class(src.source_format), 0); ++// bytes_per_element_c = get_bytes_per_element(source_format_class(src.source_format), 1); ++ vp_height_l = src->viewport_height; ++ vp_width_l = src->viewport_width; ++ vp_height_c = src->viewport_height_c; ++ vp_width_c = src->viewport_width_c; ++ ++ // Scaling ++ htaps_l = taps->htaps; ++ htaps_c = taps->htaps_c; ++ hratio_l = scl->hscl_ratio; ++ hratio_c = scl->hscl_ratio_c; ++ vratio_l = scl->vscl_ratio; ++ vratio_c = scl->vscl_ratio_c; ++ scl_enable = scl->scl_enable; + + line_time_in_us = (htotal / pclk_freq_in_mhz); +- vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit; +- vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c; +- vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot; +- vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c; ++// vinit_l = scl.vinit; ++// vinit_c = scl.vinit_c; ++// vinit_bot_l = scl.vinit_bot; ++// vinit_bot_c = scl.vinit_bot_c; + +- swath_height_l = rq_dlg_param.rq_l.swath_height; ++// unsigned int swath_height_l = rq_dlg_param.rq_l.swath_height; + swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub; +- dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub; ++// unsigned int dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub; + dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub; +- meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub; +- meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub; ++// unsigned int meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub; ++// unsigned int meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub; + +- swath_height_c = rq_dlg_param.rq_c.swath_height; ++// unsigned int swath_height_c = rq_dlg_param.rq_c.swath_height; + swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub; +- dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub; ++ // dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub; + dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub; + + meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub; +- vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset; +- vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width; +- vready_offset = e2e_pipe_param.pipe.dest.vready_offset; ++ meta_chunks_per_row_ub_c = rq_dlg_param.rq_c.meta_chunks_per_row_ub; ++ vupdate_offset = dst->vupdate_offset; ++ vupdate_width = dst->vupdate_width; ++ vready_offset = dst->vready_offset; + + dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal; + dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal; ++ ++ if (scl_enable) ++ dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl; ++ else ++ dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl_lb_only; ++ ++ dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_cnvc_formatter ++ + src->num_cursors * mode_lib->ip.dppclk_delay_cnvc_cursor; ++ ++ if (dout->dsc_enable) { ++ double dsc_delay = get_dsc_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); ++ ++ dispclk_delay_subtotal += dsc_delay; ++ } ++ + pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz + + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz; + +- vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start; ++ vstartup_start = dst->vstartup_start; ++ if (interlaced) { ++ if (vstartup_start / 2.0 ++ - (double) (vready_offset + vupdate_width + vupdate_offset) / htotal ++ <= vblank_end / 2.0) ++ disp_dlg_regs->vready_after_vcount0 = 1; ++ else ++ disp_dlg_regs->vready_after_vcount0 = 0; ++ } else { ++ if (vstartup_start ++ - (double) (vready_offset + vupdate_width + vupdate_offset) / htotal ++ <= vblank_end) ++ disp_dlg_regs->vready_after_vcount0 = 1; ++ else ++ disp_dlg_regs->vready_after_vcount0 = 0; ++ } + ++ // TODO: Where is this coming from? + if (interlaced) + vstartup_start = vstartup_start / 2; + ++ // TODO: What if this min_vblank doesn't match the value in the dml_config_settings.cpp? + if (vstartup_start >= min_vblank) { +- DTRACE( +- "WARNING_DLG: %s: vblank_start=%d vblank_end=%d", ++ dml_print("WARNING: DML_DLG: %s: vblank_start=%d vblank_end=%d\n", + __func__, + vblank_start, + vblank_end); +- DTRACE( +- "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d", ++ dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n", + __func__, + vstartup_start, + min_vblank); + min_vblank = vstartup_start + 1; +- DTRACE( +- "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d", ++ dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n", + __func__, + vstartup_start, + min_vblank); + } + +- dst_x_after_scaler = 0; +- dst_y_after_scaler = 0; +- +- if (e2e_pipe_param.pipe.src.is_hsplit) +- dst_x_after_scaler = pixel_rate_delay_subtotal +- + e2e_pipe_param.pipe.dest.recout_width; +- else +- dst_x_after_scaler = pixel_rate_delay_subtotal; +- +- if (e2e_pipe_param.dout.output_format == dm_420) +- dst_y_after_scaler = 1; +- else +- dst_y_after_scaler = 0; +- +- if (dst_x_after_scaler >= htotal) { +- dst_x_after_scaler = dst_x_after_scaler - htotal; +- dst_y_after_scaler = dst_y_after_scaler + 1; +- } ++ dst_x_after_scaler = get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); ++ dst_y_after_scaler = get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); + +- DTRACE("DLG: %s: htotal = %d", __func__, htotal); +- DTRACE( +- "DLG: %s: pixel_rate_delay_subtotal = %d", ++ dml_print("DML_DLG: %s: htotal = %d\n", __func__, htotal); ++ dml_print("DML_DLG: %s: pixel_rate_delay_subtotal = %d\n", + __func__, + pixel_rate_delay_subtotal); +- DTRACE("DLG: %s: dst_x_after_scaler = %d", __func__, dst_x_after_scaler); +- DTRACE("DLG: %s: dst_y_after_scaler = %d", __func__, dst_y_after_scaler); ++ dml_print("DML_DLG: %s: dst_x_after_scaler = %d\n", ++ __func__, ++ dst_x_after_scaler); ++ dml_print("DML_DLG: %s: dst_y_after_scaler = %d\n", ++ __func__, ++ dst_y_after_scaler); + ++ // Lwait + line_wait = mode_lib->soc.urgent_latency_us; + if (cstate_en) + line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait); + if (pstate_en) +- line_wait = dml_max( +- mode_lib->soc.dram_clock_change_latency_us ++ line_wait = dml_max(mode_lib->soc.dram_clock_change_latency_us + + mode_lib->soc.urgent_latency_us, + line_wait); + line_wait = line_wait / line_time_in_us; + +- line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal; +- line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal; +- line_calc = t_calc_us / line_time_in_us; ++ dst_y_prefetch = get_dst_y_prefetch(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); ++ dml_print("DML_DLG: %s: dst_y_prefetch (after rnd) = %3.2f\n", __func__, dst_y_prefetch); + +- DTRACE( +- "DLG: %s: soc.sr_enter_plus_exit_time_us = %3.2f", +- __func__, +- (double) mode_lib->soc.sr_enter_plus_exit_time_us); +- DTRACE( +- "DLG: %s: soc.dram_clock_change_latency_us = %3.2f", +- __func__, +- (double) mode_lib->soc.dram_clock_change_latency_us); +- DTRACE( +- "DLG: %s: soc.urgent_latency_us = %3.2f", +- __func__, +- mode_lib->soc.urgent_latency_us); +- +- DTRACE("DLG: %s: swath_height_l = %d", __func__, swath_height_l); +- if (dual_plane) +- DTRACE("DLG: %s: swath_height_c = %d", __func__, swath_height_c); +- +- DTRACE( +- "DLG: %s: t_srx_delay_us = %3.2f", +- __func__, +- (double) dlg_sys_param.t_srx_delay_us); +- DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us); +- DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset); +- DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width); +- DTRACE("DLG: %s: vready_offset = %d", __func__, vready_offset); +- DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, line_time_in_us); +- DTRACE("DLG: %s: line_wait = %3.2f", __func__, line_wait); +- DTRACE("DLG: %s: line_o = %3.2f", __func__, line_o); +- DTRACE("DLG: %s: line_setup = %3.2f", __func__, line_setup); +- DTRACE("DLG: %s: line_calc = %3.2f", __func__, line_calc); +- +- dst_y_prefetch = ((double) min_vblank - 1.0) +- - (line_setup + line_calc + line_wait + line_o); +- DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch); +- ASSERT(dst_y_prefetch >= 2.0); +- +- dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125)) / 4; +- DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch); +- +- t_pre_us = dst_y_prefetch * line_time_in_us; +- vm_bytes = 0; +- meta_row_bytes = 0; +- +- if (dcc_en && vm_en) +- vm_bytes = meta_pte_bytes_per_frame_ub_l; +- if (dcc_en) +- meta_row_bytes = meta_bytes_per_row_ub_l; +- +- max_num_sw_l = 0; +- max_num_sw_c = 0; +- max_partial_sw_l = 0; +- max_partial_sw_c = 0; +- +- max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l; +- max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c; +- +- get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l); +- if (dual_plane) +- get_swath_need( +- mode_lib, +- &max_num_sw_c, +- &max_partial_sw_c, +- swath_height_c, +- max_vinit_c); +- +- lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l; +- lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c; +- sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l; +- sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c; +- sw_bytes = 0; +- dpte_row_bytes = 0; +- +- if (vm_en) { +- if (dual_plane) +- dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c; +- else +- dpte_row_bytes = dpte_bytes_per_row_ub_l; +- } else { +- dpte_row_bytes = 0; +- } +- +- if (dual_plane) +- sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c; +- else +- sw_bytes = sw_bytes_ub_l; +- +- DTRACE("DLG: %s: sw_bytes_ub_l = %d", __func__, sw_bytes_ub_l); +- DTRACE("DLG: %s: sw_bytes_ub_c = %d", __func__, sw_bytes_ub_c); +- DTRACE("DLG: %s: sw_bytes = %d", __func__, sw_bytes); +- DTRACE("DLG: %s: vm_bytes = %d", __func__, vm_bytes); +- DTRACE("DLG: %s: meta_row_bytes = %d", __func__, meta_row_bytes); +- DTRACE("DLG: %s: dpte_row_bytes = %d", __func__, dpte_row_bytes); +- +- prefetch_bw = (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us; +- flip_bw = ((vm_bytes + dpte_row_bytes + meta_row_bytes) * dlg_sys_param.total_flip_bw) +- / (double) dlg_sys_param.total_flip_bytes; +- t_vm_us = line_time_in_us / 4.0; +- if (vm_en && dcc_en) { +- t_vm_us = dml_max( +- dlg_sys_param.t_extra_us, +- dml_max((double) vm_bytes / prefetch_bw, t_vm_us)); +- +- if (iflip_en && !dual_plane) { +- t_vm_us = dml_max(mode_lib->soc.urgent_latency_us, t_vm_us); +- if (flip_bw > 0.) +- t_vm_us = dml_max(vm_bytes / flip_bw, t_vm_us); +- } +- } +- +- t_r0_us = dml_max(dlg_sys_param.t_extra_us - t_vm_us, line_time_in_us - t_vm_us); +- +- if (vm_en || dcc_en) { +- t_r0_us = dml_max( +- (double) (dpte_row_bytes + meta_row_bytes) / prefetch_bw, +- dlg_sys_param.t_extra_us); +- t_r0_us = dml_max((double) (line_time_in_us - t_vm_us), t_r0_us); +- +- if (iflip_en && !dual_plane) { +- t_r0_us = dml_max(mode_lib->soc.urgent_latency_us * 2.0, t_r0_us); +- if (flip_bw > 0.) +- t_r0_us = dml_max( +- (dpte_row_bytes + meta_row_bytes) / flip_bw, +- t_r0_us); +- } +- } +- +- disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; /* in terms of line */ +- disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; /* in terms of refclk */ +- ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13)); +- DTRACE( +- "DLG: %s: disp_dlg_regs->dst_y_after_scaler = 0x%0x", +- __func__, +- disp_dlg_regs->dst_y_after_scaler); +- DTRACE( +- "DLG: %s: disp_dlg_regs->refcyc_x_after_scaler = 0x%0x", +- __func__, +- disp_dlg_regs->refcyc_x_after_scaler); +- +- disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2)); +- DTRACE( +- "DLG: %s: disp_dlg_regs->dst_y_prefetch = %d", +- __func__, +- disp_dlg_regs->dst_y_prefetch); +- +- dst_y_per_vm_vblank = 0.0; +- dst_y_per_row_vblank = 0.0; +- +- dst_y_per_vm_vblank = t_vm_us / line_time_in_us; +- dst_y_per_vm_vblank = dml_floor(4.0 * (dst_y_per_vm_vblank + 0.125)) / 4.0; +- disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2)); +- +- dst_y_per_row_vblank = t_r0_us / line_time_in_us; +- dst_y_per_row_vblank = dml_floor(4.0 * (dst_y_per_row_vblank + 0.125)) / 4.0; +- disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2)); +- +- DTRACE("DLG: %s: lsw_l = %d", __func__, lsw_l); +- DTRACE("DLG: %s: lsw_c = %d", __func__, lsw_c); +- DTRACE("DLG: %s: dpte_bytes_per_row_ub_l = %d", __func__, dpte_bytes_per_row_ub_l); +- DTRACE("DLG: %s: dpte_bytes_per_row_ub_c = %d", __func__, dpte_bytes_per_row_ub_c); +- +- DTRACE("DLG: %s: prefetch_bw = %3.2f", __func__, prefetch_bw); +- DTRACE("DLG: %s: flip_bw = %3.2f", __func__, flip_bw); +- DTRACE("DLG: %s: t_pre_us = %3.2f", __func__, t_pre_us); +- DTRACE("DLG: %s: t_vm_us = %3.2f", __func__, t_vm_us); +- DTRACE("DLG: %s: t_r0_us = %3.2f", __func__, t_r0_us); +- DTRACE("DLG: %s: dst_y_per_vm_vblank = %3.2f", __func__, dst_y_per_vm_vblank); +- DTRACE("DLG: %s: dst_y_per_row_vblank = %3.2f", __func__, dst_y_per_row_vblank); +- DTRACE("DLG: %s: dst_y_prefetch = %3.2f", __func__, dst_y_prefetch); ++ dst_y_per_vm_vblank = get_dst_y_per_vm_vblank(mode_lib, ++ e2e_pipe_param, ++ num_pipes, ++ pipe_idx); ++ dst_y_per_row_vblank = get_dst_y_per_row_vblank(mode_lib, ++ e2e_pipe_param, ++ num_pipes, ++ pipe_idx); ++ dst_y_per_vm_flip = get_dst_y_per_vm_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); ++ dst_y_per_row_flip = get_dst_y_per_row_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); + + min_dst_y_per_vm_vblank = 8.0; + min_dst_y_per_row_vblank = 16.0; ++ ++ // magic! + if (htotal <= 75) { + min_vblank = 300; + min_dst_y_per_vm_vblank = 100.0; + min_dst_y_per_row_vblank = 100.0; + } + ++ dml_print("DML_DLG: %s: dst_y_per_vm_vblank = %3.2f\n", __func__, dst_y_per_vm_vblank); ++ dml_print("DML_DLG: %s: dst_y_per_row_vblank = %3.2f\n", __func__, dst_y_per_row_vblank); ++ + ASSERT(dst_y_per_vm_vblank < min_dst_y_per_vm_vblank); + ASSERT(dst_y_per_row_vblank < min_dst_y_per_row_vblank); + + ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank)); + lsw = dst_y_prefetch - (dst_y_per_vm_vblank + dst_y_per_row_vblank); + +- DTRACE("DLG: %s: lsw = %3.2f", __func__, lsw); +- +- vratio_pre_l = get_vratio_pre( +- mode_lib, +- max_num_sw_l, +- max_partial_sw_l, +- swath_height_l, +- max_vinit_l, +- lsw); +- vratio_pre_c = 1.0; +- if (dual_plane) +- vratio_pre_c = get_vratio_pre( +- mode_lib, +- max_num_sw_c, +- max_partial_sw_c, +- swath_height_c, +- max_vinit_c, +- lsw); +- +- DTRACE("DLG: %s: vratio_pre_l=%3.2f", __func__, vratio_pre_l); +- DTRACE("DLG: %s: vratio_pre_c=%3.2f", __func__, vratio_pre_c); +- +- ASSERT(vratio_pre_l <= 4.0); +- if (vratio_pre_l >= 4.0) +- disp_dlg_regs->vratio_prefetch = (unsigned int) dml_pow(2, 21) - 1; +- else +- disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19)); +- +- ASSERT(vratio_pre_c <= 4.0); +- if (vratio_pre_c >= 4.0) +- disp_dlg_regs->vratio_prefetch_c = (unsigned int) dml_pow(2, 21) - 1; +- else +- disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19)); +- +- disp_dlg_regs->refcyc_per_pte_group_vblank_l = +- (unsigned int) (dst_y_per_row_vblank * (double) htotal +- * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l); +- ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13)); +- +- disp_dlg_regs->refcyc_per_pte_group_vblank_c = +- (unsigned int) (dst_y_per_row_vblank * (double) htotal +- * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_c); +- ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c < (unsigned int) dml_pow(2, 13)); ++ dml_print("DML_DLG: %s: lsw = %3.2f\n", __func__, lsw); + +- disp_dlg_regs->refcyc_per_meta_chunk_vblank_l = +- (unsigned int) (dst_y_per_row_vblank * (double) htotal +- * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l); +- ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13)); ++ vratio_pre_l = get_vratio_prefetch_l(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); ++ vratio_pre_c = get_vratio_prefetch_c(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); + +- disp_dlg_regs->refcyc_per_meta_chunk_vblank_c = +- disp_dlg_regs->refcyc_per_meta_chunk_vblank_l;/* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */ ++ dml_print("DML_DLG: %s: vratio_pre_l=%3.2f\n", __func__, vratio_pre_l); ++ dml_print("DML_DLG: %s: vratio_pre_c=%3.2f\n", __func__, vratio_pre_c); + +- /* Active */ ++ // Active + req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub; + req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub; + meta_row_height_l = rq_dlg_param.rq_l.meta_row_height; ++ meta_row_height_c = rq_dlg_param.rq_c.meta_row_height; + swath_width_pixels_ub_l = 0; + swath_width_pixels_ub_c = 0; + scaler_rec_in_width_l = 0; +@@ -1771,40 +1106,8 @@ void dml_rq_dlg_get_dlg_params( + dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height; + dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height; + +- disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l +- / (double) vratio_l * dml_pow(2, 2)); +- ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17)); +- +- disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c +- / (double) vratio_c * dml_pow(2, 2)); +- ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_c < (unsigned int) dml_pow(2, 17)); +- +- disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l +- / (double) vratio_l * dml_pow(2, 2)); +- ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17)); +- +- disp_dlg_regs->dst_y_per_meta_row_nom_c = disp_dlg_regs->dst_y_per_meta_row_nom_l; /* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */ +- +- disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l +- / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq +- / (double) dpte_groups_per_row_ub_l); +- if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23)) +- disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1; +- +- disp_dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int) ((double) dpte_row_height_c +- / (double) vratio_c * (double) htotal * ref_freq_to_pix_freq +- / (double) dpte_groups_per_row_ub_c); +- if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23)) +- disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1; +- +- disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l +- / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq +- / (double) meta_chunks_per_row_ub_l); +- if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23)) +- disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1; +- + if (mode_422) { +- swath_width_pixels_ub_l = swath_width_ub_l * 2; /* *2 for 2 pixel per element */ ++ swath_width_pixels_ub_l = swath_width_ub_l * 2; // *2 for 2 pixel per element + swath_width_pixels_ub_c = swath_width_ub_c * 2; + } else { + swath_width_pixels_ub_l = swath_width_ub_l * 1; +@@ -1819,15 +1122,15 @@ void dml_rq_dlg_get_dlg_params( + if (htaps_l <= 1) + min_hratio_fact_l = 2.0; + else if (htaps_l <= 6) { +- if ((hratios_l * 2.0) > 4.0) ++ if ((hratio_l * 2.0) > 4.0) + min_hratio_fact_l = 4.0; + else +- min_hratio_fact_l = hratios_l * 2.0; ++ min_hratio_fact_l = hratio_l * 2.0; + } else { +- if (hratios_l > 4.0) ++ if (hratio_l > 4.0) + min_hratio_fact_l = 4.0; + else +- min_hratio_fact_l = hratios_l; ++ min_hratio_fact_l = hratio_l; + } + + hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz; +@@ -1835,15 +1138,15 @@ void dml_rq_dlg_get_dlg_params( + if (htaps_c <= 1) + min_hratio_fact_c = 2.0; + else if (htaps_c <= 6) { +- if ((hratios_c * 2.0) > 4.0) ++ if ((hratio_c * 2.0) > 4.0) + min_hratio_fact_c = 4.0; + else +- min_hratio_fact_c = hratios_c * 2.0; ++ min_hratio_fact_c = hratio_c * 2.0; + } else { +- if (hratios_c > 4.0) ++ if (hratio_c > 4.0) + min_hratio_fact_c = 4.0; + else +- min_hratio_fact_c = hratios_c; ++ min_hratio_fact_c = hratio_c; + } + + hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz; +@@ -1857,97 +1160,90 @@ void dml_rq_dlg_get_dlg_params( + refcyc_per_req_delivery_pre_c = 0.; + refcyc_per_req_delivery_l = 0.; + refcyc_per_req_delivery_c = 0.; +- refcyc_per_req_delivery_pre_cur0 = 0.; +- refcyc_per_req_delivery_cur0 = 0.; + + full_recout_width = 0; +- if (e2e_pipe_param.pipe.src.is_hsplit) { +- if (e2e_pipe_param.pipe.dest.full_recout_width == 0) { +- DTRACE("DLG: %s: Warningfull_recout_width not set in hsplit mode", __func__); +- full_recout_width = e2e_pipe_param.pipe.dest.recout_width * 2; /* assume half split for dcn1 */ ++ // In ODM ++ if (src->is_hsplit) { ++ // This "hack" is only allowed (and valid) for MPC combine. In ODM ++ // combine, you MUST specify the full_recout_width...according to Oswin ++ if (dst->full_recout_width == 0 && !dst->odm_combine) { ++ dml_print("DML_DLG: %s: Warning: full_recout_width not set in hsplit mode\n", ++ __func__); ++ full_recout_width = dst->recout_width * 2; // assume half split for dcn1 + } else +- full_recout_width = e2e_pipe_param.pipe.dest.full_recout_width; ++ full_recout_width = dst->full_recout_width; + } else +- full_recout_width = e2e_pipe_param.pipe.dest.recout_width; ++ full_recout_width = dst->recout_width; + +- refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery( +- mode_lib, ++ // mpc_combine and odm_combine are mutually exclusive ++ refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, ++ dst->odm_combine, + full_recout_width, ++ dst->hactive, + vratio_pre_l, + hscale_pixel_rate_l, + swath_width_pixels_ub_l, +- 1); /* per line */ ++ 1); // per line + +- refcyc_per_line_delivery_l = get_refcyc_per_delivery( +- mode_lib, ++ refcyc_per_line_delivery_l = get_refcyc_per_delivery(mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, ++ dst->odm_combine, + full_recout_width, ++ dst->hactive, + vratio_l, + hscale_pixel_rate_l, + swath_width_pixels_ub_l, +- 1); /* per line */ ++ 1); // per line + +- DTRACE("DLG: %s: full_recout_width = %d", __func__, full_recout_width); +- DTRACE("DLG: %s: hscale_pixel_rate_l = %3.2f", __func__, hscale_pixel_rate_l); +- DTRACE( +- "DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f", ++ dml_print("DML_DLG: %s: full_recout_width = %d\n", + __func__, +- refcyc_per_line_delivery_pre_l); +- DTRACE( +- "DLG: %s: refcyc_per_line_delivery_l = %3.2f", ++ full_recout_width); ++ dml_print("DML_DLG: %s: hscale_pixel_rate_l = %3.2f\n", ++ __func__, ++ hscale_pixel_rate_l); ++ dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f\n", + __func__, +- refcyc_per_line_delivery_l); +- +- disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor( + refcyc_per_line_delivery_pre_l); +- disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor( ++ dml_print("DML_DLG: %s: refcyc_per_line_delivery_l = %3.2f\n", ++ __func__, + refcyc_per_line_delivery_l); +- ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13)); +- ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13)); + + if (dual_plane) { +- refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery( +- mode_lib, ++ refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery(mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, ++ dst->odm_combine, + full_recout_width, ++ dst->hactive, + vratio_pre_c, + hscale_pixel_rate_c, + swath_width_pixels_ub_c, +- 1); /* per line */ ++ 1); // per line + +- refcyc_per_line_delivery_c = get_refcyc_per_delivery( +- mode_lib, ++ refcyc_per_line_delivery_c = get_refcyc_per_delivery(mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, ++ dst->odm_combine, + full_recout_width, ++ dst->hactive, + vratio_c, + hscale_pixel_rate_c, + swath_width_pixels_ub_c, +- 1); /* per line */ ++ 1); // per line + +- DTRACE( +- "DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f", ++ dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f\n", + __func__, + refcyc_per_line_delivery_pre_c); +- DTRACE( +- "DLG: %s: refcyc_per_line_delivery_c = %3.2f", ++ dml_print("DML_DLG: %s: refcyc_per_line_delivery_c = %3.2f\n", + __func__, + refcyc_per_line_delivery_c); +- +- disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor( +- refcyc_per_line_delivery_pre_c); +- disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor( +- refcyc_per_line_delivery_c); +- ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13)); ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13)); + } +- disp_dlg_regs->chunk_hdl_adjust_cur0 = 3; + +- /* TTU - Luma / Chroma */ +- if (access_dir) { /* vertical access */ ++ // TTU - Luma / Chroma ++ if (access_dir) { // vertical access + scaler_rec_in_width_l = vp_height_l; + scaler_rec_in_width_c = vp_height_c; + } else { +@@ -1955,167 +1251,264 @@ void dml_rq_dlg_get_dlg_params( + scaler_rec_in_width_c = vp_width_c; + } + +- refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery( +- mode_lib, ++ refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery(mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, ++ dst->odm_combine, + full_recout_width, ++ dst->hactive, + vratio_pre_l, + hscale_pixel_rate_l, + scaler_rec_in_width_l, +- req_per_swath_ub_l); /* per req */ +- refcyc_per_req_delivery_l = get_refcyc_per_delivery( +- mode_lib, ++ req_per_swath_ub_l); // per req ++ refcyc_per_req_delivery_l = get_refcyc_per_delivery(mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, ++ dst->odm_combine, + full_recout_width, ++ dst->hactive, + vratio_l, + hscale_pixel_rate_l, + scaler_rec_in_width_l, +- req_per_swath_ub_l); /* per req */ ++ req_per_swath_ub_l); // per req + +- DTRACE( +- "DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f", ++ dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f\n", + __func__, + refcyc_per_req_delivery_pre_l); +- DTRACE( +- "DLG: %s: refcyc_per_req_delivery_l = %3.2f", ++ dml_print("DML_DLG: %s: refcyc_per_req_delivery_l = %3.2f\n", + __func__, + refcyc_per_req_delivery_l); + +- disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l +- * dml_pow(2, 10)); +- disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l +- * dml_pow(2, 10)); +- + ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13)); + ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13)); + + if (dual_plane) { +- refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery( +- mode_lib, ++ refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery(mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, ++ dst->odm_combine, + full_recout_width, ++ dst->hactive, + vratio_pre_c, + hscale_pixel_rate_c, + scaler_rec_in_width_c, +- req_per_swath_ub_c); /* per req */ +- refcyc_per_req_delivery_c = get_refcyc_per_delivery( +- mode_lib, ++ req_per_swath_ub_c); // per req ++ refcyc_per_req_delivery_c = get_refcyc_per_delivery(mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, ++ dst->odm_combine, + full_recout_width, ++ dst->hactive, + vratio_c, + hscale_pixel_rate_c, + scaler_rec_in_width_c, +- req_per_swath_ub_c); /* per req */ ++ req_per_swath_ub_c); // per req + +- DTRACE( +- "DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f", ++ dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f\n", + __func__, + refcyc_per_req_delivery_pre_c); +- DTRACE( +- "DLG: %s: refcyc_per_req_delivery_c = %3.2f", ++ dml_print("DML_DLG: %s: refcyc_per_req_delivery_c = %3.2f\n", + __func__, + refcyc_per_req_delivery_c); + +- disp_ttu_regs->refcyc_per_req_delivery_pre_c = +- (unsigned int) (refcyc_per_req_delivery_pre_c * dml_pow(2, 10)); +- disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c +- * dml_pow(2, 10)); +- + ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13)); + ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13)); + } + +- /* TTU - Cursor */ +- hratios_cur0 = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio; +- cur0_src_width = e2e_pipe_param.pipe.src.cur0_src_width; /* cursor source width */ +- cur0_bpp = (enum cursor_bpp) e2e_pipe_param.pipe.src.cur0_bpp; +- cur0_req_size = 0; +- cur0_req_width = 0; +- cur0_width_ub = 0.0; +- cur0_req_per_width = 0.0; +- hactive_cur0 = 0.0; +- +- ASSERT(cur0_src_width <= 256); +- +- if (cur0_src_width > 0) { +- unsigned int cur0_bit_per_pixel = 0; +- +- if (cur0_bpp == dm_cur_2bit) { +- cur0_req_size = 64; /* byte */ +- cur0_bit_per_pixel = 2; +- } else { /* 32bit */ +- cur0_bit_per_pixel = 32; +- if (cur0_src_width >= 1 && cur0_src_width <= 16) +- cur0_req_size = 64; +- else if (cur0_src_width >= 17 && cur0_src_width <= 31) +- cur0_req_size = 128; +- else +- cur0_req_size = 256; +- } ++ // XFC ++ xfc_transfer_delay = get_xfc_transfer_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); ++ xfc_precharge_delay = get_xfc_precharge_delay(mode_lib, ++ e2e_pipe_param, ++ num_pipes, ++ pipe_idx); ++ xfc_remote_surface_flip_latency = get_xfc_remote_surface_flip_latency(mode_lib, ++ e2e_pipe_param, ++ num_pipes, ++ pipe_idx); ++ xfc_dst_y_delta_drq_limit = xfc_remote_surface_flip_latency; ++ xfc_prefetch_margin = get_xfc_prefetch_margin(mode_lib, ++ e2e_pipe_param, ++ num_pipes, ++ pipe_idx); ++ ++ // TTU - Cursor ++ refcyc_per_req_delivery_pre_cur0 = 0.0; ++ refcyc_per_req_delivery_cur0 = 0.0; ++ if (src->num_cursors > 0) { ++ calculate_ttu_cursor(mode_lib, ++ &refcyc_per_req_delivery_pre_cur0, ++ &refcyc_per_req_delivery_cur0, ++ refclk_freq_in_mhz, ++ ref_freq_to_pix_freq, ++ hscale_pixel_rate_l, ++ scl->hscl_ratio, ++ vratio_pre_l, ++ vratio_l, ++ src->cur0_src_width, ++ (enum cursor_bpp)(src->cur0_bpp)); ++ } ++ ++ refcyc_per_req_delivery_pre_cur1 = 0.0; ++ refcyc_per_req_delivery_cur1 = 0.0; ++ if (src->num_cursors > 1) { ++ calculate_ttu_cursor(mode_lib, ++ &refcyc_per_req_delivery_pre_cur1, ++ &refcyc_per_req_delivery_cur1, ++ refclk_freq_in_mhz, ++ ref_freq_to_pix_freq, ++ hscale_pixel_rate_l, ++ scl->hscl_ratio, ++ vratio_pre_l, ++ vratio_l, ++ src->cur1_src_width, ++ (enum cursor_bpp)(src->cur1_bpp)); ++ } + +- cur0_req_width = (double) cur0_req_size / ((double) cur0_bit_per_pixel / 8.0); +- cur0_width_ub = dml_ceil((double) cur0_src_width / (double) cur0_req_width) +- * (double) cur0_req_width; +- cur0_req_per_width = cur0_width_ub / (double) cur0_req_width; +- hactive_cur0 = (double) cur0_src_width / hratios_cur0; /* FIXME: oswin to think about what to do for cursor */ ++ // TTU - Misc ++ // all hard-coded + +- if (vratio_pre_l <= 1.0) { +- refcyc_per_req_delivery_pre_cur0 = hactive_cur0 * ref_freq_to_pix_freq +- / (double) cur0_req_per_width; +- } else { +- refcyc_per_req_delivery_pre_cur0 = (double) refclk_freq_in_mhz +- * (double) cur0_src_width / hscale_pixel_rate_l +- / (double) cur0_req_per_width; +- } ++ // Assignment to register structures ++ disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; // in terms of line ++ disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; // in terms of refclk ++ ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13)); ++ disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2)); ++ disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2)); ++ disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2)); ++ disp_dlg_regs->dst_y_per_vm_flip = (unsigned int) (dst_y_per_vm_flip * dml_pow(2, 2)); ++ disp_dlg_regs->dst_y_per_row_flip = (unsigned int) (dst_y_per_row_flip * dml_pow(2, 2)); + +- disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = +- (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10)); +- ASSERT(refcyc_per_req_delivery_pre_cur0 < dml_pow(2, 13)); ++ disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19)); ++ disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19)); + +- if (vratio_l <= 1.0) { +- refcyc_per_req_delivery_cur0 = hactive_cur0 * ref_freq_to_pix_freq +- / (double) cur0_req_per_width; +- } else { +- refcyc_per_req_delivery_cur0 = (double) refclk_freq_in_mhz +- * (double) cur0_src_width / hscale_pixel_rate_l +- / (double) cur0_req_per_width; ++ disp_dlg_regs->refcyc_per_pte_group_vblank_l = ++ (unsigned int) (dst_y_per_row_vblank * (double) htotal ++ * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l); ++ ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13)); ++ ++ if (dual_plane) { ++ disp_dlg_regs->refcyc_per_pte_group_vblank_c = (unsigned int) (dst_y_per_row_vblank ++ * (double) htotal * ref_freq_to_pix_freq ++ / (double) dpte_groups_per_row_ub_c); ++ ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c ++ < (unsigned int) dml_pow(2, 13)); ++ } ++ ++ disp_dlg_regs->refcyc_per_meta_chunk_vblank_l = ++ (unsigned int) (dst_y_per_row_vblank * (double) htotal ++ * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l); ++ ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13)); ++ ++ disp_dlg_regs->refcyc_per_meta_chunk_vblank_c = ++ disp_dlg_regs->refcyc_per_meta_chunk_vblank_l; // dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now ++ ++ disp_dlg_regs->refcyc_per_pte_group_flip_l = (unsigned int) (dst_y_per_row_flip * htotal ++ * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_l; ++ disp_dlg_regs->refcyc_per_meta_chunk_flip_l = (unsigned int) (dst_y_per_row_flip * htotal ++ * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_l; ++ ++ if (dual_plane) { ++ disp_dlg_regs->refcyc_per_pte_group_flip_c = (unsigned int) (dst_y_per_row_flip ++ * htotal * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_c; ++ disp_dlg_regs->refcyc_per_meta_chunk_flip_c = (unsigned int) (dst_y_per_row_flip ++ * htotal * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_c; ++ } ++ ++ disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l ++ / (double) vratio_l * dml_pow(2, 2)); ++ ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17)); ++ ++ if (dual_plane) { ++ disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c ++ / (double) vratio_c * dml_pow(2, 2)); ++ if (disp_dlg_regs->dst_y_per_pte_row_nom_c >= (unsigned int) dml_pow(2, 17)) { ++ dml_print("DML_DLG: %s: Warning dst_y_per_pte_row_nom_c %u larger than supported by register format U15.2 %u\n", ++ __func__, ++ disp_dlg_regs->dst_y_per_pte_row_nom_c, ++ (unsigned int) dml_pow(2, 17) - 1); + } ++ } + +- DTRACE("DLG: %s: cur0_req_width = %d", __func__, cur0_req_width); +- DTRACE( +- "DLG: %s: cur0_width_ub = %3.2f", +- __func__, +- cur0_width_ub); +- DTRACE( +- "DLG: %s: cur0_req_per_width = %3.2f", +- __func__, +- cur0_req_per_width); +- DTRACE( +- "DLG: %s: hactive_cur0 = %3.2f", +- __func__, +- hactive_cur0); +- DTRACE( +- "DLG: %s: refcyc_per_req_delivery_pre_cur0 = %3.2f", +- __func__, +- refcyc_per_req_delivery_pre_cur0); +- DTRACE( +- "DLG: %s: refcyc_per_req_delivery_cur0 = %3.2f", +- __func__, +- refcyc_per_req_delivery_cur0); ++ disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l ++ / (double) vratio_l * dml_pow(2, 2)); ++ ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17)); + +- disp_ttu_regs->refcyc_per_req_delivery_cur0 = +- (unsigned int) (refcyc_per_req_delivery_cur0 * dml_pow(2, 10)); +- ASSERT(refcyc_per_req_delivery_cur0 < dml_pow(2, 13)); +- } else { +- disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = 0; +- disp_ttu_regs->refcyc_per_req_delivery_cur0 = 0; ++ disp_dlg_regs->dst_y_per_meta_row_nom_c = disp_dlg_regs->dst_y_per_meta_row_nom_l; // TODO: dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now ++ ++ disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l ++ / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq ++ / (double) dpte_groups_per_row_ub_l); ++ if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23)) ++ disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1; ++ disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l ++ / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq ++ / (double) meta_chunks_per_row_ub_l); ++ if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23)) ++ disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1; ++ ++ if (dual_plane) { ++ disp_dlg_regs->refcyc_per_pte_group_nom_c = ++ (unsigned int) ((double) dpte_row_height_c / (double) vratio_c ++ * (double) htotal * ref_freq_to_pix_freq ++ / (double) dpte_groups_per_row_ub_c); ++ if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23)) ++ disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1; ++ ++ // TODO: Is this the right calculation? Does htotal need to be halved? ++ disp_dlg_regs->refcyc_per_meta_chunk_nom_c = ++ (unsigned int) ((double) meta_row_height_c / (double) vratio_c ++ * (double) htotal * ref_freq_to_pix_freq ++ / (double) meta_chunks_per_row_ub_c); ++ if (disp_dlg_regs->refcyc_per_meta_chunk_nom_c >= (unsigned int) dml_pow(2, 23)) ++ disp_dlg_regs->refcyc_per_meta_chunk_nom_c = dml_pow(2, 23) - 1; + } + +- /* TTU - Misc */ ++ disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_l, ++ 1); ++ disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(refcyc_per_line_delivery_l, ++ 1); ++ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13)); ++ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13)); ++ ++ disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_c, ++ 1); ++ disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(refcyc_per_line_delivery_c, ++ 1); ++ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13)); ++ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13)); ++ ++ disp_dlg_regs->chunk_hdl_adjust_cur0 = 3; ++ disp_dlg_regs->dst_y_offset_cur0 = 0; ++ disp_dlg_regs->chunk_hdl_adjust_cur1 = 3; ++ disp_dlg_regs->dst_y_offset_cur1 = 0; ++ ++ disp_dlg_regs->xfc_reg_transfer_delay = xfc_transfer_delay; ++ disp_dlg_regs->xfc_reg_precharge_delay = xfc_precharge_delay; ++ disp_dlg_regs->xfc_reg_remote_surface_flip_latency = xfc_remote_surface_flip_latency; ++ disp_dlg_regs->xfc_reg_prefetch_margin = dml_ceil(xfc_prefetch_margin * refclk_freq_in_mhz, ++ 1); ++ ++ // slave has to have this value also set to off ++ if (src->xfc_enable && !src->xfc_slave) ++ disp_dlg_regs->dst_y_delta_drq_limit = dml_ceil(xfc_dst_y_delta_drq_limit, 1); ++ else ++ disp_dlg_regs->dst_y_delta_drq_limit = 0x7fff; // off ++ ++ disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l ++ * dml_pow(2, 10)); ++ disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l ++ * dml_pow(2, 10)); ++ disp_ttu_regs->refcyc_per_req_delivery_pre_c = (unsigned int) (refcyc_per_req_delivery_pre_c ++ * dml_pow(2, 10)); ++ disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c ++ * dml_pow(2, 10)); ++ disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = ++ (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10)); ++ disp_ttu_regs->refcyc_per_req_delivery_cur0 = (unsigned int) (refcyc_per_req_delivery_cur0 ++ * dml_pow(2, 10)); ++ disp_ttu_regs->refcyc_per_req_delivery_pre_cur1 = ++ (unsigned int) (refcyc_per_req_delivery_pre_cur1 * dml_pow(2, 10)); ++ disp_ttu_regs->refcyc_per_req_delivery_cur1 = (unsigned int) (refcyc_per_req_delivery_cur1 ++ * dml_pow(2, 10)); + disp_ttu_regs->qos_level_low_wm = 0; + ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14)); + disp_ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal +@@ -2137,118 +1530,232 @@ void dml_rq_dlg_get_dlg_params( + print__dlg_regs_st(mode_lib, *disp_dlg_regs); + } + +-void dml_rq_dlg_get_dlg_reg( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_dlg_regs_st *dlg_regs, +- struct _vcs_dpi_display_ttu_regs_st *ttu_regs, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe_param, +- const int unsigned num_pipes, +- const int unsigned pipe_idx, ++void dml_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, ++ display_dlg_regs_st *dlg_regs, ++ display_ttu_regs_st *ttu_regs, ++ display_e2e_pipe_params_st *e2e_pipe_param, ++ const unsigned int num_pipes, ++ const unsigned int pipe_idx, + const bool cstate_en, + const bool pstate_en, + const bool vm_en, +- const bool iflip_en) ++ const bool ignore_viewport_pos, ++ const bool immediate_flip_support) + { +- struct _vcs_dpi_display_rq_params_st rq_param = {0}; +- struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param = {0}; +- struct _vcs_dpi_wm_calc_pipe_params_st *wm_param = mode_lib->wm_param; +- struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_wm; +- struct _vcs_dpi_display_dlg_prefetch_param_st prefetch_param; +- double total_ret_bw; +- double total_active_bw; +- double total_prefetch_bw; +- int unsigned total_flip_bytes; +- int unsigned num_planes; +- int i; +- +- memset(wm_param, 0, sizeof(mode_lib->wm_param)); +- +- /* Get watermark and Tex. */ +- DTRACE("DLG: Start calculating system setting related parameters. num_pipes=%d", num_pipes); +- num_planes = dml_wm_e2e_to_wm(mode_lib, e2e_pipe_param, num_pipes, wm_param); +- +- cstate_pstate_wm = dml_wm_cstate_pstate_e2e(mode_lib, e2e_pipe_param, num_pipes); +- dlg_sys_param.t_mclk_wm_us = cstate_pstate_wm.pstate_change_us; +- dlg_sys_param.t_sr_wm_us = cstate_pstate_wm.cstate_enter_plus_exit_us; +- dlg_sys_param.t_urg_wm_us = dml_wm_urgent_e2e(mode_lib, e2e_pipe_param, num_pipes); +- dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency +- / dml_wm_dcfclk_deepsleep_mhz_e2e(mode_lib, e2e_pipe_param, num_pipes); +- dlg_sys_param.t_extra_us = dml_wm_urgent_extra(mode_lib, wm_param, num_planes); +- dlg_sys_param.deepsleep_dcfclk_mhz = dml_wm_dcfclk_deepsleep_mhz_e2e( +- mode_lib, ++ display_rq_params_st rq_param = {0}; ++ display_dlg_sys_params_st dlg_sys_param = {0}; ++ ++ // Get watermark and Tex. ++ dlg_sys_param.t_urg_wm_us = get_wm_urgent(mode_lib, e2e_pipe_param, num_pipes); ++ dlg_sys_param.deepsleep_dcfclk_mhz = get_clk_dcf_deepsleep(mode_lib, ++ e2e_pipe_param, ++ num_pipes); ++ dlg_sys_param.t_extra_us = get_urgent_extra_latency(mode_lib, e2e_pipe_param, num_pipes); ++ dlg_sys_param.mem_trip_us = get_wm_memory_trip(mode_lib, e2e_pipe_param, num_pipes); ++ dlg_sys_param.t_mclk_wm_us = get_wm_dram_clock_change(mode_lib, e2e_pipe_param, num_pipes); ++ dlg_sys_param.t_sr_wm_us = get_wm_stutter_enter_exit(mode_lib, e2e_pipe_param, num_pipes); ++ dlg_sys_param.total_flip_bw = get_total_immediate_flip_bw(mode_lib, + e2e_pipe_param, + num_pipes); ++ dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib, ++ e2e_pipe_param, ++ num_pipes); ++ dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency ++ / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated + + print__dlg_sys_params_st(mode_lib, dlg_sys_param); + +- DTRACE("DLG: Start calculating total prefetch bw. num_planes=%d", num_planes); +- total_ret_bw = dml_wm_calc_return_bw(mode_lib, wm_param, num_planes); +- total_active_bw = dml_wm_calc_total_data_read_bw(mode_lib, wm_param, num_planes); +- total_prefetch_bw = 0.0; +- total_flip_bytes = 0; ++ // system parameter calculation done + +- for (i = 0; i < num_pipes; i++) { +- dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[i].pipe.src); +- dml_rq_dlg_get_dlg_params_prefetch( +- mode_lib, +- &prefetch_param, +- rq_param.dlg, +- dlg_sys_param, +- e2e_pipe_param[i], +- cstate_en, +- pstate_en, +- vm_en); +- total_prefetch_bw += prefetch_param.prefetch_bw; +- total_flip_bytes += prefetch_param.flip_bytes; +- DTRACE( +- "DLG: pipe=%d, total_prefetch_bw=%3.2f total_flip_bytes=%d", +- i, +- total_prefetch_bw, +- total_flip_bytes); +- } +- +- dlg_sys_param.total_flip_bw = total_ret_bw - dml_max(total_active_bw, total_prefetch_bw); +- +- DTRACE("DLG: Done calculating total prefetch bw"); +- DTRACE("DLG: num_pipes = %d", num_pipes); +- DTRACE("DLG: total_ret_bw = %3.2f", total_ret_bw); +- DTRACE("DLG: total_active_bw = %3.2f", total_active_bw); +- DTRACE("DLG: total_prefetch_bw = %3.2f", total_prefetch_bw); +- DTRACE("DLG: total_flip_bw = %3.2f", dlg_sys_param.total_flip_bw); +- +- if (dlg_sys_param.total_flip_bw < 0.0 && iflip_en) { +- DTRACE("WARNING_DLG Insufficient bw for immediate flip!"); +- dlg_sys_param.total_flip_bw = 0; +- } +- +- dlg_sys_param.total_flip_bytes = total_flip_bytes; +- DTRACE("DLG: total_flip_bytes = %d", dlg_sys_param.total_flip_bytes); +- DTRACE("DLG: Done calculating system setting related parameters."); +- +- /* system parameter calculation done */ +- +- DTRACE("DLG: Calculation for pipe[%d] start", pipe_idx); ++ dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx); + dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe.src); +- dml_rq_dlg_get_dlg_params( +- mode_lib, ++ dml_rq_dlg_get_dlg_params(mode_lib, ++ e2e_pipe_param, ++ num_pipes, ++ pipe_idx, + dlg_regs, + ttu_regs, + rq_param.dlg, + dlg_sys_param, +- e2e_pipe_param[pipe_idx], + cstate_en, + pstate_en, + vm_en, +- iflip_en); +- DTRACE("DLG: Calculation for pipe[%d] end", pipe_idx); ++ ignore_viewport_pos, ++ immediate_flip_support); ++ dml_print("DML_DLG: Calculation for pipe[%d] end\n", pipe_idx); + } + +-void dml_rq_dlg_get_arb_params( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_arb_params_st *arb_param) ++void dml_rq_dlg_get_arb_params(struct display_mode_lib *mode_lib, display_arb_params_st *arb_param) + { + memset(arb_param, 0, sizeof(*arb_param)); + arb_param->max_req_outstanding = 256; + arb_param->min_req_outstanding = 68; + arb_param->sat_level_us = 60; + } ++ ++void calculate_ttu_cursor(struct display_mode_lib *mode_lib, ++ double *refcyc_per_req_delivery_pre_cur, ++ double *refcyc_per_req_delivery_cur, ++ double refclk_freq_in_mhz, ++ double ref_freq_to_pix_freq, ++ double hscale_pixel_rate_l, ++ double hscl_ratio, ++ double vratio_pre_l, ++ double vratio_l, ++ unsigned int cur_width, ++ enum cursor_bpp cur_bpp) ++{ ++ unsigned int cur_src_width = cur_width; ++ unsigned int cur_req_size = 0; ++ unsigned int cur_req_width = 0; ++ double cur_width_ub = 0.0; ++ double cur_req_per_width = 0.0; ++ double hactive_cur = 0.0; ++ ++ ASSERT(cur_src_width <= 256); ++ ++ *refcyc_per_req_delivery_pre_cur = 0.0; ++ *refcyc_per_req_delivery_cur = 0.0; ++ if (cur_src_width > 0) { ++ unsigned int cur_bit_per_pixel = 0; ++ ++ if (cur_bpp == dm_cur_2bit) { ++ cur_req_size = 64; // byte ++ cur_bit_per_pixel = 2; ++ } else { // 32bit ++ cur_bit_per_pixel = 32; ++ if (cur_src_width >= 1 && cur_src_width <= 16) ++ cur_req_size = 64; ++ else if (cur_src_width >= 17 && cur_src_width <= 31) ++ cur_req_size = 128; ++ else ++ cur_req_size = 256; ++ } ++ ++ cur_req_width = (double) cur_req_size / ((double) cur_bit_per_pixel / 8.0); ++ cur_width_ub = dml_ceil((double) cur_src_width / (double) cur_req_width, 1) ++ * (double) cur_req_width; ++ cur_req_per_width = cur_width_ub / (double) cur_req_width; ++ hactive_cur = (double) cur_src_width / hscl_ratio; // FIXME: oswin to think about what to do for cursor ++ ++ if (vratio_pre_l <= 1.0) { ++ *refcyc_per_req_delivery_pre_cur = hactive_cur * ref_freq_to_pix_freq ++ / (double) cur_req_per_width; ++ } else { ++ *refcyc_per_req_delivery_pre_cur = (double) refclk_freq_in_mhz ++ * (double) cur_src_width / hscale_pixel_rate_l ++ / (double) cur_req_per_width; ++ } ++ ++ ASSERT(*refcyc_per_req_delivery_pre_cur < dml_pow(2, 13)); ++ ++ if (vratio_l <= 1.0) { ++ *refcyc_per_req_delivery_cur = hactive_cur * ref_freq_to_pix_freq ++ / (double) cur_req_per_width; ++ } else { ++ *refcyc_per_req_delivery_cur = (double) refclk_freq_in_mhz ++ * (double) cur_src_width / hscale_pixel_rate_l ++ / (double) cur_req_per_width; ++ } ++ ++ dml_print("DML_DLG: %s: cur_req_width = %d\n", ++ __func__, ++ cur_req_width); ++ dml_print("DML_DLG: %s: cur_width_ub = %3.2f\n", ++ __func__, ++ cur_width_ub); ++ dml_print("DML_DLG: %s: cur_req_per_width = %3.2f\n", ++ __func__, ++ cur_req_per_width); ++ dml_print("DML_DLG: %s: hactive_cur = %3.2f\n", ++ __func__, ++ hactive_cur); ++ dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_cur = %3.2f\n", ++ __func__, ++ *refcyc_per_req_delivery_pre_cur); ++ dml_print("DML_DLG: %s: refcyc_per_req_delivery_cur = %3.2f\n", ++ __func__, ++ *refcyc_per_req_delivery_cur); ++ ++ ASSERT(*refcyc_per_req_delivery_cur < dml_pow(2, 13)); ++ } ++} ++ ++unsigned int dml_rq_dlg_get_calculated_vstartup(struct display_mode_lib *mode_lib, ++ display_e2e_pipe_params_st *e2e_pipe_param, ++ const unsigned int num_pipes, ++ const unsigned int pipe_idx) ++{ ++ unsigned int vstartup_pipe[DC__NUM_PIPES__MAX]; ++ bool visited[DC__NUM_PIPES__MAX]; ++ unsigned int pipe_inst = 0; ++ unsigned int i, j, k; ++ ++ for (k = 0; k < num_pipes; ++k) ++ visited[k] = false; ++ ++ for (i = 0; i < num_pipes; i++) { ++ if (e2e_pipe_param[i].pipe.src.is_hsplit && !visited[i]) { ++ unsigned int grp = e2e_pipe_param[i].pipe.src.hsplit_grp; ++ ++ for (j = i; j < num_pipes; j++) { ++ if (e2e_pipe_param[j].pipe.src.hsplit_grp == grp ++ && e2e_pipe_param[j].pipe.src.is_hsplit ++ && !visited[j]) { ++ vstartup_pipe[j] = get_vstartup_calculated(mode_lib, ++ e2e_pipe_param, ++ num_pipes, ++ pipe_inst); ++ visited[j] = true; ++ } ++ } ++ ++ pipe_inst++; ++ } ++ ++ if (!visited[i]) { ++ vstartup_pipe[i] = get_vstartup_calculated(mode_lib, ++ e2e_pipe_param, ++ num_pipes, ++ pipe_inst); ++ visited[i] = true; ++ pipe_inst++; ++ } ++ } ++ ++ return vstartup_pipe[pipe_idx]; ++ ++} ++ ++void dml_rq_dlg_get_row_heights(struct display_mode_lib *mode_lib, ++ unsigned int *o_dpte_row_height, ++ unsigned int *o_meta_row_height, ++ unsigned int vp_width, ++ unsigned int data_pitch, ++ int source_format, ++ int tiling, ++ int macro_tile_size, ++ int source_scan, ++ int is_chroma) ++{ ++ display_data_rq_dlg_params_st rq_dlg_param; ++ display_data_rq_misc_params_st rq_misc_param; ++ display_data_rq_sizing_params_st rq_sizing_param; ++ ++ get_meta_and_pte_attr(mode_lib, ++ &rq_dlg_param, ++ &rq_misc_param, ++ &rq_sizing_param, ++ vp_width, ++ 0, // dummy ++ data_pitch, ++ 0, // dummy ++ source_format, ++ tiling, ++ macro_tile_size, ++ source_scan, ++ is_chroma); ++ ++ *o_dpte_row_height = rq_dlg_param.dpte_row_height; ++ *o_meta_row_height = rq_dlg_param.meta_row_height; ++} +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h +index e63b13f..efdd4c7 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h ++++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h +@@ -22,103 +22,114 @@ + * Authors: AMD + * + */ +-#ifndef __DISPLAY_RQ_DLG_CALC_H__ +-#define __DISPLAY_RQ_DLG_CALC_H__ ++ ++#ifndef __DML2_DISPLAY_RQ_DLG_CALC_H__ ++#define __DML2_DISPLAY_RQ_DLG_CALC_H__ + + #include "dml_common_defs.h" + #include "display_rq_dlg_helpers.h" + + struct display_mode_lib; + +-void extract_rq_regs( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_rq_regs_st *rq_regs, +- const struct _vcs_dpi_display_rq_params_st rq_param); +-/* Function: dml_rq_dlg_get_rq_params +- * Calculate requestor related parameters that register definition agnostic +- * (i.e. this layer does try to separate real values from register defintion) +- * Input: +- * pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.) +- * Output: +- * rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.) +- */ ++// Function: dml_rq_dlg_get_rq_params ++// Calculate requestor related parameters that register definition agnostic ++// (i.e. this layer does try to separate real values from register definition) ++// Input: ++// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.) ++// Output: ++// rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.) ++// + void dml_rq_dlg_get_rq_params( + struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_rq_params_st *rq_param, +- const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param); ++ display_rq_params_st *rq_param, ++ const display_pipe_source_params_st pipe_src_param); + +-/* Function: dml_rq_dlg_get_rq_reg +- * Main entry point for test to get the register values out of this DML class. +- * This function calls <get_rq_param> and <extract_rq_regs> fucntions to calculate +- * and then populate the rq_regs struct +- * Input: +- * pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.) +- * Output: +- * rq_regs - struct that holds all the RQ registers field value. +- * See also: <display_rq_regs_st> +- */ ++// Function: dml_rq_dlg_get_rq_reg ++// Main entry point for test to get the register values out of this DML class. ++// This function calls <get_rq_param> and <extract_rq_regs> fucntions to calculate ++// and then populate the rq_regs struct ++// Input: ++// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.) ++// Output: ++// rq_regs - struct that holds all the RQ registers field value. ++// See also: <display_rq_regs_st> + void dml_rq_dlg_get_rq_reg( + struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_rq_regs_st *rq_regs, +- const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param); ++ display_rq_regs_st *rq_regs, ++ const display_pipe_source_params_st pipe_src_param); + +-/* Function: dml_rq_dlg_get_dlg_params +- * Calculate deadline related parameters +- */ +-void dml_rq_dlg_get_dlg_params( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_dlg_regs_st *dlg_regs, +- struct _vcs_dpi_display_ttu_regs_st *ttu_regs, +- const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, +- const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, +- const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, ++// Function: dml_rq_dlg_get_dlg_params ++// Calculate deadline related parameters ++// ++void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, ++ const display_e2e_pipe_params_st *e2e_pipe_param, ++ const unsigned int num_pipes, ++ const unsigned int pipe_idx, ++ display_dlg_regs_st *disp_dlg_regs, ++ display_ttu_regs_st *disp_ttu_regs, ++ const display_rq_dlg_params_st rq_dlg_param, ++ const display_dlg_sys_params_st dlg_sys_param, + const bool cstate_en, + const bool pstate_en, + const bool vm_en, +- const bool iflip_en); ++ const bool ignore_viewport_pos, ++ const bool immediate_flip_support); + +-/* Function: dml_rq_dlg_get_dlg_param_prefetch +- * For flip_bw programming guide change, now dml needs to calculate the flip_bytes and prefetch_bw +- * for ALL pipes and use this info to calculate the prefetch programming. +- * Output: prefetch_param.prefetch_bw and flip_bytes +- */ ++// Function: dml_rq_dlg_get_dlg_param_prefetch ++// For flip_bw programming guide change, now dml needs to calculate the flip_bytes and prefetch_bw ++// for ALL pipes and use this info to calculate the prefetch programming. ++// Output: prefetch_param.prefetch_bw and flip_bytes + void dml_rq_dlg_get_dlg_params_prefetch( + struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_dlg_prefetch_param_st *prefetch_param, +- struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, +- struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, +- struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, ++ display_dlg_prefetch_param_st *prefetch_param, ++ display_rq_dlg_params_st rq_dlg_param, ++ display_dlg_sys_params_st dlg_sys_param, ++ display_e2e_pipe_params_st e2e_pipe_param, + const bool cstate_en, + const bool pstate_en, + const bool vm_en); + +-/* Function: dml_rq_dlg_get_dlg_reg +- * Calculate and return DLG and TTU register struct given the system setting +- * Output: +- * dlg_regs - output DLG register struct +- * ttu_regs - output DLG TTU register struct +- * Input: +- * e2e_pipe_param - "compacted" array of e2e pipe param struct +- * num_pipes - num of active "pipe" or "route" +- * pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg +- * cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered. +- * Added for legacy or unrealistic timing tests. +- */ ++// Function: dml_rq_dlg_get_dlg_reg ++// Calculate and return DLG and TTU register struct given the system setting ++// Output: ++// dlg_regs - output DLG register struct ++// ttu_regs - output DLG TTU register struct ++// Input: ++// e2e_pipe_param - "compacted" array of e2e pipe param struct ++// num_pipes - num of active "pipe" or "route" ++// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg ++// cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered. ++// Added for legacy or unrealistic timing tests. + void dml_rq_dlg_get_dlg_reg( + struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_dlg_regs_st *dlg_regs, +- struct _vcs_dpi_display_ttu_regs_st *ttu_regs, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe_param, ++ display_dlg_regs_st *dlg_regs, ++ display_ttu_regs_st *ttu_regs, ++ display_e2e_pipe_params_st *e2e_pipe_param, + const unsigned int num_pipes, + const unsigned int pipe_idx, + const bool cstate_en, + const bool pstate_en, + const bool vm_en, +- const bool iflip_en); ++ const bool ignore_viewport_pos, ++ const bool immediate_flip_support); + +-/* Function: dml_rq_dlg_get_row_heights +- * Calculate dpte and meta row heights +- */ ++// Function: dml_rq_dlg_get_calculated_vstartup ++// Calculate and return vstartup ++// Output: ++// unsigned int vstartup ++// Input: ++// e2e_pipe_param - "compacted" array of e2e pipe param struct ++// num_pipes - num of active "pipe" or "route" ++// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg ++// NOTE: this MUST be called after setting the prefetch mode! ++unsigned int dml_rq_dlg_get_calculated_vstartup( ++ struct display_mode_lib *mode_lib, ++ display_e2e_pipe_params_st *e2e_pipe_param, ++ const unsigned int num_pipes, ++ const unsigned int pipe_idx); ++ ++// Function: dml_rq_dlg_get_row_heights ++// Calculate dpte and meta row heights + void dml_rq_dlg_get_row_heights( + struct display_mode_lib *mode_lib, + unsigned int *o_dpte_row_height, +@@ -131,9 +142,7 @@ void dml_rq_dlg_get_row_heights( + int source_scan, + int is_chroma); + +-/* Function: dml_rq_dlg_get_arb_params */ +-void dml_rq_dlg_get_arb_params( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_arb_params_st *arb_param); ++// Function: dml_rq_dlg_get_arb_params ++void dml_rq_dlg_get_arb_params(struct display_mode_lib *mode_lib, display_arb_params_st *arb_param); + + #endif +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c +index 3dc1136..189052e 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c +@@ -25,296 +25,368 @@ + + #include "display_rq_dlg_helpers.h" + +-void print__rq_params_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_rq_params_st rq_param) ++void print__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param) + { +- DTRACE("RQ_DLG_CALC: *************************** "); +- DTRACE("RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST"); +- DTRACE("RQ_DLG_CALC: <LUMA>"); ++ dml_print("DML_RQ_DLG_CALC: ***************************\n"); ++ dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST\n"); ++ dml_print("DML_RQ_DLG_CALC: <LUMA>\n"); + print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_l); +- DTRACE("RQ_DLG_CALC: <CHROMA> === "); ++ dml_print("DML_RQ_DLG_CALC: <CHROMA> ===\n"); + print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_c); + +- DTRACE("RQ_DLG_CALC: <LUMA>"); ++ dml_print("DML_RQ_DLG_CALC: <LUMA>\n"); + print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_l); +- DTRACE("RQ_DLG_CALC: <CHROMA>"); ++ dml_print("DML_RQ_DLG_CALC: <CHROMA>\n"); + print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_c); + +- DTRACE("RQ_DLG_CALC: <LUMA>"); ++ dml_print("DML_RQ_DLG_CALC: <LUMA>\n"); + print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_l); +- DTRACE("RQ_DLG_CALC: <CHROMA>"); ++ dml_print("DML_RQ_DLG_CALC: <CHROMA>\n"); + print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_c); +- DTRACE("RQ_DLG_CALC: *************************** "); ++ dml_print("DML_RQ_DLG_CALC: ***************************\n"); + } + +-void print__data_rq_sizing_params_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing) ++void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st rq_sizing) + { +- DTRACE("RQ_DLG_CALC: ===================================== "); +- DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST"); +- DTRACE("RQ_DLG_CALC: chunk_bytes = %0d", rq_sizing.chunk_bytes); +- DTRACE("RQ_DLG_CALC: min_chunk_bytes = %0d", rq_sizing.min_chunk_bytes); +- DTRACE("RQ_DLG_CALC: meta_chunk_bytes = %0d", rq_sizing.meta_chunk_bytes); +- DTRACE("RQ_DLG_CALC: min_meta_chunk_bytes = %0d", rq_sizing.min_meta_chunk_bytes); +- DTRACE("RQ_DLG_CALC: mpte_group_bytes = %0d", rq_sizing.mpte_group_bytes); +- DTRACE("RQ_DLG_CALC: dpte_group_bytes = %0d", rq_sizing.dpte_group_bytes); +- DTRACE("RQ_DLG_CALC: ===================================== "); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); ++ dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST\n"); ++ dml_print("DML_RQ_DLG_CALC: chunk_bytes = %0d\n", rq_sizing.chunk_bytes); ++ dml_print("DML_RQ_DLG_CALC: min_chunk_bytes = %0d\n", rq_sizing.min_chunk_bytes); ++ dml_print("DML_RQ_DLG_CALC: meta_chunk_bytes = %0d\n", rq_sizing.meta_chunk_bytes); ++ dml_print( ++ "DML_RQ_DLG_CALC: min_meta_chunk_bytes = %0d\n", ++ rq_sizing.min_meta_chunk_bytes); ++ dml_print("DML_RQ_DLG_CALC: mpte_group_bytes = %0d\n", rq_sizing.mpte_group_bytes); ++ dml_print("DML_RQ_DLG_CALC: dpte_group_bytes = %0d\n", rq_sizing.dpte_group_bytes); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); + } + +-void print__data_rq_dlg_params_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_data_rq_dlg_params_st rq_dlg_param) ++void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, display_data_rq_dlg_params_st rq_dlg_param) + { +- DTRACE("RQ_DLG_CALC: ===================================== "); +- DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST"); +- DTRACE("RQ_DLG_CALC: swath_width_ub = %0d", rq_dlg_param.swath_width_ub); +- DTRACE("RQ_DLG_CALC: swath_height = %0d", rq_dlg_param.swath_height); +- DTRACE("RQ_DLG_CALC: req_per_swath_ub = %0d", rq_dlg_param.req_per_swath_ub); +- DTRACE( +- "RQ_DLG_CALC: meta_pte_bytes_per_frame_ub = %0d", ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); ++ dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST\n"); ++ dml_print( ++ "DML_RQ_DLG_CALC: swath_width_ub = %0d\n", ++ rq_dlg_param.swath_width_ub); ++ dml_print( ++ "DML_RQ_DLG_CALC: swath_height = %0d\n", ++ rq_dlg_param.swath_height); ++ dml_print( ++ "DML_RQ_DLG_CALC: req_per_swath_ub = %0d\n", ++ rq_dlg_param.req_per_swath_ub); ++ dml_print( ++ "DML_RQ_DLG_CALC: meta_pte_bytes_per_frame_ub = %0d\n", + rq_dlg_param.meta_pte_bytes_per_frame_ub); +- DTRACE( +- "RQ_DLG_CALC: dpte_req_per_row_ub = %0d", ++ dml_print( ++ "DML_RQ_DLG_CALC: dpte_req_per_row_ub = %0d\n", + rq_dlg_param.dpte_req_per_row_ub); +- DTRACE( +- "RQ_DLG_CALC: dpte_groups_per_row_ub = %0d", ++ dml_print( ++ "DML_RQ_DLG_CALC: dpte_groups_per_row_ub = %0d\n", + rq_dlg_param.dpte_groups_per_row_ub); +- DTRACE("RQ_DLG_CALC: dpte_row_height = %0d", rq_dlg_param.dpte_row_height); +- DTRACE( +- "RQ_DLG_CALC: dpte_bytes_per_row_ub = %0d", ++ dml_print( ++ "DML_RQ_DLG_CALC: dpte_row_height = %0d\n", ++ rq_dlg_param.dpte_row_height); ++ dml_print( ++ "DML_RQ_DLG_CALC: dpte_bytes_per_row_ub = %0d\n", + rq_dlg_param.dpte_bytes_per_row_ub); +- DTRACE( +- "RQ_DLG_CALC: meta_chunks_per_row_ub = %0d", ++ dml_print( ++ "DML_RQ_DLG_CALC: meta_chunks_per_row_ub = %0d\n", + rq_dlg_param.meta_chunks_per_row_ub); +- DTRACE( +- "RQ_DLG_CALC: meta_req_per_row_ub = %0d", ++ dml_print( ++ "DML_RQ_DLG_CALC: meta_req_per_row_ub = %0d\n", + rq_dlg_param.meta_req_per_row_ub); +- DTRACE("RQ_DLG_CALC: meta_row_height = %0d", rq_dlg_param.meta_row_height); +- DTRACE( +- "RQ_DLG_CALC: meta_bytes_per_row_ub = %0d", ++ dml_print( ++ "DML_RQ_DLG_CALC: meta_row_height = %0d\n", ++ rq_dlg_param.meta_row_height); ++ dml_print( ++ "DML_RQ_DLG_CALC: meta_bytes_per_row_ub = %0d\n", + rq_dlg_param.meta_bytes_per_row_ub); +- DTRACE("RQ_DLG_CALC: ===================================== "); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); + } + +-void print__data_rq_misc_params_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_data_rq_misc_params_st rq_misc_param) ++void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, display_data_rq_misc_params_st rq_misc_param) + { +- DTRACE("RQ_DLG_CALC: ===================================== "); +- DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST"); +- DTRACE("RQ_DLG_CALC: full_swath_bytes = %0d", rq_misc_param.full_swath_bytes); +- DTRACE("RQ_DLG_CALC: stored_swath_bytes = %0d", rq_misc_param.stored_swath_bytes); +- DTRACE("RQ_DLG_CALC: blk256_width = %0d", rq_misc_param.blk256_width); +- DTRACE("RQ_DLG_CALC: blk256_height = %0d", rq_misc_param.blk256_height); +- DTRACE("RQ_DLG_CALC: req_width = %0d", rq_misc_param.req_width); +- DTRACE("RQ_DLG_CALC: req_height = %0d", rq_misc_param.req_height); +- DTRACE("RQ_DLG_CALC: ===================================== "); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); ++ dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST\n"); ++ dml_print( ++ "DML_RQ_DLG_CALC: full_swath_bytes = %0d\n", ++ rq_misc_param.full_swath_bytes); ++ dml_print( ++ "DML_RQ_DLG_CALC: stored_swath_bytes = %0d\n", ++ rq_misc_param.stored_swath_bytes); ++ dml_print("DML_RQ_DLG_CALC: blk256_width = %0d\n", rq_misc_param.blk256_width); ++ dml_print("DML_RQ_DLG_CALC: blk256_height = %0d\n", rq_misc_param.blk256_height); ++ dml_print("DML_RQ_DLG_CALC: req_width = %0d\n", rq_misc_param.req_width); ++ dml_print("DML_RQ_DLG_CALC: req_height = %0d\n", rq_misc_param.req_height); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); + } + +-void print__rq_dlg_params_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param) ++void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, display_rq_dlg_params_st rq_dlg_param) + { +- DTRACE("RQ_DLG_CALC: ===================================== "); +- DTRACE("RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST"); +- DTRACE("RQ_DLG_CALC: <LUMA> "); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); ++ dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n"); ++ dml_print("DML_RQ_DLG_CALC: <LUMA>\n"); + print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_l); +- DTRACE("RQ_DLG_CALC: <CHROMA> "); ++ dml_print("DML_RQ_DLG_CALC: <CHROMA>\n"); + print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_c); +- DTRACE("RQ_DLG_CALC: ===================================== "); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); + } + +-void print__dlg_sys_params_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param) ++void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, display_dlg_sys_params_st dlg_sys_param) + { +- DTRACE("RQ_DLG_CALC: ===================================== "); +- DTRACE("RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST"); +- DTRACE("RQ_DLG_CALC: t_mclk_wm_us = %3.2f", dlg_sys_param.t_mclk_wm_us); +- DTRACE("RQ_DLG_CALC: t_urg_wm_us = %3.2f", dlg_sys_param.t_urg_wm_us); +- DTRACE("RQ_DLG_CALC: t_sr_wm_us = %3.2f", dlg_sys_param.t_sr_wm_us); +- DTRACE("RQ_DLG_CALC: t_extra_us = %3.2f", dlg_sys_param.t_extra_us); +- DTRACE("RQ_DLG_CALC: t_srx_delay_us = %3.2f", dlg_sys_param.t_srx_delay_us); +- DTRACE("RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f", dlg_sys_param.deepsleep_dcfclk_mhz); +- DTRACE("RQ_DLG_CALC: ===================================== "); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); ++ dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n"); ++ dml_print("DML_RQ_DLG_CALC: t_mclk_wm_us = %3.2f\n", dlg_sys_param.t_mclk_wm_us); ++ dml_print("DML_RQ_DLG_CALC: t_urg_wm_us = %3.2f\n", dlg_sys_param.t_urg_wm_us); ++ dml_print("DML_RQ_DLG_CALC: t_sr_wm_us = %3.2f\n", dlg_sys_param.t_sr_wm_us); ++ dml_print("DML_RQ_DLG_CALC: t_extra_us = %3.2f\n", dlg_sys_param.t_extra_us); ++ dml_print( ++ "DML_RQ_DLG_CALC: t_srx_delay_us = %3.2f\n", ++ dlg_sys_param.t_srx_delay_us); ++ dml_print( ++ "DML_RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f\n", ++ dlg_sys_param.deepsleep_dcfclk_mhz); ++ dml_print( ++ "DML_RQ_DLG_CALC: total_flip_bw = %3.2f\n", ++ dlg_sys_param.total_flip_bw); ++ dml_print( ++ "DML_RQ_DLG_CALC: total_flip_bytes = %i\n", ++ dlg_sys_param.total_flip_bytes); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); + } + +-void print__data_rq_regs_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_data_rq_regs_st rq_regs) ++void print__data_rq_regs_st(struct display_mode_lib *mode_lib, display_data_rq_regs_st rq_regs) + { +- DTRACE("RQ_DLG_CALC: ===================================== "); +- DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST"); +- DTRACE("RQ_DLG_CALC: chunk_size = 0x%0x", rq_regs.chunk_size); +- DTRACE("RQ_DLG_CALC: min_chunk_size = 0x%0x", rq_regs.min_chunk_size); +- DTRACE("RQ_DLG_CALC: meta_chunk_size = 0x%0x", rq_regs.meta_chunk_size); +- DTRACE("RQ_DLG_CALC: min_meta_chunk_size = 0x%0x", rq_regs.min_meta_chunk_size); +- DTRACE("RQ_DLG_CALC: dpte_group_size = 0x%0x", rq_regs.dpte_group_size); +- DTRACE("RQ_DLG_CALC: mpte_group_size = 0x%0x", rq_regs.mpte_group_size); +- DTRACE("RQ_DLG_CALC: swath_height = 0x%0x", rq_regs.swath_height); +- DTRACE("RQ_DLG_CALC: pte_row_height_linear = 0x%0x", rq_regs.pte_row_height_linear); +- DTRACE("RQ_DLG_CALC: ===================================== "); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); ++ dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST\n"); ++ dml_print("DML_RQ_DLG_CALC: chunk_size = 0x%0x\n", rq_regs.chunk_size); ++ dml_print("DML_RQ_DLG_CALC: min_chunk_size = 0x%0x\n", rq_regs.min_chunk_size); ++ dml_print("DML_RQ_DLG_CALC: meta_chunk_size = 0x%0x\n", rq_regs.meta_chunk_size); ++ dml_print( ++ "DML_RQ_DLG_CALC: min_meta_chunk_size = 0x%0x\n", ++ rq_regs.min_meta_chunk_size); ++ dml_print("DML_RQ_DLG_CALC: dpte_group_size = 0x%0x\n", rq_regs.dpte_group_size); ++ dml_print("DML_RQ_DLG_CALC: mpte_group_size = 0x%0x\n", rq_regs.mpte_group_size); ++ dml_print("DML_RQ_DLG_CALC: swath_height = 0x%0x\n", rq_regs.swath_height); ++ dml_print( ++ "DML_RQ_DLG_CALC: pte_row_height_linear = 0x%0x\n", ++ rq_regs.pte_row_height_linear); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); + } + +-void print__rq_regs_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_rq_regs_st rq_regs) ++void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs) + { +- DTRACE("RQ_DLG_CALC: ===================================== "); +- DTRACE("RQ_DLG_CALC: DISPLAY_RQ_REGS_ST"); +- DTRACE("RQ_DLG_CALC: <LUMA> "); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); ++ dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_REGS_ST\n"); ++ dml_print("DML_RQ_DLG_CALC: <LUMA>\n"); + print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_l); +- DTRACE("RQ_DLG_CALC: <CHROMA> "); ++ dml_print("DML_RQ_DLG_CALC: <CHROMA>\n"); + print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_c); +- DTRACE("RQ_DLG_CALC: drq_expansion_mode = 0x%0x", rq_regs.drq_expansion_mode); +- DTRACE("RQ_DLG_CALC: prq_expansion_mode = 0x%0x", rq_regs.prq_expansion_mode); +- DTRACE("RQ_DLG_CALC: mrq_expansion_mode = 0x%0x", rq_regs.mrq_expansion_mode); +- DTRACE("RQ_DLG_CALC: crq_expansion_mode = 0x%0x", rq_regs.crq_expansion_mode); +- DTRACE("RQ_DLG_CALC: plane1_base_address = 0x%0x", rq_regs.plane1_base_address); +- DTRACE("RQ_DLG_CALC: ===================================== "); ++ dml_print("DML_RQ_DLG_CALC: drq_expansion_mode = 0x%0x\n", rq_regs.drq_expansion_mode); ++ dml_print("DML_RQ_DLG_CALC: prq_expansion_mode = 0x%0x\n", rq_regs.prq_expansion_mode); ++ dml_print("DML_RQ_DLG_CALC: mrq_expansion_mode = 0x%0x\n", rq_regs.mrq_expansion_mode); ++ dml_print("DML_RQ_DLG_CALC: crq_expansion_mode = 0x%0x\n", rq_regs.crq_expansion_mode); ++ dml_print("DML_RQ_DLG_CALC: plane1_base_address = 0x%0x\n", rq_regs.plane1_base_address); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); + } + +-void print__dlg_regs_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_dlg_regs_st dlg_regs) ++void print__dlg_regs_st(struct display_mode_lib *mode_lib, display_dlg_regs_st dlg_regs) + { +- DTRACE("RQ_DLG_CALC: ===================================== "); +- DTRACE("RQ_DLG_CALC: DISPLAY_DLG_REGS_ST "); +- DTRACE( +- "RQ_DLG_CALC: refcyc_h_blank_end = 0x%0x", ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); ++ dml_print("DML_RQ_DLG_CALC: DISPLAY_DLG_REGS_ST\n"); ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_h_blank_end = 0x%0x\n", + dlg_regs.refcyc_h_blank_end); +- DTRACE("RQ_DLG_CALC: dlg_vblank_end = 0x%0x", dlg_regs.dlg_vblank_end); +- DTRACE( +- "RQ_DLG_CALC: min_dst_y_next_start = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: dlg_vblank_end = 0x%0x\n", ++ dlg_regs.dlg_vblank_end); ++ dml_print( ++ "DML_RQ_DLG_CALC: min_dst_y_next_start = 0x%0x\n", + dlg_regs.min_dst_y_next_start); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_htotal = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_htotal = 0x%0x\n", + dlg_regs.refcyc_per_htotal); +- DTRACE( +- "RQ_DLG_CALC: refcyc_x_after_scaler = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_x_after_scaler = 0x%0x\n", + dlg_regs.refcyc_x_after_scaler); +- DTRACE( +- "RQ_DLG_CALC: dst_y_after_scaler = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: dst_y_after_scaler = 0x%0x\n", + dlg_regs.dst_y_after_scaler); +- DTRACE("RQ_DLG_CALC: dst_y_prefetch = 0x%0x", dlg_regs.dst_y_prefetch); +- DTRACE( +- "RQ_DLG_CALC: dst_y_per_vm_vblank = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: dst_y_prefetch = 0x%0x\n", ++ dlg_regs.dst_y_prefetch); ++ dml_print( ++ "DML_RQ_DLG_CALC: dst_y_per_vm_vblank = 0x%0x\n", + dlg_regs.dst_y_per_vm_vblank); +- DTRACE( +- "RQ_DLG_CALC: dst_y_per_row_vblank = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: dst_y_per_row_vblank = 0x%0x\n", + dlg_regs.dst_y_per_row_vblank); +- DTRACE( +- "RQ_DLG_CALC: ref_freq_to_pix_freq = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: dst_y_per_vm_flip = 0x%0x\n", ++ dlg_regs.dst_y_per_vm_flip); ++ dml_print( ++ "DML_RQ_DLG_CALC: dst_y_per_row_flip = 0x%0x\n", ++ dlg_regs.dst_y_per_row_flip); ++ dml_print( ++ "DML_RQ_DLG_CALC: ref_freq_to_pix_freq = 0x%0x\n", + dlg_regs.ref_freq_to_pix_freq); +- DTRACE("RQ_DLG_CALC: vratio_prefetch = 0x%0x", dlg_regs.vratio_prefetch); +- DTRACE( +- "RQ_DLG_CALC: vratio_prefetch_c = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: vratio_prefetch = 0x%0x\n", ++ dlg_regs.vratio_prefetch); ++ dml_print( ++ "DML_RQ_DLG_CALC: vratio_prefetch_c = 0x%0x\n", + dlg_regs.vratio_prefetch_c); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_pte_group_vblank_l = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_l = 0x%0x\n", + dlg_regs.refcyc_per_pte_group_vblank_l); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_pte_group_vblank_c = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_c = 0x%0x\n", + dlg_regs.refcyc_per_pte_group_vblank_c); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_l = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_l = 0x%0x\n", + dlg_regs.refcyc_per_meta_chunk_vblank_l); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_c = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_c = 0x%0x\n", + dlg_regs.refcyc_per_meta_chunk_vblank_c); +- DTRACE( +- "RQ_DLG_CALC: dst_y_per_pte_row_nom_l = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_l = 0x%0x\n", ++ dlg_regs.refcyc_per_pte_group_flip_l); ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_c = 0x%0x\n", ++ dlg_regs.refcyc_per_pte_group_flip_c); ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_l = 0x%0x\n", ++ dlg_regs.refcyc_per_meta_chunk_flip_l); ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_c = 0x%0x\n", ++ dlg_regs.refcyc_per_meta_chunk_flip_c); ++ dml_print( ++ "DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_l = 0x%0x\n", + dlg_regs.dst_y_per_pte_row_nom_l); +- DTRACE( +- "RQ_DLG_CALC: dst_y_per_pte_row_nom_c = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_c = 0x%0x\n", + dlg_regs.dst_y_per_pte_row_nom_c); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_pte_group_nom_l = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_l = 0x%0x\n", + dlg_regs.refcyc_per_pte_group_nom_l); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_pte_group_nom_c = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_c = 0x%0x\n", + dlg_regs.refcyc_per_pte_group_nom_c); +- DTRACE( +- "RQ_DLG_CALC: dst_y_per_meta_row_nom_l = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_l = 0x%0x\n", + dlg_regs.dst_y_per_meta_row_nom_l); +- DTRACE( +- "RQ_DLG_CALC: dst_y_per_meta_row_nom_c = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_c = 0x%0x\n", + dlg_regs.dst_y_per_meta_row_nom_c); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_meta_chunk_nom_l = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_l = 0x%0x\n", + dlg_regs.refcyc_per_meta_chunk_nom_l); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_meta_chunk_nom_c = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_c = 0x%0x\n", + dlg_regs.refcyc_per_meta_chunk_nom_c); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_line_delivery_pre_l = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_l = 0x%0x\n", + dlg_regs.refcyc_per_line_delivery_pre_l); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_line_delivery_pre_c = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_c = 0x%0x\n", + dlg_regs.refcyc_per_line_delivery_pre_c); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_line_delivery_l = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_line_delivery_l = 0x%0x\n", + dlg_regs.refcyc_per_line_delivery_l); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_line_delivery_c = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_line_delivery_c = 0x%0x\n", + dlg_regs.refcyc_per_line_delivery_c); +- DTRACE( +- "RQ_DLG_CALC: chunk_hdl_adjust_cur0 = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: chunk_hdl_adjust_cur0 = 0x%0x\n", + dlg_regs.chunk_hdl_adjust_cur0); +- DTRACE("RQ_DLG_CALC: ===================================== "); ++ dml_print( ++ "DML_RQ_DLG_CALC: dst_y_offset_cur1 = 0x%0x\n", ++ dlg_regs.dst_y_offset_cur1); ++ dml_print( ++ "DML_RQ_DLG_CALC: chunk_hdl_adjust_cur1 = 0x%0x\n", ++ dlg_regs.chunk_hdl_adjust_cur1); ++ dml_print( ++ "DML_RQ_DLG_CALC: vready_after_vcount0 = 0x%0x\n", ++ dlg_regs.vready_after_vcount0); ++ dml_print( ++ "DML_RQ_DLG_CALC: dst_y_delta_drq_limit = 0x%0x\n", ++ dlg_regs.dst_y_delta_drq_limit); ++ dml_print( ++ "DML_RQ_DLG_CALC: xfc_reg_transfer_delay = 0x%0x\n", ++ dlg_regs.xfc_reg_transfer_delay); ++ dml_print( ++ "DML_RQ_DLG_CALC: xfc_reg_precharge_delay = 0x%0x\n", ++ dlg_regs.xfc_reg_precharge_delay); ++ dml_print( ++ "DML_RQ_DLG_CALC: xfc_reg_remote_surface_flip_latency = 0x%0x\n", ++ dlg_regs.xfc_reg_remote_surface_flip_latency); ++ ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); + } + +-void print__ttu_regs_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_ttu_regs_st ttu_regs) ++void print__ttu_regs_st(struct display_mode_lib *mode_lib, display_ttu_regs_st ttu_regs) + { +- DTRACE("RQ_DLG_CALC: ===================================== "); +- DTRACE("RQ_DLG_CALC: DISPLAY_TTU_REGS_ST "); +- DTRACE( +- "RQ_DLG_CALC: qos_level_low_wm = 0x%0x", ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); ++ dml_print("DML_RQ_DLG_CALC: DISPLAY_TTU_REGS_ST\n"); ++ dml_print( ++ "DML_RQ_DLG_CALC: qos_level_low_wm = 0x%0x\n", + ttu_regs.qos_level_low_wm); +- DTRACE( +- "RQ_DLG_CALC: qos_level_high_wm = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: qos_level_high_wm = 0x%0x\n", + ttu_regs.qos_level_high_wm); +- DTRACE("RQ_DLG_CALC: min_ttu_vblank = 0x%0x", ttu_regs.min_ttu_vblank); +- DTRACE("RQ_DLG_CALC: qos_level_flip = 0x%0x", ttu_regs.qos_level_flip); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_req_delivery_pre_l = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: min_ttu_vblank = 0x%0x\n", ++ ttu_regs.min_ttu_vblank); ++ dml_print( ++ "DML_RQ_DLG_CALC: qos_level_flip = 0x%0x\n", ++ ttu_regs.qos_level_flip); ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_l = 0x%0x\n", + ttu_regs.refcyc_per_req_delivery_pre_l); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_req_delivery_l = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_l = 0x%0x\n", + ttu_regs.refcyc_per_req_delivery_l); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_req_delivery_pre_c = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_c = 0x%0x\n", + ttu_regs.refcyc_per_req_delivery_pre_c); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_req_delivery_c = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_c = 0x%0x\n", + ttu_regs.refcyc_per_req_delivery_c); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_req_delivery_cur0 = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur0 = 0x%0x\n", + ttu_regs.refcyc_per_req_delivery_cur0); +- DTRACE( +- "RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur0 = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur0 = 0x%0x\n", + ttu_regs.refcyc_per_req_delivery_pre_cur0); +- DTRACE( +- "RQ_DLG_CALC: qos_level_fixed_l = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur1 = 0x%0x\n", ++ ttu_regs.refcyc_per_req_delivery_cur1); ++ dml_print( ++ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur1 = 0x%0x\n", ++ ttu_regs.refcyc_per_req_delivery_pre_cur1); ++ dml_print( ++ "DML_RQ_DLG_CALC: qos_level_fixed_l = 0x%0x\n", + ttu_regs.qos_level_fixed_l); +- DTRACE( +- "RQ_DLG_CALC: qos_ramp_disable_l = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: qos_ramp_disable_l = 0x%0x\n", + ttu_regs.qos_ramp_disable_l); +- DTRACE( +- "RQ_DLG_CALC: qos_level_fixed_c = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: qos_level_fixed_c = 0x%0x\n", + ttu_regs.qos_level_fixed_c); +- DTRACE( +- "RQ_DLG_CALC: qos_ramp_disable_c = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: qos_ramp_disable_c = 0x%0x\n", + ttu_regs.qos_ramp_disable_c); +- DTRACE( +- "RQ_DLG_CALC: qos_level_fixed_cur0 = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: qos_level_fixed_cur0 = 0x%0x\n", + ttu_regs.qos_level_fixed_cur0); +- DTRACE( +- "RQ_DLG_CALC: qos_ramp_disable_cur0 = 0x%0x", ++ dml_print( ++ "DML_RQ_DLG_CALC: qos_ramp_disable_cur0 = 0x%0x\n", + ttu_regs.qos_ramp_disable_cur0); +- DTRACE("RQ_DLG_CALC: ===================================== "); ++ dml_print( ++ "DML_RQ_DLG_CALC: qos_level_fixed_cur1 = 0x%0x\n", ++ ttu_regs.qos_level_fixed_cur1); ++ dml_print( ++ "DML_RQ_DLG_CALC: qos_ramp_disable_cur1 = 0x%0x\n", ++ ttu_regs.qos_ramp_disable_cur1); ++ dml_print("DML_RQ_DLG_CALC: =====================================\n"); + } +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h +index 7403cca..1f24db8 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h ++++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h +@@ -22,6 +22,7 @@ + * Authors: AMD + * + */ ++ + #ifndef __DISPLAY_RQ_DLG_HELPERS_H__ + #define __DISPLAY_RQ_DLG_HELPERS_H__ + +@@ -31,36 +32,16 @@ + /* Function: Printer functions + * Print various struct + */ +-void print__rq_params_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_rq_params_st rq_param); +-void print__data_rq_sizing_params_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing); +-void print__data_rq_dlg_params_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_data_rq_dlg_params_st rq_dlg_param); +-void print__data_rq_misc_params_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_data_rq_misc_params_st rq_misc_param); +-void print__rq_dlg_params_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param); +-void print__dlg_sys_params_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param); ++void print__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param); ++void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st rq_sizing); ++void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, display_data_rq_dlg_params_st rq_dlg_param); ++void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, display_data_rq_misc_params_st rq_misc_param); ++void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, display_rq_dlg_params_st rq_dlg_param); ++void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, display_dlg_sys_params_st dlg_sys_param); + +-void print__data_rq_regs_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_data_rq_regs_st data_rq_regs); +-void print__rq_regs_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_rq_regs_st rq_regs); +-void print__dlg_regs_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_dlg_regs_st dlg_regs); +-void print__ttu_regs_st( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_ttu_regs_st ttu_regs); ++void print__data_rq_regs_st(struct display_mode_lib *mode_lib, display_data_rq_regs_st data_rq_regs); ++void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs); ++void print__dlg_regs_st(struct display_mode_lib *mode_lib, display_dlg_regs_st dlg_regs); ++void print__ttu_regs_st(struct display_mode_lib *mode_lib, display_ttu_regs_st ttu_regs); + + #endif +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c b/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c +deleted file mode 100644 +index 390f093..0000000 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c ++++ /dev/null +@@ -1,1281 +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. +- * +- * Authors: AMD +- * +- */ +-#include "display_watermark.h" +-#include "display_mode_lib.h" +- +-static void get_bytes_per_pixel( +- enum source_format_class format, +- struct _vcs_dpi_wm_calc_pipe_params_st *plane) +-{ +- switch (format) { +- case dm_444_64: +- plane->bytes_per_pixel_y = 8.0; +- plane->bytes_per_pixel_c = 0.0; +- break; +- case dm_444_32: +- plane->bytes_per_pixel_y = 4.0; +- plane->bytes_per_pixel_c = 0.0; +- break; +- case dm_444_16: +- plane->bytes_per_pixel_y = 2.0; +- plane->bytes_per_pixel_c = 0.0; +- break; +- case dm_422_10: +- plane->bytes_per_pixel_y = 4.0; +- plane->bytes_per_pixel_c = 0.0; +- break; +- case dm_422_8: +- plane->bytes_per_pixel_y = 2.0; +- plane->bytes_per_pixel_c = 0.0; +- break; +- case dm_420_8: +- plane->bytes_per_pixel_y = 1.0; +- plane->bytes_per_pixel_c = 2.0; +- break; +- case dm_420_10: +- plane->bytes_per_pixel_y = 4.0 / 3; +- plane->bytes_per_pixel_c = 8.0 / 3; +- break; +- default: +- BREAK_TO_DEBUGGER(); /* invalid format in get_bytes_per_pixel */ +- } +-} +- +-static unsigned int get_swath_width_y( +- struct _vcs_dpi_display_pipe_source_params_st *src_param, +- unsigned int num_dpp) +-{ +- unsigned int val; +- +- /* note that we don't divide by num_dpp here because we have an interface which has already split +- * any viewports +- */ +- if (src_param->source_scan == dm_horz) { +- val = src_param->viewport_width; +- } else { +- val = src_param->viewport_height; +- } +- +- return val; +-} +- +-static void get_swath_height( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_pipe_source_params_st *src_param, +- struct _vcs_dpi_wm_calc_pipe_params_st *plane, +- unsigned int swath_width_y) +-{ +- double buffer_width; +- +- if (src_param->source_format == dm_444_64 || src_param->source_format == dm_444_32 +- || src_param->source_format == dm_444_16) { +- if (src_param->sw_mode == dm_sw_linear) { +- plane->swath_height_y = 1; +- } else if (src_param->source_format == dm_444_64) { +- plane->swath_height_y = 4; +- } else { +- plane->swath_height_y = 8; +- } +- +- if (src_param->source_scan != dm_horz) { +- plane->swath_height_y = 256 / (unsigned int) plane->bytes_per_pixel_y +- / plane->swath_height_y; +- } +- +- plane->swath_height_c = 0; +- +- } else { +- if (src_param->sw_mode == dm_sw_linear) { +- plane->swath_height_y = 1; +- plane->swath_height_c = 1; +- } else if (src_param->source_format == dm_420_8) { +- plane->swath_height_y = 16; +- plane->swath_height_c = 8; +- } else { +- plane->swath_height_y = 8; +- plane->swath_height_c = 8; +- } +- +- if (src_param->source_scan != dm_horz) { +- double bytes_per_pixel_c_ceil; +- +- plane->swath_height_y = 256 / dml_ceil(plane->bytes_per_pixel_y) +- / plane->swath_height_y; +- +- bytes_per_pixel_c_ceil = dml_ceil_2(plane->bytes_per_pixel_c); +- +- plane->swath_height_c = 256 / bytes_per_pixel_c_ceil +- / plane->swath_height_c; +- } +- } +- +- /* use swath height min if buffer isn't big enough */ +- +- buffer_width = ((double) mode_lib->ip.det_buffer_size_kbytes * 1024.0 / 2.0) +- / (plane->bytes_per_pixel_y * (double) plane->swath_height_y +- + (plane->bytes_per_pixel_c / 2.0 +- * (double) plane->swath_height_c)); +- +- if ((double) swath_width_y <= buffer_width) { +- /* do nothing, just keep code structure from Gabes vba */ +- } else { +- /* substitute swath height with swath height min */ +- if (src_param->source_format == dm_444_64 || src_param->source_format == dm_444_32 +- || src_param->source_format == dm_444_16) { +- if ((src_param->sw_mode == dm_sw_linear) +- || (src_param->source_format == dm_444_64 +- && (src_param->sw_mode == dm_sw_4kb_s +- || src_param->sw_mode +- == dm_sw_4kb_s_x +- || src_param->sw_mode +- == dm_sw_64kb_s +- || src_param->sw_mode +- == dm_sw_64kb_s_t +- || src_param->sw_mode +- == dm_sw_64kb_s_x +- || src_param->sw_mode +- == dm_sw_var_s +- || src_param->sw_mode +- == dm_sw_var_s_x) +- && src_param->source_scan == dm_horz)) { +- /* do nothing, just keep code structure from Gabes vba */ +- } else { +- plane->swath_height_y = plane->swath_height_y / 2; +- } +- } else { +- if (src_param->sw_mode == dm_sw_linear) { +- /* do nothing, just keep code structure from Gabes vba */ +- } else if (src_param->source_format == dm_420_8 +- && src_param->source_scan == dm_horz) { +- plane->swath_height_y = plane->swath_height_y / 2; +- } else if (src_param->source_format == dm_420_10 +- && src_param->source_scan == dm_horz) { +- plane->swath_height_c = plane->swath_height_c / 2; +- } +- } +- } +- +- if (plane->swath_height_c == 0) { +- plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0; +- } else if (plane->swath_height_c <= plane->swath_height_y) { +- plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0 / 2.0; +- } else { +- plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0 * 2.0 / 3.0; +- } +-} +- +-static void calc_display_pipe_line_delivery_time( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes) +-{ +- unsigned int i; +- +- for (i = 0; i < num_planes; i++) { +- if (planes[i].v_ratio <= 1.0) { +- planes[i].display_pipe_line_delivery_time = planes[i].swath_width_y +- * planes[i].num_dpp / planes[i].h_ratio +- / planes[i].pixclk_mhz; +- } else { +- double dchub_pscl_bw_per_clk; +- +- if (planes[i].h_ratio > 1) { +- double num_hscl_kernels; +- +- num_hscl_kernels = dml_ceil((double) planes[i].h_taps / 6); +- dchub_pscl_bw_per_clk = +- dml_min( +- (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk, +- mode_lib->ip.max_pscl_lb_bw_pix_per_clk +- * planes[i].h_ratio +- / num_hscl_kernels); +- } else { +- dchub_pscl_bw_per_clk = +- dml_min( +- (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk, +- (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk); +- } +- +- planes[i].display_pipe_line_delivery_time = planes[i].swath_width_y +- / dchub_pscl_bw_per_clk / planes[i].dppclk_mhz; +- } +- } +-} +- +-static double calc_total_data_read_bw( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes) +-{ +- double val = 0.0; +- unsigned int i; +- +- for (i = 0; i < num_planes; i++) { +- double swath_width_y_plane = planes[i].swath_width_y * planes[i].num_dpp; +- +- planes[i].read_bw = swath_width_y_plane +- * (dml_ceil(planes[i].bytes_per_pixel_y) +- + dml_ceil_2(planes[i].bytes_per_pixel_c) / 2) +- / (planes[i].h_total / planes[i].pixclk_mhz) * planes[i].v_ratio; +- +- val += planes[i].read_bw; +- +- DTRACE("plane[%d] start", i); +- DTRACE("read_bw = %f", planes[i].read_bw); +- DTRACE("plane[%d] end", i); +- } +- +- return val; +-} +- +-double dml_wm_calc_total_data_read_bw( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes) +-{ +- return calc_total_data_read_bw(mode_lib, planes, num_planes); +-} +- +-static double calc_dcfclk_mhz( +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes) +-{ +- double dcfclk_mhz = -1.0; +- unsigned int i; +- +- for (i = 0; i < num_planes; i++) { +- /* voltage and dcfclk must be the same for all pipes */ +- ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == planes[i].dcfclk_mhz); +- dcfclk_mhz = planes[i].dcfclk_mhz; +- } +- +- return dcfclk_mhz; +-} +- +-static enum voltage_state find_voltage( +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes) +-{ +- int voltage = -1; +- unsigned int i; +- +- for (i = 0; i < num_planes; i++) { +- ASSERT(voltage == -1 || voltage == planes[i].voltage); +- voltage = planes[i].voltage; +- } +- +- return (enum voltage_state) voltage; +-} +- +-static bool find_dcc_enable(struct _vcs_dpi_wm_calc_pipe_params_st *planes, unsigned int num_planes) +-{ +- unsigned int i; +- +- for (i = 0; i < num_planes; i++) { +- if (planes[i].dcc_enable) { +- return true; +- } +- } +- +- return false; +-} +- +-static double calc_return_bw( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes) +-{ +- struct _vcs_dpi_soc_bounding_box_st *soc; +- double return_bw_mbps; +- double dcfclk_mhz; +- double return_bus_bw; +- enum voltage_state voltage; +- double return_bw_to_dcn; +- bool dcc_enable; +- double rob_chunk_diff; +- double urgent_latency_traffic; +- double critical_compression; +- struct _vcs_dpi_voltage_scaling_st state; +- +- soc = &mode_lib->soc; +- +- dcfclk_mhz = calc_dcfclk_mhz(planes, num_planes); +- return_bus_bw = dcfclk_mhz * soc->return_bus_width_bytes; +- +- DTRACE("INTERMEDIATE dcfclk_mhz = %f", dcfclk_mhz); +- DTRACE("INTERMEDIATE return_bus_bw = %f", return_bus_bw); +- +- voltage = find_voltage(planes, num_planes); +- return_bw_to_dcn = dml_socbb_return_bw_mhz(soc, voltage); +- +- dcc_enable = find_dcc_enable(planes, num_planes); +- +- return_bw_mbps = return_bw_to_dcn; +- DTRACE("INTERMEDIATE return_bw_mbps = %f", return_bw_mbps); +- +- rob_chunk_diff = +- (mode_lib->ip.rob_buffer_size_kbytes - mode_lib->ip.pixel_chunk_size_kbytes) +- * 1024.0; +- DTRACE("INTERMEDIATE rob_chunk_diff = %f", rob_chunk_diff); +- +- if (dcc_enable && return_bw_to_dcn > return_bus_bw / 4) { +- double dcc_return_bw = +- return_bw_to_dcn * 4.0 +- * (1.0 +- - soc->urgent_latency_us +- / (rob_chunk_diff +- / (return_bw_to_dcn +- - return_bus_bw +- / 4.0) +- + soc->urgent_latency_us)); +- return_bw_mbps = dml_min(return_bw_mbps, dcc_return_bw); +- DTRACE("INTERMEDIATE dcc_return_bw = %f", dcc_return_bw); +- } +- +- urgent_latency_traffic = return_bus_bw * soc->urgent_latency_us; +- DTRACE("INTERMEDIATE urgent_latency_traffic = %f", urgent_latency_traffic); +- critical_compression = 2.0 * urgent_latency_traffic +- / (return_bw_to_dcn * soc->urgent_latency_us + rob_chunk_diff); +- DTRACE("INTERMEDIATE critical_compression = %f", critical_compression); +- +- if (dcc_enable && critical_compression > 1.0 && critical_compression < 4.0) { +- double crit_return_bw = (4 * return_bw_to_dcn * rob_chunk_diff +- * urgent_latency_traffic); +- crit_return_bw = crit_return_bw +- / dml_pow( +- return_bw_to_dcn * soc->urgent_latency_us +- + rob_chunk_diff, +- 2); +- DTRACE("INTERMEDIATE critical_return_bw = %f", crit_return_bw); +- return_bw_mbps = dml_min(return_bw_mbps, crit_return_bw); +- } +- +- /* Gabe does this again for some reason using the value of return_bw_mpbs from the previous calculation +- * and a lightly different return_bw_to_dcn +- */ +- +- state = dml_socbb_voltage_scaling(soc, voltage); +- return_bw_to_dcn = dml_min( +- soc->return_bus_width_bytes * dcfclk_mhz, +- state.dram_bw_per_chan_gbps * 1000.0 * (double) soc->num_chans); +- +- DTRACE("INTERMEDIATE rob_chunk_diff = %f", rob_chunk_diff); +- +- if (dcc_enable && return_bw_to_dcn > return_bus_bw / 4) { +- double dcc_return_bw = +- return_bw_to_dcn * 4.0 +- * (1.0 +- - soc->urgent_latency_us +- / (rob_chunk_diff +- / (return_bw_to_dcn +- - return_bus_bw +- / 4.0) +- + soc->urgent_latency_us)); +- return_bw_mbps = dml_min(return_bw_mbps, dcc_return_bw); +- DTRACE("INTERMEDIATE dcc_return_bw = %f", dcc_return_bw); +- } +- +- urgent_latency_traffic = return_bus_bw * soc->urgent_latency_us; +- DTRACE("INTERMEDIATE urgent_latency_traffic = %f", urgent_latency_traffic); +- critical_compression = 2.0 * urgent_latency_traffic +- / (return_bw_to_dcn * soc->urgent_latency_us + rob_chunk_diff); +- DTRACE("INTERMEDIATE critical_compression = %f", critical_compression); +- +- /* problem here? */ +- if (dcc_enable && critical_compression > 1.0 && critical_compression < 4.0) { +- double crit_return_bw = (4 * return_bw_to_dcn * rob_chunk_diff +- * urgent_latency_traffic); +- crit_return_bw = crit_return_bw +- / dml_pow( +- return_bw_to_dcn * soc->urgent_latency_us +- + rob_chunk_diff, +- 2); +- DTRACE("INTERMEDIATE critical_return_bw = %f", crit_return_bw); +- DTRACE("INTERMEDIATE return_bw_to_dcn = %f", return_bw_to_dcn); +- DTRACE("INTERMEDIATE rob_chunk_diff = %f", rob_chunk_diff); +- DTRACE("INTERMEDIATE urgent_latency_traffic = %f", urgent_latency_traffic); +- +- return_bw_mbps = dml_min(return_bw_mbps, crit_return_bw); +- } +- +- DTRACE("INTERMEDIATE final return_bw_mbps = %f", return_bw_mbps); +- return return_bw_mbps; +-} +- +-double dml_wm_calc_return_bw( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes) +-{ +- return calc_return_bw(mode_lib, planes, num_planes); +-} +- +-static double calc_last_pixel_of_line_extra_wm_us( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes) +-{ +- double val = 0.0; +- double total_data_read_bw = calc_total_data_read_bw(mode_lib, planes, num_planes); +- int voltage = -1; +- unsigned int i; +- double return_bw_mbps; +- +- for (i = 0; i < num_planes; i++) { +- /* voltage mode must be the same for all pipes */ +- ASSERT(voltage == -1 || voltage == planes[i].voltage); +- voltage = planes[i].voltage; +- } +- return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes); +- +- for (i = 0; i < num_planes; i++) { +- double bytes_pp_y = dml_ceil(planes[i].bytes_per_pixel_y); +- double bytes_pp_c = dml_ceil_2(planes[i].bytes_per_pixel_c); +- double swath_bytes_y = (double) planes[i].swath_width_y +- * (double) planes[i].swath_height_y * (double) bytes_pp_y; +- double swath_bytes_c = ((double) planes[i].swath_width_y / 2.0) +- * (double) planes[i].swath_height_c * (double) bytes_pp_c; +- double data_fabric_line_delivery_time = (swath_bytes_y + swath_bytes_c) +- / (return_bw_mbps * planes[i].read_bw / (double) planes[i].num_dpp +- / total_data_read_bw); +- +- DTRACE( +- "bytes_pp_y = %f, swath_width_y = %f, swath_height_y = %f, swath_bytes_y = %f", +- bytes_pp_y, +- (double) planes[i].swath_width_y, +- (double) planes[i].swath_height_y, +- swath_bytes_y); +- DTRACE( +- "bytes_pp_c = %f, swath_width_c = %f, swath_height_c = %f, swath_bytes_c = %f", +- bytes_pp_c, +- ((double) planes[i].swath_width_y / 2.0), +- (double) planes[i].swath_height_c, +- swath_bytes_c); +- DTRACE( +- "return_bw_mbps = %f, read_bw = %f, num_dpp = %d, total_data_read_bw = %f", +- return_bw_mbps, +- planes[i].read_bw, +- planes[i].num_dpp, +- total_data_read_bw); +- DTRACE("data_fabric_line_delivery_time = %f", data_fabric_line_delivery_time); +- DTRACE( +- "display_pipe_line_delivery_time = %f", +- planes[i].display_pipe_line_delivery_time); +- +- val = dml_max( +- val, +- data_fabric_line_delivery_time +- - planes[i].display_pipe_line_delivery_time); +- } +- +- DTRACE("last_pixel_of_line_extra_wm is %f us", val); +- return val; +-} +- +-static bool calc_pte_enable(struct _vcs_dpi_wm_calc_pipe_params_st *planes, unsigned int num_planes) +-{ +- unsigned int i; +- +- for (i = 0; i < num_planes; i++) { +- if (planes[i].pte_enable) { +- return true; +- } +- } +- +- return false; +-} +- +-static void calc_lines_in_det_y(struct _vcs_dpi_wm_calc_pipe_params_st *plane) +-{ +- plane->lines_in_det_y = plane->det_buffer_size_y / plane->bytes_per_pixel_y +- / plane->swath_width_y; +- plane->lines_in_det_y_rounded_down_to_swath = dml_floor( +- (double) plane->lines_in_det_y / plane->swath_height_y) +- * plane->swath_height_y; +- plane->full_det_buffering_time = plane->lines_in_det_y_rounded_down_to_swath +- * (plane->h_total / plane->pixclk_mhz); +-} +- +-/* CHECKME: not obviously 1:1 with calculation described in architectural +- * document or spreadsheet */ +-static void calc_dcfclk_deepsleep_mhz_per_plane( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *plane) +-{ +- double bus_width_per_pixel; +- +- if (plane->swath_height_c == 0) { +- bus_width_per_pixel = dml_ceil(plane->bytes_per_pixel_y) / 64; +- } else { +- double bus_width_per_pixel_c; +- +- bus_width_per_pixel = dml_ceil(plane->bytes_per_pixel_y) / 32; +- bus_width_per_pixel_c = dml_ceil(plane->bytes_per_pixel_c) / 32; +- if (bus_width_per_pixel < bus_width_per_pixel_c) +- bus_width_per_pixel = bus_width_per_pixel_c; +- } +- +- if (plane->v_ratio <= 1) { +- plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->pixclk_mhz / plane->num_dpp +- * plane->h_ratio * bus_width_per_pixel; +- } else if (plane->h_ratio > 1) { +- double num_hscl_kernels = dml_ceil((double) plane->h_taps / 6); +- double dchub_pscl_bw_per_clk = dml_min( +- (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk, +- mode_lib->ip.max_pscl_lb_bw_pix_per_clk * plane->h_ratio +- / num_hscl_kernels); +- +- plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->dppclk_mhz +- * dchub_pscl_bw_per_clk * bus_width_per_pixel; +- } else { +- double dchub_pscl_bw_per_clk = dml_min( +- (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk, +- (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk); +- +- plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->dppclk_mhz +- * dchub_pscl_bw_per_clk * bus_width_per_pixel; +- } +- +- plane->dcfclk_deepsleep_mhz_per_plane = dml_max( +- plane->dcfclk_deepsleep_mhz_per_plane, +- plane->pixclk_mhz / 16); +-} +- +-/* Implementation of expected stutter efficiency from DCN1_Display_Mode.docx */ +-double dml_wm_expected_stutter_eff_e2e( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- unsigned int num_pipes) +-{ +- double min_full_det_buffering_time_us; +- double frame_time_for_min_full_det_buffering_time_us = 0.0; +- struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param; +- unsigned int num_planes; +- unsigned int i; +- double total_data_read_bw_mbps; +- double average_read_bw_gbps; +- double min_full_det_buffer_size_bytes; +- double rob_fill_size_bytes; +- double part_of_burst_that_fits_in_rob; +- int voltage; +- double dcfclk_mhz; +- unsigned int total_writeback; +- double return_bw_mbps; +- double stutter_burst_time_us; +- double stutter_eff_not_including_vblank; +- double smallest_vblank_us; +- double stutter_eff; +- +- memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param)); +- DTRACE("calculating expected stutter efficiency"); +- +- num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, planes); +- +- for (i = 0; i < num_planes; i++) { +- calc_lines_in_det_y(&planes[i]); +- +- DTRACE("swath width y plane %d = %d", i, planes[i].swath_width_y); +- DTRACE("swath height y plane %d = %d", i, planes[i].swath_height_y); +- DTRACE( +- "bytes per pixel det y plane %d = %f", +- i, +- planes[i].bytes_per_pixel_y); +- DTRACE( +- "bytes per pixel det c plane %d = %f", +- i, +- planes[i].bytes_per_pixel_c); +- DTRACE( +- "det buffer size plane %d = %d", +- i, +- planes[i].det_buffer_size_y); +- DTRACE("lines in det plane %d = %d", i, planes[i].lines_in_det_y); +- DTRACE( +- "lines in det rounded to swaths plane %d = %d", +- i, +- planes[i].lines_in_det_y_rounded_down_to_swath); +- } +- +- min_full_det_buffering_time_us = 9999.0; +- for (i = 0; i < num_planes; i++) { +- if (planes[i].full_det_buffering_time < min_full_det_buffering_time_us) { +- min_full_det_buffering_time_us = planes[i].full_det_buffering_time; +- frame_time_for_min_full_det_buffering_time_us = (double) planes[i].v_total +- * planes[i].h_total / planes[i].pixclk_mhz; +- } +- } +- +- DTRACE("INTERMEDIATE: min_full_det_buffering_time_us = %f", min_full_det_buffering_time_us); +- +- total_data_read_bw_mbps = calc_total_data_read_bw(mode_lib, planes, num_planes); +- +- average_read_bw_gbps = 0.0; +- +- for (i = 0; i < num_planes; i++) { +- if (planes[i].dcc_enable) { +- average_read_bw_gbps += planes[i].read_bw / planes[i].dcc_rate / 1000; +- } else { +- average_read_bw_gbps += planes[i].read_bw / 1000; +- } +- +- if (planes[i].dcc_enable) { +- average_read_bw_gbps += planes[i].read_bw / 1000 / 256; +- } +- +- if (planes[i].pte_enable) { +- average_read_bw_gbps += planes[i].read_bw / 1000 / 512; +- } +- } +- +- min_full_det_buffer_size_bytes = min_full_det_buffering_time_us * total_data_read_bw_mbps; +- rob_fill_size_bytes = mode_lib->ip.rob_buffer_size_kbytes * 1024 * total_data_read_bw_mbps +- / (average_read_bw_gbps * 1000); +- part_of_burst_that_fits_in_rob = dml_min( +- min_full_det_buffer_size_bytes, +- rob_fill_size_bytes); +- +- voltage = -1; +- dcfclk_mhz = -1.0; +- total_writeback = 0; +- +- for (i = 0; i < num_pipes; i++) { +- /* voltage and dcfclk must be the same for all pipes */ +- ASSERT(voltage == -1 || voltage == e2e[i].clks_cfg.voltage); +- voltage = e2e[i].clks_cfg.voltage; +- ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == e2e[i].clks_cfg.dcfclk_mhz); +- dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz; +- +- if (e2e[i].dout.output_type == dm_wb) +- total_writeback++; +- } +- +- return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes); +- +- DTRACE("INTERMEDIATE: part_of_burst_that_fits_in_rob = %f", part_of_burst_that_fits_in_rob); +- DTRACE("INTERMEDIATE: average_read_bw_gbps = %f", average_read_bw_gbps); +- DTRACE("INTERMEDIATE: total_data_read_bw_mbps = %f", total_data_read_bw_mbps); +- DTRACE("INTERMEDIATE: return_bw_mbps = %f", return_bw_mbps); +- +- stutter_burst_time_us = part_of_burst_that_fits_in_rob * (average_read_bw_gbps * 1000) +- / total_data_read_bw_mbps / return_bw_mbps +- + (min_full_det_buffering_time_us * total_data_read_bw_mbps +- - part_of_burst_that_fits_in_rob) / (dcfclk_mhz * 64); +- DTRACE("INTERMEDIATE: stutter_burst_time_us = %f", stutter_burst_time_us); +- +- if (total_writeback == 0) { +- stutter_eff_not_including_vblank = (1.0 +- - ((mode_lib->soc.sr_exit_time_us + stutter_burst_time_us) +- / min_full_det_buffering_time_us)) * 100.0; +- } else { +- stutter_eff_not_including_vblank = 0.0; +- } +- +- DTRACE("stutter_efficiency_not_including_vblank = %f", stutter_eff_not_including_vblank); +- +- smallest_vblank_us = 9999.0; +- +- for (i = 0; i < num_pipes; i++) { +- double vblank_us; +- if (e2e[i].pipe.dest.syncronized_vblank_all_planes != 0 || num_pipes == 1) { +- vblank_us = (double) (e2e[i].pipe.dest.vtotal + 1 +- - e2e[i].pipe.dest.vblank_start +- + e2e[i].pipe.dest.vblank_end * e2e[i].pipe.dest.htotal) +- / e2e[i].pipe.dest.pixel_rate_mhz; +- } else { +- vblank_us = 0.0; +- } +- +- smallest_vblank_us = dml_min(smallest_vblank_us, vblank_us); +- } +- +- DTRACE("smallest vblank = %f us", smallest_vblank_us); +- +- stutter_eff = 100.0 +- * (((stutter_eff_not_including_vblank / 100.0) +- * (frame_time_for_min_full_det_buffering_time_us +- - smallest_vblank_us) + smallest_vblank_us) +- / frame_time_for_min_full_det_buffering_time_us); +- +- DTRACE("stutter_efficiency = %f", stutter_eff); +- +- return stutter_eff_not_including_vblank; +-} +- +-double dml_wm_expected_stutter_eff_e2e_with_vblank( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- unsigned int num_pipes) +-{ +- double min_full_det_buffering_time_us; +- double frame_time_for_min_full_det_buffering_time_us = 0.0; +- struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param; +- unsigned int num_planes; +- unsigned int i; +- double total_data_read_bw_mbps; +- double average_read_bw_gbps; +- double min_full_det_buffer_size_bytes; +- double rob_fill_size_bytes; +- double part_of_burst_that_fits_in_rob; +- int voltage; +- double dcfclk_mhz; +- unsigned int total_writeback; +- double return_bw_mbps; +- double stutter_burst_time_us; +- double stutter_eff_not_including_vblank; +- double smallest_vblank_us; +- double stutter_eff; +- +- memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param)); +- num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, planes); +- +- for (i = 0; i < num_planes; i++) { +- calc_lines_in_det_y(&planes[i]); +- } +- +- min_full_det_buffering_time_us = 9999.0; +- for (i = 0; i < num_planes; i++) { +- if (planes[i].full_det_buffering_time < min_full_det_buffering_time_us) { +- min_full_det_buffering_time_us = planes[i].full_det_buffering_time; +- frame_time_for_min_full_det_buffering_time_us = (double) planes[i].v_total +- * planes[i].h_total / planes[i].pixclk_mhz; +- } +- } +- +- total_data_read_bw_mbps = calc_total_data_read_bw(mode_lib, planes, num_planes); +- average_read_bw_gbps = 0.0; +- +- for (i = 0; i < num_planes; i++) { +- if (planes[i].dcc_enable) { +- average_read_bw_gbps += planes[i].read_bw / planes[i].dcc_rate / 1000; +- } else { +- average_read_bw_gbps += planes[i].read_bw / 1000; +- } +- +- if (planes[i].dcc_enable) { +- average_read_bw_gbps += planes[i].read_bw / 1000 / 256; +- } +- +- if (planes[i].pte_enable) { +- average_read_bw_gbps += planes[i].read_bw / 1000 / 512; +- } +- } +- +- min_full_det_buffer_size_bytes = min_full_det_buffering_time_us * total_data_read_bw_mbps; +- rob_fill_size_bytes = mode_lib->ip.rob_buffer_size_kbytes * 1024 * total_data_read_bw_mbps +- / (average_read_bw_gbps * 1000); +- part_of_burst_that_fits_in_rob = dml_min( +- min_full_det_buffer_size_bytes, +- rob_fill_size_bytes); +- +- voltage = -1; +- dcfclk_mhz = -1.0; +- total_writeback = 0; +- +- for (i = 0; i < num_pipes; i++) { +- /* voltage and dcfclk must be the same for all pipes */ +- ASSERT(voltage == -1 || voltage == e2e[i].clks_cfg.voltage); +- voltage = e2e[i].clks_cfg.voltage; +- ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == e2e[i].clks_cfg.dcfclk_mhz); +- dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz; +- +- if (e2e[i].dout.output_type == dm_wb) +- total_writeback++; +- } +- +- return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes); +- +- stutter_burst_time_us = part_of_burst_that_fits_in_rob * (average_read_bw_gbps * 1000) +- / total_data_read_bw_mbps / return_bw_mbps +- + (min_full_det_buffering_time_us * total_data_read_bw_mbps +- - part_of_burst_that_fits_in_rob) / (dcfclk_mhz * 64); +- +- if (total_writeback == 0) { +- stutter_eff_not_including_vblank = (1.0 +- - ((mode_lib->soc.sr_exit_time_us + stutter_burst_time_us) +- / min_full_det_buffering_time_us)) * 100.0; +- } else { +- stutter_eff_not_including_vblank = 0.0; +- } +- +- smallest_vblank_us = 9999.0; +- +- for (i = 0; i < num_pipes; i++) { +- double vblank_us; +- if (e2e[i].pipe.dest.syncronized_vblank_all_planes != 0 || num_pipes == 1) { +- vblank_us = (double) (e2e[i].pipe.dest.vtotal + 1 +- - e2e[i].pipe.dest.vblank_start +- + e2e[i].pipe.dest.vblank_end * e2e[i].pipe.dest.htotal) +- / e2e[i].pipe.dest.pixel_rate_mhz; +- } else { +- vblank_us = 0.0; +- } +- +- smallest_vblank_us = dml_min(smallest_vblank_us, vblank_us); +- } +- +- stutter_eff = 100.0 +- * (((stutter_eff_not_including_vblank / 100.0) +- * (frame_time_for_min_full_det_buffering_time_us +- - smallest_vblank_us) + smallest_vblank_us) +- / frame_time_for_min_full_det_buffering_time_us); +- +- +- return stutter_eff; +-} +- +-double urgent_extra_calc( +- struct display_mode_lib *mode_lib, +- double dcfclk_mhz, +- double return_bw_mbps, +- unsigned int total_active_dpp, +- unsigned int total_dcc_active_dpp) +-{ +- double urgent_extra_latency_us = 0.0; +- double urgent_round_trip_ooo_latency_us; +- +- urgent_round_trip_ooo_latency_us = +- (((double) mode_lib->soc.round_trip_ping_latency_dcfclk_cycles + 32) +- / dcfclk_mhz) +- + (((double) (mode_lib->soc.urgent_out_of_order_return_per_channel_bytes +- * mode_lib->soc.num_chans)) / return_bw_mbps); +- +- DTRACE( +- "INTERMEDIATE round_trip_ping_latency_dcfclk_cycles = %d", +- mode_lib->soc.round_trip_ping_latency_dcfclk_cycles); +- DTRACE("INTERMEDIATE dcfclk_mhz = %f", dcfclk_mhz); +- DTRACE( +- "INTERMEDIATE urgent_out_of_order_return_per_channel_bytes = %d", +- mode_lib->soc.urgent_out_of_order_return_per_channel_bytes); +- +- urgent_extra_latency_us = urgent_round_trip_ooo_latency_us +- + ((double) total_active_dpp * mode_lib->ip.pixel_chunk_size_kbytes +- + (double) total_dcc_active_dpp +- * mode_lib->ip.meta_chunk_size_kbytes) +- * 1024.0 / return_bw_mbps; /* to us */ +- +- DTRACE( +- "INTERMEDIATE urgent_round_trip_ooo_latency_us = %f", +- urgent_round_trip_ooo_latency_us); +- DTRACE("INTERMEDIATE total_active_dpp = %d", total_active_dpp); +- DTRACE( +- "INTERMEDIATE pixel_chunk_size_kbytes = %d", +- mode_lib->ip.pixel_chunk_size_kbytes); +- DTRACE("INTERMEDIATE total_dcc_active_dpp = %d", total_dcc_active_dpp); +- DTRACE( +- "INTERMEDIATE meta_chunk_size_kbyte = %d", +- mode_lib->ip.meta_chunk_size_kbytes); +- DTRACE("INTERMEDIATE return_bw_mbps = %f", return_bw_mbps); +- +- return urgent_extra_latency_us; +-} +- +-double dml_wm_urgent_extra_max(struct display_mode_lib *mode_lib) +-{ +- unsigned int total_active_dpp = DC__NUM_DPP; +- unsigned int total_dcc_active_dpp = total_active_dpp; +- double urgent_extra_latency_us = 0.0; +- double dcfclk_mhz = 0.0; +- double return_bw_mbps = 0.0; +- int voltage = dm_vmin; +- +- /* use minimum voltage */ +- return_bw_mbps = dml_socbb_return_bw_mhz(&mode_lib->soc, (enum voltage_state) voltage); +- /* use minimum dcfclk */ +- dcfclk_mhz = mode_lib->soc.vmin.dcfclk_mhz; +- /* use max dpps and dpps with dcc */ +- +- urgent_extra_latency_us = urgent_extra_calc( +- mode_lib, +- dcfclk_mhz, +- return_bw_mbps, +- total_active_dpp, +- total_dcc_active_dpp); +- +- DTRACE("urgent extra max = %f", urgent_extra_latency_us); +- return urgent_extra_latency_us; +-} +- +-double dml_wm_urgent_extra( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *pipes, +- unsigned int num_pipes) +-{ +- unsigned int total_active_dpp = 0; +- unsigned int total_dcc_active_dpp = 0; +- double urgent_extra_latency_us = 0.0; +- double dcfclk_mhz = 0.0; +- double return_bw_mbps = 0.0; +- int voltage = -1; +- bool pte_enable = false; +- unsigned int i; +- +- for (i = 0; i < num_pipes; i++) { +- /* num_dpp must be greater than 0 */ +- ASSERT(pipes[i].num_dpp > 0); +- +- /* voltage mode must be the same for all pipes */ +- ASSERT(voltage == -1 || voltage == pipes[i].voltage); +- voltage = pipes[i].voltage; +- +- /* dcfclk for all pipes must be the same */ +- ASSERT(dcfclk_mhz == 0.0 || dcfclk_mhz == pipes[i].dcfclk_mhz); +- dcfclk_mhz = pipes[i].dcfclk_mhz; +- +- total_active_dpp += pipes[i].num_dpp; +- +- if (pipes[i].dcc_enable) { +- total_dcc_active_dpp += pipes[i].num_dpp; +- } +- } +- +- DTRACE("total active dpps %d", total_active_dpp); +- DTRACE("total active dpps with dcc %d", total_dcc_active_dpp); +- DTRACE("voltage state is %d", voltage); +- +- return_bw_mbps = calc_return_bw(mode_lib, pipes, num_pipes); +- +- DTRACE("return_bandwidth is %f MBps", return_bw_mbps); +- +- pte_enable = calc_pte_enable(pipes, num_pipes); +- +- /* calculate the maximum extra latency just for comparison purposes */ +- /* dml_wm_urgent_extra_max(); */ +- urgent_extra_latency_us = urgent_extra_calc( +- mode_lib, +- dcfclk_mhz, +- return_bw_mbps, +- total_active_dpp, +- total_dcc_active_dpp); +- +- DTRACE("INTERMEDIATE urgent_extra_latency_us_before_pte = %f", urgent_extra_latency_us); +- +- if (pte_enable) { +- urgent_extra_latency_us += total_active_dpp * mode_lib->ip.pte_chunk_size_kbytes +- * 1024.0 / return_bw_mbps; +- +- DTRACE("INTERMEDIATE pte_enable = true"); +- DTRACE("INTERMEDIATE total_active_dpp = %d", total_active_dpp); +- DTRACE( +- "INTERMEDIATE pte_chunk_size_kbytes = %d", +- mode_lib->ip.pte_chunk_size_kbytes); +- DTRACE("INTERMEDIATE return_bw_mbps = %f", return_bw_mbps); +- } +- +- return urgent_extra_latency_us; +-} +- +-double dml_wm_urgent_e2e( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *pipes, +- unsigned int num_pipes) +-{ +- struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param; +- unsigned int combined_pipes; +- double urgent_wm; +- +- memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param)); +- combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm); +- +- urgent_wm = dml_wm_urgent(mode_lib, wm, combined_pipes); +- +- return urgent_wm; +-} +- +-double dml_wm_urgent( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes) +-{ +- double urgent_watermark; +- double urgent_extra_latency_us; +- double last_pixel_of_line_extra_wm_us = 0.0; +- +- DTRACE("calculating urgent watermark"); +- calc_display_pipe_line_delivery_time(mode_lib, planes, num_planes); +- urgent_extra_latency_us = dml_wm_urgent_extra(mode_lib, planes, num_planes); +- +- last_pixel_of_line_extra_wm_us = calc_last_pixel_of_line_extra_wm_us( +- mode_lib, +- planes, +- num_planes); +- +- urgent_watermark = mode_lib->soc.urgent_latency_us + last_pixel_of_line_extra_wm_us +- + urgent_extra_latency_us; +- +- DTRACE("INTERMEDIATE urgent_latency_us = %f", mode_lib->soc.urgent_latency_us); +- DTRACE("INTERMEDIATE last_pixel_of_line_extra_wm_us = %f", last_pixel_of_line_extra_wm_us); +- DTRACE("INTERMEDIATE urgent_extra_latency_us = %f", urgent_extra_latency_us); +- +- DTRACE("urgent_watermark_us = %f", urgent_watermark); +- return urgent_watermark; +-} +- +-double dml_wm_pte_meta_urgent(struct display_mode_lib *mode_lib, double urgent_wm_us) +-{ +- double val; +- +- val = urgent_wm_us + 2.0 * mode_lib->soc.urgent_latency_us; +- DTRACE("pte_meta_urgent_watermark_us = %f", val); +- +- return val; +-} +- +-double dml_wm_dcfclk_deepsleep_mhz_e2e( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *pipes, +- unsigned int num_pipes) +-{ +- struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param; +- unsigned int num_planes; +- double val; +- +- memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param)); +- num_planes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, planes); +- +- val = dml_wm_dcfclk_deepsleep_mhz(mode_lib, planes, num_planes); +- +- return val; +-} +- +-double dml_wm_dcfclk_deepsleep_mhz( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes) +-{ +- double val = 8.0; +- unsigned int i; +- +- for (i = 0; i < num_planes; i++) { +- calc_dcfclk_deepsleep_mhz_per_plane(mode_lib, &planes[i]); +- +- if (val < planes[i].dcfclk_deepsleep_mhz_per_plane) { +- val = planes[i].dcfclk_deepsleep_mhz_per_plane; +- } +- +- DTRACE("plane[%d] start", i); +- DTRACE("dcfclk_deepsleep_per_plane = %f", planes[i].dcfclk_deepsleep_mhz_per_plane); +- DTRACE("plane[%d] end", i); +- } +- +- DTRACE("dcfclk_deepsleep_mhz = %f", val); +- +- return val; +-} +- +-struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate_e2e( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *pipes, +- unsigned int num_pipes) +-{ +- struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param; +- unsigned int combined_pipes; +- struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_wm; +- +- memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param)); +- combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm); +- cstate_pstate_wm = dml_wm_cstate_pstate(mode_lib, wm, combined_pipes); +- +- +- return cstate_pstate_wm; +-} +- +-struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *pipes, +- unsigned int num_pipes) +-{ +- struct _vcs_dpi_cstate_pstate_watermarks_st wm; +- double urgent_extra_latency_us; +- double urgent_watermark_us; +- double last_pixel_of_line_extra_wm_us; +- double dcfclk_deepsleep_freq; +- +- DTRACE("calculating cstate and pstate watermarks"); +- urgent_extra_latency_us = dml_wm_urgent_extra(mode_lib, pipes, num_pipes); +- urgent_watermark_us = dml_wm_urgent(mode_lib, pipes, num_pipes); +- +- last_pixel_of_line_extra_wm_us = calc_last_pixel_of_line_extra_wm_us( +- mode_lib, +- pipes, +- num_pipes); +- dcfclk_deepsleep_freq = dml_wm_dcfclk_deepsleep_mhz(mode_lib, pipes, num_pipes); +- +- wm.cstate_exit_us = mode_lib->soc.sr_exit_time_us + last_pixel_of_line_extra_wm_us +- + urgent_extra_latency_us +- + mode_lib->ip.dcfclk_cstate_latency / dcfclk_deepsleep_freq; +- wm.cstate_enter_plus_exit_us = mode_lib->soc.sr_enter_plus_exit_time_us +- + last_pixel_of_line_extra_wm_us + urgent_extra_latency_us; +- wm.pstate_change_us = mode_lib->soc.dram_clock_change_latency_us + urgent_watermark_us; +- +- DTRACE("stutter_exit_watermark_us = %f", wm.cstate_exit_us); +- DTRACE("stutter_enter_plus_exit_watermark_us = %f", wm.cstate_enter_plus_exit_us); +- DTRACE("dram_clock_change_watermark_us = %f", wm.pstate_change_us); +- +- return wm; +-} +- +-double dml_wm_writeback_pstate_e2e( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *pipes, +- unsigned int num_pipes) +-{ +- struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param; +- unsigned int combined_pipes; +- +- memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param)); +- combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm); +- +- +- return dml_wm_writeback_pstate(mode_lib, wm, combined_pipes); +-} +- +-double dml_wm_writeback_pstate( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *pipes, +- unsigned int num_pipes) +-{ +- unsigned int total_active_wb = 0; +- double wm = 0.0; +- double socclk_mhz = 0.0; +- unsigned int i; +- +- DTRACE("calculating wb pstate watermark"); +- for (i = 0; i < num_pipes; i++) { +- if (pipes[i].output_type == dm_wb) +- total_active_wb++; +- ASSERT(socclk_mhz == 0.0 || socclk_mhz == pipes[i].socclk_mhz); +- socclk_mhz = pipes[i].socclk_mhz; +- } +- +- DTRACE("total wb outputs %d", total_active_wb); +- DTRACE("socclk frequency %f Mhz", socclk_mhz); +- +- if (total_active_wb <= 1) { +- wm = mode_lib->soc.writeback_dram_clock_change_latency_us; +- } else { +- wm = mode_lib->soc.writeback_dram_clock_change_latency_us +- + (mode_lib->ip.writeback_chunk_size_kbytes * 1024.0) / 32.0 +- / socclk_mhz; +- } +- +- DTRACE("wb pstate watermark %f us", wm); +- return wm; +-} +- +-unsigned int dml_wm_e2e_to_wm( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- unsigned int num_pipes, +- struct _vcs_dpi_wm_calc_pipe_params_st *wm) +-{ +- unsigned int num_planes = 0; +- bool visited[DC__NUM_PIPES]; +- unsigned int i, j; +- +- for (i = 0; i < num_pipes; i++) { +- visited[i] = false; +- } +- +- for (i = 0; i < num_pipes; i++) { +- unsigned int num_dpp = 1; +- +- if (visited[i]) { +- continue; +- } +- +- visited[i] = true; +- +- if (e2e[i].pipe.src.is_hsplit) { +- for (j = i + 1; j < num_pipes; j++) { +- if (e2e[j].pipe.src.is_hsplit && !visited[j] +- && (e2e[i].pipe.src.hsplit_grp +- == e2e[j].pipe.src.hsplit_grp)) { +- num_dpp++; +- visited[j] = true; +- } +- } +- } +- +- wm[num_planes].num_dpp = num_dpp; +- wm[num_planes].voltage = e2e[i].clks_cfg.voltage; +- wm[num_planes].output_type = e2e[i].dout.output_type; +- wm[num_planes].dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz; +- wm[num_planes].socclk_mhz = e2e[i].clks_cfg.socclk_mhz; +- wm[num_planes].dppclk_mhz = e2e[i].clks_cfg.dppclk_mhz; +- wm[num_planes].pixclk_mhz = e2e[i].pipe.dest.pixel_rate_mhz; +- +- wm[num_planes].pte_enable = e2e[i].pipe.src.vm; +- wm[num_planes].dcc_enable = e2e[i].pipe.src.dcc; +- wm[num_planes].dcc_rate = e2e[i].pipe.src.dcc_rate; +- +- get_bytes_per_pixel( +- (enum source_format_class) e2e[i].pipe.src.source_format, +- &wm[num_planes]); +- wm[num_planes].swath_width_y = get_swath_width_y(&e2e[i].pipe.src, num_dpp); +- get_swath_height( +- mode_lib, +- &e2e[i].pipe.src, +- &wm[num_planes], +- wm[num_planes].swath_width_y); +- +- wm[num_planes].interlace_en = e2e[i].pipe.dest.interlaced; +- wm[num_planes].h_ratio = e2e[i].pipe.scale_ratio_depth.hscl_ratio; +- wm[num_planes].v_ratio = e2e[i].pipe.scale_ratio_depth.vscl_ratio; +- if (wm[num_planes].interlace_en) { +- wm[num_planes].v_ratio = 2 * wm[num_planes].v_ratio; +- } +- wm[num_planes].h_taps = e2e[i].pipe.scale_taps.htaps; +- wm[num_planes].h_total = e2e[i].pipe.dest.htotal; +- wm[num_planes].v_total = e2e[i].pipe.dest.vtotal; +- wm[num_planes].v_active = e2e[i].pipe.dest.vactive; +- wm[num_planes].e2e_index = i; +- num_planes++; +- } +- +- for (i = 0; i < num_planes; i++) { +- DTRACE("plane[%d] start", i); +- DTRACE("voltage = %d", wm[i].voltage); +- DTRACE("v_active = %d", wm[i].v_active); +- DTRACE("h_total = %d", wm[i].h_total); +- DTRACE("v_total = %d", wm[i].v_total); +- DTRACE("pixclk_mhz = %f", wm[i].pixclk_mhz); +- DTRACE("dcfclk_mhz = %f", wm[i].dcfclk_mhz); +- DTRACE("dppclk_mhz = %f", wm[i].dppclk_mhz); +- DTRACE("h_ratio = %f", wm[i].h_ratio); +- DTRACE("v_ratio = %f", wm[i].v_ratio); +- DTRACE("interlaced = %d", wm[i].interlace_en); +- DTRACE("h_taps = %d", wm[i].h_taps); +- DTRACE("num_dpp = %d", wm[i].num_dpp); +- DTRACE("swath_width_y = %d", wm[i].swath_width_y); +- DTRACE("swath_height_y = %d", wm[i].swath_height_y); +- DTRACE("swath_height_c = %d", wm[i].swath_height_c); +- DTRACE("det_buffer_size_y = %d", wm[i].det_buffer_size_y); +- DTRACE("dcc_rate = %f", wm[i].dcc_rate); +- DTRACE("dcc_enable = %s", wm[i].dcc_enable ? "true" : "false"); +- DTRACE("pte_enable = %s", wm[i].pte_enable ? "true" : "false"); +- DTRACE("plane[%d] end", i); +- } +- +- return num_planes; +-} +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.h b/drivers/gpu/drm/amd/display/dc/dml/display_watermark.h +deleted file mode 100644 +index 94cde8b..0000000 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.h ++++ /dev/null +@@ -1,98 +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. +- * +- * Authors: AMD +- * +- */ +-#ifndef __DISPLAY_WATERMARK_H__ +-#define __DISPLAY_WATERMARK_H__ +- +-#include "dml_common_defs.h" +- +-struct display_mode_lib; +- +-double dml_wm_urgent_extra( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *pipes, +- unsigned int num_pipes); +-double dml_wm_urgent_extra_max(struct display_mode_lib *mode_lib); +- +-double dml_wm_urgent_e2e( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *pipes, +- unsigned int num_pipes); +-double dml_wm_urgent( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes); +-double dml_wm_pte_meta_urgent(struct display_mode_lib *mode_lib, double urgent_wm_us); +-double dml_wm_dcfclk_deepsleep_mhz_e2e( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *pipes, +- unsigned int num_pipes); +-double dml_wm_dcfclk_deepsleep_mhz( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes); +- +-struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate_e2e( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *pipes, +- unsigned int num_pipes); +-struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *pipes, +- unsigned int num_pipes); +- +-double dml_wm_writeback_pstate_e2e( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *pipes, +- unsigned int num_pipes); +-double dml_wm_writeback_pstate( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *pipes, +- unsigned int num_pipes); +- +-double dml_wm_expected_stutter_eff_e2e( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- unsigned int num_pipes); +-double dml_wm_expected_stutter_eff_e2e_with_vblank( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- unsigned int num_pipes); +- +-unsigned int dml_wm_e2e_to_wm( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_display_e2e_pipe_params_st *e2e, +- unsigned int num_pipes, +- struct _vcs_dpi_wm_calc_pipe_params_st *wm); +- +-double dml_wm_calc_total_data_read_bw( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes); +-double dml_wm_calc_return_bw( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_wm_calc_pipe_params_st *planes, +- unsigned int num_planes); +- +-#endif +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c +new file mode 100644 +index 0000000..8229f78 +--- /dev/null ++++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c +@@ -0,0 +1,1903 @@ ++/* ++ * 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. ++ * ++ * Authors: AMD ++ * ++ */ ++ ++#include "dml1_display_rq_dlg_calc.h" ++#include "display_mode_lib.h" ++ ++static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma) ++{ ++ unsigned int ret_val = 0; ++ ++ if (source_format == dm_444_16) { ++ if (!is_chroma) ++ ret_val = 2; ++ } else if (source_format == dm_444_32) { ++ if (!is_chroma) ++ ret_val = 4; ++ } else if (source_format == dm_444_64) { ++ if (!is_chroma) ++ ret_val = 8; ++ } else if (source_format == dm_420_8) { ++ if (is_chroma) ++ ret_val = 2; ++ else ++ ret_val = 1; ++ } else if (source_format == dm_420_10) { ++ if (is_chroma) ++ ret_val = 4; ++ else ++ ret_val = 2; ++ } ++ return ret_val; ++} ++ ++static bool is_dual_plane(enum source_format_class source_format) ++{ ++ bool ret_val = 0; ++ ++ if ((source_format == dm_420_8) || (source_format == dm_420_10)) ++ ret_val = 1; ++ ++ return ret_val; ++} ++ ++static void get_blk256_size( ++ unsigned int *blk256_width, ++ unsigned int *blk256_height, ++ unsigned int bytes_per_element) ++{ ++ if (bytes_per_element == 1) { ++ *blk256_width = 16; ++ *blk256_height = 16; ++ } else if (bytes_per_element == 2) { ++ *blk256_width = 16; ++ *blk256_height = 8; ++ } else if (bytes_per_element == 4) { ++ *blk256_width = 8; ++ *blk256_height = 8; ++ } else if (bytes_per_element == 8) { ++ *blk256_width = 8; ++ *blk256_height = 4; ++ } ++} ++ ++static double get_refcyc_per_delivery( ++ struct display_mode_lib *mode_lib, ++ double refclk_freq_in_mhz, ++ double pclk_freq_in_mhz, ++ unsigned int recout_width, ++ double vratio, ++ double hscale_pixel_rate, ++ unsigned int delivery_width, ++ unsigned int req_per_swath_ub) ++{ ++ double refcyc_per_delivery = 0.0; ++ ++ if (vratio <= 1.0) { ++ refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width ++ / pclk_freq_in_mhz / (double) req_per_swath_ub; ++ } else { ++ refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) delivery_width ++ / (double) hscale_pixel_rate / (double) req_per_swath_ub; ++ } ++ ++ DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz); ++ DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz); ++ DTRACE("DLG: %s: recout_width = %d", __func__, recout_width); ++ DTRACE("DLG: %s: vratio = %3.2f", __func__, vratio); ++ DTRACE("DLG: %s: req_per_swath_ub = %d", __func__, req_per_swath_ub); ++ DTRACE("DLG: %s: refcyc_per_delivery= %3.2f", __func__, refcyc_per_delivery); ++ ++ return refcyc_per_delivery; ++ ++} ++ ++static double get_vratio_pre( ++ struct display_mode_lib *mode_lib, ++ unsigned int max_num_sw, ++ unsigned int max_partial_sw, ++ unsigned int swath_height, ++ double vinit, ++ double l_sw) ++{ ++ double prefill = dml_floor(vinit, 1); ++ double vratio_pre = 1.0; ++ ++ vratio_pre = (max_num_sw * swath_height + max_partial_sw) / l_sw; ++ ++ if (swath_height > 4) { ++ double tmp0 = (max_num_sw * swath_height) / (l_sw - (prefill - 3.0) / 2.0); ++ ++ if (tmp0 > vratio_pre) ++ vratio_pre = tmp0; ++ } ++ ++ DTRACE("DLG: %s: max_num_sw = %0d", __func__, max_num_sw); ++ DTRACE("DLG: %s: max_partial_sw = %0d", __func__, max_partial_sw); ++ DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height); ++ DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit); ++ DTRACE("DLG: %s: vratio_pre = %3.2f", __func__, vratio_pre); ++ ++ if (vratio_pre < 1.0) { ++ DTRACE("WARNING_DLG: %s: vratio_pre=%3.2f < 1.0, set to 1.0", __func__, vratio_pre); ++ vratio_pre = 1.0; ++ } ++ ++ if (vratio_pre > 4.0) { ++ DTRACE( ++ "WARNING_DLG: %s: vratio_pre=%3.2f > 4.0 (max scaling ratio). set to 4.0", ++ __func__, ++ vratio_pre); ++ vratio_pre = 4.0; ++ } ++ ++ return vratio_pre; ++} ++ ++static void get_swath_need( ++ struct display_mode_lib *mode_lib, ++ unsigned int *max_num_sw, ++ unsigned int *max_partial_sw, ++ unsigned int swath_height, ++ double vinit) ++{ ++ double prefill = dml_floor(vinit, 1); ++ unsigned int max_partial_sw_int; ++ ++ DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height); ++ DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit); ++ ++ ASSERT(prefill > 0.0 && prefill <= 8.0); ++ ++ *max_num_sw = (unsigned int) (dml_ceil((prefill - 1.0) / (double) swath_height, 1) + 1.0); /* prefill has to be >= 1 */ ++ max_partial_sw_int = ++ (prefill == 1) ? ++ (swath_height - 1) : ++ ((unsigned int) (prefill - 2.0) % swath_height); ++ *max_partial_sw = (max_partial_sw_int < 1) ? 1 : max_partial_sw_int; /* ensure minimum of 1 is used */ ++ ++ DTRACE("DLG: %s: max_num_sw = %0d", __func__, *max_num_sw); ++ DTRACE("DLG: %s: max_partial_sw = %0d", __func__, *max_partial_sw); ++} ++ ++static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size) ++{ ++ if (tile_size == dm_256k_tile) ++ return (256 * 1024); ++ else if (tile_size == dm_64k_tile) ++ return (64 * 1024); ++ else ++ return (4 * 1024); ++} ++ ++static void extract_rq_sizing_regs( ++ struct display_mode_lib *mode_lib, ++ struct _vcs_dpi_display_data_rq_regs_st *rq_regs, ++ const struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing) ++{ ++ DTRACE("DLG: %s: rq_sizing param", __func__); ++ print__data_rq_sizing_params_st(mode_lib, rq_sizing); ++ ++ rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10; ++ ++ if (rq_sizing.min_chunk_bytes == 0) ++ rq_regs->min_chunk_size = 0; ++ else ++ rq_regs->min_chunk_size = dml_log2(rq_sizing.min_chunk_bytes) - 8 + 1; ++ ++ rq_regs->meta_chunk_size = dml_log2(rq_sizing.meta_chunk_bytes) - 10; ++ if (rq_sizing.min_meta_chunk_bytes == 0) ++ rq_regs->min_meta_chunk_size = 0; ++ else ++ rq_regs->min_meta_chunk_size = dml_log2(rq_sizing.min_meta_chunk_bytes) - 6 + 1; ++ ++ rq_regs->dpte_group_size = dml_log2(rq_sizing.dpte_group_bytes) - 6; ++ rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6; ++} ++ ++void dml1_extract_rq_regs( ++ struct display_mode_lib *mode_lib, ++ struct _vcs_dpi_display_rq_regs_st *rq_regs, ++ const struct _vcs_dpi_display_rq_params_st rq_param) ++{ ++ unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; ++ unsigned int detile_buf_plane1_addr = 0; ++ ++ extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l); ++ if (rq_param.yuv420) ++ extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c); ++ ++ rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height); ++ rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height); ++ ++ /* FIXME: take the max between luma, chroma chunk size? ++ * okay for now, as we are setting chunk_bytes to 8kb anyways ++ */ ++ if (rq_param.sizing.rq_l.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->mrq_expansion_mode = 1; ++ rq_regs->crq_expansion_mode = 1; ++ ++ if (rq_param.yuv420) { ++ if ((double) rq_param.misc.rq_l.stored_swath_bytes ++ / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) { ++ detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); /* half to chroma */ ++ } else { ++ detile_buf_plane1_addr = dml_round_to_multiple( ++ (unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0), ++ 256, ++ 0) / 64.0; /* 2/3 to chroma */ ++ } ++ } ++ rq_regs->plane1_base_address = detile_buf_plane1_addr; ++} ++ ++static void handle_det_buf_split( ++ struct display_mode_lib *mode_lib, ++ struct _vcs_dpi_display_rq_params_st *rq_param, ++ const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param) ++{ ++ unsigned int total_swath_bytes = 0; ++ unsigned int swath_bytes_l = 0; ++ unsigned int swath_bytes_c = 0; ++ unsigned int full_swath_bytes_packed_l = 0; ++ unsigned int full_swath_bytes_packed_c = 0; ++ bool req128_l = 0; ++ bool req128_c = 0; ++ bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); ++ bool surf_vert = (pipe_src_param.source_scan == dm_vert); ++ unsigned int log2_swath_height_l = 0; ++ unsigned int log2_swath_height_c = 0; ++ unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; ++ ++ full_swath_bytes_packed_l = rq_param->misc.rq_l.full_swath_bytes; ++ full_swath_bytes_packed_c = rq_param->misc.rq_c.full_swath_bytes; ++ ++ if (rq_param->yuv420_10bpc) { ++ full_swath_bytes_packed_l = dml_round_to_multiple( ++ rq_param->misc.rq_l.full_swath_bytes * 2 / 3, ++ 256, ++ 1) + 256; ++ full_swath_bytes_packed_c = dml_round_to_multiple( ++ rq_param->misc.rq_c.full_swath_bytes * 2 / 3, ++ 256, ++ 1) + 256; ++ } ++ ++ if (rq_param->yuv420) { ++ total_swath_bytes = 2 * full_swath_bytes_packed_l + 2 * full_swath_bytes_packed_c; ++ ++ if (total_swath_bytes <= detile_buf_size_in_bytes) { /*full 256b request */ ++ req128_l = 0; ++ req128_c = 0; ++ swath_bytes_l = full_swath_bytes_packed_l; ++ swath_bytes_c = full_swath_bytes_packed_c; ++ } else { /*128b request (for luma only for yuv420 8bpc) */ ++ req128_l = 1; ++ req128_c = 0; ++ swath_bytes_l = full_swath_bytes_packed_l / 2; ++ swath_bytes_c = full_swath_bytes_packed_c; ++ } ++ ++ /* Bug workaround, luma and chroma req size needs to be the same. (see: DEGVIDCN10-137) ++ * TODO: Remove after rtl fix ++ */ ++ if (req128_l == 1) { ++ req128_c = 1; ++ DTRACE("DLG: %s: bug workaround DEGVIDCN10-137", __func__); ++ } ++ ++ /* Note: assumption, the config that pass in will fit into ++ * the detiled buffer. ++ */ ++ } else { ++ total_swath_bytes = 2 * full_swath_bytes_packed_l; ++ ++ if (total_swath_bytes <= detile_buf_size_in_bytes) ++ req128_l = 0; ++ else ++ req128_l = 1; ++ ++ swath_bytes_l = total_swath_bytes; ++ swath_bytes_c = 0; ++ } ++ rq_param->misc.rq_l.stored_swath_bytes = swath_bytes_l; ++ rq_param->misc.rq_c.stored_swath_bytes = swath_bytes_c; ++ ++ if (surf_linear) { ++ log2_swath_height_l = 0; ++ log2_swath_height_c = 0; ++ } else if (!surf_vert) { ++ log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; ++ log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; ++ } else { ++ log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; ++ log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; ++ } ++ rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; ++ rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; ++ ++ DTRACE("DLG: %s: req128_l = %0d", __func__, req128_l); ++ DTRACE("DLG: %s: req128_c = %0d", __func__, req128_c); ++ DTRACE("DLG: %s: full_swath_bytes_packed_l = %0d", __func__, full_swath_bytes_packed_l); ++ DTRACE("DLG: %s: full_swath_bytes_packed_c = %0d", __func__, full_swath_bytes_packed_c); ++} ++ ++/* Need refactor. */ ++static void dml1_rq_dlg_get_row_heights( ++ struct display_mode_lib *mode_lib, ++ unsigned int *o_dpte_row_height, ++ unsigned int *o_meta_row_height, ++ unsigned int vp_width, ++ unsigned int data_pitch, ++ int source_format, ++ int tiling, ++ int macro_tile_size, ++ int source_scan, ++ int is_chroma) ++{ ++ bool surf_linear = (tiling == dm_sw_linear); ++ bool surf_vert = (source_scan == dm_vert); ++ ++ unsigned int bytes_per_element = get_bytes_per_element( ++ (enum source_format_class) source_format, ++ is_chroma); ++ unsigned int log2_bytes_per_element = dml_log2(bytes_per_element); ++ unsigned int blk256_width = 0; ++ unsigned int blk256_height = 0; ++ ++ unsigned int log2_blk256_height; ++ unsigned int blk_bytes; ++ unsigned int log2_blk_bytes; ++ unsigned int log2_blk_height; ++ unsigned int log2_blk_width; ++ unsigned int log2_meta_req_bytes; ++ unsigned int log2_meta_req_height; ++ unsigned int log2_meta_req_width; ++ unsigned int log2_meta_row_height; ++ unsigned int log2_vmpg_bytes; ++ unsigned int dpte_buf_in_pte_reqs; ++ unsigned int log2_vmpg_height; ++ unsigned int log2_vmpg_width; ++ unsigned int log2_dpte_req_height_ptes; ++ unsigned int log2_dpte_req_width_ptes; ++ unsigned int log2_dpte_req_height; ++ unsigned int log2_dpte_req_width; ++ unsigned int log2_dpte_row_height_linear; ++ unsigned int log2_dpte_row_height; ++ unsigned int dpte_req_width; ++ ++ if (surf_linear) { ++ blk256_width = 256; ++ blk256_height = 1; ++ } else { ++ get_blk256_size(&blk256_width, &blk256_height, bytes_per_element); ++ } ++ ++ log2_blk256_height = dml_log2((double) blk256_height); ++ blk_bytes = surf_linear ? ++ 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size); ++ log2_blk_bytes = dml_log2((double) blk_bytes); ++ log2_blk_height = 0; ++ log2_blk_width = 0; ++ ++ /* remember log rule ++ * "+" in log is multiply ++ * "-" in log is divide ++ * "/2" is like square root ++ * blk is vertical biased ++ */ ++ if (tiling != dm_sw_linear) ++ log2_blk_height = log2_blk256_height ++ + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1); ++ else ++ log2_blk_height = 0; /* blk height of 1 */ ++ ++ log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height; ++ ++ /* ------- */ ++ /* meta */ ++ /* ------- */ ++ log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */ ++ ++ /* each 64b meta request for dcn is 8x8 meta elements and ++ * a meta element covers one 256b block of the the data surface. ++ */ ++ log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 */ ++ log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element ++ - log2_meta_req_height; ++ log2_meta_row_height = 0; ++ ++ /* the dimensions of a meta row are meta_row_width x meta_row_height in elements. ++ * calculate upper bound of the meta_row_width ++ */ ++ if (!surf_vert) ++ log2_meta_row_height = log2_meta_req_height; ++ else ++ log2_meta_row_height = log2_meta_req_width; ++ ++ *o_meta_row_height = 1 << log2_meta_row_height; ++ ++ /* ------ */ ++ /* dpte */ ++ /* ------ */ ++ log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes); ++ dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs; ++ ++ log2_vmpg_height = 0; ++ log2_vmpg_width = 0; ++ log2_dpte_req_height_ptes = 0; ++ log2_dpte_req_width_ptes = 0; ++ log2_dpte_req_height = 0; ++ log2_dpte_req_width = 0; ++ log2_dpte_row_height_linear = 0; ++ log2_dpte_row_height = 0; ++ dpte_req_width = 0; /* 64b dpte req width in data element */ ++ ++ if (surf_linear) ++ log2_vmpg_height = 0; /* one line high */ ++ else ++ log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height; ++ log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height; ++ ++ /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */ ++ if (log2_blk_bytes <= log2_vmpg_bytes) ++ log2_dpte_req_height_ptes = 0; ++ else if (log2_blk_height - log2_vmpg_height >= 2) ++ log2_dpte_req_height_ptes = 2; ++ else ++ log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height; ++ log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes; ++ ++ ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */ ++ (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */ ++ (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */ ++ ++ /* the dpte request dimensions in data elements is dpte_req_width x dpte_req_height ++ * log2_wmpg_width is how much 1 pte represent, now trying to calculate how much 64b pte req represent ++ */ ++ log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes; ++ log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes; ++ dpte_req_width = 1 << log2_dpte_req_width; ++ ++ /* calculate pitch dpte row buffer can hold ++ * round the result down to a power of two. ++ */ ++ if (surf_linear) { ++ log2_dpte_row_height_linear = dml_floor( ++ dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch), ++ 1); ++ ++ ASSERT(log2_dpte_row_height_linear >= 3); ++ ++ if (log2_dpte_row_height_linear > 7) ++ log2_dpte_row_height_linear = 7; ++ ++ log2_dpte_row_height = log2_dpte_row_height_linear; ++ } else { ++ /* the upper bound of the dpte_row_width without dependency on viewport position follows. */ ++ if (!surf_vert) ++ log2_dpte_row_height = log2_dpte_req_height; ++ else ++ log2_dpte_row_height = ++ (log2_blk_width < log2_dpte_req_width) ? ++ log2_blk_width : log2_dpte_req_width; ++ } ++ ++ /* From programming guide: ++ * There is a special case of saving only half of ptes returned due to buffer space limits. ++ * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16 ++ * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb). ++ */ ++ if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12 ++ && log2_blk_bytes >= 16) ++ log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */ ++ ++ *o_dpte_row_height = 1 << log2_dpte_row_height; ++} ++ ++static void get_surf_rq_param( ++ struct display_mode_lib *mode_lib, ++ struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing_param, ++ struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param, ++ struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param, ++ const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param, ++ bool is_chroma) ++{ ++ bool mode_422 = 0; ++ unsigned int vp_width = 0; ++ unsigned int vp_height = 0; ++ unsigned int data_pitch = 0; ++ unsigned int meta_pitch = 0; ++ unsigned int ppe = mode_422 ? 2 : 1; ++ bool surf_linear; ++ bool surf_vert; ++ unsigned int bytes_per_element; ++ unsigned int log2_bytes_per_element; ++ unsigned int blk256_width; ++ unsigned int blk256_height; ++ unsigned int log2_blk256_width; ++ unsigned int log2_blk256_height; ++ unsigned int blk_bytes; ++ unsigned int log2_blk_bytes; ++ unsigned int log2_blk_height; ++ unsigned int log2_blk_width; ++ unsigned int log2_meta_req_bytes; ++ unsigned int log2_meta_req_height; ++ unsigned int log2_meta_req_width; ++ unsigned int meta_req_width; ++ unsigned int meta_req_height; ++ unsigned int log2_meta_row_height; ++ unsigned int meta_row_width_ub; ++ unsigned int log2_meta_chunk_bytes; ++ unsigned int log2_meta_chunk_height; ++ unsigned int log2_meta_chunk_width; ++ unsigned int log2_min_meta_chunk_bytes; ++ unsigned int min_meta_chunk_width; ++ unsigned int meta_chunk_width; ++ unsigned int meta_chunk_per_row_int; ++ unsigned int meta_row_remainder; ++ unsigned int meta_chunk_threshold; ++ unsigned int meta_blk_bytes; ++ unsigned int meta_blk_height; ++ unsigned int meta_blk_width; ++ unsigned int meta_surface_bytes; ++ unsigned int vmpg_bytes; ++ unsigned int meta_pte_req_per_frame_ub; ++ unsigned int meta_pte_bytes_per_frame_ub; ++ unsigned int log2_vmpg_bytes; ++ unsigned int dpte_buf_in_pte_reqs; ++ unsigned int log2_vmpg_height; ++ unsigned int log2_vmpg_width; ++ unsigned int log2_dpte_req_height_ptes; ++ unsigned int log2_dpte_req_width_ptes; ++ unsigned int log2_dpte_req_height; ++ unsigned int log2_dpte_req_width; ++ unsigned int log2_dpte_row_height_linear; ++ unsigned int log2_dpte_row_height; ++ unsigned int log2_dpte_group_width; ++ unsigned int dpte_row_width_ub; ++ unsigned int dpte_row_height; ++ unsigned int dpte_req_height; ++ unsigned int dpte_req_width; ++ unsigned int dpte_group_width; ++ unsigned int log2_dpte_group_bytes; ++ unsigned int log2_dpte_group_length; ++ unsigned int func_meta_row_height, func_dpte_row_height; ++ ++ /* FIXME check if ppe apply for both luma and chroma in 422 case */ ++ if (is_chroma) { ++ vp_width = pipe_src_param.viewport_width_c / ppe; ++ vp_height = pipe_src_param.viewport_height_c; ++ data_pitch = pipe_src_param.data_pitch_c; ++ meta_pitch = pipe_src_param.meta_pitch_c; ++ } else { ++ vp_width = pipe_src_param.viewport_width / ppe; ++ vp_height = pipe_src_param.viewport_height; ++ data_pitch = pipe_src_param.data_pitch; ++ meta_pitch = pipe_src_param.meta_pitch; ++ } ++ ++ rq_sizing_param->chunk_bytes = 8192; ++ ++ if (rq_sizing_param->chunk_bytes == 64 * 1024) ++ rq_sizing_param->min_chunk_bytes = 0; ++ else ++ rq_sizing_param->min_chunk_bytes = 1024; ++ ++ rq_sizing_param->meta_chunk_bytes = 2048; ++ rq_sizing_param->min_meta_chunk_bytes = 256; ++ ++ rq_sizing_param->mpte_group_bytes = 2048; ++ ++ surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); ++ surf_vert = (pipe_src_param.source_scan == dm_vert); ++ ++ bytes_per_element = get_bytes_per_element( ++ (enum source_format_class) pipe_src_param.source_format, ++ is_chroma); ++ log2_bytes_per_element = dml_log2(bytes_per_element); ++ blk256_width = 0; ++ blk256_height = 0; ++ ++ if (surf_linear) { ++ blk256_width = 256 / bytes_per_element; ++ blk256_height = 1; ++ } else { ++ get_blk256_size(&blk256_width, &blk256_height, bytes_per_element); ++ } ++ ++ DTRACE("DLG: %s: surf_linear = %d", __func__, surf_linear); ++ DTRACE("DLG: %s: surf_vert = %d", __func__, surf_vert); ++ DTRACE("DLG: %s: blk256_width = %d", __func__, blk256_width); ++ DTRACE("DLG: %s: blk256_height = %d", __func__, blk256_height); ++ ++ log2_blk256_width = dml_log2((double) blk256_width); ++ log2_blk256_height = dml_log2((double) blk256_height); ++ blk_bytes = ++ surf_linear ? 256 : get_blk_size_bytes( ++ (enum source_macro_tile_size) pipe_src_param.macro_tile_size); ++ log2_blk_bytes = dml_log2((double) blk_bytes); ++ log2_blk_height = 0; ++ log2_blk_width = 0; ++ ++ /* remember log rule ++ * "+" in log is multiply ++ * "-" in log is divide ++ * "/2" is like square root ++ * blk is vertical biased ++ */ ++ if (pipe_src_param.sw_mode != dm_sw_linear) ++ log2_blk_height = log2_blk256_height ++ + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1); ++ else ++ log2_blk_height = 0; /* blk height of 1 */ ++ ++ log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height; ++ ++ if (!surf_vert) { ++ rq_dlg_param->swath_width_ub = dml_round_to_multiple(vp_width - 1, blk256_width, 1) ++ + blk256_width; ++ rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_width; ++ } else { ++ rq_dlg_param->swath_width_ub = dml_round_to_multiple( ++ vp_height - 1, ++ blk256_height, ++ 1) + blk256_height; ++ rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_height; ++ } ++ ++ if (!surf_vert) ++ rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_height ++ * bytes_per_element; ++ else ++ rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_width ++ * bytes_per_element; ++ ++ rq_misc_param->blk256_height = blk256_height; ++ rq_misc_param->blk256_width = blk256_width; ++ ++ /* ------- */ ++ /* meta */ ++ /* ------- */ ++ log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */ ++ ++ /* each 64b meta request for dcn is 8x8 meta elements and ++ * a meta element covers one 256b block of the the data surface. ++ */ ++ log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 byte, each byte represent 1 blk256 */ ++ log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element ++ - log2_meta_req_height; ++ meta_req_width = 1 << log2_meta_req_width; ++ meta_req_height = 1 << log2_meta_req_height; ++ log2_meta_row_height = 0; ++ meta_row_width_ub = 0; ++ ++ /* the dimensions of a meta row are meta_row_width x meta_row_height in elements. ++ * calculate upper bound of the meta_row_width ++ */ ++ if (!surf_vert) { ++ log2_meta_row_height = log2_meta_req_height; ++ meta_row_width_ub = dml_round_to_multiple(vp_width - 1, meta_req_width, 1) ++ + meta_req_width; ++ rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_width; ++ } else { ++ log2_meta_row_height = log2_meta_req_width; ++ meta_row_width_ub = dml_round_to_multiple(vp_height - 1, meta_req_height, 1) ++ + meta_req_height; ++ rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_height; ++ } ++ rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64; ++ ++ log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes); ++ log2_meta_chunk_height = log2_meta_row_height; ++ ++ /*full sized meta chunk width in unit of data elements */ ++ log2_meta_chunk_width = log2_meta_chunk_bytes + 8 - log2_bytes_per_element ++ - log2_meta_chunk_height; ++ log2_min_meta_chunk_bytes = dml_log2(rq_sizing_param->min_meta_chunk_bytes); ++ min_meta_chunk_width = 1 ++ << (log2_min_meta_chunk_bytes + 8 - log2_bytes_per_element ++ - log2_meta_chunk_height); ++ meta_chunk_width = 1 << log2_meta_chunk_width; ++ meta_chunk_per_row_int = (unsigned int) (meta_row_width_ub / meta_chunk_width); ++ meta_row_remainder = meta_row_width_ub % meta_chunk_width; ++ meta_chunk_threshold = 0; ++ meta_blk_bytes = 4096; ++ meta_blk_height = blk256_height * 64; ++ meta_blk_width = meta_blk_bytes * 256 / bytes_per_element / meta_blk_height; ++ meta_surface_bytes = meta_pitch ++ * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1) ++ + meta_blk_height) * bytes_per_element / 256; ++ vmpg_bytes = mode_lib->soc.vmm_page_size_bytes; ++ meta_pte_req_per_frame_ub = (dml_round_to_multiple( ++ meta_surface_bytes - vmpg_bytes, ++ 8 * vmpg_bytes, ++ 1) + 8 * vmpg_bytes) / (8 * vmpg_bytes); ++ meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; /*64B mpte request */ ++ rq_dlg_param->meta_pte_bytes_per_frame_ub = meta_pte_bytes_per_frame_ub; ++ ++ DTRACE("DLG: %s: meta_blk_height = %d", __func__, meta_blk_height); ++ DTRACE("DLG: %s: meta_blk_width = %d", __func__, meta_blk_width); ++ DTRACE("DLG: %s: meta_surface_bytes = %d", __func__, meta_surface_bytes); ++ DTRACE("DLG: %s: meta_pte_req_per_frame_ub = %d", __func__, meta_pte_req_per_frame_ub); ++ DTRACE("DLG: %s: meta_pte_bytes_per_frame_ub = %d", __func__, meta_pte_bytes_per_frame_ub); ++ ++ if (!surf_vert) ++ meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width; ++ else ++ meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_height; ++ ++ if (meta_row_remainder <= meta_chunk_threshold) ++ rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 1; ++ else ++ rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 2; ++ ++ rq_dlg_param->meta_row_height = 1 << log2_meta_row_height; ++ ++ /* ------ */ ++ /* dpte */ ++ /* ------ */ ++ log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes); ++ dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs; ++ ++ log2_vmpg_height = 0; ++ log2_vmpg_width = 0; ++ log2_dpte_req_height_ptes = 0; ++ log2_dpte_req_width_ptes = 0; ++ log2_dpte_req_height = 0; ++ log2_dpte_req_width = 0; ++ log2_dpte_row_height_linear = 0; ++ log2_dpte_row_height = 0; ++ log2_dpte_group_width = 0; ++ dpte_row_width_ub = 0; ++ dpte_row_height = 0; ++ dpte_req_height = 0; /* 64b dpte req height in data element */ ++ dpte_req_width = 0; /* 64b dpte req width in data element */ ++ dpte_group_width = 0; ++ log2_dpte_group_bytes = 0; ++ log2_dpte_group_length = 0; ++ ++ if (surf_linear) ++ log2_vmpg_height = 0; /* one line high */ ++ else ++ log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height; ++ log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height; ++ ++ /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */ ++ if (log2_blk_bytes <= log2_vmpg_bytes) ++ log2_dpte_req_height_ptes = 0; ++ else if (log2_blk_height - log2_vmpg_height >= 2) ++ log2_dpte_req_height_ptes = 2; ++ else ++ log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height; ++ log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes; ++ ++ /* Ensure we only have the 3 shapes */ ++ ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */ ++ (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */ ++ (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */ ++ ++ /* The dpte request dimensions in data elements is dpte_req_width x dpte_req_height ++ * log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent ++ * That depends on the pte shape (i.e. 8x1, 4x2, 2x4) ++ */ ++ log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes; ++ log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes; ++ dpte_req_height = 1 << log2_dpte_req_height; ++ dpte_req_width = 1 << log2_dpte_req_width; ++ ++ /* calculate pitch dpte row buffer can hold ++ * round the result down to a power of two. ++ */ ++ if (surf_linear) { ++ log2_dpte_row_height_linear = dml_floor( ++ dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch), ++ 1); ++ ++ ASSERT(log2_dpte_row_height_linear >= 3); ++ ++ if (log2_dpte_row_height_linear > 7) ++ log2_dpte_row_height_linear = 7; ++ ++ log2_dpte_row_height = log2_dpte_row_height_linear; ++ rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; ++ ++ /* For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary. ++ * the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering. ++ */ ++ dpte_row_width_ub = dml_round_to_multiple( ++ data_pitch * dpte_row_height - 1, ++ dpte_req_width, ++ 1) + dpte_req_width; ++ rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width; ++ } else { ++ /* for tiled mode, row height is the same as req height and row store up to vp size upper bound */ ++ if (!surf_vert) { ++ log2_dpte_row_height = log2_dpte_req_height; ++ dpte_row_width_ub = dml_round_to_multiple(vp_width - 1, dpte_req_width, 1) ++ + dpte_req_width; ++ rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width; ++ } else { ++ log2_dpte_row_height = ++ (log2_blk_width < log2_dpte_req_width) ? ++ log2_blk_width : log2_dpte_req_width; ++ dpte_row_width_ub = dml_round_to_multiple(vp_height - 1, dpte_req_height, 1) ++ + dpte_req_height; ++ rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_height; ++ } ++ rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; ++ } ++ rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64; ++ ++ /* From programming guide: ++ * There is a special case of saving only half of ptes returned due to buffer space limits. ++ * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16 ++ * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb). ++ */ ++ if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12 ++ && log2_blk_bytes >= 16) { ++ log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */ ++ rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; ++ } ++ ++ /* the dpte_group_bytes is reduced for the specific case of vertical ++ * access of a tile surface that has dpte request of 8x1 ptes. ++ */ ++ if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) /*reduced, in this case, will have page fault within a group */ ++ rq_sizing_param->dpte_group_bytes = 512; ++ else ++ /*full size */ ++ rq_sizing_param->dpte_group_bytes = 2048; ++ ++ /*since pte request size is 64byte, the number of data pte requests per full sized group is as follows. */ ++ log2_dpte_group_bytes = dml_log2(rq_sizing_param->dpte_group_bytes); ++ log2_dpte_group_length = log2_dpte_group_bytes - 6; /*length in 64b requests */ ++ ++ /* full sized data pte group width in elements */ ++ if (!surf_vert) ++ log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width; ++ else ++ log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height; ++ ++ dpte_group_width = 1 << log2_dpte_group_width; ++ ++ /* since dpte groups are only aligned to dpte_req_width and not dpte_group_width, ++ * the upper bound for the dpte groups per row is as follows. ++ */ ++ rq_dlg_param->dpte_groups_per_row_ub = dml_ceil( ++ (double) dpte_row_width_ub / dpte_group_width, ++ 1); ++ ++ dml1_rq_dlg_get_row_heights( ++ mode_lib, ++ &func_dpte_row_height, ++ &func_meta_row_height, ++ vp_width, ++ data_pitch, ++ pipe_src_param.source_format, ++ pipe_src_param.sw_mode, ++ pipe_src_param.macro_tile_size, ++ pipe_src_param.source_scan, ++ is_chroma); ++ ++ /* Just a check to make sure this function and the new one give the same ++ * result. The standalone get_row_heights() function is based off of the ++ * code in this function so the same changes need to be made to both. ++ */ ++ if (rq_dlg_param->meta_row_height != func_meta_row_height) { ++ DTRACE( ++ "MISMATCH: rq_dlg_param->meta_row_height = %d", ++ rq_dlg_param->meta_row_height); ++ DTRACE("MISMATCH: func_meta_row_height = %d", func_meta_row_height); ++ ASSERT(0); ++ } ++ ++ if (rq_dlg_param->dpte_row_height != func_dpte_row_height) { ++ DTRACE( ++ "MISMATCH: rq_dlg_param->dpte_row_height = %d", ++ rq_dlg_param->dpte_row_height); ++ DTRACE("MISMATCH: func_dpte_row_height = %d", func_dpte_row_height); ++ ASSERT(0); ++ } ++} ++ ++void dml1_rq_dlg_get_rq_params( ++ struct display_mode_lib *mode_lib, ++ struct _vcs_dpi_display_rq_params_st *rq_param, ++ const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param) ++{ ++ /* get param for luma surface */ ++ rq_param->yuv420 = pipe_src_param.source_format == dm_420_8 ++ || pipe_src_param.source_format == dm_420_10; ++ rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10; ++ ++ get_surf_rq_param( ++ mode_lib, ++ &(rq_param->sizing.rq_l), ++ &(rq_param->dlg.rq_l), ++ &(rq_param->misc.rq_l), ++ pipe_src_param, ++ 0); ++ ++ if (is_dual_plane((enum source_format_class) pipe_src_param.source_format)) { ++ /* get param for chroma surface */ ++ get_surf_rq_param( ++ mode_lib, ++ &(rq_param->sizing.rq_c), ++ &(rq_param->dlg.rq_c), ++ &(rq_param->misc.rq_c), ++ pipe_src_param, ++ 1); ++ } ++ ++ /* calculate how to split the det buffer space between luma and chroma */ ++ handle_det_buf_split(mode_lib, rq_param, pipe_src_param); ++ print__rq_params_st(mode_lib, *rq_param); ++} ++ ++/* Note: currently taken in as is. ++ * Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma. ++ */ ++void dml1_rq_dlg_get_dlg_params( ++ struct display_mode_lib *mode_lib, ++ struct _vcs_dpi_display_dlg_regs_st *disp_dlg_regs, ++ struct _vcs_dpi_display_ttu_regs_st *disp_ttu_regs, ++ const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, ++ const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, ++ const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, ++ const bool cstate_en, ++ const bool pstate_en, ++ const bool vm_en, ++ const bool iflip_en) ++{ ++ /* Timing */ ++ unsigned int htotal = e2e_pipe_param.pipe.dest.htotal; ++ unsigned int hblank_end = e2e_pipe_param.pipe.dest.hblank_end; ++ unsigned int vblank_start = e2e_pipe_param.pipe.dest.vblank_start; ++ unsigned int vblank_end = e2e_pipe_param.pipe.dest.vblank_end; ++ bool interlaced = e2e_pipe_param.pipe.dest.interlaced; ++ unsigned int min_vblank = mode_lib->ip.min_vblank_lines; ++ ++ double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz; ++ double refclk_freq_in_mhz = e2e_pipe_param.clks_cfg.refclk_mhz; ++ double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz; ++ double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz; ++ ++ double ref_freq_to_pix_freq; ++ double prefetch_xy_calc_in_dcfclk; ++ double min_dcfclk_mhz; ++ double t_calc_us; ++ double min_ttu_vblank; ++ double min_dst_y_ttu_vblank; ++ unsigned int dlg_vblank_start; ++ bool dcc_en; ++ bool dual_plane; ++ bool mode_422; ++ unsigned int access_dir; ++ unsigned int bytes_per_element_l; ++ unsigned int bytes_per_element_c; ++ unsigned int vp_height_l; ++ unsigned int vp_width_l; ++ unsigned int vp_height_c; ++ unsigned int vp_width_c; ++ unsigned int htaps_l; ++ unsigned int htaps_c; ++ double hratios_l; ++ double hratios_c; ++ double vratio_l; ++ double vratio_c; ++ double line_time_in_us; ++ double vinit_l; ++ double vinit_c; ++ double vinit_bot_l; ++ double vinit_bot_c; ++ unsigned int swath_height_l; ++ unsigned int swath_width_ub_l; ++ unsigned int dpte_bytes_per_row_ub_l; ++ unsigned int dpte_groups_per_row_ub_l; ++ unsigned int meta_pte_bytes_per_frame_ub_l; ++ unsigned int meta_bytes_per_row_ub_l; ++ unsigned int swath_height_c; ++ unsigned int swath_width_ub_c; ++ unsigned int dpte_bytes_per_row_ub_c; ++ unsigned int dpte_groups_per_row_ub_c; ++ unsigned int meta_chunks_per_row_ub_l; ++ unsigned int vupdate_offset; ++ unsigned int vupdate_width; ++ unsigned int vready_offset; ++ unsigned int dppclk_delay_subtotal; ++ unsigned int dispclk_delay_subtotal; ++ unsigned int pixel_rate_delay_subtotal; ++ unsigned int vstartup_start; ++ unsigned int dst_x_after_scaler; ++ unsigned int dst_y_after_scaler; ++ double line_wait; ++ double line_o; ++ double line_setup; ++ double line_calc; ++ double dst_y_prefetch; ++ double t_pre_us; ++ unsigned int vm_bytes; ++ unsigned int meta_row_bytes; ++ unsigned int max_num_sw_l; ++ unsigned int max_num_sw_c; ++ unsigned int max_partial_sw_l; ++ unsigned int max_partial_sw_c; ++ double max_vinit_l; ++ double max_vinit_c; ++ unsigned int lsw_l; ++ unsigned int lsw_c; ++ unsigned int sw_bytes_ub_l; ++ unsigned int sw_bytes_ub_c; ++ unsigned int sw_bytes; ++ unsigned int dpte_row_bytes; ++ double prefetch_bw; ++ double flip_bw; ++ double t_vm_us; ++ double t_r0_us; ++ double dst_y_per_vm_vblank; ++ double dst_y_per_row_vblank; ++ double min_dst_y_per_vm_vblank; ++ double min_dst_y_per_row_vblank; ++ double lsw; ++ double vratio_pre_l; ++ double vratio_pre_c; ++ unsigned int req_per_swath_ub_l; ++ unsigned int req_per_swath_ub_c; ++ unsigned int meta_row_height_l; ++ unsigned int swath_width_pixels_ub_l; ++ unsigned int swath_width_pixels_ub_c; ++ unsigned int scaler_rec_in_width_l; ++ unsigned int scaler_rec_in_width_c; ++ unsigned int dpte_row_height_l; ++ unsigned int dpte_row_height_c; ++ double hscale_pixel_rate_l; ++ double hscale_pixel_rate_c; ++ double min_hratio_fact_l; ++ double min_hratio_fact_c; ++ double refcyc_per_line_delivery_pre_l; ++ double refcyc_per_line_delivery_pre_c; ++ double refcyc_per_line_delivery_l; ++ double refcyc_per_line_delivery_c; ++ double refcyc_per_req_delivery_pre_l; ++ double refcyc_per_req_delivery_pre_c; ++ double refcyc_per_req_delivery_l; ++ double refcyc_per_req_delivery_c; ++ double refcyc_per_req_delivery_pre_cur0; ++ double refcyc_per_req_delivery_cur0; ++ unsigned int full_recout_width; ++ double hratios_cur0; ++ unsigned int cur0_src_width; ++ enum cursor_bpp cur0_bpp; ++ unsigned int cur0_req_size; ++ unsigned int cur0_req_width; ++ double cur0_width_ub; ++ double cur0_req_per_width; ++ double hactive_cur0; ++ ++ memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs)); ++ memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs)); ++ ++ DTRACE("DLG: %s: cstate_en = %d", __func__, cstate_en); ++ DTRACE("DLG: %s: pstate_en = %d", __func__, pstate_en); ++ DTRACE("DLG: %s: vm_en = %d", __func__, vm_en); ++ DTRACE("DLG: %s: iflip_en = %d", __func__, iflip_en); ++ ++ /* ------------------------- */ ++ /* Section 1.5.2.1: OTG dependent Params */ ++ /* ------------------------- */ ++ DTRACE("DLG: %s: dppclk_freq_in_mhz = %3.2f", __func__, dppclk_freq_in_mhz); ++ DTRACE("DLG: %s: dispclk_freq_in_mhz = %3.2f", __func__, dispclk_freq_in_mhz); ++ DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz); ++ DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz); ++ DTRACE("DLG: %s: interlaced = %d", __func__, interlaced); ++ ++ ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz; ++ ASSERT(ref_freq_to_pix_freq < 4.0); ++ disp_dlg_regs->ref_freq_to_pix_freq = ++ (unsigned int) (ref_freq_to_pix_freq * dml_pow(2, 19)); ++ disp_dlg_regs->refcyc_per_htotal = (unsigned int) (ref_freq_to_pix_freq * (double) htotal ++ * dml_pow(2, 8)); ++ disp_dlg_regs->refcyc_h_blank_end = (unsigned int) ((double) hblank_end ++ * (double) ref_freq_to_pix_freq); ++ ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int) dml_pow(2, 13)); ++ disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; /* 15 bits */ ++ ++ prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */ ++ min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz; ++ t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz; ++ min_ttu_vblank = dlg_sys_param.t_urg_wm_us; ++ if (cstate_en) ++ min_ttu_vblank = dml_max(dlg_sys_param.t_sr_wm_us, min_ttu_vblank); ++ if (pstate_en) ++ min_ttu_vblank = dml_max(dlg_sys_param.t_mclk_wm_us, min_ttu_vblank); ++ min_ttu_vblank = min_ttu_vblank + t_calc_us; ++ ++ min_dst_y_ttu_vblank = min_ttu_vblank * pclk_freq_in_mhz / (double) htotal; ++ dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start; ++ ++ disp_dlg_regs->min_dst_y_next_start = (unsigned int) (((double) dlg_vblank_start ++ + min_dst_y_ttu_vblank) * dml_pow(2, 2)); ++ ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int) dml_pow(2, 18)); ++ ++ DTRACE("DLG: %s: min_dcfclk_mhz = %3.2f", __func__, min_dcfclk_mhz); ++ DTRACE("DLG: %s: min_ttu_vblank = %3.2f", __func__, min_ttu_vblank); ++ DTRACE( ++ "DLG: %s: min_dst_y_ttu_vblank = %3.2f", ++ __func__, ++ min_dst_y_ttu_vblank); ++ DTRACE("DLG: %s: t_calc_us = %3.2f", __func__, t_calc_us); ++ DTRACE( ++ "DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x", ++ __func__, ++ disp_dlg_regs->min_dst_y_next_start); ++ DTRACE( ++ "DLG: %s: ref_freq_to_pix_freq = %3.2f", ++ __func__, ++ ref_freq_to_pix_freq); ++ ++ /* ------------------------- */ ++ /* Section 1.5.2.2: Prefetch, Active and TTU */ ++ /* ------------------------- */ ++ /* Prefetch Calc */ ++ /* Source */ ++ dcc_en = e2e_pipe_param.pipe.src.dcc; ++ dual_plane = is_dual_plane( ++ (enum source_format_class) e2e_pipe_param.pipe.src.source_format); ++ mode_422 = 0; /* FIXME */ ++ access_dir = (e2e_pipe_param.pipe.src.source_scan == dm_vert); /* vp access direction: horizontal or vertical accessed */ ++ bytes_per_element_l = get_bytes_per_element( ++ (enum source_format_class) e2e_pipe_param.pipe.src.source_format, ++ 0); ++ bytes_per_element_c = get_bytes_per_element( ++ (enum source_format_class) e2e_pipe_param.pipe.src.source_format, ++ 1); ++ vp_height_l = e2e_pipe_param.pipe.src.viewport_height; ++ vp_width_l = e2e_pipe_param.pipe.src.viewport_width; ++ vp_height_c = e2e_pipe_param.pipe.src.viewport_height_c; ++ vp_width_c = e2e_pipe_param.pipe.src.viewport_width_c; ++ ++ /* Scaling */ ++ htaps_l = e2e_pipe_param.pipe.scale_taps.htaps; ++ htaps_c = e2e_pipe_param.pipe.scale_taps.htaps_c; ++ hratios_l = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio; ++ hratios_c = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio_c; ++ vratio_l = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio; ++ vratio_c = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio_c; ++ ++ line_time_in_us = (htotal / pclk_freq_in_mhz); ++ vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit; ++ vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c; ++ vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot; ++ vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c; ++ ++ swath_height_l = rq_dlg_param.rq_l.swath_height; ++ swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub; ++ dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub; ++ dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub; ++ meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub; ++ meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub; ++ ++ swath_height_c = rq_dlg_param.rq_c.swath_height; ++ swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub; ++ dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub; ++ dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub; ++ ++ meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub; ++ vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset; ++ vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width; ++ vready_offset = e2e_pipe_param.pipe.dest.vready_offset; ++ ++ dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal; ++ dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal; ++ pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz ++ + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz; ++ ++ vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start; ++ ++ if (interlaced) ++ vstartup_start = vstartup_start / 2; ++ ++ if (vstartup_start >= min_vblank) { ++ DTRACE( ++ "WARNING_DLG: %s: vblank_start=%d vblank_end=%d", ++ __func__, ++ vblank_start, ++ vblank_end); ++ DTRACE( ++ "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d", ++ __func__, ++ vstartup_start, ++ min_vblank); ++ min_vblank = vstartup_start + 1; ++ DTRACE( ++ "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d", ++ __func__, ++ vstartup_start, ++ min_vblank); ++ } ++ ++ dst_x_after_scaler = 0; ++ dst_y_after_scaler = 0; ++ ++ if (e2e_pipe_param.pipe.src.is_hsplit) ++ dst_x_after_scaler = pixel_rate_delay_subtotal ++ + e2e_pipe_param.pipe.dest.recout_width; ++ else ++ dst_x_after_scaler = pixel_rate_delay_subtotal; ++ ++ if (e2e_pipe_param.dout.output_format == dm_420) ++ dst_y_after_scaler = 1; ++ else ++ dst_y_after_scaler = 0; ++ ++ if (dst_x_after_scaler >= htotal) { ++ dst_x_after_scaler = dst_x_after_scaler - htotal; ++ dst_y_after_scaler = dst_y_after_scaler + 1; ++ } ++ ++ DTRACE("DLG: %s: htotal = %d", __func__, htotal); ++ DTRACE( ++ "DLG: %s: pixel_rate_delay_subtotal = %d", ++ __func__, ++ pixel_rate_delay_subtotal); ++ DTRACE("DLG: %s: dst_x_after_scaler = %d", __func__, dst_x_after_scaler); ++ DTRACE("DLG: %s: dst_y_after_scaler = %d", __func__, dst_y_after_scaler); ++ ++ line_wait = mode_lib->soc.urgent_latency_us; ++ if (cstate_en) ++ line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait); ++ if (pstate_en) ++ line_wait = dml_max( ++ mode_lib->soc.dram_clock_change_latency_us ++ + mode_lib->soc.urgent_latency_us, ++ line_wait); ++ line_wait = line_wait / line_time_in_us; ++ ++ line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal; ++ line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal; ++ line_calc = t_calc_us / line_time_in_us; ++ ++ DTRACE( ++ "DLG: %s: soc.sr_enter_plus_exit_time_us = %3.2f", ++ __func__, ++ (double) mode_lib->soc.sr_enter_plus_exit_time_us); ++ DTRACE( ++ "DLG: %s: soc.dram_clock_change_latency_us = %3.2f", ++ __func__, ++ (double) mode_lib->soc.dram_clock_change_latency_us); ++ DTRACE( ++ "DLG: %s: soc.urgent_latency_us = %3.2f", ++ __func__, ++ mode_lib->soc.urgent_latency_us); ++ ++ DTRACE("DLG: %s: swath_height_l = %d", __func__, swath_height_l); ++ if (dual_plane) ++ DTRACE("DLG: %s: swath_height_c = %d", __func__, swath_height_c); ++ ++ DTRACE( ++ "DLG: %s: t_srx_delay_us = %3.2f", ++ __func__, ++ (double) dlg_sys_param.t_srx_delay_us); ++ DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us); ++ DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset); ++ DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width); ++ DTRACE("DLG: %s: vready_offset = %d", __func__, vready_offset); ++ DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, line_time_in_us); ++ DTRACE("DLG: %s: line_wait = %3.2f", __func__, line_wait); ++ DTRACE("DLG: %s: line_o = %3.2f", __func__, line_o); ++ DTRACE("DLG: %s: line_setup = %3.2f", __func__, line_setup); ++ DTRACE("DLG: %s: line_calc = %3.2f", __func__, line_calc); ++ ++ dst_y_prefetch = ((double) min_vblank - 1.0) ++ - (line_setup + line_calc + line_wait + line_o); ++ DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch); ++ ASSERT(dst_y_prefetch >= 2.0); ++ ++ dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125), 1) / 4; ++ DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch); ++ ++ t_pre_us = dst_y_prefetch * line_time_in_us; ++ vm_bytes = 0; ++ meta_row_bytes = 0; ++ ++ if (dcc_en && vm_en) ++ vm_bytes = meta_pte_bytes_per_frame_ub_l; ++ if (dcc_en) ++ meta_row_bytes = meta_bytes_per_row_ub_l; ++ ++ max_num_sw_l = 0; ++ max_num_sw_c = 0; ++ max_partial_sw_l = 0; ++ max_partial_sw_c = 0; ++ ++ max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l; ++ max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c; ++ ++ get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l); ++ if (dual_plane) ++ get_swath_need( ++ mode_lib, ++ &max_num_sw_c, ++ &max_partial_sw_c, ++ swath_height_c, ++ max_vinit_c); ++ ++ lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l; ++ lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c; ++ sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l; ++ sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c; ++ sw_bytes = 0; ++ dpte_row_bytes = 0; ++ ++ if (vm_en) { ++ if (dual_plane) ++ dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c; ++ else ++ dpte_row_bytes = dpte_bytes_per_row_ub_l; ++ } else { ++ dpte_row_bytes = 0; ++ } ++ ++ if (dual_plane) ++ sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c; ++ else ++ sw_bytes = sw_bytes_ub_l; ++ ++ DTRACE("DLG: %s: sw_bytes_ub_l = %d", __func__, sw_bytes_ub_l); ++ DTRACE("DLG: %s: sw_bytes_ub_c = %d", __func__, sw_bytes_ub_c); ++ DTRACE("DLG: %s: sw_bytes = %d", __func__, sw_bytes); ++ DTRACE("DLG: %s: vm_bytes = %d", __func__, vm_bytes); ++ DTRACE("DLG: %s: meta_row_bytes = %d", __func__, meta_row_bytes); ++ DTRACE("DLG: %s: dpte_row_bytes = %d", __func__, dpte_row_bytes); ++ ++ prefetch_bw = (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us; ++ flip_bw = ((vm_bytes + dpte_row_bytes + meta_row_bytes) * dlg_sys_param.total_flip_bw) ++ / (double) dlg_sys_param.total_flip_bytes; ++ t_vm_us = line_time_in_us / 4.0; ++ if (vm_en && dcc_en) { ++ t_vm_us = dml_max( ++ dlg_sys_param.t_extra_us, ++ dml_max((double) vm_bytes / prefetch_bw, t_vm_us)); ++ ++ if (iflip_en && !dual_plane) { ++ t_vm_us = dml_max(mode_lib->soc.urgent_latency_us, t_vm_us); ++ if (flip_bw > 0.) ++ t_vm_us = dml_max(vm_bytes / flip_bw, t_vm_us); ++ } ++ } ++ ++ t_r0_us = dml_max(dlg_sys_param.t_extra_us - t_vm_us, line_time_in_us - t_vm_us); ++ ++ if (vm_en || dcc_en) { ++ t_r0_us = dml_max( ++ (double) (dpte_row_bytes + meta_row_bytes) / prefetch_bw, ++ dlg_sys_param.t_extra_us); ++ t_r0_us = dml_max((double) (line_time_in_us - t_vm_us), t_r0_us); ++ ++ if (iflip_en && !dual_plane) { ++ t_r0_us = dml_max(mode_lib->soc.urgent_latency_us * 2.0, t_r0_us); ++ if (flip_bw > 0.) ++ t_r0_us = dml_max( ++ (dpte_row_bytes + meta_row_bytes) / flip_bw, ++ t_r0_us); ++ } ++ } ++ ++ disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; /* in terms of line */ ++ disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; /* in terms of refclk */ ++ ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13)); ++ DTRACE( ++ "DLG: %s: disp_dlg_regs->dst_y_after_scaler = 0x%0x", ++ __func__, ++ disp_dlg_regs->dst_y_after_scaler); ++ DTRACE( ++ "DLG: %s: disp_dlg_regs->refcyc_x_after_scaler = 0x%0x", ++ __func__, ++ disp_dlg_regs->refcyc_x_after_scaler); ++ ++ disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2)); ++ DTRACE( ++ "DLG: %s: disp_dlg_regs->dst_y_prefetch = %d", ++ __func__, ++ disp_dlg_regs->dst_y_prefetch); ++ ++ dst_y_per_vm_vblank = 0.0; ++ dst_y_per_row_vblank = 0.0; ++ ++ dst_y_per_vm_vblank = t_vm_us / line_time_in_us; ++ dst_y_per_vm_vblank = dml_floor(4.0 * (dst_y_per_vm_vblank + 0.125), 1) / 4.0; ++ disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2)); ++ ++ dst_y_per_row_vblank = t_r0_us / line_time_in_us; ++ dst_y_per_row_vblank = dml_floor(4.0 * (dst_y_per_row_vblank + 0.125), 1) / 4.0; ++ disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2)); ++ ++ DTRACE("DLG: %s: lsw_l = %d", __func__, lsw_l); ++ DTRACE("DLG: %s: lsw_c = %d", __func__, lsw_c); ++ DTRACE("DLG: %s: dpte_bytes_per_row_ub_l = %d", __func__, dpte_bytes_per_row_ub_l); ++ DTRACE("DLG: %s: dpte_bytes_per_row_ub_c = %d", __func__, dpte_bytes_per_row_ub_c); ++ ++ DTRACE("DLG: %s: prefetch_bw = %3.2f", __func__, prefetch_bw); ++ DTRACE("DLG: %s: flip_bw = %3.2f", __func__, flip_bw); ++ DTRACE("DLG: %s: t_pre_us = %3.2f", __func__, t_pre_us); ++ DTRACE("DLG: %s: t_vm_us = %3.2f", __func__, t_vm_us); ++ DTRACE("DLG: %s: t_r0_us = %3.2f", __func__, t_r0_us); ++ DTRACE("DLG: %s: dst_y_per_vm_vblank = %3.2f", __func__, dst_y_per_vm_vblank); ++ DTRACE("DLG: %s: dst_y_per_row_vblank = %3.2f", __func__, dst_y_per_row_vblank); ++ DTRACE("DLG: %s: dst_y_prefetch = %3.2f", __func__, dst_y_prefetch); ++ ++ min_dst_y_per_vm_vblank = 8.0; ++ min_dst_y_per_row_vblank = 16.0; ++ if (htotal <= 75) { ++ min_vblank = 300; ++ min_dst_y_per_vm_vblank = 100.0; ++ min_dst_y_per_row_vblank = 100.0; ++ } ++ ++ ASSERT(dst_y_per_vm_vblank < min_dst_y_per_vm_vblank); ++ ASSERT(dst_y_per_row_vblank < min_dst_y_per_row_vblank); ++ ++ ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank)); ++ lsw = dst_y_prefetch - (dst_y_per_vm_vblank + dst_y_per_row_vblank); ++ ++ DTRACE("DLG: %s: lsw = %3.2f", __func__, lsw); ++ ++ vratio_pre_l = get_vratio_pre( ++ mode_lib, ++ max_num_sw_l, ++ max_partial_sw_l, ++ swath_height_l, ++ max_vinit_l, ++ lsw); ++ vratio_pre_c = 1.0; ++ if (dual_plane) ++ vratio_pre_c = get_vratio_pre( ++ mode_lib, ++ max_num_sw_c, ++ max_partial_sw_c, ++ swath_height_c, ++ max_vinit_c, ++ lsw); ++ ++ DTRACE("DLG: %s: vratio_pre_l=%3.2f", __func__, vratio_pre_l); ++ DTRACE("DLG: %s: vratio_pre_c=%3.2f", __func__, vratio_pre_c); ++ ++ ASSERT(vratio_pre_l <= 4.0); ++ if (vratio_pre_l >= 4.0) ++ disp_dlg_regs->vratio_prefetch = (unsigned int) dml_pow(2, 21) - 1; ++ else ++ disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19)); ++ ++ ASSERT(vratio_pre_c <= 4.0); ++ if (vratio_pre_c >= 4.0) ++ disp_dlg_regs->vratio_prefetch_c = (unsigned int) dml_pow(2, 21) - 1; ++ else ++ disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19)); ++ ++ disp_dlg_regs->refcyc_per_pte_group_vblank_l = ++ (unsigned int) (dst_y_per_row_vblank * (double) htotal ++ * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l); ++ ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13)); ++ ++ disp_dlg_regs->refcyc_per_pte_group_vblank_c = ++ (unsigned int) (dst_y_per_row_vblank * (double) htotal ++ * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_c); ++ ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c < (unsigned int) dml_pow(2, 13)); ++ ++ disp_dlg_regs->refcyc_per_meta_chunk_vblank_l = ++ (unsigned int) (dst_y_per_row_vblank * (double) htotal ++ * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l); ++ ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13)); ++ ++ disp_dlg_regs->refcyc_per_meta_chunk_vblank_c = ++ disp_dlg_regs->refcyc_per_meta_chunk_vblank_l;/* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */ ++ ++ /* Active */ ++ req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub; ++ req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub; ++ meta_row_height_l = rq_dlg_param.rq_l.meta_row_height; ++ swath_width_pixels_ub_l = 0; ++ swath_width_pixels_ub_c = 0; ++ scaler_rec_in_width_l = 0; ++ scaler_rec_in_width_c = 0; ++ dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height; ++ dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height; ++ ++ disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l ++ / (double) vratio_l * dml_pow(2, 2)); ++ ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17)); ++ ++ disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c ++ / (double) vratio_c * dml_pow(2, 2)); ++ ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_c < (unsigned int) dml_pow(2, 17)); ++ ++ disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l ++ / (double) vratio_l * dml_pow(2, 2)); ++ ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17)); ++ ++ disp_dlg_regs->dst_y_per_meta_row_nom_c = disp_dlg_regs->dst_y_per_meta_row_nom_l; /* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */ ++ ++ disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l ++ / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq ++ / (double) dpte_groups_per_row_ub_l); ++ if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23)) ++ disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1; ++ ++ disp_dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int) ((double) dpte_row_height_c ++ / (double) vratio_c * (double) htotal * ref_freq_to_pix_freq ++ / (double) dpte_groups_per_row_ub_c); ++ if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23)) ++ disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1; ++ ++ disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l ++ / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq ++ / (double) meta_chunks_per_row_ub_l); ++ if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23)) ++ disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1; ++ ++ if (mode_422) { ++ swath_width_pixels_ub_l = swath_width_ub_l * 2; /* *2 for 2 pixel per element */ ++ swath_width_pixels_ub_c = swath_width_ub_c * 2; ++ } else { ++ swath_width_pixels_ub_l = swath_width_ub_l * 1; ++ swath_width_pixels_ub_c = swath_width_ub_c * 1; ++ } ++ ++ hscale_pixel_rate_l = 0.; ++ hscale_pixel_rate_c = 0.; ++ min_hratio_fact_l = 1.0; ++ min_hratio_fact_c = 1.0; ++ ++ if (htaps_l <= 1) ++ min_hratio_fact_l = 2.0; ++ else if (htaps_l <= 6) { ++ if ((hratios_l * 2.0) > 4.0) ++ min_hratio_fact_l = 4.0; ++ else ++ min_hratio_fact_l = hratios_l * 2.0; ++ } else { ++ if (hratios_l > 4.0) ++ min_hratio_fact_l = 4.0; ++ else ++ min_hratio_fact_l = hratios_l; ++ } ++ ++ hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz; ++ ++ if (htaps_c <= 1) ++ min_hratio_fact_c = 2.0; ++ else if (htaps_c <= 6) { ++ if ((hratios_c * 2.0) > 4.0) ++ min_hratio_fact_c = 4.0; ++ else ++ min_hratio_fact_c = hratios_c * 2.0; ++ } else { ++ if (hratios_c > 4.0) ++ min_hratio_fact_c = 4.0; ++ else ++ min_hratio_fact_c = hratios_c; ++ } ++ ++ hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz; ++ ++ refcyc_per_line_delivery_pre_l = 0.; ++ refcyc_per_line_delivery_pre_c = 0.; ++ refcyc_per_line_delivery_l = 0.; ++ refcyc_per_line_delivery_c = 0.; ++ ++ refcyc_per_req_delivery_pre_l = 0.; ++ refcyc_per_req_delivery_pre_c = 0.; ++ refcyc_per_req_delivery_l = 0.; ++ refcyc_per_req_delivery_c = 0.; ++ refcyc_per_req_delivery_pre_cur0 = 0.; ++ refcyc_per_req_delivery_cur0 = 0.; ++ ++ full_recout_width = 0; ++ if (e2e_pipe_param.pipe.src.is_hsplit) { ++ if (e2e_pipe_param.pipe.dest.full_recout_width == 0) { ++ DTRACE("DLG: %s: Warningfull_recout_width not set in hsplit mode", __func__); ++ full_recout_width = e2e_pipe_param.pipe.dest.recout_width * 2; /* assume half split for dcn1 */ ++ } else ++ full_recout_width = e2e_pipe_param.pipe.dest.full_recout_width; ++ } else ++ full_recout_width = e2e_pipe_param.pipe.dest.recout_width; ++ ++ refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery( ++ mode_lib, ++ refclk_freq_in_mhz, ++ pclk_freq_in_mhz, ++ full_recout_width, ++ vratio_pre_l, ++ hscale_pixel_rate_l, ++ swath_width_pixels_ub_l, ++ 1); /* per line */ ++ ++ refcyc_per_line_delivery_l = get_refcyc_per_delivery( ++ mode_lib, ++ refclk_freq_in_mhz, ++ pclk_freq_in_mhz, ++ full_recout_width, ++ vratio_l, ++ hscale_pixel_rate_l, ++ swath_width_pixels_ub_l, ++ 1); /* per line */ ++ ++ DTRACE("DLG: %s: full_recout_width = %d", __func__, full_recout_width); ++ DTRACE("DLG: %s: hscale_pixel_rate_l = %3.2f", __func__, hscale_pixel_rate_l); ++ DTRACE( ++ "DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f", ++ __func__, ++ refcyc_per_line_delivery_pre_l); ++ DTRACE( ++ "DLG: %s: refcyc_per_line_delivery_l = %3.2f", ++ __func__, ++ refcyc_per_line_delivery_l); ++ ++ disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor( ++ refcyc_per_line_delivery_pre_l, ++ 1); ++ disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor( ++ refcyc_per_line_delivery_l, ++ 1); ++ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13)); ++ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13)); ++ ++ if (dual_plane) { ++ refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery( ++ mode_lib, ++ refclk_freq_in_mhz, ++ pclk_freq_in_mhz, ++ full_recout_width, ++ vratio_pre_c, ++ hscale_pixel_rate_c, ++ swath_width_pixels_ub_c, ++ 1); /* per line */ ++ ++ refcyc_per_line_delivery_c = get_refcyc_per_delivery( ++ mode_lib, ++ refclk_freq_in_mhz, ++ pclk_freq_in_mhz, ++ full_recout_width, ++ vratio_c, ++ hscale_pixel_rate_c, ++ swath_width_pixels_ub_c, ++ 1); /* per line */ ++ ++ DTRACE( ++ "DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f", ++ __func__, ++ refcyc_per_line_delivery_pre_c); ++ DTRACE( ++ "DLG: %s: refcyc_per_line_delivery_c = %3.2f", ++ __func__, ++ refcyc_per_line_delivery_c); ++ ++ disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor( ++ refcyc_per_line_delivery_pre_c, ++ 1); ++ disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor( ++ refcyc_per_line_delivery_c, ++ 1); ++ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13)); ++ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13)); ++ } ++ disp_dlg_regs->chunk_hdl_adjust_cur0 = 3; ++ ++ /* TTU - Luma / Chroma */ ++ if (access_dir) { /* vertical access */ ++ scaler_rec_in_width_l = vp_height_l; ++ scaler_rec_in_width_c = vp_height_c; ++ } else { ++ scaler_rec_in_width_l = vp_width_l; ++ scaler_rec_in_width_c = vp_width_c; ++ } ++ ++ refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery( ++ mode_lib, ++ refclk_freq_in_mhz, ++ pclk_freq_in_mhz, ++ full_recout_width, ++ vratio_pre_l, ++ hscale_pixel_rate_l, ++ scaler_rec_in_width_l, ++ req_per_swath_ub_l); /* per req */ ++ refcyc_per_req_delivery_l = get_refcyc_per_delivery( ++ mode_lib, ++ refclk_freq_in_mhz, ++ pclk_freq_in_mhz, ++ full_recout_width, ++ vratio_l, ++ hscale_pixel_rate_l, ++ scaler_rec_in_width_l, ++ req_per_swath_ub_l); /* per req */ ++ ++ DTRACE( ++ "DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f", ++ __func__, ++ refcyc_per_req_delivery_pre_l); ++ DTRACE( ++ "DLG: %s: refcyc_per_req_delivery_l = %3.2f", ++ __func__, ++ refcyc_per_req_delivery_l); ++ ++ disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l ++ * dml_pow(2, 10)); ++ disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l ++ * dml_pow(2, 10)); ++ ++ ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13)); ++ ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13)); ++ ++ if (dual_plane) { ++ refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery( ++ mode_lib, ++ refclk_freq_in_mhz, ++ pclk_freq_in_mhz, ++ full_recout_width, ++ vratio_pre_c, ++ hscale_pixel_rate_c, ++ scaler_rec_in_width_c, ++ req_per_swath_ub_c); /* per req */ ++ refcyc_per_req_delivery_c = get_refcyc_per_delivery( ++ mode_lib, ++ refclk_freq_in_mhz, ++ pclk_freq_in_mhz, ++ full_recout_width, ++ vratio_c, ++ hscale_pixel_rate_c, ++ scaler_rec_in_width_c, ++ req_per_swath_ub_c); /* per req */ ++ ++ DTRACE( ++ "DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f", ++ __func__, ++ refcyc_per_req_delivery_pre_c); ++ DTRACE( ++ "DLG: %s: refcyc_per_req_delivery_c = %3.2f", ++ __func__, ++ refcyc_per_req_delivery_c); ++ ++ disp_ttu_regs->refcyc_per_req_delivery_pre_c = ++ (unsigned int) (refcyc_per_req_delivery_pre_c * dml_pow(2, 10)); ++ disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c ++ * dml_pow(2, 10)); ++ ++ ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13)); ++ ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13)); ++ } ++ ++ /* TTU - Cursor */ ++ hratios_cur0 = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio; ++ cur0_src_width = e2e_pipe_param.pipe.src.cur0_src_width; /* cursor source width */ ++ cur0_bpp = (enum cursor_bpp) e2e_pipe_param.pipe.src.cur0_bpp; ++ cur0_req_size = 0; ++ cur0_req_width = 0; ++ cur0_width_ub = 0.0; ++ cur0_req_per_width = 0.0; ++ hactive_cur0 = 0.0; ++ ++ ASSERT(cur0_src_width <= 256); ++ ++ if (cur0_src_width > 0) { ++ unsigned int cur0_bit_per_pixel = 0; ++ ++ if (cur0_bpp == dm_cur_2bit) { ++ cur0_req_size = 64; /* byte */ ++ cur0_bit_per_pixel = 2; ++ } else { /* 32bit */ ++ cur0_bit_per_pixel = 32; ++ if (cur0_src_width >= 1 && cur0_src_width <= 16) ++ cur0_req_size = 64; ++ else if (cur0_src_width >= 17 && cur0_src_width <= 31) ++ cur0_req_size = 128; ++ else ++ cur0_req_size = 256; ++ } ++ ++ cur0_req_width = (double) cur0_req_size / ((double) cur0_bit_per_pixel / 8.0); ++ cur0_width_ub = dml_ceil((double) cur0_src_width / (double) cur0_req_width, 1) ++ * (double) cur0_req_width; ++ cur0_req_per_width = cur0_width_ub / (double) cur0_req_width; ++ hactive_cur0 = (double) cur0_src_width / hratios_cur0; /* FIXME: oswin to think about what to do for cursor */ ++ ++ if (vratio_pre_l <= 1.0) { ++ refcyc_per_req_delivery_pre_cur0 = hactive_cur0 * ref_freq_to_pix_freq ++ / (double) cur0_req_per_width; ++ } else { ++ refcyc_per_req_delivery_pre_cur0 = (double) refclk_freq_in_mhz ++ * (double) cur0_src_width / hscale_pixel_rate_l ++ / (double) cur0_req_per_width; ++ } ++ ++ disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = ++ (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10)); ++ ASSERT(refcyc_per_req_delivery_pre_cur0 < dml_pow(2, 13)); ++ ++ if (vratio_l <= 1.0) { ++ refcyc_per_req_delivery_cur0 = hactive_cur0 * ref_freq_to_pix_freq ++ / (double) cur0_req_per_width; ++ } else { ++ refcyc_per_req_delivery_cur0 = (double) refclk_freq_in_mhz ++ * (double) cur0_src_width / hscale_pixel_rate_l ++ / (double) cur0_req_per_width; ++ } ++ ++ DTRACE("DLG: %s: cur0_req_width = %d", __func__, cur0_req_width); ++ DTRACE( ++ "DLG: %s: cur0_width_ub = %3.2f", ++ __func__, ++ cur0_width_ub); ++ DTRACE( ++ "DLG: %s: cur0_req_per_width = %3.2f", ++ __func__, ++ cur0_req_per_width); ++ DTRACE( ++ "DLG: %s: hactive_cur0 = %3.2f", ++ __func__, ++ hactive_cur0); ++ DTRACE( ++ "DLG: %s: refcyc_per_req_delivery_pre_cur0 = %3.2f", ++ __func__, ++ refcyc_per_req_delivery_pre_cur0); ++ DTRACE( ++ "DLG: %s: refcyc_per_req_delivery_cur0 = %3.2f", ++ __func__, ++ refcyc_per_req_delivery_cur0); ++ ++ disp_ttu_regs->refcyc_per_req_delivery_cur0 = ++ (unsigned int) (refcyc_per_req_delivery_cur0 * dml_pow(2, 10)); ++ ASSERT(refcyc_per_req_delivery_cur0 < dml_pow(2, 13)); ++ } else { ++ disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = 0; ++ disp_ttu_regs->refcyc_per_req_delivery_cur0 = 0; ++ } ++ ++ /* TTU - Misc */ ++ disp_ttu_regs->qos_level_low_wm = 0; ++ ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14)); ++ disp_ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal ++ * ref_freq_to_pix_freq); ++ ASSERT(disp_ttu_regs->qos_level_high_wm < dml_pow(2, 14)); ++ ++ 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_level_fixed_cur0 = 8; ++ disp_ttu_regs->qos_ramp_disable_l = 0; ++ disp_ttu_regs->qos_ramp_disable_c = 0; ++ disp_ttu_regs->qos_ramp_disable_cur0 = 0; ++ ++ disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz; ++ ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24)); ++ ++ print__ttu_regs_st(mode_lib, *disp_ttu_regs); ++ print__dlg_regs_st(mode_lib, *disp_dlg_regs); ++} +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h +new file mode 100644 +index 0000000..987d767 +--- /dev/null ++++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h +@@ -0,0 +1,67 @@ ++/* ++ * 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. ++ * ++ * Authors: AMD ++ * ++ */ ++ ++#ifndef __DISPLAY_RQ_DLG_CALC_H__ ++#define __DISPLAY_RQ_DLG_CALC_H__ ++ ++#include "dml_common_defs.h" ++#include "display_rq_dlg_helpers.h" ++ ++struct display_mode_lib; ++ ++void dml1_extract_rq_regs( ++ struct display_mode_lib *mode_lib, ++ struct _vcs_dpi_display_rq_regs_st *rq_regs, ++ const struct _vcs_dpi_display_rq_params_st rq_param); ++/* Function: dml_rq_dlg_get_rq_params ++ * Calculate requestor related parameters that register definition agnostic ++ * (i.e. this layer does try to separate real values from register definition) ++ * Input: ++ * pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.) ++ * Output: ++ * rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.) ++ */ ++void dml1_rq_dlg_get_rq_params( ++ struct display_mode_lib *mode_lib, ++ struct _vcs_dpi_display_rq_params_st *rq_param, ++ const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param); ++ ++ ++/* Function: dml_rq_dlg_get_dlg_params ++ * Calculate deadline related parameters ++ */ ++void dml1_rq_dlg_get_dlg_params( ++ struct display_mode_lib *mode_lib, ++ struct _vcs_dpi_display_dlg_regs_st *dlg_regs, ++ struct _vcs_dpi_display_ttu_regs_st *ttu_regs, ++ const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, ++ const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, ++ const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, ++ const bool cstate_en, ++ const bool pstate_en, ++ const bool vm_en, ++ const bool iflip_en); ++ ++#endif +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c +index 21349a02..9cbd415 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c +@@ -36,21 +36,21 @@ double dml_max(double a, double b) + return (double) dcn_bw_max2(a, b); + } + +-double dml_ceil(double a) ++double dml_ceil(double a, double granularity) + { +- return (double) dcn_bw_ceil2(a, 1); ++ return (double) dcn_bw_ceil2(a, granularity); + } + +-double dml_floor(double a) ++double dml_floor(double a, double granularity) + { +- return (double) dcn_bw_floor2(a, 1); ++ return (double) dcn_bw_floor2(a, granularity); + } + + double dml_round(double a) + { + double round_pt = 0.5; +- double ceil = dml_ceil(a); +- double floor = dml_floor(a); ++ double ceil = dml_ceil(a, 1); ++ double floor = dml_floor(a, 1); + + if (a - floor >= round_pt) + return ceil; +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h +index c5340d4..19271e7 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h ++++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h +@@ -22,6 +22,7 @@ + * Authors: AMD + * + */ ++ + #ifndef __DC_COMMON_DEFS_H__ + #define __DC_COMMON_DEFS_H__ + +@@ -30,7 +31,8 @@ + #include "display_mode_structs.h" + #include "display_mode_enums.h" + +-#define DTRACE(str, ...) dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); ++#define dml_print(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); } ++#define DTRACE(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); } + + double dml_min(double a, double b); + double dml_max(double a, double b); +@@ -38,8 +40,8 @@ bool dml_util_is_420(enum source_format_class sorce_format); + double dml_ceil_ex(double x, double granularity); + double dml_floor_ex(double x, double granularity); + double dml_log(double x, double base); +-double dml_ceil(double a); +-double dml_floor(double a); ++double dml_ceil(double a, double granularity); ++double dml_floor(double a, double granularity); + double dml_round(double a); + int dml_log2(double x); + double dml_pow(double a, int exp); +diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c +index 112b0b72..8b85125 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c +@@ -24,49 +24,45 @@ + */ + #include "soc_bounding_box.h" + #include "display_mode_lib.h" ++#include "dc_features.h" + +-void dml_socbb_set_latencies( +- struct display_mode_lib *mode_lib, +- struct _vcs_dpi_soc_bounding_box_st *from_box) ++void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box) + { +- struct _vcs_dpi_soc_bounding_box_st *to_box = &mode_lib->soc; +- + to_box->dram_clock_change_latency_us = from_box->dram_clock_change_latency_us; + to_box->sr_exit_time_us = from_box->sr_exit_time_us; + to_box->sr_enter_plus_exit_time_us = from_box->sr_enter_plus_exit_time_us; + to_box->urgent_latency_us = from_box->urgent_latency_us; + to_box->writeback_latency_us = from_box->writeback_latency_us; +- DTRACE("box.dram_clock_change_latency_us: %f", from_box->dram_clock_change_latency_us); +- DTRACE("box.sr_exit_time_us: %f", from_box->sr_exit_time_us); +- DTRACE("box.sr_enter_plus_exit_time_us: %f", from_box->sr_enter_plus_exit_time_us); +- DTRACE("box.urgent_latency_us: %f", from_box->urgent_latency_us); +- DTRACE("box.writeback_latency_us: %f", from_box->writeback_latency_us); +- + } + +-struct _vcs_dpi_voltage_scaling_st dml_socbb_voltage_scaling( +- struct _vcs_dpi_soc_bounding_box_st *box, ++voltage_scaling_st dml_socbb_voltage_scaling( ++ const soc_bounding_box_st *soc, + enum voltage_state voltage) + { +- switch (voltage) { +- case dm_vmin: +- return box->vmin; +- case dm_vnom: +- return box->vnom; +- case dm_vmax: +- default: +- return box->vmax; ++ const voltage_scaling_st *voltage_state; ++ const voltage_scaling_st * const voltage_end = soc->clock_limits + DC__VOLTAGE_STATES; ++ ++ for (voltage_state = soc->clock_limits; ++ voltage_state < voltage_end && voltage_state->state != voltage; ++ voltage_state++) { + } ++ ++ if (voltage_state < voltage_end) ++ return *voltage_state; ++ return soc->clock_limits[DC__VOLTAGE_STATES - 1]; + } + +-double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage) ++double dml_socbb_return_bw_mhz(soc_bounding_box_st *box, enum voltage_state voltage) + { + double return_bw; + +- struct _vcs_dpi_voltage_scaling_st state = dml_socbb_voltage_scaling(box, voltage); ++ voltage_scaling_st state = dml_socbb_voltage_scaling(box, voltage); ++ ++ return_bw = dml_min((double) box->return_bus_width_bytes * state.dcfclk_mhz, ++ state.dram_bw_per_chan_gbps * 1000.0 * (double) box->num_chans ++ * box->ideal_dram_bw_after_urgent_percent / 100.0); ++ ++ return_bw = dml_min((double) box->return_bus_width_bytes * state.fabricclk_mhz, return_bw); + +- return_bw = dml_min( +- ((double) box->return_bus_width_bytes) * state.dcfclk_mhz, +- state.dram_bw_per_chan_gbps * 1000.0 * box->ideal_dram_bw_after_urgent_percent / 100.0); + return return_bw; + } +diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h +index 7bbae33..7a65206 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h ++++ b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h +@@ -22,15 +22,14 @@ + * Authors: AMD + * + */ ++ + #ifndef __SOC_BOUNDING_BOX_H__ + #define __SOC_BOUNDING_BOX_H__ + + #include "dml_common_defs.h" + +-struct display_mode_lib; +- +-void dml_socbb_set_latencies(struct display_mode_lib *mode_lib, struct _vcs_dpi_soc_bounding_box_st *from_box); +-struct _vcs_dpi_voltage_scaling_st dml_socbb_voltage_scaling(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage); +-double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage); ++void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box); ++voltage_scaling_st dml_socbb_voltage_scaling(const soc_bounding_box_st *box, enum voltage_state voltage); ++double dml_socbb_return_bw_mhz(soc_bounding_box_st *box, enum voltage_state voltage); + + #endif +-- +2.7.4 + |