Commit 6d04ee9d authored by Dmytro Laktyushkin's avatar Dmytro Laktyushkin Committed by Alex Deucher

drm/amd/display: Restructuring and cleaning up DML

Signed-off-by: default avatarDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <Harry.Wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 19b7fe4a
......@@ -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;
}
......
......@@ -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) {
......
......@@ -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;
......
......@@ -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)
......
......@@ -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))
......
......@@ -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
......
......@@ -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
......@@ -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 */
}
}
void dml_init_instance(struct display_mode_lib *lib, enum dml_project project)
......
......@@ -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;
};
......
......@@ -25,13 +25,55 @@
#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 {
......@@ -49,6 +91,10 @@ struct _vcs_dpi_soc_bounding_box_st {
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;
......@@ -58,12 +104,19 @@ struct _vcs_dpi_soc_bounding_box_st {
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;
......@@ -73,10 +126,10 @@ struct _vcs_dpi_ip_params_st {
unsigned int writeback_chunk_size_kbytes;
unsigned int line_buffer_size_bits;
unsigned int max_line_buffer_lines;
unsigned int IsLineBufferBppFixed;
unsigned int LineBufferFixedBpp;
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;
......@@ -89,28 +142,54 @@ struct _vcs_dpi_ip_params_st {
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 max_inter_dcn_tile_repeaters;
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 can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one;
unsigned int bug_forcing_LC_req_same_size_fixed;
};
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;
......@@ -119,15 +198,41 @@ struct _vcs_dpi_display_pipe_source_params_st {
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 {
......@@ -145,6 +250,7 @@ struct _vcs_dpi_scaler_ratio_depth_st {
double vinit_bot;
double vinit_bot_c;
int lb_depth;
int scl_enable;
};
struct _vcs_dpi_scaler_taps_st {
......@@ -166,22 +272,25 @@ struct _vcs_dpi_display_pipe_dest_params_st {
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 int vsync_plus_back_porch;
unsigned char interlaced;
unsigned char underscan;
double pixel_rate_mhz;
unsigned char syncronized_vblank_all_planes;
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 {
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;
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 {
......@@ -194,9 +303,9 @@ struct _vcs_dpi_display_clocks_and_cfg_st {
};
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;
display_pipe_params_st pipe;
display_output_params_st dout;
display_clocks_and_cfg_st clks_cfg;
};
struct _vcs_dpi_dchub_buffer_sizing_st {
......@@ -298,27 +407,27 @@ struct _vcs_dpi_display_cur_rq_dlg_params_st {
};
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;
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 {
struct _vcs_dpi_display_data_rq_sizing_params_st rq_l;
struct _vcs_dpi_display_data_rq_sizing_params_st rq_c;
display_data_rq_sizing_params_st rq_l;
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;
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;
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;
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 {
......@@ -331,6 +440,8 @@ struct _vcs_dpi_display_dlg_regs_st {
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;
......@@ -338,6 +449,10 @@ struct _vcs_dpi_display_dlg_regs_st {
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;
......@@ -351,6 +466,15 @@ struct _vcs_dpi_display_dlg_regs_st {
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 {
......@@ -361,15 +485,19 @@ struct _vcs_dpi_display_ttu_regs_st {
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 {
......@@ -384,8 +512,8 @@ struct _vcs_dpi_display_data_rq_regs_st {
};
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;
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;
......@@ -398,6 +526,7 @@ struct _vcs_dpi_display_dlg_sys_params_st {
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;
......@@ -412,8 +541,9 @@ struct _vcs_dpi_display_dlg_prefetch_param_st {
struct _vcs_dpi_display_pipe_clock_st {
double dcfclk_mhz;
double dispclk_mhz;
double dppclk_mhz[4];
unsigned char dppclk_div[4];
double socclk_mhz;
double dscclk_mhz[6];
double dppclk_mhz[6];
};
struct _vcs_dpi_display_arb_params_st {
......@@ -422,8 +552,4 @@ struct _vcs_dpi_display_arb_params_st {
int sat_level_us;
};
struct _vcs_dpi_mode_evaluation_st {
int voltage_override;
};
#endif /*__DISPLAY_MODE_STRUCTS_H__*/
/*
* 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);
}
/*
* 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
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* 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_ */
......@@ -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)
display_e2e_pipe_params_st *e2e,
unsigned int num_pipes)
{
enum voltage_state state1;
enum voltage_state state2;
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;
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;
DTRACE("Calculating pipe clocks...");
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;
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;
if (state1 > state2)
return state1;
else
return state2;
}
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(" socclk: %f Mhz", clocks.socclk_mhz);
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 (k = 0; k < num_pipes; ++k)
visited[k] = false;
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;
}
clocks.dppclk_mhz[i] = get_dppclk_calculated(mode_lib, e2e, num_pipes, i);
DTRACE(" dppclk%d: %f Mhz", i, clocks.dppclk_mhz[i]);
dispclk_ramp_margin_percent = mode_lib->ip.dispclk_ramp_margin_percent;
if (e2e[i].pipe.src.is_hsplit && !visited[i]) {
unsigned int grp = e2e[i].pipe.src.hsplit_grp;
/* 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(
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,
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;
dsc_inst);
DTRACE(" dscclk%d: %f Mhz", j, clocks.dscclk_mhz[j]);
visited[j] = true;
}
}
DTRACE("p%d: dispclk: %f", i, dispclks[i]);
dsc_inst++;
}
}
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 */
}
}
if (!visited[i]) {
unsigned int otg_inst = e2e[i].pipe.dest.otg_inst;
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);
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;
}
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;
dsc_inst++;
}
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,
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;
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;
clocks.dcfclk_mhz = dcfclk;
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]);
}
clocks.dispclk_mhz = max_dispclk;
DTRACE("dispclk: %f Mhz", clocks.dispclk_mhz);
DTRACE("dcfclk: %f Mhz", clocks.dcfclk_mhz);
for (i = 0; i < num_pipes; i++) {
if (dppclks[i] * 2 < max_dispclk)
dppdiv[i] = 1;
if (dppdiv[i])
clocks.dppclk_div[i] = 1;
else
clocks.dppclk_div[i] = 0;
clocks.dppclk_mhz[i] = max_dispclk / ((dppdiv[i]) ? 2.0 : 1.0);
DTRACE("dppclk%d: %f Mhz", i, clocks.dppclk_mhz[i]);
}
return clocks;
......
......@@ -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
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -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
......@@ -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");
}
......@@ -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
/*
* 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;
}
/*
* 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);
}
......@@ -22,77 +22,46 @@
* Authors: AMD
*
*/
#ifndef __DISPLAY_WATERMARK_H__
#define __DISPLAY_WATERMARK_H__
#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;
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(
void dml1_extract_rq_regs(
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 _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_e2e_pipe_params_st *e2e,
unsigned int num_pipes);
struct _vcs_dpi_display_rq_params_st *rq_param,
const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param);
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(
/* 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_wm_calc_pipe_params_st *planes,
unsigned int num_planes);
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
......@@ -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;
......
......@@ -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);
......
......@@ -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;
}
......@@ -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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment